Changeset 1496 for trunk


Ignore:
Timestamp:
Nov 10, 2015, 2:36:29 PM (10 years ago)
Author:
flefevre
Message:

Optimisation du solveur chimique ASIS

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.MARS/libf/aeronomars/photochemistry_asis.F90

    r1495 r1496  
    9999real (kind = 8), dimension(nesp)        :: cnew ! number densities at next timestep (molecule.cm-3)
    100100 
    101 !real (kind = 8), dimension(ngridmx,nlayer,nesp), save :: cold3d ! cold saved from previous timestep
    102 !real (kind = 8), dimension(ngridmx,nlayer), save      :: dt3d   ! saved timestep
    103 
    104101! reaction rates
    105102 
     
    111108! matrix
    112109
    113 real (kind = 8), dimension(nesp,nesp) :: mat
     110real (kind = 8), dimension(nesp,nesp) :: mat, mat1
    114111integer, dimension(nesp)              :: indx
    115112integer                               :: code
     113
     114! production and loss terms (for first-guess solution only)
     115
     116real (kind = 8), dimension(nesp) :: prod, loss
    116117
    117118! curvatures
     
    128129               i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
    129130               i_n, i_n2d, i_no, i_no2, i_n2)
    130 !  dt3d(:,:) = 600.
    131131   firstcall = .false.
    132132end if
     
    199199   dt_guess = ctimestep
    200200   cold(:) = c(ilev,:)
    201 !  dt_guess = dt3d(ig,ilev)
    202 !  cold(:) = cold3d(ig,ilev,:)
    203201
    204202!  internal loop for the chemistry
     
    206204   do while (time < ptimestep)
    207205
    208    iter(ilev) = iter(ilev) + 1
     206   iter(ilev) = iter(ilev) + 1    ! iteration counter
    209207 
    210208!  first-guess: fill matrix
    211209
    212    call fill_matrix(ilev, nesp, c, nlayer, v_phot, v_3, v_4, dt_guess, mat)
     210   call fill_matrix(ilev, mat1, prod, loss, c, nesp, nlayer, v_phot, v_3, v_4)
     211
     212! first guess : form the matrix identity + mat*dt_guess
     213
     214   mat(:,:) = mat1(:,:)*dt_guess
     215   do iesp = 1,nesp
     216      mat(iesp,iesp) = 1. + mat(iesp,iesp)
     217   end do
    213218
    214219!  first-guess: solve linear system
     
    266271
    267272   if (time + dt_corrected > ptimestep) then
    268 !     dt3d(ig,ilev) = dt_corrected
    269273      dt_corrected = ptimestep - time
    270274   end if
     
    272276   if (dt_corrected /= dt_guess) then  ! the timestep has been modified
    273277
    274 !  fill matrix
    275 
    276       call fill_matrix(ilev, nesp, c, nlayer, v_phot, v_3, v_4, dt_corrected, mat)
     278!  form the matrix identity + mat*dt_guess
     279
     280      mat(:,:) = mat1(:,:)*dt_corrected
     281      do iesp = 1,nesp
     282         mat(iesp,iesp) = 1. + mat(iesp,iesp)
     283      end do
    277284
    278285!  solve linear system
     
    956963!======================================================================
    957964
    958  subroutine fill_matrix(ilev, nesp, c, nlayer, v_phot, v_3, v_4,  &
    959                         dtx, mat)
     965 subroutine fill_matrix(ilev, mat, prod, loss, c, nesp, nlayer, v_phot, v_3, v_4)
    960966
    961967!======================================================================
     
    974980integer             :: nesp    ! number of species in the chemistry
    975981integer, intent(in) :: nlayer  ! number of atmospheric layers
    976 
    977 real                :: dtx     ! timestep (s)
    978 real(kind = jprb)   :: eps, eps_4  ! implicit/explicit coefficient
    979982
    980983real (kind = 8), dimension(nlayer,nesp)              :: c    ! number densities
     
    985988! output
    986989
    987 real (kind = 8), dimension(nesp,nesp)     :: mat  ! matrix
     990real (kind = 8), dimension(nesp,nesp), intent(out) :: mat  ! matrix
     991real (kind = 8), dimension(nesp), intent(out)      :: prod, loss
    988992
    989993! local
     
    995999integer :: iphot,i3,i4
    9961000
    997 ! initialisation
     1001real(kind = jprb) :: eps, eps_4  ! implicit/explicit coefficient
     1002
     1003! initialisations
    9981004
    9991005mat(:,:) = 0.
    1000 do iesp = 1,nesp
    1001    mat(iesp,iesp) = 1.
    1002 end do 
     1006prod(:)  = 0.
     1007loss(:)  = 0.
    10031008
    10041009! photodissociations
     
    10121017  ind_phot_6 = indice_phot(iphot)%z6
    10131018
    1014   mat(ind_phot_2,ind_phot_2) = mat(ind_phot_2,ind_phot_2) + indice_phot(iphot)%z1*v_phot(ilev,iphot)*dtx
    1015   mat(ind_phot_4,ind_phot_2) = mat(ind_phot_4,ind_phot_2) - indice_phot(iphot)%z3*v_phot(ilev,iphot)*dtx
    1016   mat(ind_phot_6,ind_phot_2) = mat(ind_phot_6,ind_phot_2) - indice_phot(iphot)%z5*v_phot(ilev,iphot)*dtx
     1019  mat(ind_phot_2,ind_phot_2) = mat(ind_phot_2,ind_phot_2) + indice_phot(iphot)%z1*v_phot(ilev,iphot)
     1020  mat(ind_phot_4,ind_phot_2) = mat(ind_phot_4,ind_phot_2) - indice_phot(iphot)%z3*v_phot(ilev,iphot)
     1021  mat(ind_phot_6,ind_phot_2) = mat(ind_phot_6,ind_phot_2) - indice_phot(iphot)%z5*v_phot(ilev,iphot)
     1022
     1023  loss(ind_phot_2) = loss(ind_phot_2) + indice_phot(iphot)%z1*v_phot(ilev,iphot)
     1024  prod(ind_phot_4) = prod(ind_phot_4) + indice_phot(iphot)%z3*v_phot(ilev,iphot)*c(ilev,ind_phot_2)
     1025  prod(ind_phot_6) = prod(ind_phot_6) + indice_phot(iphot)%z5*v_phot(ilev,iphot)*c(ilev,ind_phot_2)
    10171026
    10181027end do
     
    10261035  ind_3_6 = indice_3(i3)%z6
    10271036
    1028   mat(ind_3_2,ind_3_2) = mat(ind_3_2,ind_3_2) + indice_3(i3)%z1*v_3(ilev,i3)*c(ilev,ind_3_2)*dtx
    1029   mat(ind_3_4,ind_3_2) = mat(ind_3_4,ind_3_2) - indice_3(i3)%z3*v_3(ilev,i3)*c(ilev,ind_3_2)*dtx
    1030   mat(ind_3_6,ind_3_2) = mat(ind_3_6,ind_3_2) - indice_3(i3)%z5*v_3(ilev,i3)*c(ilev,ind_3_2)*dtx
     1037  mat(ind_3_2,ind_3_2) = mat(ind_3_2,ind_3_2) + indice_3(i3)%z1*v_3(ilev,i3)*c(ilev,ind_3_2)
     1038  mat(ind_3_4,ind_3_2) = mat(ind_3_4,ind_3_2) - indice_3(i3)%z3*v_3(ilev,i3)*c(ilev,ind_3_2)
     1039  mat(ind_3_6,ind_3_2) = mat(ind_3_6,ind_3_2) - indice_3(i3)%z5*v_3(ilev,i3)*c(ilev,ind_3_2)
     1040
     1041  loss(ind_3_2) = loss(ind_3_2) + indice_3(i3)%z1*v_3(ilev,i3)*c(ilev,ind_3_2)
     1042  prod(ind_3_4) = prod(ind_3_4) + indice_3(i3)%z3*v_3(ilev,i3)*c(ilev,ind_3_2)*c(ilev,ind_3_2)
     1043  prod(ind_3_6) = prod(ind_3_6) + indice_3(i3)%z5*v_3(ilev,i3)*c(ilev,ind_3_2)*c(ilev,ind_3_2)
    10311044
    10321045end do
     
    10461059  eps_4 = min(eps_4,1.0_jprb)
    10471060
    1048   mat(ind_4_2,ind_4_2) = mat(ind_4_2,ind_4_2) + indice_4(i4)%z1*v_4(ilev,i4)*dtx*(1. - eps_4)*c(ilev,ind_4_4)
    1049   mat(ind_4_2,ind_4_4) = mat(ind_4_2,ind_4_4) + indice_4(i4)%z1*v_4(ilev,i4)*dtx*eps_4*c(ilev,ind_4_2)
    1050   mat(ind_4_4,ind_4_2) = mat(ind_4_4,ind_4_2) + indice_4(i4)%z3*v_4(ilev,i4)*dtx*(1. - eps_4)*c(ilev,ind_4_4)
    1051   mat(ind_4_4,ind_4_4) = mat(ind_4_4,ind_4_4) + indice_4(i4)%z3*v_4(ilev,i4)*dtx*eps_4*c(ilev,ind_4_2)   
    1052   mat(ind_4_6,ind_4_2) = mat(ind_4_6,ind_4_2) - indice_4(i4)%z5*v_4(ilev,i4)*dtx*(1. - eps_4)*c(ilev,ind_4_4)
    1053   mat(ind_4_6,ind_4_4) = mat(ind_4_6,ind_4_4) - indice_4(i4)%z5*v_4(ilev,i4)*dtx*eps_4*c(ilev,ind_4_2)
    1054   mat(ind_4_8,ind_4_2) = mat(ind_4_8,ind_4_2) - indice_4(i4)%z7*v_4(ilev,i4)*dtx*(1. - eps_4)*c(ilev,ind_4_4)
    1055   mat(ind_4_8,ind_4_4) = mat(ind_4_8,ind_4_4) - indice_4(i4)%z7*v_4(ilev,i4)*dtx*eps_4*c(ilev,ind_4_2)
     1061  mat(ind_4_2,ind_4_2) = mat(ind_4_2,ind_4_2) + indice_4(i4)%z1*v_4(ilev,i4)*(1. - eps_4)*c(ilev,ind_4_4)
     1062  mat(ind_4_2,ind_4_4) = mat(ind_4_2,ind_4_4) + indice_4(i4)%z1*v_4(ilev,i4)*eps_4*c(ilev,ind_4_2)
     1063  mat(ind_4_4,ind_4_2) = mat(ind_4_4,ind_4_2) + indice_4(i4)%z3*v_4(ilev,i4)*(1. - eps_4)*c(ilev,ind_4_4)
     1064  mat(ind_4_4,ind_4_4) = mat(ind_4_4,ind_4_4) + indice_4(i4)%z3*v_4(ilev,i4)*eps_4*c(ilev,ind_4_2)   
     1065  mat(ind_4_6,ind_4_2) = mat(ind_4_6,ind_4_2) - indice_4(i4)%z5*v_4(ilev,i4)*(1. - eps_4)*c(ilev,ind_4_4)
     1066  mat(ind_4_6,ind_4_4) = mat(ind_4_6,ind_4_4) - indice_4(i4)%z5*v_4(ilev,i4)*eps_4*c(ilev,ind_4_2)
     1067  mat(ind_4_8,ind_4_2) = mat(ind_4_8,ind_4_2) - indice_4(i4)%z7*v_4(ilev,i4)*(1. - eps_4)*c(ilev,ind_4_4)
     1068  mat(ind_4_8,ind_4_4) = mat(ind_4_8,ind_4_4) - indice_4(i4)%z7*v_4(ilev,i4)*eps_4*c(ilev,ind_4_2)
     1069
     1070  loss(ind_4_2) = loss(ind_4_2) + indice_4(i4)%z1*v_4(ilev,i4)*c(ilev,ind_4_4)
     1071  loss(ind_4_4) = loss(ind_4_4) + indice_4(i4)%z3*v_4(ilev,i4)*c(ilev,ind_4_2)
     1072  prod(ind_4_6) = prod(ind_4_6) + indice_4(i4)%z5*v_4(ilev,i4)*c(ilev,ind_4_2)*c(ilev,ind_4_4)
     1073  prod(ind_4_8) = prod(ind_4_8) + indice_4(i4)%z7*v_4(ilev,i4)*c(ilev,ind_4_2)*c(ilev,ind_4_4)
    10561074
    10571075end do
Note: See TracChangeset for help on using the changeset viewer.