Open jeff-cohere opened 1 year ago
Here's the notes about indexing etc., that I mentioned.
From Brian (paraphrased):
For given
imode
in the big, concatenated arrays,qoi(mam_idx(imode,0))
is number concentration (modal qoi),mam_idx(imode,lspec>0)
is mass concentration of specieslspec
. The module basically defines new indicesmm = mam_idx(imode,0)
to simplify the local referencing to these elements, ensuring a contiguous 1-D array.
So... the max amount of modes that's currently possible in E3SM is 9
In the case of 9 modes, we have the following numbers of species/mode:
There's also the number mixing ratios for each mode, for both cloudborne and interstitial aerosols $\implies$ 18 entries
These are the density and hygroscopicity values found in the following validation inputs:
ccncalc_ts_1400.yaml
dropmixnuc_ts_1407.yaml
dropmixnuc_ts_1417.yaml
stand_dropmixnuc_ts_1407.yaml
specdens_amode: [0.1770000000E+004,0.1797693135E+309,0.1797693135E+309,
0.1000000000E+004,0.1000000000E+004,0.1700000000E+004,0.1900000000E+004,
0.2600000000E+004,0.1601000000E+004,0.0000000000E+000,0.0000000000E+000,
0.0000000000E+000,0.0000000000E+000,0.0000000000E+000]
spechygro: [0.5070000000E+000,0.1797693135E+309,0.1797693135E+309,
0.1000000083E-009,0.1400000000E+000,0.1000000013E-009,0.1160000000E+001,
0.6800000000E-001,0.1000000015E+000,0.0000000000E+000,0.0000000000E+000,
0.0000000000E+000,0.0000000000E+000,0.0000000000E+000]
So, based on comparison to aero_modes.hpp
/// mam4 aerosol densities [kg/m3]
static constexpr Real mam4_density_soa = 1000.0;
static constexpr Real mam4_density_so4 = 1770.0;
static constexpr Real mam4_density_pom = 1000.0;
static constexpr Real mam4_density_bc = 1700.0;
static constexpr Real mam4_density_nacl = 1900.0;
static constexpr Real mam4_density_dst = 2600.0;
static constexpr Real mam4_density_mom = 1601.0;
/// mam4 aerosol hygroscopicities static constexpr Real mam4_hyg_soa = 0.1; static constexpr Real mam4_hyg_so4 = 0.507; static constexpr Real mam4_hyg_pom = 1e-10; static constexpr Real mam4_hyg_bc = 1e-10; static constexpr Real mam4_hyg_nacl = 1.16; static constexpr Real mam4_hyg_dst = 0.14; static constexpr Real mam4_hyg_mom = 0.1;
- `specdens_amode` appears to have the entries:
```fortran
[so4, garbage, garbage, soa/pom, soa/pom, bc, nacl, dust, mom, <zeros>]
And for spechygro
:
[so4, junk, junk, pom/bc, dust, pom/bc, nacl, mom/soa?, mom/soa?, <zeros>]
mom/soa
value is different from that given in aero_modes.hpp
These also come from the above-referenced yaml files, so I'm leaving them here for reference
lspectype_amode: [1, 4, 5, 6, 8, 7, 9, 0, 0, 0, 0, 0, 0, 0, 1, 5, 7, 9,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 1, 6, 4, 5, 9, 0, 0, 0, 0, 0, 0, 0,
4, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
lmassptrcw_amode: [16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 24,
25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 32, 33, 34, 35,
0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
numptrcw_amode: [23, 28, 36, 40]
lmassptr_amode: [16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 24,
25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 32, 33, 34, 35,
0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
numptr_amode: [23, 28, 36, 40]
MODAL_AERO_4MODE_MOM .and. RAIN_EVAP_TO_COARSE_AERO
#elif ( defined MODAL_AERO_4MODE_MOM )
real(r8), parameter :: specmw_amode(ntot_aspectype) = (/
115.0_r8, 115.0_r8, 62.0_r8, 12.0_r8, 12.0_r8, 12.0_r8,
58.5_r8, 135.0_r8, 250092.0_r8 /)
#elif
[...]
integer, parameter :: nspec_amode(ntot_amode) = (/ 7, 4, 7, 3 /)
integer, parameter :: nspec_amode(ntot_amode) = (/ 7, 4, 3, 3 /)
[...]
integer, parameter :: ntot_aspectype = 9 character(len=*),parameter :: specname_amode(ntot_aspectype) = (/ 'sulfate', 'ammonium', 'nitrate', 'p-organic', 's-organic', 'black-c', 'seasalt', 'dust', 'm-organic' /)
[...]
real(r8), parameter :: specmw_amode(ntot_aspectype) = (/
115.0_r8, 115.0_r8, 62.0_r8, 12.0_r8, 12.0_r8, 12.0_r8,
58.5_r8, 135.0_r8, 250092.0_r8 /)
[...]
character(len=*), parameter :: modename_amode(ntot_amode) = (/
'accum', 'aitken', 'coarse', 'primary_carbon '/)
[...]
integer, parameter :: mprognum_amode(ntot_amode) = (/ 1, 1, 1, 1/)
integer, parameter :: mdiagnum_amode(ntot_amode) = (/ 0, 0, 0, 0/)
integer, parameter :: mprogsfc_amode(ntot_amode) = (/ 0, 0, 0, 0/)
integer, parameter :: mcalcwater_amode(ntot_amode) = (/ 0, 0, 0, 0/)
- From [modal_aero_initialize_data.F90](https://github.com/eagles-project/e3sm_mam4_refactor/blob/refactor-maint-2.0/components/eam/src/chemistry/modal_aero/modal_aero_initialize_data.F90#L92):
```fortran
#elif ( defined MODAL_AERO_4MODE_MOM )
xname_massptr(:nspec_amode(1),1) = (/ 'so4_a1', 'pom_a1',
'soa_a1', 'bc_a1', 'dst_a1', 'ncl_a1', 'mom_a1 ' /)
xname_massptrcw(:nspec_amode(1),1) = (/ 'so4_c1', 'pom_c1',
'soa_c1', 'bc_c1', 'dst_c1', 'ncl_c1', 'mom_c1' /)
xname_spectype(:nspec_amode(1),1) = (/ 'sulfate', 'p-organic',
's-organic', 'black-c', 'dust', 'seasalt', 'm-organic' /)
#elif ( defined MODAL_AERO_3MODE || defined MODAL_AERO_4MODE )
xname_massptr(:nspec_amode(1),1) = (/ 'so4_a1', 'pom_a1',
'soa_a1', 'bc_a1', 'dst_a1', 'ncl_a1' /)
xname_massptrcw(:nspec_amode(1),1) = (/ 'so4_c1', 'pom_c1',
'soa_c1', 'bc_c1', 'dst_c1', 'ncl_c1' /)
xname_spectype(:nspec_amode(1),1) = (/ 'sulfate', 'p-organic',
's-organic', 'black-c', 'dust', 'seasalt' /)
#endif
[...]
#elif ( defined MODAL_AERO_4MODE_MOM )
xname_massptr(:nspec_amode(2),2) = (/ 'so4_a2', 'soa_a2',
'ncl_a2', 'mom_a2' /)
xname_massptrcw(:nspec_amode(2),2) = (/ 'so4_c2', 'soa_c2',
'ncl_c2', 'mom_c2' /)
xname_spectype(:nspec_amode(2),2) = (/ 'sulfate', 's-organic',
'seasalt', 'm-organic' /)
#elif
[...]
#elif ( defined MODAL_AERO_4MODE_MOM )
! mode 3 (coarse dust & seasalt) species
#if (defined RAIN_EVAP_TO_COARSE_AERO)
xname_massptr(:nspec_amode(3),3) = (/ 'dst_a3',
'ncl_a3', 'so4_a3', 'bc_a3', 'pom_a3', 'soa_a3', 'mom_a3' /)
xname_massptrcw(:nspec_amode(3),3) = (/ 'dst_c3',
'ncl_c3', 'so4_c3', 'bc_c3', 'pom_c3', 'soa_c3', 'mom_c3' /)
xname_spectype(:nspec_amode(3),3) = (/ 'dust', 'seasalt',
'sulfate', 'black-c', 'p-organic', 's-organic', 'm-organic' /)
#else
xname_massptr(:nspec_amode(3),3) = (/ 'dst_a3', 'ncl_a3',
'so4_a3' /)
xname_massptrcw(:nspec_amode(3),3) = (/ 'dst_c3', 'ncl_c3',
'so4_c3' /)
xname_spectype(:nspec_amode(3),3) = (/ 'dust', 'seasalt',
'sulfate' /)
#endif
#endif
[...]
#if ( defined MODAL_AERO_4MODE_MOM )
! mode 4 (primary carbon) species
xname_massptr(:nspec_amode(4),4) = (/ 'pom_a4', 'bc_a4',
'mom_a4' /)
xname_massptrcw(:nspec_amode(4),4) = (/ 'pom_c4', 'bc_c4',
'mom_c4' /)
xname_spectype(:nspec_amode(4),4) = (/ 'p-organic', 'black-c',
'm-organic' /)
#elif
I'm making some progress here. Some diagnostic quantities apparently are needed in order to compute aerosol microphysics, so perhaps we need to do this during initialization. The required diagnostic (modal) quantities are
dgncur_a
and dgncur_awet
: wet and dry geometric particle diameters [m] (mean or nominal? Total or interstitial?)wetdens
: the wet density of aerosols [kg/m3]qaerwat
: the aerosol water mass mixing ratio [kg/kg]All but qaerwat
currently exist in the Diagnostics
type. Once I figure out how to compute qaerwat
, I'll probably put up a little PR to add an aerosol_water_mass_mixing_ratio
field to Diagnostics
.
Copying @pressel because he's got the most fingerprints on Diagnostics
, if I'm not mistaken.
This issue is my scratch space for bringing all of the mam4xx aerosol microphysics parameterizations into their corresponding EAMxx AtmosphereProcess subclass. This code is not part of mam4xx's parameterizations, so I'm taking the liberty of eliminating unneeded code and changing its structure as needed.
I'm working in this branch.
Code Inventory
The code to be transplanted to EAMxx is in mam4_amicphys_1gridcell.cpp, a test suite assembled by @overfelt
Functions (subroutines)
modal_aero_amicphys_intr
: top-level "driver" subroutine for performing all aerosol microphysics calculationsconstruct_subareas_1gridcell
: determines the number of "sub-areas" (subvolumes?) within a given cell (1 for cloudy/clear cells and 2 for partially cloudy cells) and computes sub-area mean mixing ratiossubarea_partition_factors
: sets the interstitial mixing ratios in the sub-areas of a cell (called byconstruct_subareas_1gridcell
)mam_amicphys_1gridcell
: determines whether a cell is cloudy or clear and dispatches microphysics calculationsmam_amicphys_1subarea_cloudy
: computes cloudy-sky microphysics within a single subareamam_amicphys_1subarea_clear
: computes clear-sky microphysics within a single subareaConstants
Many of these seem related to history data that we may dispose of, since legacy MAM's I/O model ("write anything out whenever you want") won't work with GPUs. Also, there are some weird-looking "conversion factors" that might not actually be used.
int nqtendaa (5)
: number of contributions tracked for different parameterizations, used to write history dataint nqtendbb (4)
: number of tendencies recorded for box-model diagnostic output for different parameterizationsint nqqcwtendaa (1)
: a variant ofnqtendaa
(not sure of its original purpose)int nqqcwtendbb (1)
: a variant ofnqtendbb
(not sure of its original purpose)int iqtend_cond (0)
: the index of conduction contributions in e.g.qX_delaa
int iqtend_rnam (1)
: the index of rename contributions in e.g.qX_delaa
int iqtend_nnuc (2)
: the index of nucleation contributions in e.g.qX_delaa
int iqtend_coag (3)
: the index of coagulation contributions in e.g.qX_delaa
int iqtend_cond_only (4)
: the index of conduction contributions when only conduction is considered (?)int iqqcwtend_rnam (0)
: a variant ofiqtend_rnam
related tonqqcwtendaa
int maxsubarea (2)
: the maximum number of "subareas" in a cell (clear cells have 1 "clear subarea", cloudy cells have 1 "cloudy" subarea, partially cloudy cells have 1 "clear" and 1 "cloudy" subarea)Real fcvt_gas[AeroConfig::num_gas_ids()] ({1, 1, 1})
: conversion factors for converting gas mixing ratios from (kg/kg) to (mol/mol) (?)Real fcvt_aer[AeroConfig::num_aerosol_ids()] ({1, 1, 1, 1, 1, 1, 1})
; conversion factors for converting aerosol mixing ratios from (kg/kg) to (mol/mol) (?)Real fcvt_num (1.0)
: leave number mix-ratios unchanged (#/kmol-air)Real fcvt_wtr (1.0)
: factor for converting aerosol water mix-ratios from (kg/kg) to (mol/mol)int gaexch_h2so4_uptake_optaa (2)
: controls treatment of h2so4 condensation in mam_gasaerexch_1subarea (1 = sequential calc. of gas-chem prod then condensation loss; 2 = simultaneous calc. of gas-chem prod and condensation loss)Indexing Shenanigans
I'm not sure any of this stuff will survive the integration process. :-)
static constexpr int lmapcc_val_nul = 0; static constexpr int lmapcc_val_gas = 1; static constexpr int lmapcc_val_aer = 2; static constexpr int lmapcc_val_num = 3; static constexpr int gas_pcnst = 30; const int lmapcc_all[gas_pcnst] = { lmapcc_val_nul, lmapcc_val_gas, lmapcc_val_nul, lmapcc_val_nul, lmapcc_val_gas, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_num, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_num, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_num, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_aer, lmapcc_val_num};
// Where lmapcc_val_num are defined in lmapcc_all const int numptr_amode[AeroConfig::num_modes()] = {12, 17, 25, 29}; // Where lmapcc_val_gas are defined in lmapcc_all const int lmap_gas[AeroConfig::num_modes()] = {4, 1};
Notes
nstep
andncol
are passed to many subroutines but aren't useddeltat
is used to compute gas production and nucleation ratesAerosol Microphysics Configuration
These parameters can be set to allow specific test/diagnostic setups for analyzing the effects of aerosol microphysics in EAMxx simulations.