Ignore:
Timestamp:
Oct 24, 2017, 1:20:18 PM (7 years ago)
Author:
bclmd
Message:

Updating photochemical core for the early Earth

Location:
trunk/LMDZ.GENERIC/libf/aeronostd/chemistry_early_earth
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.GENERIC/libf/aeronostd/chemistry_early_earth/calchim_asis_early_earth.F90

    r1796 r1810  
    7070!=======================================================================
    7171
    72 #include "chimiedata.h"
     72#include "chimiedata_early_earth.h"
    7373
    7474!     input:
     
    159159 
    160160      logical,save :: firstcall = .true.
    161       logical,save :: depos = .true.  ! switch for dry deposition
     161      logical,save :: depos = .false.  ! switch for dry deposition
    162162
    163163!     for each column of atmosphere:
     
    543543!           search for switch index between regions
    544544
    545             if (photochem .and. thermochem) then
    546                if (foundswitch == 0 .and. pplay(ig,l) < 1.e-1) then
    547                   lswitch = l
    548                   foundswitch = 1
    549                end if
    550             end if
     545!            if (photochem .and. thermochem) then
     546!               if (foundswitch == 0 .and. pplay(ig,l) < 1.e-1) then
     547!                  lswitch = l
     548!                  foundswitch = 1
     549!               end if
     550!            end if
    551551            if (.not. photochem) then
    552552               lswitch = 22
    553553            end if
    554             if (.not. thermochem) then
     554!            if (.not. thermochem) then
    555555               lswitch = min(50,nlayer+1)
    556             end if
     556!            end if
    557557
    558558         end do ! of do l=1,nlayer
  • trunk/LMDZ.GENERIC/libf/aeronostd/chemistry_early_earth/chimiedata_early_earth.h

    r1796 r1810  
    1919      real, parameter :: kb = 1.3806e-23
    2020
    21       common/chimiedata/jphot,colairtab,table_ozo
     21      common/chimiedata_early_earth/jphot,colairtab,table_ozo
    2222
    2323      real jphot(ntemp,nsza,nz,nozo,ntau,nch4,nd)
  • trunk/LMDZ.GENERIC/libf/aeronostd/chemistry_early_earth/photochemistry_asis_early_earth.F90

    r1796 r1810  
    1919implicit none
    2020
    21 #include "chimiedata.h"
     21#include "chimiedata_early_earth.h"
    2222
    2323!===================================================================
     
    178178!===================================================================
    179179
    180 call photolysis_asis(nlayer, ngrid, lswitch, press, temp, sza, fractcol,tau, zmmean, dist_sol, &
     180call photolysis_asis_early_earth(nlayer, ngrid, lswitch, press, temp, sza, fractcol,tau, zmmean, dist_sol, &
    181181                     rm(:,i_co2), rm(:,i_o3), rm(:,i_ch4), v_phot)
    182182
     
    249249   call fill_matrix(ilev, mat1, prod, loss, c, nesp, nlayer, v_phot, v_3, v_4)
    250250
    251 ! first guess : form the matrix identity + mat*dt_guess
    252 
    253    mat(:,:) = mat1(:,:)*dt_guess
     251!  adaptative evaluation of the sub time step
     252
     253   call define_dt(nesp, dt_corrected, dt_guess, ctimestep, cold(:), c(ilev,:),  &
     254                  mat1, prod, loss, dens(ilev))
     255
     256   if (time + dt_corrected > ptimestep) then
     257      dt_corrected = ptimestep - time
     258   end if
     259
     260!  if (dt_corrected /= dt_guess) then  ! the timestep has been modified
     261
     262!  form the matrix identity + mat*dt_corrected
     263
     264   mat(:,:) = mat1(:,:)*dt_corrected
    254265   do iesp = 1,nesp
    255266      mat(iesp,iesp) = 1. + mat(iesp,iesp)
    256267   end do
    257268
    258 first-guess: solve linear system
    259      
     269solve the linear system  M*Cn+1 = Cn (RHS in cnew, then replaced by solution)
     270
    260271   cnew(:) = c(ilev,:)
    261272
    262 !#ifdef LAPACK
     273#ifdef LAPACK
    263274   call dgesv(nesp,1,mat,nesp,indx,cnew,nesp,code)
    264 !#else
    265 !   write(*,*) "photochemistry_asis error, missing LAPACK routine dgesv"
    266 !   stop
    267 !#endif
     275#else
     276#   write(*,*) "photochemistry_asis error, missing LAPACK routine dgesv"
     277#   stop
     278#endif
     279
     280!  end if
     281
    268282!  eliminate small values
    269283
     
    272286   end where
    273287
    274 !  curvature of the solution and weighted error norm for O
    275 !
    276 !  cold : concentrations at time t - dt
    277 !  c    : concentrations at time t
    278 !  cnew : concentrations guessed at time t + dt
    279 
    280 !  ratio = dtold/dtnew
    281 !  here ratio = 1 since the timestep for the guess is equal to the previous timestep
    282 
    283    ratio = 1.
    284 
    285    curv = 2.*(ratio*cnew(i_o) - (1. + ratio)*c(ilev,i_o) + cold(i_o)) &
    286           /(ratio*(1. + ratio))
    287    e1 = (curv/(cnew(i_o) + cnew(i_o3)))*100.
    288    e1 = abs(e1)
    289 
    290 !  curvature of the solution and weighted error norm for HO2
    291 
    292    curv = 2.*(ratio*cnew(i_ho2) - (1. + ratio)*c(ilev,i_ho2) + cold(i_ho2)) &
    293           /(ratio*(1. + ratio))
    294    e2 = (curv/(cnew(i_h) + cnew(i_oh) + cnew(i_ho2) + 2.*cnew(i_h2o2)))*100.
    295    e2 = abs(e2)
    296 
    297 !  curvature of the solution and weighted error norm for NO2
    298 
    299 !  curv = 2.*(ratio*cnew(i_no2) - (1. + ratio)*c(ilev,i_no2) + cold(i_no2)) &
    300 !         /(ratio*(1. + ratio))
    301 !  e3 = (curv/(cnew(i_no) + cnew(i_no2)))*100.
    302 !  e3 = abs(e3)
    303    e3 = 0.
    304 
    305 !  timestep correction
    306 
    307    e = max(e1, e2)
    308    e = max(e,  e3)
    309    e = max(e, 0.1)
    310    dtg = max(0.001, min(2.5,0.8/sqrt(e)))
    311 !  dtg = 1.                                     ! uncomment this line to turn off the variable timestep scheme
    312    dt_corrected = max(dt_min,dtg*dt_guess)      ! minimal timestep: dt_min
    313    dt_corrected = min(dt_corrected,ctimestep)   ! maximal timestep: ctimestep
    314 
    315    if (time + dt_corrected > ptimestep) then
    316       dt_corrected = ptimestep - time
    317    end if
    318 
    319    if (dt_corrected /= dt_guess) then  ! the timestep has been modified
    320 
    321 !  form the matrix identity + mat*dt_corrected
    322 
    323       mat(:,:) = mat1(:,:)*dt_corrected
    324       do iesp = 1,nesp
    325          mat(iesp,iesp) = 1. + mat(iesp,iesp)
    326       end do
    327 
    328 !  solve linear system
    329      
    330       cnew(:) = c(ilev,:)
    331 
    332 !#ifdef LAPACK
    333       call dgesv(nesp,1,mat,nesp,indx,cnew,nesp,code)
    334 !#else
    335 !   write(*,*) "photochemistry_asis error, missing LAPACK routine dgesv"
    336 !   stop
    337 !#endif
    338    end if
    339 
    340 !  eliminate small values
    341 
    342    where (cnew(:)/dens(ilev) < 1.e-30)
    343       cnew(:) = 0.
    344    end where
     288!  update concentrations
    345289
    346290   cold(:)   = c(ilev,:)
     
    356300
    357301end do ! ilev
     302
     303
     304
    358305
    359306!===================================================================
     
    370317
    371318contains
     319
     320!================================================================
     321
     322 subroutine define_dt(nesp, dtnew, dtold, ctimestep, cold, ccur, mat1, &
     323                      prod, loss, dens)
     324
     325!================================================================
     326! iterative evaluation of the appropriate time step dtnew
     327! according to curvature criterion based on
     328! e = 2 Rtol [r Cn+1 -(1-r) Cn + Cn-1 ]/[(1+r) Cn]
     329! with r = (tn - tn-1)/(tn+1 - tn)
     330!================================================================
     331
     332implicit none
     333
     334! input
     335
     336integer :: nesp  ! number of species in the chemistry
     337
     338real :: dtold, ctimestep
     339real (kind = 8), dimension(nesp)      :: cold, ccur
     340real (kind = 8), dimension(nesp,nesp) :: mat1
     341real (kind = 8), dimension(nesp)      :: prod, loss
     342real                                  :: dens
     343
     344! output
     345
     346real :: dtnew
     347
     348! local
     349
     350real (kind = 8), dimension(nesp)      :: cnew
     351real (kind = 8), dimension(nesp,nesp) :: mat
     352real (kind = 8) :: atol, ratio, e, es, coef
     353
     354integer                  :: code, iesp, iter
     355integer, dimension(nesp) :: indx
     356
     357real :: dttest
     358
     359! parameters
     360
     361real (kind = 8), parameter :: dtmin   = 10.      ! minimum time step (s)
     362real (kind = 8), parameter :: vmrtol  = 1.e-11   ! absolute tolerance on vmr
     363real (kind = 8), parameter :: rtol    = 1./0.05   ! 1/rtol recommended value : 0.1-0.02
     364integer,         parameter :: niter   = 3        ! number of iterations
     365real (kind = 8), parameter :: coefmax = 2.
     366real (kind = 8), parameter :: coefmin = 0.1
     367logical                    :: fast_guess = .true.
     368
     369dttest = dtold   ! dttest = dtold = dt_guess
     370
     371atol = vmrtol*dens ! absolute tolerance in molecule.cm-3
     372
     373do iter = 1,niter
     374
     375if (fast_guess) then
     376
     377! first guess : fast semi-implicit method
     378
     379   do iesp = 1, nesp
     380      cnew(iesp) = (ccur(iesp) + prod(iesp)*dttest)/(1. + loss(iesp)*dttest)
     381   end do
     382
     383else
     384
     385! first guess : form the matrix identity + mat*dt_guess
     386
     387   mat(:,:) = mat1(:,:)*dttest
     388   do iesp = 1,nesp
     389      mat(iesp,iesp) = 1. + mat(iesp,iesp)
     390   end do
     391
     392! form right-hand side (RHS) of the system
     393
     394   cnew(:) = ccur(:)
     395
     396! solve the linear system  M*Cn+1 = Cn (RHS in cnew, then replaced by solution)
     397
     398#ifdef LAPACK
     399      call dgesv(nesp,1,mat,nesp,indx,cnew,nesp,code)
     400#else
     401   write(*,*) "photochemistry_asis error, missing LAPACK routine dgesv"
     402   stop
     403#endif
     404
     405end if
     406
     407! ratio old/new subtimestep
     408
     409ratio = dtold/dttest
     410
     411! e : local error indicatocitr
     412
     413e = 0.
     414
     415do iesp = 1,nesp
     416   es = 2.*abs((ratio*cnew(iesp) - (1. + ratio)*ccur(iesp) + cold(iesp))   &
     417         /(1. + ratio)/max(ccur(iesp),atol))
     418
     419   if (es > e) then
     420      e = es
     421   end if
     422end do
     423e = rtol*e
     424
     425! timestep correction
     426
     427coef = max(coefmin, min(coefmax,0.8/sqrt(e)))
     428
     429dttest = max(dtmin,dttest*coef)
     430dttest = min(ctimestep,dttest)
     431
     432end do ! iter
     433
     434! new timestep
     435
     436dtnew = dttest
     437
     438end subroutine define_dt
     439
    372440
    373441!======================================================================
     
    394462implicit none
    395463
    396 #include "chimiedata.h"
     464#include "chimiedata_early_earth.h"
    397465
    398466!----------------------------------------------------------------------
     
    17961864implicit none
    17971865
    1798 #include "chimiedata.h"
     1866#include "chimiedata_early_earth.h"
    17991867
    18001868! input
     
    19251993implicit none
    19261994
    1927 #include "chimiedata.h"
     1995#include "chimiedata_early_earth.h"
    19281996
    19291997! input
     
    32493317    (nb_reaction_4 /= nb_reaction_4_max)) then
    32503318   print*, 'wrong dimensions in indice'
     3319   print*, 'nb_phot_max       = ', nb_phot_max
     3320   print*, 'nb_reaction_4_max = ', nb_reaction_4_max
     3321   print*, 'nb_reaction_3_max = ', nb_reaction_3_max
    32513322   stop
    32523323end if 
     
    36363707      end subroutine chimtogcm
    36373708
    3638 end subroutine photochemistry_asis
    3639 
     3709end subroutine photochemistry_asis_early_earth
     3710
Note: See TracChangeset for help on using the changeset viewer.