123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- !#################################################################
- !
- ! tendency dimensions
- !
- !### macro's #####################################################
- !
- #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- !
- #include "tm5.inc"
- !
- !#################################################################
- module TM5_Tendency_eval
- use GO, only : gol, goPr, goErr
-
- use tm5_tendency
- implicit none
-
-
- ! --- in/out --------------------------------
-
- #ifdef oasis4
- public :: prism_init_time
- #endif
- public :: set_init_tend,apply_tendency,reset_tendency
- contains
- #ifdef oasis4
- subroutine prism_init_time
- ! subroutine to get start/end timing from prism-coupler.
-
- use dims , only : idatei,idatee, idatet
- use PRISM , only : PRISM_Jobstart_date, PRISM_Jobend_date
- !
- ! set times provided by prism coupler:
- !
- idatei(1) = PRISM_Jobstart_date%year
- idatei(2) = PRISM_Jobstart_date%month
- idatei(3) = PRISM_Jobstart_date%day
- idatei(4) = PRISM_Jobstart_date%hour
- idatei(5) = PRISM_Jobstart_date%minute
- idatei(6) = nint(PRISM_Jobstart_date%second)
- !
- idatee(1) = PRISM_Jobend_date%year
- idatee(2) = PRISM_Jobend_date%month
- idatee(3) = PRISM_Jobend_date%day
- idatee(4) = PRISM_Jobend_date%hour
- idatee(5) = PRISM_Jobend_date%minute
- idatee(6) = nint(PRISM_Jobend_date%second)
- ! copy
- idatet = idatee
- end subroutine prism_init_time
- #endif
- subroutine set_init_tend (rcfile,status)
- use GO , only : gol, goPr, goErr, goLabel
- use GO , only : TrcFile, Init, Done, ReadRc
- use GO , only : TDate, NewDate, IncrDate, AnyDate
- use dims , only : idate
- use tracer_data , only : PLC_Set, PLC_Reset
- use tracer_data , only : plc_reset_period
- #ifdef with_feedback
- use tm5_feedback , only : fdb_ntr, fdb_trname, fdb_replace
- use tm5_feedback , only : fdb_firstonly
- #endif
- #ifdef oasis4
- use prism_putget , only : TM5_Prism_Puts
- #endif
- ! --- in/out ----------------------------------------
- character(len=*), intent(in) :: rcfile
- integer, intent(out) :: status
- ! --- const ----------------------------------------
- character(len=*), parameter :: rname = mname//'/set_tend'
- ! --- local ---------------------------------------------
- integer :: itr, ipr
- #ifdef with_feedback
- integer :: fdb_itr
- #endif
-
- type(TrcFile) :: rcF
- type(TDate) :: tdyn
- ! --- begin -----------------------------------------------
- write (gol,'(a,": read tendency settings ...")') rname; call goPr
- ! open rcfile:
- call Init( rcF, rcfile, status )
- IF_NOTOK_RETURN(status=1)
- ! which tendencies form pchem ?
- call ReadRc( rcF, 'tend.pchem.emis' , tend_pchem_emis , status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.pchem.drydepos', tend_pchem_drydepos, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.pchem.convdiff', tend_pchem_convdiff, status )
- IF_NOTOK_RETURN(status=1)
- ! which tendencies form lchem ?
- call ReadRc( rcF, 'tend.lchem.convdiff', tend_lchem_convdiff, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.lchem.chem' , tend_lchem_chem , status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.lchem.emis' , tend_lchem_emis , status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.lchem.drydepos', tend_lchem_drydepos, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'tend.lchem.wetdepos', tend_lchem_wetdepos, status )
- IF_NOTOK_RETURN(status=1)
- #ifdef with_feedback
- ! apply feedbacks for certain tracers ?
- do fdb_itr = 1, fdb_ntr
- call ReadRc( rcF, 'feedback.replace.'//trim(fdb_trname(fdb_itr)), fdb_replace(fdb_it
- r), status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! adhoc: only at start time field seem to be send:
- call ReadRc( rcF, 'feedback.firstonly', fdb_firstonly, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- call Done( rcF, status )
- IF_NOTOK_RETURN(status=1)
- write (gol,'(a,": initialize tendency data ...")') rname; call goPr
- ! Do not fill current tracer fields from rm_k / rm_t: They are not present yet.
- ! Use the previously stored values instead.
- ! do itr = 1, plc_ntr
- ! call PLC_Set( 'fill-tracer', itr, plc_ipr_conc, status )
- ! IF_NOTOK_RETURN(status=1)
- ! end do
- ! reset pchem and lchem only:
- do itr = 1, plc_ntr
- ipr = plc_ipr_pchem
- call PLC_Reset( itr, ipr, status )
- IF_NOTOK_RETURN(status=1)
- ipr = plc_ipr_lchem
- call PLC_Reset( itr, ipr, status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! add tendencies:
- do itr = 1, plc_ntr
- ! ~~ collected into pchem
- if ( tend_pchem_emis ) then
- call PLC_Set( 'add-low', itr, plc_ipr_pchem, status, ipr2=plc_ipr_pemi )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_pchem_drydepos ) then
- call PLC_Set( 'add', itr, plc_ipr_pchem, status, ipr2=plc_ipr_lddep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_pchem_convdiff ) then
- call PLC_Set( 'add', itr, plc_ipr_pchem, status, ipr2=plc_ipr_tcnvd )
- IF_NOTOK_RETURN(status=1)
- end if
- ! ~~ collected into lchem
- ! conventions: lchem negative means 'loss',
- ! thus emissions have a positive contribution to lchem ...
- if ( tend_lchem_convdiff ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_tcnvd )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_chem ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_tchem )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_emis ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_pemi )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_drydepos ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_lddep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_wetdepos ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_lwdep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- end do
- #ifdef oasis4
- write (gol,'(a,": send chemical tendency data ...")') rname; call goPr
- ! put tendencies to IFS:
- ! current time (begin of dynamics step)
- tdyn = NewDate( time6=idate )
- call TM5_Prism_Puts( tdyn , status, isfirst=.true. )
- IF_NOTOK_RETURN(status=1)
- #endif
- end subroutine set_init_tend
- subroutine apply_tendency (isfirst, tdyn, status )
- use GO, only : gol, goPr, goErr
- use GO , only : TDate
- use tracer_data , only : PLC_Set
- #ifdef oasis4
- use prism_putget , only : TM5_Prism_Puts, TM5_Prism_gets
- #endif
- ! --- in/out ----------------------------------
- type(TDate),intent(in) :: tdyn
- logical, intent(in) :: isfirst
- integer, intent(out) :: status
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/apply_tendency'
- ! --- local ----------------------------------
- integer :: itr, ipr
- ! --- begin -----------------------------------
- ! no modifications of tendencies if this is initial time,
- ! since fields are either zero or read from restart file:
- if ( .not. isfirst ) then
- ! add budgets collected parallel over tracers:
- do itr = 1, plc_ntr
- call PLC_Set( 'add-t', itr, plc_ipr_tcnvd, status ) ! convection/diffusion
- IF_NOTOK_RETURN(status=1)
- call PLC_Set( 'add-t', itr, plc_ipr_lwdep, status ) ! wet deposition
- IF_NOTOK_RETURN(status=1)
- call PLC_Set( 'add-t', itr, plc_ipr_pemi , status ) ! emissions (not nox)
- IF_NOTOK_RETURN(status=1)
- end do
- ! dry depos is applied in chemistry, thus substract loss from chemical production
- ! (note that loss is positive, thus adding loss to change is the same as removing it):
- do itr = 1, plc_ntr
- call PLC_Set( 'add', itr, plc_ipr_tchem, status, ipr2=plc_ipr_lddep )
- IF_NOTOK_RETURN(status=1)
- end do
- ! nox emis is applied in chemistry, thus substract nox emis from chemical tendency:
- call PLC_Set( 'add', plc_itr_nox, plc_ipr_tchem, status, ipr2=plc_ipr_pemi, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- ! fill current tracer fields:
- do itr = 1, plc_ntr
- call PLC_Set( 'fill-tracer', itr, plc_ipr_conc, status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! add tendencies:
- do itr = 1, plc_ntr
- ! ~~ collected into pchem
- if ( tend_pchem_emis ) then
- call PLC_Set( 'add-low', itr, plc_ipr_pchem, status, ipr2=plc_ipr_pemi )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_pchem_drydepos ) then
- call PLC_Set( 'add', itr, plc_ipr_pchem, status, ipr2=plc_ipr_lddep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_pchem_convdiff ) then
- call PLC_Set( 'add', itr, plc_ipr_pchem, status, ipr2=plc_ipr_tcnvd)
- IF_NOTOK_RETURN(status=1)
- end if
- ! ~~ collected into lchem
- ! conventions: lchem negative means 'loss',
- ! thus emissions have a positive contribution to lchem ...
- if ( tend_lchem_convdiff ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_tcnvd )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_chem ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_tchem )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_emis ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_pemi )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_drydepos ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_lddep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( tend_lchem_wetdepos ) then
- call PLC_Set( 'add', itr, plc_ipr_lchem, status, ipr2=plc_ipr_lwdep, fac=-1.0 )
- IF_NOTOK_RETURN(status=1)
- end if
- end do
- end if ! not first
- #ifdef oasis4
- ! put tendencies to IFS:
- if ( .not. isfirst ) then ! First submission is already performed in initexit.F90, before meteo-gets.
- call TM5_Prism_Puts( tdyn, status )
- IF_NOTOK_RETURN(status=1)
- endif
- ! get concentrations, eventuall feedback:
- call TM5_Prism_Gets( tdyn, isfirst, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- end subroutine apply_tendency
- subroutine reset_tendency ( status )
- use GO , only : gol, goPr, goErr, goLabel
- use tracer_data , only : PLC_Reset
- ! --- in/out ----------------------------------
- integer, intent(out) :: status
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/reset_tendency'
- ! --- local ----------------------------------
- integer :: itr, ipr
- ! --- begin -----------------------------------
- ! loops over plc tracers and processes:
- do itr = 1, plc_ntr
- do ipr = 1, plc_npr
- ! not for for concentrations
- if ( ipr == plc_ipr_conc ) cycle
- ! reset tendencies to zero:
- call PLC_Reset( itr, ipr, status )
- IF_NOTOK_RETURN(status=1)
- end do ! ipr
- end do ! itr
- end subroutine reset_tendency
- end module TM5_Tendency_eval
|