source: trunk/LMDZ.TITAN/libf/muphytitan/mmp_gcm.f90 @ 3604

Last change on this file since 3604 was 3090, checked in by slebonnois, 16 months ago

BdeBatz? : Cleans microphysics and makes few corrections for physics

File size: 13.6 KB
Line 
1! Copyright (2017,2022-2023) Université de Reims Champagne-Ardenne
2! Contributors : J. Burgalat (GSMA, URCA), B. de Batz de Trenquelléon (GSMA, URCA)
3! email of the author : jeremie.burgalat@univ-reims.fr
4!
5! This software is a computer program whose purpose is to compute
6! microphysics processes using a two-moments scheme.
7!
8! This library is governed by the CeCILL license under French law and
9! abiding by the rules of distribution of free software.  You can  use,
10! modify and/ or redistribute the software under the terms of the CeCILL
11! license as circulated by CEA, CNRS and INRIA at the following URL
12! "http://www.cecill.info".
13!
14! As a counterpart to the access to the source code and  rights to copy,
15! modify and redistribute granted by the license, users are provided only
16! with a limited warranty  and the software's author,  the holder of the
17! economic rights,  and the successive licensors  have only  limited
18! liability.
19!
20! In this respect, the user's attention is drawn to the risks associated
21! with loading,  using,  modifying and/or developing or reproducing the
22! software by the user in light of its specific status of free software,
23! that may mean  that it is complicated to manipulate,  and  that  also
24! therefore means  that it is reserved for developers  and  experienced
25! professionals having in-depth computer knowledge. Users are therefore
26! encouraged to load and test the software's suitability as regards their
27! requirements in conditions enabling the security of their systems and/or
28! data to be ensured and,  more generally, to use and operate it in the
29! same conditions as regards security.
30!
31! The fact that you are presently reading this means that you have had
32! knowledge of the CeCILL license and that you accept its terms.
33
34!! file: mmp_gcm.f90
35!! summary: YAMMS interfaces for the LMDZ GCM.
36!! author: J. Burgalat
37!! date: 2017,2022,2023
38!! modifications: B. de Batz de Trenquelléon
39MODULE MMP_GCM
40  !! Interface to YAMMS for the LMDZ GCM.
41  USE MMP_GLOBALS
42  USE MM_LIB
43  USE CFGPARSE
44  USE DATASETS
45  IMPLICIT NONE
46
47  CONTAINS
48
49  SUBROUTINE mmp_initialize(dt,p_prod,tx_prod,rc_prod,rplanet,g0, air_rad,air_mmol,clouds,cfgpath)
50    !! Initialize global parameters of the model.
51    !!
52    !! The function initializes all the global parameters of the model from direct input.
53    !! Boolean (and Fiadero) parameters are optional as they are rather testing parameters. Their
54    !! default values are suitable for production runs.
55    !! @note
56    !! If the subroutine fails to initialize parameters, the run is aborted.
57    !!
58    !! @warning
59    !! If OpenMP is activated, this subroutine must be called in an $OMP SINGLE statement as it
60    !! initializes global variable that are not thread private.
61    !!
62    !! ```
63    !! !$OMP SINGLE
64    !! call mmp_initialize(...)
65    !! !$OMP END SINGLE
66    !! ```
67    !!
68    REAL(kind=mm_wp), INTENT(in)           :: dt
69      !! Microphysics timestep in seconds.
70    REAL(kind=mm_wp), INTENT(in)           :: p_prod
71      !!  Aerosol production pressure level in Pa.
72    REAL(kind=mm_wp), INTENT(in)           :: tx_prod
73      !! Spherical aerosol mode production rate in \(kg.m^{-2}.s^{-1}\).
74    REAL(kind=mm_wp), INTENT(in)           :: rc_prod
75      !! Spherical mode characteristic radius for production in meter.
76    REAL(kind=mm_wp), INTENT(in)           :: rplanet
77      !! Planet radius in meter
78    REAL(kind=mm_wp), INTENT(in)           :: g0
79      !! Planet gravity acceleration at ground level in \(m.s^{-2}\).
80    REAL(kind=mm_wp), INTENT(in)           :: air_rad
81      !! Air molecules mean radius in meter.
82    REAL(kind=mm_wp), INTENT(in)           :: air_mmol
83      !! Air molecules mean molar mass in \(kg.mol^{-1}\).
84    LOGICAL, INTENT(in)                    :: clouds
85      !! Clouds microphysics control flag.
86    CHARACTER(len=*), INTENT(in), OPTIONAL :: cfgpath
87      !! Internal microphysic configuration file.
88
89    INTEGER                                           :: coag_choice
90    REAL(kind=mm_wp)                                  :: fiad_max,fiad_min,df,rm,rho_aer
91    LOGICAL                                           :: w_h_prod,w_h_sed,w_h_coag,w_c_sed,w_c_nucond, &
92                                                         no_fiadero,fwsed_m0,fwsed_m3
93    TYPE(error)                                       :: err
94    INTEGER                                           :: i
95    TYPE(cfgparser)                                   :: cparser
96    CHARACTER(len=st_slen)                            :: spcpath,pssfile,mqfile,opt_file
97    CHARACTER(len=st_slen), DIMENSION(:), ALLOCATABLE :: species
98    REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE       :: tmp
99    REAL(kind=mm_wp)                                  :: m0as_min,rcs_min,m0af_min,rcf_min,m0n_min
100    LOGICAL                                           :: wdebug
101
102    w_h_prod    = .true.
103    w_h_sed     = .true.
104    w_h_coag    = .true.
105    w_c_sed     = clouds
106    w_c_nucond  = clouds
107    fwsed_m0    = .true.
108    fwsed_m3    = .false.
109    no_fiadero  = .true.
110    fiad_min    = 0.1_mm_wp
111    fiad_max    = 10._mm_wp
112    coag_choice = 7
113    wdebug      = .false.
114    m0as_min    = 1e-10_mm_wp
115    rcs_min     = 1e-9_mm_wp
116    m0af_min    = 1e-10_mm_wp
117    rcf_min     = 1e-9_mm_wp
118    m0n_min     = 1e-10_mm_wp
119
120    WRITE(*,'(a)') "##### MMP_GCM SPEAKING #####"
121    WRITE(*,'(a)') "I will initialize the microphysics model in moments YAMMS"
122    WRITE(*,'(a)') "On error I will simply abort the program. Stay near your computer !"
123    WRITE(*,*)
124    WRITE(*,'(a)') "Reading muphys configuration file ("//trim(cfgpath)//")..."
125    err = cfg_read_config(cparser,TRIM(cfgpath),.true.)
126    IF (err /= 0) THEN
127      ! RETURN AN ERROR !!
128      call abort_program(err)
129    ENDIF
130
131    ! YAMMS internal parameters:
132    err = mm_check_opt(cfg_get_value(cparser,"rm",rm),rm,50e-9_mm_wp,mm_log)
133    err = mm_check_opt(cfg_get_value(cparser,"df",df),df,2._mm_wp,mm_log)
134    err = mm_check_opt(cfg_get_value(cparser,"rho_aer",rho_aer),rho_aer,1000._mm_wp,mm_log)
135    ! the following parameters are primarily used to test and debug YAMMS.
136    ! They are set in an optional configuration file and default to suitable values for production runs.
137    err = mm_check_opt(cfg_get_value(cparser,"haze_production",w_h_prod)          ,w_h_prod   ,.true.     ,mm_log)
138    err = mm_check_opt(cfg_get_value(cparser,"haze_sedimentation",w_h_sed)        ,w_h_sed    ,.true.     ,mm_log)
139    err = mm_check_opt(cfg_get_value(cparser,"haze_coagulation",w_h_coag)         ,w_h_coag   ,.true.     ,mm_log)
140    err = mm_check_opt(cfg_get_value(cparser,"clouds_sedimentation",w_c_sed)      ,w_c_sed    ,clouds     ,mm_log)
141    err = mm_check_opt(cfg_get_value(cparser,"clouds_nucl_cond",w_c_nucond)       ,w_c_nucond ,clouds     ,mm_log)
142    err = mm_check_opt(cfg_get_value(cparser,"wsed_m0",fwsed_m0)                  ,fwsed_m0   ,.true.     ,mm_log)
143    err = mm_check_opt(cfg_get_value(cparser,"wsed_m3",fwsed_m3)                  ,fwsed_m3   ,.false.    ,mm_log)
144    err = mm_check_opt(cfg_get_value(cparser,"no_fiadero",no_fiadero)             ,no_fiadero ,.true.     ,mm_log)
145    err = mm_check_opt(cfg_get_value(cparser,"fiadero_min_ratio",fiad_min)        ,fiad_min   ,0.1_mm_wp  ,mm_log)
146    err = mm_check_opt(cfg_get_value(cparser,"fiadero_max_ratio",fiad_max)        ,fiad_max   ,10._mm_wp  ,mm_log)
147    err = mm_check_opt(cfg_get_value(cparser,"haze_coag_interactions",coag_choice),coag_choice,7          ,mm_log)
148    err = mm_check_opt(cfg_get_value(cparser,"m0as_min",m0as_min)                 ,m0as_min   ,1e-10_mm_wp,mm_log)
149    err = mm_check_opt(cfg_get_value(cparser,"rcs_min",rcs_min)                   ,rcs_min    ,1e-9_mm_wp ,mm_log)
150    err = mm_check_opt(cfg_get_value(cparser,"m0af_min",m0af_min)                 ,m0af_min   ,1e-10_mm_wp,mm_log)
151    err = mm_check_opt(cfg_get_value(cparser,"rcf_min",rcf_min)                   ,rcf_min    ,rm         ,mm_log)
152    err = mm_check_opt(cfg_get_value(cparser,"m0n_min",m0n_min)                   ,m0n_min    ,1e-10_mm_wp,mm_log)
153    err = mm_check_opt(cfg_get_value(cparser,"debug",wdebug)                      ,wdebug     ,.false.    ,mm_log)
154
155    ! Retrieve clouds species configuration file
156    spcpath = ''
157    IF (clouds) THEN
158      err = mm_check_opt(cfg_get_value(cparser,"specie_cfg",spcpath), spcpath, wlog=mm_log)
159      IF (err/=0) call abort_program(err)
160    ENDIF
161
162    ! Setup alpha function: THEY ARE REQUIRED IN YAMMS global initialization !
163    ! spherical mode inter-moments function parameters
164    IF (.NOT.cfg_has_section(cparser,'alpha_s')) call abort_program(error("Cannot find [alpha_s] section",-1))
165    err = read_aprm(cparser,'alpha_s',mmp_asp)
166    IF (err /= 0) call abort_program(error("alpha_s: "//TRIM(err%msg),-1))
167    ! fractal mode inter-moments function parameters
168    IF (.NOT.cfg_has_section(cparser,'alpha_f')) call abort_program(error("Cannot find [alpha_f] section",-1))
169    err = read_aprm(cparser,'alpha_f',mmp_afp)
170    IF (err /= 0) call abort_program(error("alpha_s: "//TRIM(err%msg),-1))
171
172    ! YAMMS initialization.
173    err = mm_global_init_0(dt,df,rm,rho_aer,p_prod,tx_prod,rc_prod,rplanet,g0, &
174                           air_rad,air_mmol,coag_choice,clouds,spcpath,  &
175                           w_h_prod,w_h_sed,w_h_coag,w_c_nucond,  &
176                           w_c_sed,fwsed_m0,fwsed_m3, &
177                           no_fiadero,fiad_min,fiad_max, &
178                           m0as_min,rcs_min,m0af_min,rcf_min,m0n_min,wdebug)
179    IF (err /= 0) call abort_program(err)
180
181    ! Extra initialization (needed for YAMMS method interfaces)
182    err = mm_check_opt(cfg_get_value(cparser, "transfert_probability", mmp_w_ps2s), mmp_w_ps2s, wlog=mm_log)
183    IF (err/=0) call abort_program(err)
184    err = mm_check_opt(cfg_get_value(cparser, "electric_charging"    , mmp_w_qe  ), mmp_w_qe, wlog=mm_log)
185    IF (err/=0) call abort_program(err)
186
187    ! initialize transfert probabilities look-up tables
188    IF (mm_w_haze_coag .AND. mmp_w_ps2s) THEN
189      err = mm_check_opt(cfg_get_value(cparser, "ps2s_file", pssfile), pssfile)
190      IF (err /= 0) call abort_program(err)
191
192      IF (.NOT.read_dset(pssfile,'p_m0_co',mmp_pco0p)) THEN
193        call abort_program(error("Cannot get 'p_m0_co' from "//pssfile,-1))
194      ENDIF
195      IF (.NOT.read_dset(pssfile,'p_m3_co',mmp_pco3p)) THEN
196        call abort_program(error("Cannot get 'p_m3_co' from "//pssfile,-1))
197      ENDIF
198      IF (.NOT.read_dset(pssfile,'p_m0_fm',mmp_pfm0p)) THEN
199        call abort_program(error("Cannot get 'p_m0_fm' from "//pssfile,-1))
200      ENDIF
201      IF (.NOT.read_dset(pssfile,'p_m3_fm',mmp_pfm3p)) THEN
202        call abort_program(error("Cannot get 'p_m3_fm' from "//pssfile,-1))
203      ENDIF
204    ENDIF
205    ! initialize mean electric correction look-up tables
206    IF (mm_w_haze_coag .AND. mmp_w_qe) THEN
207      err = mm_check_opt(cfg_get_value(cparser, "mq_file", mqfile), mqfile)
208      IF (err /= 0) call abort_program(err)
209
210      IF (.NOT.read_dset(mqfile,'qbsf0',mmp_qbsf0)) THEN
211        call abort_program(error("Cannot get 'qbsf0' from "//mqfile,-1))
212      ELSE
213        mmp_qbsf0_e(1,1) = MINVAL(mmp_qbsf0%x)
214        mmp_qbsf0_e(1,2) = MAXVAL(mmp_qbsf0%x)
215        mmp_qbsf0_e(2,1) = MINVAL(mmp_qbsf0%y)
216        mmp_qbsf0_e(2,2) = MAXVAL(mmp_qbsf0%y)
217      ENDIF
218      IF (.NOT.read_dset(mqfile,'qbsf3',mmp_qbsf3)) THEN
219        call abort_program(error("Cannot get 'qbsf3' from "//mqfile,-1))
220      ELSE
221        mmp_qbsf3_e(1,1) = MINVAL(mmp_qbsf3%x)
222        mmp_qbsf3_e(1,2) = MAXVAL(mmp_qbsf3%x)
223        mmp_qbsf3_e(2,1) = MINVAL(mmp_qbsf3%y)
224        mmp_qbsf3_e(2,2) = MAXVAL(mmp_qbsf3%y)
225      ENDIF
226      IF (.NOT.read_dset(mqfile,'qbff0',mmp_qbff0)) THEN
227        call abort_program(error("Cannot get 'qbff0' from "//mqfile,-1))
228      ELSE
229        mmp_qbff0_e(1,1) = MINVAL(mmp_qbff0%x)
230        mmp_qbff0_e(1,2) = MAXVAL(mmp_qbff0%x)
231        mmp_qbff0_e(2,1) = MINVAL(mmp_qbff0%y)
232        mmp_qbff0_e(2,2) = MAXVAL(mmp_qbff0%y)
233      ENDIF
234    ENDIF
235
236    ! btk coefficients
237    IF (.NOT.cfg_has_section(cparser,'btks')) call abort_program(error("Cannot find [btks] section",-1))
238    err = cfg_get_value(cparser,"btks/bt0",tmp) ; IF (err/=0) call abort_program(error("bt0: "//TRIM(err%msg),-1))
239    IF (SIZE(tmp) /= 5)  call abort_program(error("bt0: Inconsistent number of coefficients",-1))
240    mmp_bt0 = tmp
241    err = cfg_get_value(cparser,"btks/bt3",tmp) ; IF (err/=0) call abort_program(error("bt3: "//TRIM(err%msg),-1))
242    IF (SIZE(tmp) /= 5)  call abort_program(error("bt3: Inconsistent number of coefficients",-1))
243    mmp_bt3 = tmp
244
245    ! dump parameters ...
246    WRITE(*,'(a)')        "========= MUPHYS PARAMETERS ==========="
247    WRITE(*,'(a,L2)')     "transfert_probability: ", mmp_w_ps2s
248    WRITE(*,'(a,L2)')     "electric_charging    : ", mmp_w_qe
249    call mm_dump_parameters()
250    IF (clouds) THEN
251      DO i=1, size(mm_xESPS)
252        print*, TRIM(mm_xESPS(i)%name), " fmol2fmas = ", mm_xESPS(i)%fmol2fmas
253      ENDDO
254    ENDIF
255
256  END SUBROUTINE mmp_initialize
257
258  FUNCTION read_aprm(parser,sec,pp) RESULT(err)
259    !! Read and store [[mmp_gcm(module):aprm(type)]] parameters.
260    TYPE(cfgparser), INTENT(in)  :: parser !! Configuration parser
261    CHARACTER(len=*), INTENT(in) :: sec    !! Name of the section that contains the parameters.
262    TYPE(aprm), INTENT(out)      :: pp     !! [[mmp_gcm(module):aprm(type)]] object that stores the parameters values.
263    TYPE(error) :: err                     !! Error status of the function.
264    err = cfg_get_value(parser,TRIM(sec)//'/a',pp%a) ; IF (err /= 0) RETURN
265    err = cfg_get_value(parser,TRIM(sec)//'/b',pp%b) ; IF (err /= 0) RETURN
266    err = cfg_get_value(parser,TRIM(sec)//'/c',pp%c) ; IF (err /= 0) RETURN
267    IF (SIZE(pp%a) /= SIZE(pp%b) .OR. SIZE(pp%a) /= SIZE(pp%c)) &
268    err = error("Inconsistent number of coefficients (a,b, and c must have the same size)",-1)
269    RETURN
270  END FUNCTION read_aprm
271
272END MODULE MMP_GCM
273
Note: See TracBrowser for help on using the repository browser.