1 ! module_cam_mam_init.F
2 ! created by r.c.easter, june 2010
5 ! 1. In CAM, stratiform-cloudborne aerosol species are held in the qqcw
6 ! array (of physics buffer), interstital aerosol water species are held in
7 ! the qaerwat array (of physics buffer), and other trace species (water vapor,
8 ! "stratiform cloud microphysical", trace gases, interstitial aerosol)
9 ! are held in the state%q array. Which interfacing to CAM routines,
10 ! species must by transferred to/from the q and qqcw arrays.
11 ! Initial implementations in WRF-Chem will use CBMZ gas-phase chemistry
12 ! and CAM MAM aerosols, so the trace gases will differ from CAM5.
13 ! The species in the q array will be
14 ! a. Moisture species (pcnst_non_chem_modal_aero of them)
15 ! b. Trace gas species with WRF-Chem indices between param_first_scalar
17 ! c. Interstitial aerosol species (except for aerosol water).
19 !--------------------------------------------------------------
20 #include "MODAL_AERO_CPP_DEFINES.h"
22 module module_cam_mam_init
25 public :: cam_mam_init
28 ! in cam5, pom is assumed to by 10/14 carbon and 4/14 other elements (oxygen, etc)
29 ! when the following 2 parameters are positive, a factor of 1.4 is applied
30 ! in the emissions and IC/BC routines, so that pom in cam5 will be
31 ! ~1.4x the equivalent mosaic and sorgam primary organic species
32 ! when a flag is zero/negative, the factor is not applied
33 ! *** the 2 integer parameters can be modified by user (normally all 0 or all 1),
34 ! but the 2 real variables are set later based on the parameter values
35 integer, parameter :: pom_emit_1p4_factor_flag = 0
36 integer, parameter :: pom_icbc_1p4_factor_flag = 0
37 real, public :: pom_emit_1p4_factor
38 real, public :: pom_icbc_1p4_factor
40 ! in 3-mode cam5, so4 is assumed to be ammonium-bisulfate (molec-wght = 115)
41 ! when the following 3 parameters are positive, a factor of 115/96 ~= 1.2 is applied
42 ! to so4 species in the emissions and IC/BC routines, and the so4 molec-wght
43 ! is set to 115 (which affect so2->so4 gas and aqueous oxidation),
44 ! so that so4 in cam5 will be ~1.2x the equivalent mosaic and sorgam primary organic species
45 ! when a flag is zero/negative, the factor is not applied, or the molec-wght is set to 96
46 ! *** the 3 integer parameters can be modified by user (normally all 0 or all 1),
47 ! but the 2 real variables are set later based on the parameter values
48 integer, parameter :: so4_emit_1p2_factor_flag = 1
49 integer, parameter :: so4_icbc_1p2_factor_flag = 1
50 integer, parameter :: so4_mwgt_1p2_factor_flag = 1
51 real, public :: so4_emit_1p2_factor
52 real, public :: so4_icbc_1p2_factor
55 !Balwinder.Singh@pnnl.gov: cnst_name_loc is defined as a local array for this module
56 !The cnst_name array of phys/constituent module is populated using 'cnst_add' calls
57 !in this module to be consistent with the CAM way of populating cnst_name array
58 character(len=16),allocatable, public :: cnst_name_loc(:) ! constituent names
60 integer, parameter :: init_val = -999888777
61 LOGICAL :: CAM_INITIALIZED_CHEM = .FALSE.
65 !==============================================================
66 subroutine cam_mam_init( &
67 id, numgas, config_flags, &
68 ids,ide, jds,jde, kds,kde, &
69 ims,ime, jms,jme, kms,kme, &
70 its,ite, jts,jte, kts,kte )
71 !--------------------------------------------------------------
73 ! 1. call routines that allocated and initialize data structures used
74 ! by cam modal aerosol (cam_mam) code
75 ! 2. call routines that initialize aerosol mixing ratios
76 ! for specific test scenarios
77 !--------------------------------------------------------------
79 use module_state_description, only: num_chem,CBMZ_CAM_MAM3_NOAQ,CBMZ_CAM_MAM3_AQ,CBMZ_CAM_MAM7_NOAQ,CBMZ_CAM_MAM7_AQ
80 use module_configure, only: grid_config_rec_type
82 use shr_kind_mod, only: r8 => shr_kind_r8
83 use physconst, only: epsilo, latvap, latice, rh2o, cpair, tmelt
84 use module_cam_esinti, only: esinti
86 use module_cam_support, only: pver, pverp, pcols, &
87 pcnst => pcnst_runtime, &
90 use modal_aero_data, only: cnst_name_cw, ntot_aspectype, &
91 qneg3_worst_thresh_amode, species_class, &
92 specmw_amode, specname_amode, &
93 specdens_so4_amode, specmw_so4_amode, &
94 specdens_nh4_amode, specmw_nh4_amode, &
95 specdens_no3_amode, specmw_no3_amode, &
96 specdens_pom_amode, specmw_pom_amode, &
97 specdens_soa_amode, specmw_soa_amode, &
98 specdens_bc_amode, specmw_bc_amode, &
99 specdens_dust_amode, specmw_dust_amode, &
100 specdens_seasalt_amode, specmw_seasalt_amode
102 use modal_aero_initialize_data, only: modal_aero_initialize, modal_aero_register, decouple_mam_mp
103 use ndrop , only: activate_init
104 USE module_cam_mam_cloudchem, only: cam_mam_cloudchem_inti
105 USE module_cam_mam_gas_wetdep_driver, only: cam_mam_gas_wetdep_inti
109 !--------------------------------------------------------------
111 !--------------------------------------------------------------
112 type(grid_config_rec_type), intent(in) :: config_flags
114 integer, intent(in) :: &
116 ids, ide, jds, jde, kds, kde, &
117 ims, ime, jms, jme, kms, kme, &
118 its, ite, jts, jte, kts, kte
121 !--------------------------------------------------------------
122 ! ... local variables
123 !--------------------------------------------------------------
124 integer :: ierr, l, m
125 character(len=16) :: tmpname
126 character(len=160) :: msg
129 !Balwinder.Singh@pnnl.gov: Added a sanity check so that chem_opt package corresponds to the right CPP directive for 3 or 7 mode
130 #if ( defined MODAL_AERO_3MODE )
131 if ( (config_flags%chem_opt /= CBMZ_CAM_MAM3_NOAQ) .and. &
132 (config_flags%chem_opt /= CBMZ_CAM_MAM3_AQ ) ) then
133 call wrf_error_fatal( 'cam_mam_init - MODAL_AERO_3MODE is defined but chem_opt is not a CAM_MAM3 package' )
136 #elif ( defined MODAL_AERO_7MODE )
137 if ( (config_flags%chem_opt /= CBMZ_CAM_MAM7_NOAQ) .and. &
138 (config_flags%chem_opt /= CBMZ_CAM_MAM7_AQ ) ) then
139 call wrf_error_fatal( 'cam_mam_init - MODAL_AERO_7MODE is defined but chem_opt is not a CAM_MAM7 package' )
143 call wrf_error_fatal( 'cam_mam_init - neither MODAL_AERO_3MODE or MODAL_AERO_7MODE is defined' )
147 !Balwinder.Singh@pnnl.gov: Sanity check for cam_mam_mode variable in namelist
148 if((config_flags%chem_opt == CBMZ_CAM_MAM3_NOAQ .OR. config_flags%chem_opt == CBMZ_CAM_MAM3_AQ) .AND. config_flags%cam_mam_mode .NE. 3)then
149 call wrf_error_fatal( 'CAM_MAM_INIT - For MODAL_AERO_3MODE (chem_opt - 503 CAM_MAM3 package), cam_mam_mode in namelist should be set to 3' )
150 elseif((config_flags%chem_opt == CBMZ_CAM_MAM7_NOAQ .OR. config_flags%chem_opt == CBMZ_CAM_MAM7_AQ) .AND. config_flags%cam_mam_mode .NE. 7)then
151 call wrf_error_fatal('CAM_MAM_INIT - For MODAL_AERO_7MODE (chem_opt - 504 CAM_MAM7 package), cam_mam_mode in namelist should be set to 7')
154 !Balwinder.Singh@pnnl.gov: Sanity check for cam_mam_nspec variable in namelist
155 !BSINGH (01/23/2014):Please make sure cam_mam_nspec is equal to pcnst in phys/module_physics_init.F and registry.chem
156 if((config_flags%chem_opt == CBMZ_CAM_MAM3_NOAQ .OR. config_flags%chem_opt == CBMZ_CAM_MAM3_AQ) .AND. config_flags%cam_mam_nspec .NE. 85)then
157 call wrf_error_fatal( 'CAM_MAM_INIT - For MODAL_AERO_3MODE (chem_opt - 503 CAM_MAM3 package), cam_mam_nspec in namelist should be set to 85' )
158 elseif((config_flags%chem_opt == CBMZ_CAM_MAM7_NOAQ .OR. config_flags%chem_opt == CBMZ_CAM_MAM7_AQ) .AND. config_flags%cam_mam_nspec .NE. 90)then
159 !BSINGH (01/23/2014): DMS species are NOT included in MAM7 package.
160 call wrf_error_fatal('CAM_MAM_INIT - For MODAL_AERO_7MODE (chem_opt - 504 CAM_MAM7 package), cam_mam_nspec in namelist should be set to 90')
163 !--------------------------------------------------------------
165 !--------------------------------------------------------------
166 write(*,'(/a)') 'cam_mam_init'
167 write(*,*) 'id, num_chem, pcnst =', id, num_chem, pcnst
169 write(*,'(a,3(4x,2i5))') 'ids/e, j..., k... ', ids,ide, jds,jde, kds,kde
170 write(*,'(a,3(4x,2i5))') 'ims/e, j..., k... ', ims,ime, jms,jme, kms,kme
171 write(*,'(a,3(4x,2i5))') 'its/e, j..., k... ', its,ite, jts,jte, kts,kte
172 write(*,'(a,3( i14))') 'pver, pverp, pcols', pver, pverp, pcols
175 ! initialize water vapor saturation routines
176 call esinti(epsilo, latvap, latice, rh2o, cpair, tmelt)
180 if ( (max(pver,pverp) > 0) .and. &
181 (pver /= kte-kts+1) .and. &
182 (pverp /= pver+1) ) then
183 write( msg, '(2a,3i15)' ) &
184 'cam_mam_init fatal error ', &
185 '- bad pver - id, pver, pverp = ', id, pver, pverp
186 call wrf_error_fatal( msg )
192 write(*,'(a,3( i14))') 'pver, pverp, pcols', pver, pverp, pcols
195 ! set pcnst and cnst_name_loc
197 'cam_mam_init calling cam_mam_init_set_cnst'
198 call cam_mam_init_set_cnst( id, numgas, config_flags )
200 !Balwinder.Singh@pnnl.gov: Before calling 'modal_aero_initialize', we have to
201 !call 'modal_aero_register'[nuance of CAM5.1]
203 'cam_mam_init calling modal_aero_register'
204 call modal_aero_register
206 ! do modal_aero_initialize_data
208 'cam_mam_init calling modal_aero_initialize'
209 call modal_aero_initialize
211 !For assisting decoupled microphysics (MP) CAM MAM simulations (simulations, where MAM package is coupled with
212 !radiation but decoupled with MP - i.e. MP runs with 'prescribed' aerosols)
213 call decouple_mam_mp(config_flags%CAM_MP_MAM_cpled)
215 !Balwinder.Singh@pnnl.gov: initialize aerosol activation
218 #if ( defined MODAL_AERO_3MODE )
219 if (so4_mwgt_1p2_factor_flag <= 0) then
220 ! in this case, the so4 molec-wght will be 96 instead of 115,
221 ! so do the following to override what was done in modal_aero_initialize
222 do m = 1, ntot_aspectype
223 if (specname_amode(m).eq.'sulfate ') then
224 !specmw_amode(m) = 96.0_r8 !Balwinder.Singh@pnnl.gov: defined as a 'parameter' in module_data_cam_mam_aero.F
225 specmw_so4_amode = specmw_amode(m)
226 else if (specname_amode(m).eq.'ammonium ') then
227 !specmw_amode(m) = 18.0_r8 !Balwinder.Singh@pnnl.gov: defined as a 'parameter' in module_data_cam_mam_aero.F
228 specmw_nh4_amode = specmw_amode(m)
234 write(*,'(a,2f12.4)') 'so4 dens, mw', specdens_so4_amode, specmw_so4_amode
235 write(*,'(a,2f12.4)') 'nh4 dens, mw', specdens_nh4_amode, specmw_nh4_amode
236 write(*,'(a,2f12.4)') 'no3 dens, mw', specdens_no3_amode, specmw_no3_amode
237 write(*,'(a,2f12.4)') 'pom dens, mw', specdens_pom_amode, specmw_pom_amode
238 write(*,'(a,2f12.4)') 'soa dens, mw', specdens_soa_amode, specmw_soa_amode
239 write(*,'(a,2f12.4)') 'bc dens, mw', specdens_bc_amode, specmw_bc_amode
240 write(*,'(a,2f12.4)') 'dst dens, mw', specdens_dust_amode, specmw_dust_amode
241 write(*,'(a,2f12.4)') 'ncl dens, mw', specdens_seasalt_amode, specmw_seasalt_amode
244 ! set variables that contain the pom 1.4 or 1.0 factors
245 ! and the so4 1.2 or 1.0 factors used with emissions and IC/BC
246 pom_emit_1p4_factor = 1.0
247 pom_icbc_1p4_factor = 1.0
248 if (pom_emit_1p4_factor_flag > 0) pom_emit_1p4_factor = 1.4
249 if (pom_icbc_1p4_factor_flag > 0) pom_icbc_1p4_factor = 1.4
251 so4_emit_1p2_factor = 1.0
252 so4_icbc_1p2_factor = 1.0
253 #if ( defined MODAL_AERO_3MODE )
254 if (so4_emit_1p2_factor_flag > 0) so4_emit_1p2_factor = 115.0/96.0
255 if (so4_icbc_1p2_factor_flag > 0) so4_icbc_1p2_factor = 115.0/96.0
258 write(*,'(/a,2f10.4)') 'pom_emit_1p4_factor & _init_', &
259 pom_emit_1p4_factor, pom_icbc_1p4_factor
260 write(*,'( a,2f10.4)') 'so4_emit_1p2_factor & _init_', &
261 so4_emit_1p2_factor, so4_icbc_1p2_factor
264 ! initialize the module_data_cam_mam_asect data
266 'cam_mam_init calling cam_mam_init_asect'
267 call cam_mam_init_asect( id, config_flags )
270 ! allocate and initialize arrays used to map aerosol and trace gas species
271 ! between the wrf-chem "chem" array and the cam "q" array
273 'cam_mam_init calling cam_mam_init_other'
274 call cam_mam_init_other( id, numgas, config_flags )
276 !Initialize CAM Cloud Chemistry
277 call cam_mam_cloudchem_inti()
279 !Initialize CAM gas wetdep
280 call cam_mam_gas_wetdep_inti
282 deallocate(cnst_name_loc)
289 end subroutine cam_mam_init
292 !==============================================================
293 subroutine cam_mam_init_set_cnst( id, numgas, config_flags )
294 !--------------------------------------------------------------
296 ! 1. set the value of the pcnst variable
297 ! (which currently is pcnst_runtime in module_cam_support),
298 ! and the pcnst_non_chem variable too.
299 ! 2. load the cnst_name array of constituent module using 'cnst_add' calls
300 ! and load it with appropriate trace species names
302 ! Modified by Balwinder.Singh@pnnl.gov: pcnst is set up at runtime
303 ! now. This subroutine serves
304 ! as a test to check whether
305 ! the value of pcnst is set
307 ! module_physics_init.F
308 !*NOTE*: As a quick solution, correct value for the Molecular weights
309 ! of the constituents is updated in 'cam_mam_init_other'. In
310 ! the current subroutine, molecular weights are set to 1.
312 !*WARNING*: Minimum threshold for the constituents is set to ZERO here.
313 ! This value is updated in 'cam_mam_init_other' subroutine
314 !--------------------------------------------------------------
316 use module_configure, only: grid_config_rec_type
317 use module_state_description, only: num_chem, param_first_scalar
318 use module_scalar_tables, only: chem_dname_table
320 use module_cam_support, only: pcnst => pcnst_runtime, &
321 pcnst_non_chem => pcnst_non_chem_modal_aero, &
322 gas_pcnst => gas_pcnst_modal_aero, &
325 use constituents, only: cnst_add
326 use physconst, only: cpair
330 !--------------------------------------------------------------
332 !--------------------------------------------------------------
333 type(grid_config_rec_type), intent(in) :: config_flags
334 integer, intent(in) :: id ! domain index
335 integer, intent(in) :: numgas
337 !--------------------------------------------------------------
338 ! ... local variables
339 !--------------------------------------------------------------
340 integer :: ierr, itmpa, dumind
343 character(len=360) :: msg
345 !--------------------------------------------------------------
347 !--------------------------------------------------------------
348 write(*,*) 'cam_mam_init_set_cnst'
349 write(*,*) 'id, num_chem =', id, num_chem
350 write(*,*) 'pcnst, gas_pcnst old =', pcnst, gas_pcnst
352 ! set pcnst value (and pcnst_non_chem too)
353 p1st = param_first_scalar
356 ! start with the non-chemistry trace species
357 itmpa = pcnst_non_chem
358 ! add on the trace gas species
362 ! add on the interstitial aerosol apecies
363 ! (except aerosol water)
364 ! *** their species names are assumed to end
365 ! with "_aN", where N=1,2,...,9 ***
366 do l = numgas+1, num_chem
367 if ( cam_mam_is_q_aerosol_species( l, numgas ) ) then
372 if (pcnst == itmpa) then !Balwinder.Singh@pnnl.gov: check if pcnst has the correct value
374 gas_pcnst = pcnst - pcnst_non_chem
375 write(*,*) 'pcnst, gas_pcnst new =', pcnst, gas_pcnst
376 else if (pcnst /= itmpa) then
378 'CAM_MAM_INIT_SET_CNST fatal error: The value of PCNST should be set to:',itmpa, &
379 ' in module_physics_init.F where pcnst is mentioned as', pcnst,'. ID is',id
380 call wrf_error_fatal( msg )
383 ! allocate cnst_name_loc
384 if ( .not. allocated(cnst_name_loc) ) then
385 allocate( cnst_name_loc(pcnst) )
389 ! set cnst_name_loc values
391 write( cnst_name_loc(l), '(a,i4.4)' ) 'empty_cnst_', l
393 !First 5 constituents are already added in the phys/module_physics_init module.
394 !Therefore cnst_add calls are not required for the same
395 if (pcnst_non_chem >= 1) cnst_name_loc(1) = 'Q'
396 if (pcnst_non_chem >= 2) cnst_name_loc(2) = 'CLDLIQ'
397 if (pcnst_non_chem >= 3) cnst_name_loc(3) = 'CLDICE'
398 if (pcnst_non_chem >= 4) cnst_name_loc(4) = 'NUMLIQ'
399 if (pcnst_non_chem >= 5) cnst_name_loc(5) = 'NUMICE'
404 IF(.NOT.CAM_INITIALIZED_CHEM) call cnst_add(trim(adjustl(chem_dname_table(1,l))), 1.0_r8, cpair, 0._r8, dumind)
405 cnst_name_loc(l2) = chem_dname_table(1,l)
408 do l = numgas+1, num_chem
409 if ( cam_mam_is_q_aerosol_species( l, numgas ) ) then
411 IF(.NOT.CAM_INITIALIZED_CHEM) call cnst_add(trim(adjustl(chem_dname_table(1,l))), 1.0_r8, cpair, 0._r8, dumind)
412 cnst_name_loc(l2) = chem_dname_table(1,l)
415 if (l2 /= pcnst) then
416 write( msg, '(2a,3i15)' ) &
417 'cam_mam_init_set_cnst fatal error 101', &
418 'for cnst_name, id, l2, pcnst = ', id, l2, pcnst
419 call wrf_error_fatal( msg )
424 end subroutine cam_mam_init_set_cnst
427 !==============================================================
428 function cam_mam_is_q_aerosol_species( lspec, numgas )
430 ! returns true if the wrf-chem species with index lspec is an aerosol species
431 ! that belongs in the q array, otherwise returns false.
432 ! the q array aerosol species are interstitial aerosol species
433 ! other than aerosol water
434 ! *** currently it is assumed that for these species, the
435 ! wrf-chem species name ends with "_aN", where N=1,2,...,7
437 use module_state_description, only: num_chem, param_first_scalar
438 use module_scalar_tables, only: chem_dname_table
439 use modal_aero_data, only: ntot_amode
443 logical :: cam_mam_is_q_aerosol_species
444 integer, intent(in) :: lspec, numgas
447 integer, parameter :: upper_to_lower = iachar('a')-iachar('A')
448 character(len=32) :: tmpname
449 character(len=1) :: tmpch
451 cam_mam_is_q_aerosol_species = .false.
452 if ( (lspec < param_first_scalar) .or. &
453 (lspec <= numgas) .or. &
454 (lspec > num_chem) ) return
456 call lower_case( chem_dname_table(1,lspec), tmpname )
458 ! aerosol water species are not in the q array
459 if (tmpname(1:5) == 'wtr_a') return
461 n = len( trim(tmpname) )
463 if (tmpname(n-2:n) == '_a1') cam_mam_is_q_aerosol_species = .true.
464 if (tmpname(n-2:n) == '_a2') cam_mam_is_q_aerosol_species = .true.
465 if (tmpname(n-2:n) == '_a3') cam_mam_is_q_aerosol_species = .true.
466 if (ntot_amode == 3) return
468 if (tmpname(n-2:n) == '_a4') cam_mam_is_q_aerosol_species = .true.
469 if (tmpname(n-2:n) == '_a5') cam_mam_is_q_aerosol_species = .true.
470 if (tmpname(n-2:n) == '_a6') cam_mam_is_q_aerosol_species = .true.
471 if (tmpname(n-2:n) == '_a7') cam_mam_is_q_aerosol_species = .true.
472 if (ntot_amode == 7) return
475 end function cam_mam_is_q_aerosol_species
478 !==============================================================
479 subroutine lower_case( txt_in, txt_lc )
481 ! converts a character string (txt_in) to lowercase (txt_lc)
485 character(len=*), intent(in) :: txt_in
486 character(len=*), intent(out) :: txt_lc
489 integer, parameter :: iachar_lowera = iachar('a')
490 integer, parameter :: iachar_uppera = iachar('A')
491 integer, parameter :: iachar_upperz = iachar('Z')
494 do i = 1, len( trim(txt_lc) )
495 j = iachar( txt_lc(i:i) )
496 if (j < iachar_uppera) cycle
497 if (j > iachar_upperz) cycle
498 txt_lc(i:i) = achar( j + iachar_lowera - iachar_uppera )
502 end subroutine lower_case
505 !==============================================================
506 subroutine cam_mam_init_asect( id, config_flags )
507 !--------------------------------------------------------------
509 ! initialize the aerosol pointer and property (density, molec wght,
510 ! hygroscopicity) variables in module_data_cam_mam_asect
511 ! from information in module_data_cam_mam_aero
512 ! the module_data_cam_mam_aero variables are an "older version"
513 ! designed for the mirage code, and are used by cam routines
514 ! the module_data_cam_mam_asect variables are a "newer version"
515 ! designed for the wrf-chem code, and they are useful for
516 ! the wrf-chem-->cam interface/driver routines
517 !--------------------------------------------------------------
519 use module_state_description, only: num_chem,param_first_scalar,CBMZ_CAM_MAM3_AQ,CBMZ_CAM_MAM7_AQ
521 use module_configure, only: grid_config_rec_type
522 use module_scalar_tables, only: chem_dname_table
524 use modal_aero_data, only: &
525 dgnum_amode, lspectype_amode, nspec_amode, ntot_amode, ntot_aspectype, &
526 sigmag_amode, specdens_amode, spechygro, specmw_amode, specname_amode
528 use module_data_cam_mam_asect
534 integer, intent(in) :: id
535 type(grid_config_rec_type), intent(in) :: config_flags
538 integer :: iphase, isize, itype
539 integer :: l, l2, l3, l4, la, lc
542 real, parameter :: pi=3.1415926536
543 real :: dp_meanvol_tmp
545 character(len=160) :: msg
546 character(len=32) :: tmpname, tmpnamec, tmptxtaa
549 p1st = param_first_scalar
551 ! set master component information
552 ntot_mastercomp_aer = ntot_aspectype
553 do l = 1, ntot_mastercomp_aer
554 name_mastercomp_aer(l) = specname_amode(l)
555 ! densities in modal_aero_data are kg/m3
556 ! densities in module_data_cam_mam_asect are g/cm3 (for consistency with mosaic and sorgam)
557 dens_mastercomp_aer(l) = specdens_amode(l)*1.0e-3
558 mw_mastercomp_aer(l) = specmw_amode(l)
559 hygro_mastercomp_aer(l) = spechygro(l)
560 if (name_mastercomp_aer(l) == 'sulfate') then
561 mastercompindx_so4_aer = l
562 namebb_mastercomp_aer(l) = 'so4'
563 mw_so4_aer = mw_mastercomp_aer(l)
564 dens_so4_aer = dens_mastercomp_aer(l)
565 else if (name_mastercomp_aer(l) == 'ammonium') then
566 mastercompindx_nh4_aer = l
567 namebb_mastercomp_aer(l) = 'nh4'
568 mw_nh4_aer = mw_mastercomp_aer(l)
569 dens_nh4_aer = dens_mastercomp_aer(l)
570 else if (name_mastercomp_aer(l) == 'nitrate') then
571 mastercompindx_no3_aer = l
572 namebb_mastercomp_aer(l) = 'no3'
573 mw_no3_aer = mw_mastercomp_aer(l)
574 dens_no3_aer = dens_mastercomp_aer(l)
575 else if (name_mastercomp_aer(l) == 'p-organic') then
576 mastercompindx_pom_aer = l
577 namebb_mastercomp_aer(l) = 'pom'
578 mw_pom_aer = mw_mastercomp_aer(l)
579 dens_pom_aer = dens_mastercomp_aer(l)
580 else if (name_mastercomp_aer(l) == 's-organic') then
581 mastercompindx_soa_aer = l
582 namebb_mastercomp_aer(l) = 'soa'
583 mw_soa_aer = mw_mastercomp_aer(l)
584 dens_soa_aer = dens_mastercomp_aer(l)
585 else if (name_mastercomp_aer(l) == 'black-c') then
586 mastercompindx_bc_aer = l
587 namebb_mastercomp_aer(l) = 'bc'
588 mw_bc_aer = mw_mastercomp_aer(l)
589 dens_bc_aer = dens_mastercomp_aer(l)
590 else if (name_mastercomp_aer(l) == 'seasalt') then
591 mastercompindx_seas_aer = l
592 namebb_mastercomp_aer(l) = 'ncl'
593 mw_seas_aer = mw_mastercomp_aer(l)
594 dens_seas_aer = dens_mastercomp_aer(l)
595 else if (name_mastercomp_aer(l) == 'dust') then
596 mastercompindx_dust_aer = l
597 namebb_mastercomp_aer(l) = 'dst'
598 mw_dust_aer = mw_mastercomp_aer(l)
599 dens_dust_aer = dens_mastercomp_aer(l)
601 msg = '*** cam_mam_init_asect error 100 - mastercompindx'
602 call wrf_message( msg )
603 write( msg, '(a,i4,2x,a)' ) 'l, specname_amode = ', &
605 call wrf_error_fatal( msg )
610 ! set number of phases
613 ! if (config_flags%chem_opt == ...) then
614 if ((config_flags%chem_opt == CBMZ_CAM_MAM3_AQ) .or. &
615 (config_flags%chem_opt == CBMZ_CAM_MAM7_AQ )) then
620 if (nphase_aer > 2) then
621 msg = '*** cam_mam_init_asect error 120 - nphase_aer > 2'
622 call wrf_error_fatal( msg )
628 ncomp_plustracer_aer(:) = 0
629 mastercompptr_aer(:,:) = init_val
630 massptr_aer(:,:,:,:) = init_val
631 waterptr_aer(:,:) = init_val
632 hyswptr_aer(:,:) = init_val
633 numptr_aer(:,:,:) = init_val
634 mprognum_aer(:,:,:) = 0
636 lptr_so4_aer(:,:,:) = init_val
637 lptr_nh4_aer(:,:,:) = init_val
638 lptr_no3_aer(:,:,:) = init_val
639 lptr_pom_aer(:,:,:) = init_val
640 lptr_soa_aer(:,:,:) = init_val
641 lptr_bc_aer(:,:,:) = init_val
642 lptr_dust_aer(:,:,:) = init_val
643 lptr_seas_aer(:,:,:) = init_val
645 volumcen_sect(:,:) = 0.0
646 volumlo_sect(:,:) = 0.0
647 volumhi_sect(:,:) = 0.0
651 sigmag_aer(:,:) = 1.0
653 ! set mode information
655 ! each cam_mam mode corresponds to a wrfchem type,
656 ! and each wrfchm type has a single size bin
657 ! (this differs from sorgam, where the aitken and accum. modes
658 ! have the same species, and so can both have the same type)
660 ntype_aer = ntot_amode
662 do itype = 1, ntype_aer
665 ncomp_aer(itype) = nspec_amode(itype)
666 ncomp_plustracer_aer(itype) = ncomp_aer(itype)
669 ! the dhi/dlo_sect are the upper/lower bounds for
670 ! mean-volume diameter for a section/bin
672 ! they should be set to reasonable upper/lower
673 ! bounds for mean-volume diameters of each modes
674 ! they are primarily used to put reasonable bounds
675 ! on number (in relation to mass/volume)
676 ! the dcen_sect are used by initwet for the impaction scavenging
677 ! lookup tables, and should represent a "base" mean-volume diameter
678 ! dp_meanvol_tmp (below) is the cam-mam default value
679 ! for mean-volume diameter (in cm)
680 ! terminology: (pi/6) * (mean-volume diameter)**3 ==
681 ! (volume mixing ratio of section/mode)/(number mixing ratio)
683 sigmag_aer(isize,itype) = sigmag_amode(itype)
684 dp_meanvol_tmp = 1.0e2*dgnum_amode(itype) & ! 1.0e2 converts m to cm
685 *exp( 1.5 * log(sigmag_aer(isize,itype))**2 )
686 dcen_sect(isize,itype) = dp_meanvol_tmp
687 dhi_sect( isize,itype) = dp_meanvol_tmp*4.0
688 dlo_sect( isize,itype) = dp_meanvol_tmp/4.0
690 do isize = 1, nsize_aer(itype)
691 volumcen_sect(isize,itype) = (pi/6.0)*(dcen_sect(isize,itype)**3)
692 volumlo_sect( isize,itype) = (pi/6.0)*(dlo_sect( isize,itype)**3)
693 volumhi_sect( isize,itype) = (pi/6.0)*(dhi_sect( isize,itype)**3)
695 write(*,'(a,i3,1p,5e11.3)') 'type, sg, dg, dp, vol', itype, &
696 sigmag_aer(1,itype), dgnum_amode(itype), dp_meanvol_tmp, volumcen_sect(1,itype)
699 do l = 1, ncomp_aer(itype)
700 l2 = lspectype_amode(l,itype)
701 if ((l2 > 0) .and. (l2 <= ntot_mastercomp_aer)) then
702 mastercompptr_aer(l,itype) = l2
704 msg = '*** cam_mam_init_asect error 200 - mastercompptr'
705 call wrf_message( msg )
706 write( msg, '(a,4(1x,i10))' ) &
707 'itype, l, l2, ntot_mastercomp_aer = ', &
708 itype, l, l2, ntot_mastercomp_aer
709 call wrf_error_fatal( msg )
711 dens_aer(l,itype) = dens_mastercomp_aer(l2)
712 mw_aer(l,itype) = mw_mastercomp_aer(l2)
713 hygro_aer(l,itype) = hygro_mastercomp_aer(l2)
714 name_aer(l,itype) = name_mastercomp_aer(l2)
718 do l = -1, ncomp_aer(itype)
719 do iphase = 1, nphase_aer
722 else if (l == 0) then
724 if (iphase > 1) cycle
726 l2 = lspectype_amode(l,itype)
727 tmpname = namebb_mastercomp_aer(l2)
730 if (iphase == 1) then
731 tmpname = trim(tmpname) // '_a'
733 tmpname = trim(tmpname) // '_c'
735 write( tmptxtaa, '(i1)' ) itype
736 tmpname = trim(tmpname) // tmptxtaa(1:1)
739 do l4 = p1st, num_chem
740 if (chem_dname_table(1,l4) == tmpname) then
746 msg = '*** cam_mam_init_asect error 300' // &
747 ' - finding species - ' // tmpname
748 call wrf_error_fatal( msg )
752 numptr_aer(isize,itype,iphase) = l3
753 mprognum_aer(isize,itype,iphase) = 1
754 else if (l == 0) then
755 waterptr_aer(isize,itype) = l3
757 massptr_aer(l,isize,itype,iphase) = l3
758 mastercompptr_aer(l,itype) = l2
759 if (l2 == mastercompindx_so4_aer) then
760 lptr_so4_aer(isize,itype,iphase) = l3
761 else if (l2 == mastercompindx_nh4_aer) then
762 lptr_nh4_aer(isize,itype,iphase) = l3
763 ! else if (l2 == mastercompindx_no3_aer) then
764 ! lptr_no3_aer(isize,itype,iphase) = l3
765 else if (l2 == mastercompindx_pom_aer) then
766 lptr_pom_aer(isize,itype,iphase) = l3
767 else if (l2 == mastercompindx_soa_aer) then
768 lptr_soa_aer(isize,itype,iphase) = l3
769 else if (l2 == mastercompindx_bc_aer) then
770 lptr_bc_aer(isize,itype,iphase) = l3
771 else if (l2 == mastercompindx_dust_aer) then
772 lptr_dust_aer(isize,itype,iphase) = l3
773 else if (l2 == mastercompindx_seas_aer) then
774 lptr_seas_aer(isize,itype,iphase) = l3
776 msg = '*** cam_mam_init_asect error 400' // &
777 ' - finding species type - ' // tmpname
778 call wrf_error_fatal( msg )
790 write(*,'(/a)') 'cam_mam_init_asect diagnostics'
792 write(*,'(/a,i5)') 'ntot_mastercomp_aer', ntot_mastercomp_aer
793 write(*,'(a)') 'mastercomp name, l, mw, dens, hygro'
794 do l = 1, ntot_mastercomp_aer
795 write(*,'(a,i5,1p,3e12.4)') name_mastercomp_aer(l), l, &
796 mw_mastercomp_aer(l), dens_mastercomp_aer(l), hygro_mastercomp_aer(l)
799 'mastercompindx_so4_aer, nh4, no3, pom, soa, bc, seas, dust'
801 mastercompindx_so4_aer, mastercompindx_nh4_aer, mastercompindx_no3_aer, &
802 mastercompindx_pom_aer, mastercompindx_soa_aer, mastercompindx_bc_aer, &
803 mastercompindx_seas_aer, mastercompindx_dust_aer
804 write(*,'(a)') '........... mw_so4_aer, nh4, no3, pom, soa, bc, seas, dust'
805 write(*,'(1p,4e12.4)') &
806 mw_so4_aer, mw_nh4_aer, mw_no3_aer, &
807 mw_pom_aer, mw_soa_aer, mw_bc_aer, &
808 mw_seas_aer, mw_dust_aer
809 write(*,'(a)') '......... dens_so4_aer, nh4, no3, pom, soa, bc, seas, dust'
810 write(*,'(1p,4e12.4)') &
811 dens_so4_aer, dens_nh4_aer, dens_no3_aer, &
812 dens_pom_aer, dens_soa_aer, dens_bc_aer, &
813 dens_seas_aer, dens_dust_aer
815 write(*,'(/a/6i12)') 'nphase_aer, ai_phase, cw_phase', &
816 nphase_aer, ai_phase, cw_phase
818 do itype = 1, ntype_aer
819 do isize = 1, nsize_aer(itype)
820 write(*,'(/a,2i5,a)') 'info for itype, isize = ', itype, isize, &
821 'species; id, name for ai & cw; mw, dens, hygro'
823 la = numptr_aer(isize,itype,1)
824 lc = numptr_aer(isize,itype,2)
826 if ((la >= p1st) .and. (la <= num_chem)) tmpname = chem_dname_table(1,la)
828 if ((lc >= p1st) .and. (lc <= num_chem)) tmpnamec = chem_dname_table(1,la)
829 write(*,'(a,i12,1x,a,i12,1x,a,1p,3e12.4)') 'number ', &
830 la, tmpname(1:10), lc, tmpnamec(1:10)
832 do l = 1, ncomp_aer(itype)
833 la = massptr_aer(l,isize,itype,1)
834 lc = massptr_aer(l,isize,itype,2)
836 if ((la >= p1st) .and. (la <= num_chem)) tmpname = chem_dname_table(1,la)
838 if ((lc >= p1st) .and. (lc <= num_chem)) tmpnamec = chem_dname_table(1,la)
839 write(*,'(a,i12,1x,a,i12,1x,a,1p,3e12.4)') name_aer(l,itype), &
840 la, tmpname(1:10), lc, tmpnamec(1:10), &
841 mw_aer(l,itype), dens_aer(l,itype), hygro_aer(l,itype)
844 la = waterptr_aer(isize,itype)
846 if ((la >= p1st) .and. (la <= num_chem)) tmpname = chem_dname_table(1,la)
847 write(*,'(a,i12,1x,a,23x,1p,3e12.4)') 'water ', &
850 la = hyswptr_aer(isize,itype)
852 if ((la >= p1st) .and. (la <= num_chem)) tmpname = chem_dname_table(1,la)
853 write(*,'(a,i12,1x,a,23x,1p,3e12.4)') 'hys-water ', &
861 end subroutine cam_mam_init_asect
865 !==============================================================
866 subroutine cam_mam_init_other( id, numgas, config_flags )
867 !--------------------------------------------------------------
869 ! allocate and initialize variables in module_data_cam_mam_asect
870 ! that are used for mapping trace species mixing ratios from
871 ! wrf-chem arrays (e.g., "chem") to cam arrays (q, qqcw, qaerwat)
872 !--------------------------------------------------------------
873 use shr_kind_mod, only: r8 => shr_kind_r8
874 use module_state_description, only: num_chem, param_first_scalar
875 use module_configure, only: grid_config_rec_type, &
876 p_h2o2, p_hno3, p_nh3, p_o3, p_so2, p_soag, p_sulf
877 use module_scalar_tables, only: chem_dname_table
879 use module_cam_support, only: pcnst => pcnst_runtime, &
880 pcnst_non_chem => pcnst_non_chem_modal_aero, &
881 gas_pcnst => gas_pcnst_modal_aero
882 use modal_aero_data, only: cnst_name_cw
883 use module_data_cam_mam_asect
884 use constituents, only: cnst_mw, cnst_rgas, cnst_cv, cnst_cp, &
886 use physconst, only: r_universal
887 use infnan, only: nan
889 !Balwinder.Singh@pnnl.gov:*NOTE* cnst_cv and cnst_cp are set to 'nan'
890 !as the cpair value for the chemical species is NOT set correctly.
891 !The 'nan' assigment will produce an error whenever cnst_cv or
892 !cnst_cp is used for any computation
898 integer, intent(in) :: id, numgas
899 type(grid_config_rec_type), intent(in) :: config_flags
902 integer :: iphase, isize, itype, dumind
903 integer :: l, ll, l2, l3, l4
906 character(len=160) :: msg
907 character(len=16) :: tmpname, tmpname2, tmpname3
908 real(r8) :: qmin_gas, qmin_aer,qmin_num
910 IF(.NOT.CAM_INITIALIZED_CHEM) THEN
911 qmin_gas = 1.0E-17_r8 !Typical val(H2SO4) : 1E-12 kg/kg; Negligible val: 1E-17 kg/kg - Balwinder.Singh@pnnl.gov
912 qmin_aer = 1.0E-14_r8 !Typical val(accum or coarse) : 1E-9 kg/kg; Negligible val: 1E-14 kg/kg - Balwinder.Singh@pnnl.gov
913 qmin_num = 1.0E+01_r8 !Typical val(coarse) : 1E5 #/kg; Negligible val: 1E1 #/kg - Balwinder.Singh@pnnl.gov
916 p1st = param_first_scalar
918 ! allocate lptr_chem_to_..., factconv_chem_to_..., and mw_... arrays
919 if ( .not. allocated(lptr_chem_to_q) ) then
920 allocate( lptr_chem_to_q(num_chem) )
923 if ( .not. allocated(lptr_chem_to_qqcw) ) then
924 allocate( lptr_chem_to_qqcw(num_chem) )
927 if ( .not. allocated(factconv_chem_to_q) ) then
928 allocate( factconv_chem_to_q(num_chem) )
931 if ( .not. allocated(factconv_chem_to_qqcw) ) then
932 allocate( factconv_chem_to_qqcw(num_chem) )
935 if ( .not. allocated(mw_chem_array) ) then
936 allocate( mw_chem_array(num_chem) )
939 if ( .not. allocated(mw_q_array) ) then
940 allocate( mw_q_array(pcnst) )
943 if ( .not. allocated(mw_q_mo_array) ) then
944 allocate( mw_q_mo_array(gas_pcnst) )
948 ! set values of lptr_chem_to_... arrays
949 lptr_chem_to_q(:) = init_val
950 lptr_chem_to_qqcw(:) = init_val
952 do l = p1st, num_chem
953 tmpname = chem_dname_table(1,l)
955 if (tmpname == cnst_name_loc(l2)) then
956 lptr_chem_to_q(l) = l2
959 if (tmpname == cnst_name_cw(l2)) then
960 lptr_chem_to_qqcw(l) = l2
967 ! set values of factconv_chem_to_..., and mw_... arrays
968 factconv_chem_to_q(:) = 1.0
969 factconv_chem_to_qqcw(:) = 1.0
970 mw_chem_array(:) = 1.0
972 mw_q_mo_array(:) = 1.0
976 l2 = lptr_chem_to_q(l)
977 if ((l2 < 1) .or. (l2 > pcnst)) cycle
979 ! set molecular weights of gas species that may be used by cam_mam routines
980 if (l == p_sulf) mw_chem_array(l) = 96.0
981 if (l == p_so2 ) mw_chem_array(l) = 64.0
982 if (l == p_nh3 ) mw_chem_array(l) = 17.0
983 if (l == p_hno3) mw_chem_array(l) = 63.0
984 if (l == p_soag) mw_chem_array(l) = 12.0
985 if (l == p_h2o2) mw_chem_array(l) = 34.0
986 if (l == p_o3 ) mw_chem_array(l) = 48.0
987 mw_q_array(l2) = mw_chem_array(l)
988 IF(.NOT.CAM_INITIALIZED_CHEM) THEN
989 cnst_mw(l2) = mw_q_array(l2)
990 cnst_rgas(l2) = r_universal * cnst_mw(l2)
994 qmincg (l2) = qmin(l2)
996 ! convert wrf-chem ppmv to cam kg/kg-air
997 factconv_chem_to_q(l) = 1.0e-6*mw_chem_array(l)/28.966
1001 do itype = 1, ntype_aer
1002 do isize = 1, nsize_aer(itype)
1003 l = numptr_aer(isize,itype,iphase)
1004 mw_chem_array(l) = 1.0
1005 l2 = lptr_chem_to_q(l)
1006 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1007 mw_q_array(l2) = mw_chem_array(l)
1008 IF(.NOT.CAM_INITIALIZED_CHEM) THEN
1009 cnst_mw(l2) = mw_q_array(l2)
1010 cnst_rgas(l2) = r_universal * cnst_mw(l2)
1013 qmin (l2) = qmin_num
1014 qmincg (l2) = qmin(l2)
1016 ! wrf-chem and cam units for number are identical (#/kg-air)
1017 factconv_chem_to_q(l) = 1.0
1020 l = waterptr_aer(isize,itype)
1021 if ((l >= p1st) .and. (l <= num_chem)) then
1022 mw_chem_array(l) = 18.0
1023 ! convert wrf-chem ug/kg-air to cam kg/kg-air
1024 factconv_chem_to_q(l) = 1.0e-9
1027 do ll = 1, ncomp_aer(itype)
1028 l = massptr_aer(ll,isize,itype,iphase)
1029 mw_chem_array(l) = mw_aer(ll,itype)
1030 l2 = lptr_chem_to_q(l)
1031 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1032 mw_q_array(l2) = mw_chem_array(l)
1033 IF(.NOT.CAM_INITIALIZED_CHEM) THEN
1034 cnst_mw(l2) = mw_q_array(l2)
1035 cnst_rgas(l2) = r_universal * cnst_mw(l2)
1038 qmin (l2) = qmin_aer
1039 qmincg (l2) = qmin(l2)
1041 ! convert wrf-chem ug/kg-air to cam kg/kg-air
1042 factconv_chem_to_q(l) = 1.0e-9
1048 ! conversion for cloud-borne aerosols
1050 if (nphase_aer > 1) then
1052 do itype = 1, ntype_aer
1053 do isize = 1, nsize_aer(itype)
1054 l = numptr_aer(isize,itype,iphase)
1055 if (l < p1st .or. l > num_chem) then
1056 write(*,'(a,10i10)') '*** cw_phase numb error', iphase, itype, isize, l
1058 mw_chem_array(l) = 1.0
1059 l2 = lptr_chem_to_qqcw(l)
1060 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1061 ! mw_qqcw_array(l2) = mw_chem_array(l)
1062 ! wrf-chem and cam units for number are identical (#/kg-air)
1063 factconv_chem_to_q(l) = 1.0
1067 do ll = 1, ncomp_aer(itype)
1068 l = massptr_aer(ll,isize,itype,iphase)
1069 if (l < p1st .or. l > num_chem) then
1070 write(*,'(a,10i10)') '*** cw_phase mass error', iphase, itype, isize, ll, l
1072 mw_chem_array(l) = mw_aer(ll,itype)
1073 l2 = lptr_chem_to_qqcw(l)
1074 if ((l2 >= 1) .and. (l2 <= pcnst)) then
1075 ! mw_qqcw_array(l2) = mw_chem_array(l)
1076 ! convert wrf-chem ug/kg-air to cam kg/kg-air
1077 factconv_chem_to_q(l) = 1.0e-9
1086 ! mw_q_mo_array is equivalent to the cam adv_mass array
1087 mw_q_mo_array(1:gas_pcnst) = mw_q_array(pcnst_non_chem+1:pcnst)
1090 write( *, '(/2a)' ) &
1091 'l, cnst_name, chem_name, l3, chem_name2, ', &
1092 'lptr_chem_to_q, factconv_..., mw_...'
1093 do l = 1, max( pcnst, num_chem )
1097 if (l <= pcnst) then
1098 tmpname = cnst_name_loc(l)
1099 do l2 = p1st, num_chem
1100 if (lptr_chem_to_q(l2) == l) tmpname2 = chem_dname_table(1,l2)
1105 if ((l3 >= p1st) .and. (l3 <= num_chem)) then
1106 tmpname3 = chem_dname_table(1,l3)
1107 l4 = lptr_chem_to_q(l3)
1109 if (l3 <= num_chem) then
1110 write( *, '(i4,2(2x,a),i6,2x,a,i12,1p,2e10.2)' ) &
1111 l, tmpname, tmpname2, l3, tmpname3, l4, &
1112 factconv_chem_to_q(l3), mw_chem_array(l3)
1114 write( *, '(i4,2(2x,a),i6,2x,a,i12,1p,e10.2)' ) &
1115 l, tmpname, tmpname2
1119 IF(.NOT.CAM_INITIALIZED_CHEM) CAM_INITIALIZED_CHEM = .TRUE.
1121 end subroutine cam_mam_init_other
1125 !==============================================================
1126 end module module_cam_mam_init