@@ -128,17 +128,17 @@ void MAMMicrophysics::set_grids(
128
128
constexpr int nmodes = mam4::AeroConfig::num_modes ();
129
129
130
130
// layout for 3D (ncol, nmodes, nlevs)
131
- FieldLayout scalar3d_mid_nmodes = grid_->get_3d_vector_layout (
131
+ FieldLayout vector3d_mid_nmodes = grid_->get_3d_vector_layout (
132
132
true , nmodes, mam_coupling::num_modes_tag_name ());
133
133
134
134
// Geometric mean dry diameter for number distribution [m]
135
- add_field<Required>(" dgnum" , scalar3d_mid_nmodes , m, grid_name);
135
+ add_field<Required>(" dgnum" , vector3d_mid_nmodes , m, grid_name);
136
136
// Geometric mean wet diameter for number distribution [m]
137
- add_field<Required>(" dgnumwet" , scalar3d_mid_nmodes , m, grid_name);
137
+ add_field<Required>(" dgnumwet" , vector3d_mid_nmodes , m, grid_name);
138
138
139
139
constexpr auto m3 = pow (m, 3 );
140
140
// Wet density of interstitial aerosol [kg/m3]
141
- add_field<Required>(" wetdens" , scalar3d_mid_nmodes , kg / m3, grid_name);
141
+ add_field<Required>(" wetdens" , vector3d_mid_nmodes , kg / m3, grid_name);
142
142
143
143
// For fractional land use
144
144
const FieldLayout vector2d_class =
@@ -161,12 +161,6 @@ void MAMMicrophysics::set_grids(
161
161
// Downwelling solar flux at the surface [w/m2]
162
162
add_field<Required>(" SW_flux_dn" , scalar3d_int, W / m2, grid_name);
163
163
164
- // Diagnostic fluxes
165
- const FieldLayout vector2d_nmodes =
166
- grid_->get_2d_vector_layout (nmodes, " nmodes" );
167
- add_field<Computed>(" dqdt_so4_aqueous_chemistry" , vector2d_nmodes, kg/m2/s, grid_name);
168
- add_field<Computed>(" dqdt_h2so4_uptake" , vector2d_nmodes, kg/m2/s, grid_name);
169
-
170
164
// ---------------------------------------------------------------------
171
165
// These variables are "updated" or inputs/outputs for the process
172
166
// ---------------------------------------------------------------------
@@ -181,21 +175,43 @@ void MAMMicrophysics::set_grids(
181
175
add_fields_cloudborne_aerosol ();
182
176
// ----------- Updated variables from other mam4xx processes ------------
183
177
// layout for Constituent fluxes
184
- FieldLayout scalar2d_pcnst =
178
+ FieldLayout vector2d_pcnst =
185
179
grid_->get_2d_vector_layout (mam4::pcnst, " num_phys_constituents" );
186
-
187
180
// Constituent fluxes of species in [kg/m2/s]
188
- add_field<Updated>(" constituent_fluxes" , scalar2d_pcnst , kg / m2 / s,
181
+ add_field<Updated>(" constituent_fluxes" , vector2d_pcnst , kg / m2 / s,
189
182
grid_name);
190
183
184
+ // ---------------------------------------------------------------------
185
+ // These variables are "computed" or outputs for the process
186
+ // ---------------------------------------------------------------------
191
187
// Number of externally forced chemical species
192
188
constexpr int extcnt = mam4::gas_chemistry::extcnt;
193
189
194
- FieldLayout scalar3d_extcnt = grid_->get_3d_vector_layout (true , extcnt, " ext_cnt" );
190
+ FieldLayout vector3d_extcnt = grid_->get_3d_vector_layout (true , extcnt, " ext_cnt" );
195
191
196
192
// Register computed fields for external forcing
197
193
// - extfrc: 3D instantaneous forcing rate [kg/m³/s]
198
- add_field<Computed>(" mam4_external_forcing" , scalar3d_extcnt, kg / m3 / s, grid_name);
194
+ add_field<Computed>(" mam4_external_forcing" , vector3d_extcnt, kg / m3 / s, grid_name);
195
+
196
+ // Diagnostic fluxes
197
+ const FieldLayout vector2d_nmodes =
198
+ grid_->get_2d_vector_layout (nmodes, " nmodes" );
199
+
200
+ // Register computed diagnostic fields
201
+ add_field<Computed>(" dqdt_so4_aqueous_chemistry" , vector2d_nmodes, kg/m2/s, grid_name);
202
+ add_field<Computed>(" dqdt_h2so4_uptake" , vector2d_nmodes, kg/m2/s, grid_name);
203
+
204
+ // Diagnostic fields for aerosol microphysics
205
+ extra_mam4_aero_microphys_diags_ = m_params.get <bool >(" extra_mam4_aero_microphys_diags" , false );
206
+ if (extra_mam4_aero_microphys_diags_) {
207
+ const FieldLayout vector3d_num_gas_aerosol_constituents =
208
+ grid_->get_3d_vector_layout (true , mam_coupling::gas_pcnst (), " num_gas_aerosol_constituents" );
209
+
210
+ // Fields for tendencies due to gas phase chemistry
211
+ // - dvmr/dt: Tendencies for mixing ratios [kg/kg/s]
212
+ add_field<Computed>(" mam4_microphysics_tendency_gas_phase_chemistry" , vector3d_num_gas_aerosol_constituents, kg / kg / s, grid_name);
213
+ add_field<Computed>(" mam4_microphysics_tendency_aqueous_chemistry" , vector3d_num_gas_aerosol_constituents, kg / kg / s, grid_name);
214
+ }
199
215
200
216
// Creating a Linoz reader and setting Linoz parameters involves reading data
201
217
// from a file and configuring the necessary parameters for the Linoz model.
@@ -637,6 +653,13 @@ void MAMMicrophysics::run_impl(const double dt) {
637
653
view_2d aqso4_flx = get_field_out (" dqdt_so4_aqueous_chemistry" ).get_view <Real **>();
638
654
view_2d aqh2so4_flx = get_field_out (" dqdt_h2so4_uptake" ).get_view <Real **>();
639
655
656
+ // - dvmr/dt: Tendencies for mixing ratios [kg/kg/s]
657
+ view_3d gas_phase_chemistry_dvmrdt, aqueous_chemistry_dvmrdt;
658
+ if (extra_mam4_aero_microphys_diags_) {
659
+ gas_phase_chemistry_dvmrdt = get_field_out (" mam4_microphysics_tendency_gas_phase_chemistry" ).get_view <Real ***>();
660
+ aqueous_chemistry_dvmrdt = get_field_out (" mam4_microphysics_tendency_aqueous_chemistry" ).get_view <Real ***>();
661
+ }
662
+
640
663
// climatology data for linear stratospheric chemistry
641
664
// ozone (climatology) [vmr]
642
665
auto linoz_o3_clim = buffer_.scratch [0 ];
@@ -774,18 +797,18 @@ void MAMMicrophysics::run_impl(const double dt) {
774
797
Kokkos::deep_copy (acos_cosine_zenith_, acos_cosine_zenith_host_);
775
798
}
776
799
const auto zenith_angle = acos_cosine_zenith_;
777
- constexpr int gas_pcnst = mam_coupling::gas_pcnst ();
800
+ constexpr int num_gas_aerosol_constituents = mam_coupling::gas_pcnst ();
778
801
779
802
const auto &extfrc = extfrc_;
780
803
const auto &forcings = forcings_;
781
804
constexpr int extcnt = mam4::gas_chemistry::extcnt;
782
805
783
806
const int offset_aerosol = mam4::utils::gasses_start_ind ();
784
- Real adv_mass_kg_per_moles[gas_pcnst ];
807
+ Real adv_mass_kg_per_moles[num_gas_aerosol_constituents ];
785
808
// NOTE: Making copies of clsmap_4 and permute_4 to fix undefined arrays on
786
809
// the device.
787
- int clsmap_4[gas_pcnst ], permute_4[gas_pcnst ];
788
- for (int i = 0 ; i < gas_pcnst ; ++i) {
810
+ int clsmap_4[num_gas_aerosol_constituents ], permute_4[num_gas_aerosol_constituents ];
811
+ for (int i = 0 ; i < num_gas_aerosol_constituents ; ++i) {
789
812
// NOTE: state_q is kg/kg-dry-air; adv_mass is in g/mole.
790
813
// Convert adv_mass to kg/mole as vmr_from_mmr function uses
791
814
// molec_weight_dry_air with kg/mole units
@@ -802,6 +825,8 @@ void MAMMicrophysics::run_impl(const double dt) {
802
825
const int surface_lev = nlev - 1 ; // Surface level
803
826
const auto &index_season_lai = index_season_lai_;
804
827
const int pcnst = mam4::pcnst;
828
+ const bool extra_mam4_aero_microphys_diags = extra_mam4_aero_microphys_diags_;
829
+
805
830
// NOTE: we need to initialize photo_rates_
806
831
Kokkos::deep_copy (photo_rates_,0.0 );
807
832
// loop over atmosphere columns and compute aerosol microphyscs
@@ -874,6 +899,12 @@ void MAMMicrophysics::run_impl(const double dt) {
874
899
const auto prain_icol = ekat::subview (prain, icol);
875
900
const auto work_set_het_icol = ekat::subview (work_set_het, icol);
876
901
902
+ mam4::MicrophysDiagnosticArrays diag_arrays;
903
+ if (extra_mam4_aero_microphys_diags) {
904
+ diag_arrays.gas_phase_chemistry_dvmrdt = ekat::subview (gas_phase_chemistry_dvmrdt, icol);
905
+ diag_arrays.aqueous_chemistry_dvmrdt = ekat::subview (aqueous_chemistry_dvmrdt, icol);
906
+ }
907
+
877
908
// Wind speed at the surface
878
909
const Real wind_speed =
879
910
haero::sqrt (u_wind (icol, surface_lev) * u_wind (icol, surface_lev) +
@@ -918,8 +949,8 @@ void MAMMicrophysics::run_impl(const double dt) {
918
949
// These output values need to be put somewhere:
919
950
const auto aqso4_flx_col = ekat::subview (aqso4_flx, icol); // deposition flux of so4 [mole/mole/s]
920
951
const auto aqh2so4_flx_col = ekat::subview (aqh2so4_flx, icol); // deposition flux of h2so4 [mole/mole/s]
921
- Real dflx_col[gas_pcnst ] = {}; // deposition velocity [1/cm/s]
922
- Real dvel_col[gas_pcnst ] = {}; // deposition flux [1/cm^2/s]
952
+ Real dflx_col[num_gas_aerosol_constituents ] = {}; // deposition velocity [1/cm/s]
953
+ Real dvel_col[num_gas_aerosol_constituents ] = {}; // deposition flux [1/cm^2/s]
923
954
// Output: values are dvel, dflx
924
955
// Input/Output: progs::stateq, progs::qqcw
925
956
team.team_barrier ();
@@ -937,7 +968,8 @@ void MAMMicrophysics::run_impl(const double dt) {
937
968
offset_aerosol, config.linoz .o3_sfc , config.linoz .o3_tau ,
938
969
config.linoz .o3_lbl , dry_diameter_icol, wet_diameter_icol,
939
970
wetdens_icol, dry_atm.phis (icol), cmfdqr, prain_icol, nevapr_icol,
940
- work_set_het_icol, drydep_data, aqso4_flx_col, aqh2so4_flx_col, dvel_col, dflx_col, progs);
971
+ work_set_het_icol, drydep_data, aqso4_flx_col, aqh2so4_flx_col, diag_arrays,
972
+ dvel_col, dflx_col, progs);
941
973
942
974
team.team_barrier ();
943
975
// Update constituent fluxes with gas drydep fluxes (dflx)
@@ -958,8 +990,8 @@ void MAMMicrophysics::run_impl(const double dt) {
958
990
// NOTE: These indices should match the species in extfrc_lst
959
991
// TODO: getting rid of hard-coded indices
960
992
Kokkos::Array<int , extcnt> extfrc_pcnst_index = {3 , 6 , 14 , 27 , 28 , 13 , 18 , 30 , 5 };
961
- Kokkos::Array<Real, gas_pcnst > molar_mass_g_per_mol_tmp;
962
- for (int i = 0 ; i < gas_pcnst ; ++i) {
993
+ Kokkos::Array<Real, num_gas_aerosol_constituents > molar_mass_g_per_mol_tmp;
994
+ for (int i = 0 ; i < num_gas_aerosol_constituents ; ++i) {
963
995
molar_mass_g_per_mol_tmp[i] = mam4::gas_chemistry::adv_mass[i]; // host-only access
964
996
}
965
997
0 commit comments