From 1f470ad3ac33c6b48315eb1948507ad6cbdc19ed Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 15 May 2024 17:50:59 -0600 Subject: [PATCH] EAMxx: fix usage of ekat's Units --- .../atmosphere_surface_coupling_exporter.cpp | 25 +++---- .../atmosphere_surface_coupling_importer.cpp | 8 +- .../eamxx/src/diagnostics/atm_density.cpp | 11 +-- .../src/diagnostics/dry_static_energy.cpp | 16 ++-- .../diagnostics/longwave_cloud_forcing.cpp | 6 +- .../eamxx/src/diagnostics/number_path.cpp | 5 +- .../src/diagnostics/potential_temperature.cpp | 5 +- .../src/diagnostics/relative_humidity.cpp | 12 ++- .../src/diagnostics/sea_level_pressure.cpp | 6 +- .../diagnostics/shortwave_cloud_forcing.cpp | 13 ++-- .../surf_upward_latent_heat_flux.cpp | 8 +- .../eamxx/src/diagnostics/vapor_flux.cpp | 12 +-- .../eamxx/src/diagnostics/vertical_layer.cpp | 8 +- .../src/diagnostics/virtual_temperature.cpp | 7 +- .../eamxx/src/diagnostics/water_path.cpp | 8 +- .../dynamics/homme/eamxx_homme_fv_phys.cpp | 6 +- .../homme/eamxx_homme_process_interface.cpp | 10 +-- .../dynamics/homme/homme_grids_manager.cpp | 14 ++-- .../eamxx_cld_fraction_process_interface.cpp | 4 +- .../eamxx/src/physics/cosp/eamxx_cosp.cpp | 16 ++-- ...mxx_mam_microphysics_process_interface.cpp | 21 +++--- .../eamxx_mam_optics_process_interface.cpp | 21 +++--- .../eamxx_ml_correction_process_interface.cpp | 22 +++--- .../eamxx_nudging_process_interface.cpp | 4 +- .../physics/p3/eamxx_p3_process_interface.cpp | 43 ++++++----- .../rrtmgp/eamxx_rrtmgp_process_interface.cpp | 75 +++++++++---------- .../shoc/eamxx_shoc_process_interface.cpp | 27 +++---- .../spa/eamxx_spa_process_interface.cpp | 4 - .../tms/eamxx_tms_process_interface.cpp | 10 +-- .../physics/zm/eamxx_zm_process_interface.cpp | 11 +-- .../atm_process/atmosphere_process_dag.cpp | 2 +- .../src/share/field/field_identifier.cpp | 2 +- .../eamxx/src/share/field/field_manager.cpp | 4 +- .../share/grid/mesh_free_grids_manager.cpp | 13 ++-- .../eamxx/src/share/io/scorpio_output.cpp | 2 +- 35 files changed, 189 insertions(+), 272 deletions(-) diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_exporter.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_exporter.cpp index dfdea16ae93..7a0253ec908 100644 --- a/components/eamxx/src/control/atmosphere_surface_coupling_exporter.cpp +++ b/components/eamxx/src/control/atmosphere_surface_coupling_exporter.cpp @@ -25,15 +25,8 @@ void SurfaceCouplingExporter::set_grids(const std::shared_ptrget_num_local_dofs(); // Number of columns on this rank m_num_levs = m_grid->get_num_vertical_levels(); // Number of levels per column - const auto m2 = m*m; - const auto s2 = s*s; - auto Wm2 = W/m2; - Wm2.set_string("W/m2"); - - // The units of mixing ratio Q are technically non-dimensional. - // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Qunit = kg/kg; - Qunit.set_string("kg/kg"); + Units m2 (m*m,"m2"); + Units s2 (s*s,"s2"); // Define the different field layouts that will be used for this process using namespace ShortFieldTagsNames; @@ -50,16 +43,16 @@ void SurfaceCouplingExporter::set_grids(const std::shared_ptr("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); add_field("phis", scalar2d_layout, m2/s2, grid_name); add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); - add_field("qv", scalar3d_layout_mid, Qunit, grid_name, "tracers", ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); add_field("T_mid", scalar3d_layout_mid, K, grid_name, ps); // TODO: Switch horiz_winds to using U and V, note right now there is an issue with when the subfields are created, so can't switch yet. add_field("horiz_winds", vector3d_layout, m/s, grid_name); - add_field("sfc_flux_dir_nir", scalar2d_layout, Wm2, grid_name); - add_field("sfc_flux_dir_vis", scalar2d_layout, Wm2, grid_name); - add_field("sfc_flux_dif_nir", scalar2d_layout, Wm2, grid_name); - add_field("sfc_flux_dif_vis", scalar2d_layout, Wm2, grid_name); - add_field("sfc_flux_sw_net" , scalar2d_layout, Wm2, grid_name); - add_field("sfc_flux_lw_dn" , scalar2d_layout, Wm2, grid_name); + add_field("sfc_flux_dir_nir", scalar2d_layout, W/m2, grid_name); + add_field("sfc_flux_dir_vis", scalar2d_layout, W/m2, grid_name); + add_field("sfc_flux_dif_nir", scalar2d_layout, W/m2, grid_name); + add_field("sfc_flux_dif_vis", scalar2d_layout, W/m2, grid_name); + add_field("sfc_flux_sw_net" , scalar2d_layout, W/m2, grid_name); + add_field("sfc_flux_lw_dn" , scalar2d_layout, W/m2, grid_name); add_field("precip_liq_surf_mass", scalar2d_layout, kg/m2, grid_name); add_field("precip_ice_surf_mass", scalar2d_layout, kg/m2, grid_name); diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp index e816801fa61..52deba16e8d 100644 --- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp +++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp @@ -28,12 +28,8 @@ void SurfaceCouplingImporter::set_grids(const std::shared_ptr("surf_mom_flux", vector2d_layout, N/m2, grid_name); add_field("surf_radiative_T", scalar2d_layout, K, grid_name); add_field("T_2m", scalar2d_layout, K, grid_name); - add_field("qv_2m", scalar2d_layout, Qunit, grid_name); + add_field("qv_2m", scalar2d_layout, kg/kg, grid_name); add_field("wind_speed_10m", scalar2d_layout, m/s, grid_name); add_field("snow_depth_land", scalar2d_layout, m, grid_name); add_field("ocnfrac", scalar2d_layout, nondim, grid_name); diff --git a/components/eamxx/src/diagnostics/atm_density.cpp b/components/eamxx/src/diagnostics/atm_density.cpp index 24749ba1a1e..8f1e8b77b54 100644 --- a/components/eamxx/src/diagnostics/atm_density.cpp +++ b/components/eamxx/src/diagnostics/atm_density.cpp @@ -16,9 +16,6 @@ void AtmDensityDiagnostic::set_grids(const std::shared_ptr g using namespace ekat::units; using namespace ShortFieldTagsNames; - auto Q = kg/kg; - Q.set_string("kg/kg"); - // Boiler Plate auto grid = grids_manager->get_grid("Physics"); const auto& grid_name = grid->name(); @@ -29,10 +26,10 @@ void AtmDensityDiagnostic::set_grids(const std::shared_ptr g FieldLayout scalar3d_layout_mid { {COL,LEV}, {m_num_cols,m_num_levs} }; // The fields required for this diagnostic to be computed - add_field("T_mid", scalar3d_layout_mid, K, grid_name, SCREAM_PACK_SIZE); - add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); - add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); - add_field("qv", scalar3d_layout_mid, Q, grid_name, SCREAM_PACK_SIZE); + add_field("T_mid", scalar3d_layout_mid, K, grid_name, SCREAM_PACK_SIZE); + add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); + add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, SCREAM_PACK_SIZE); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar3d_layout_mid, kg/(m*m*m), grid_name); diff --git a/components/eamxx/src/diagnostics/dry_static_energy.cpp b/components/eamxx/src/diagnostics/dry_static_energy.cpp index f4ed33ca56b..8b0264dd053 100644 --- a/components/eamxx/src/diagnostics/dry_static_energy.cpp +++ b/components/eamxx/src/diagnostics/dry_static_energy.cpp @@ -20,10 +20,8 @@ void DryStaticEnergyDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); @@ -35,11 +33,11 @@ void DryStaticEnergyDiagnostic::set_grids(const std::shared_ptr("T_mid", scalar3d_layout_mid, K, grid_name, ps); - add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); - add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); - add_field("qv", scalar3d_layout_mid, Q, grid_name, ps); - add_field("phis", scalar2d_layout_col, m2/s2, grid_name, ps); + add_field("T_mid", scalar3d_layout_mid, K, grid_name, ps); + add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); + add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, ps); + add_field("phis", scalar2d_layout_col, m2/s2, grid_name, ps); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar3d_layout_mid, m2/s2, grid_name); diff --git a/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp b/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp index 4e44dff9dc7..49109b64ef7 100644 --- a/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp +++ b/components/eamxx/src/diagnostics/longwave_cloud_forcing.cpp @@ -18,9 +18,7 @@ void LongwaveCloudForcingDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); @@ -35,7 +33,7 @@ void LongwaveCloudForcingDiagnostic::set_grids(const std::shared_ptr("LW_clrsky_flux_up", scalar3d_layout_mid, W/m2, grid_name); // Construct and allocate the diagnostic field - FieldIdentifier fid (name(), scalar2d_layout_col, radflux_units, grid_name); + FieldIdentifier fid (name(), scalar2d_layout_col, W/m2, grid_name); m_diagnostic_output = Field(fid); auto& C_ap = m_diagnostic_output.get_header().get_alloc_properties(); C_ap.request_allocation(); diff --git a/components/eamxx/src/diagnostics/number_path.cpp b/components/eamxx/src/diagnostics/number_path.cpp index 6ce0e773b68..d4df2f1bc22 100644 --- a/components/eamxx/src/diagnostics/number_path.cpp +++ b/components/eamxx/src/diagnostics/number_path.cpp @@ -39,8 +39,7 @@ void NumberPathDiagnostic::set_grids( const std::shared_ptr grids_manager) { using namespace ekat::units; - auto out_units = kg / (kg * m * m); - out_units.set_string("kg/(kg m2)"); + auto m2 = pow(m,2); auto grid = grids_manager->get_grid("Physics"); const auto &grid_name = grid->name(); @@ -56,7 +55,7 @@ void NumberPathDiagnostic::set_grids( add_field(m_nname, scalar3d, 1 / kg, grid_name); // Construct and allocate the diagnostic field - FieldIdentifier fid(name(), scalar2d, out_units, grid_name); + FieldIdentifier fid(name(), scalar2d, kg/(kg*m2), grid_name); m_diagnostic_output = Field(fid); m_diagnostic_output.allocate_view(); } diff --git a/components/eamxx/src/diagnostics/potential_temperature.cpp b/components/eamxx/src/diagnostics/potential_temperature.cpp index 988bb555224..67260e647f6 100644 --- a/components/eamxx/src/diagnostics/potential_temperature.cpp +++ b/components/eamxx/src/diagnostics/potential_temperature.cpp @@ -35,9 +35,6 @@ void PotentialTemperatureDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); m_num_cols = grid->get_num_local_dofs(); // Number of columns on this rank @@ -51,7 +48,7 @@ void PotentialTemperatureDiagnostic::set_grids(const std::shared_ptr("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); // Only needed for LiqPotentialTemperature, but put it here for ease // TODO: only request it if it is needed - add_field("qc", scalar3d_layout_mid, Q, grid_name, ps); + add_field("qc", scalar3d_layout_mid, kg/kg, grid_name, ps); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar3d_layout_mid, K, grid_name); diff --git a/components/eamxx/src/diagnostics/relative_humidity.cpp b/components/eamxx/src/diagnostics/relative_humidity.cpp index e7ceca4b895..909213a95b6 100644 --- a/components/eamxx/src/diagnostics/relative_humidity.cpp +++ b/components/eamxx/src/diagnostics/relative_humidity.cpp @@ -18,8 +18,6 @@ void RelativeHumidityDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); @@ -29,11 +27,11 @@ void RelativeHumidityDiagnostic::set_grids(const std::shared_ptr("T_mid", scalar3d_layout_mid, K, grid_name, SCREAM_PACK_SIZE); - add_field("p_dry_mid", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); - add_field("qv", scalar3d_layout_mid, Q, grid_name, SCREAM_PACK_SIZE); - add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); - add_field("pseudo_density_dry", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); + add_field("T_mid", scalar3d_layout_mid, K, grid_name, SCREAM_PACK_SIZE); + add_field("p_dry_mid", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, SCREAM_PACK_SIZE); + add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); + add_field("pseudo_density_dry", scalar3d_layout_mid, Pa, grid_name, SCREAM_PACK_SIZE); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar3d_layout_mid, nondim, grid_name); diff --git a/components/eamxx/src/diagnostics/sea_level_pressure.cpp b/components/eamxx/src/diagnostics/sea_level_pressure.cpp index 54f6b52fbea..fdbab884762 100644 --- a/components/eamxx/src/diagnostics/sea_level_pressure.cpp +++ b/components/eamxx/src/diagnostics/sea_level_pressure.cpp @@ -17,10 +17,8 @@ void SeaLevelPressureDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); diff --git a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp index 9ca5ea4a8a1..89b687123f9 100644 --- a/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp +++ b/components/eamxx/src/diagnostics/shortwave_cloud_forcing.cpp @@ -17,8 +17,7 @@ void ShortwaveCloudForcingDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); @@ -29,13 +28,13 @@ void ShortwaveCloudForcingDiagnostic::set_grids(const std::shared_ptr("SW_flux_dn", scalar3d_layout_mid, radflux_units, grid_name); - add_field("SW_flux_up", scalar3d_layout_mid, radflux_units, grid_name); - add_field("SW_clrsky_flux_dn", scalar3d_layout_mid, radflux_units, grid_name); - add_field("SW_clrsky_flux_up", scalar3d_layout_mid, radflux_units, grid_name); + add_field("SW_flux_dn", scalar3d_layout_mid, W/m2, grid_name); + add_field("SW_flux_up", scalar3d_layout_mid, W/m2, grid_name); + add_field("SW_clrsky_flux_dn", scalar3d_layout_mid, W/m2, grid_name); + add_field("SW_clrsky_flux_up", scalar3d_layout_mid, W/m2, grid_name); // Construct and allocate the diagnostic field - FieldIdentifier fid (name(), scalar2d_layout_col, radflux_units, grid_name); + FieldIdentifier fid (name(), scalar2d_layout_col, W/m2, grid_name); m_diagnostic_output = Field(fid); auto& C_ap = m_diagnostic_output.get_header().get_alloc_properties(); C_ap.request_allocation(); diff --git a/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp b/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp index 009f8e6dd77..91ee2833888 100644 --- a/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp +++ b/components/eamxx/src/diagnostics/surf_upward_latent_heat_flux.cpp @@ -20,10 +20,8 @@ SurfaceUpwardLatentHeatFlux(const ekat::Comm& comm, const ekat::ParameterList& p void SurfaceUpwardLatentHeatFlux:: set_grids (const std::shared_ptr grids_manager) { - const auto m2 = ekat::units::m * ekat::units::m; - const auto W = ekat::units::W; - auto radflux_units = W/(m2); - radflux_units.set_string("W/m2"); + using namespace ekat::units; + Units m2(m*m,"m2"); const auto surf_evap_units = ekat::units::kg / m2 / ekat::units::s; @@ -38,7 +36,7 @@ set_grids (const std::shared_ptr grids_manager) add_field("surf_evap", scalar2d_layout_mid, surf_evap_units, grid_name); // Construct and allocate the diagnostic field - FieldIdentifier fid(name(), scalar2d_layout_mid, radflux_units, grid_name); + FieldIdentifier fid(name(), scalar2d_layout_mid, W/m2, grid_name); // handle parent class member variables m_diagnostic_output = Field(fid); m_diagnostic_output.get_header().get_alloc_properties().request_allocation(); diff --git a/components/eamxx/src/diagnostics/vapor_flux.cpp b/components/eamxx/src/diagnostics/vapor_flux.cpp index 66abf10d5bb..ce88c144301 100644 --- a/components/eamxx/src/diagnostics/vapor_flux.cpp +++ b/components/eamxx/src/diagnostics/vapor_flux.cpp @@ -36,12 +36,6 @@ void VaporFluxDiagnostic::set_grids(const std::shared_ptr gr using namespace ekat::units; using namespace ShortFieldTagsNames; - auto Q = kg/kg; - Q.set_string("kg/kg"); - - auto vel = m/s; - vel.set_string("m/s"); - auto grid = grids_manager->get_grid("Physics"); const auto& grid_name = grid->name(); m_num_cols = grid->get_num_local_dofs(); // Number of columns on this rank @@ -52,9 +46,9 @@ void VaporFluxDiagnostic::set_grids(const std::shared_ptr gr auto vector3d = grid->get_3d_vector_layout(true,2); // The fields required for this diagnostic to be computed - add_field("pseudo_density", scalar3d, Pa, grid_name); - add_field("qv", scalar3d, Q, grid_name); - add_field("horiz_winds", vector3d, m/s, grid_name); + add_field("pseudo_density", scalar3d, Pa, grid_name); + add_field("qv", scalar3d, kg/kg, grid_name); + add_field("horiz_winds", vector3d, m/s, grid_name); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar2d, kg/m/s, grid_name); diff --git a/components/eamxx/src/diagnostics/vertical_layer.cpp b/components/eamxx/src/diagnostics/vertical_layer.cpp index ad6b785d2af..8766649cbaf 100644 --- a/components/eamxx/src/diagnostics/vertical_layer.cpp +++ b/components/eamxx/src/diagnostics/vertical_layer.cpp @@ -29,10 +29,8 @@ set_grids(const std::shared_ptr grids_manager) using namespace ekat::units; using namespace ShortFieldTagsNames; - auto Q = kg/kg; - Q.set_string("kg/kg"); - auto m2 = m*m; - auto s2 = s*s; + auto m2 = pow(m,2); + auto s2 = pow(s,2); auto grid = grids_manager->get_grid("Physics"); const auto& grid_name = grid->name(); @@ -48,7 +46,7 @@ set_grids(const std::shared_ptr grids_manager) add_field("T_mid", scalar3d_layout_mid, K, grid_name, ps); add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); - add_field("qv", scalar3d_layout_mid, Q, grid_name, ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, ps); // Only need phis if computing geopotential_* if (not m_only_compute_dz and not m_from_sea_level) { diff --git a/components/eamxx/src/diagnostics/virtual_temperature.cpp b/components/eamxx/src/diagnostics/virtual_temperature.cpp index 9ddcd18549b..47b042ffb09 100644 --- a/components/eamxx/src/diagnostics/virtual_temperature.cpp +++ b/components/eamxx/src/diagnostics/virtual_temperature.cpp @@ -15,9 +15,6 @@ void VirtualTemperatureDiagnostic::set_grids(const std::shared_ptrget_grid("Physics"); const auto& grid_name = grid->name(); m_num_cols = grid->get_num_local_dofs(); // Number of columns on this rank @@ -27,8 +24,8 @@ void VirtualTemperatureDiagnostic::set_grids(const std::shared_ptr("T_mid", scalar3d_layout_mid, K, grid_name, ps); - add_field("qv", scalar3d_layout_mid, Q, grid_name, ps); + add_field("T_mid", scalar3d_layout_mid, K, grid_name, ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, ps); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar3d_layout_mid, K, grid_name); diff --git a/components/eamxx/src/diagnostics/water_path.cpp b/components/eamxx/src/diagnostics/water_path.cpp index 2e8da274bfb..15fa5cdef38 100644 --- a/components/eamxx/src/diagnostics/water_path.cpp +++ b/components/eamxx/src/diagnostics/water_path.cpp @@ -42,9 +42,7 @@ set_grids(const std::shared_ptr grids_manager) { using namespace ekat::units; - const auto m2 = m*m; - auto Q = kg/kg; - Q.set_string("kg/kg"); + auto m2 = pow (m,2); auto grid = grids_manager->get_grid("Physics"); const auto& grid_name = grid->name(); @@ -55,8 +53,8 @@ set_grids(const std::shared_ptr grids_manager) auto scalar3d = grid->get_3d_scalar_layout(true); // The fields required for this diagnostic to be computed - add_field("pseudo_density", scalar3d, Pa, grid_name); - add_field(m_qname, scalar3d, Q, grid_name); + add_field("pseudo_density", scalar3d, Pa, grid_name); + add_field(m_qname, scalar3d, kg/kg, grid_name); // Construct and allocate the diagnostic field FieldIdentifier fid (name(), scalar2d, kg/m2, grid_name); diff --git a/components/eamxx/src/dynamics/homme/eamxx_homme_fv_phys.cpp b/components/eamxx/src/dynamics/homme/eamxx_homme_fv_phys.cpp index 4e815c7266a..a121600536b 100644 --- a/components/eamxx/src/dynamics/homme/eamxx_homme_fv_phys.cpp +++ b/components/eamxx/src/dynamics/homme/eamxx_homme_fv_phys.cpp @@ -238,8 +238,6 @@ ::fv_phys_rrtmgp_active_gases_init (const std::shared_ptr& g if (trace_gases_workaround.is_restart()) return; // always false b/c it hasn't been set yet using namespace ekat::units; using namespace ShortFieldTagsNames; - auto molmol = mol/mol; - molmol.set_string("mol/mol"); const auto& rgn = m_cgll_grid->name(); const auto& pgn = m_phys_grid->name(); const auto rnc = m_cgll_grid->get_num_local_dofs(); @@ -247,10 +245,10 @@ ::fv_phys_rrtmgp_active_gases_init (const std::shared_ptr& g const auto nlev = m_cgll_grid->get_num_vertical_levels(); constexpr int ps = SCREAM_SMALL_PACK_SIZE; for (const auto& e : trace_gases_workaround.get_active_gases()) { - add_field(e, FieldLayout({COL,LEV},{rnc,nlev}), molmol, rgn, ps); + add_field(e, FieldLayout({COL,LEV},{rnc,nlev}), mol/mol, rgn, ps); // 'Updated' rather than just 'Computed' so that it gets written to the // restart file. - add_field(e, FieldLayout({COL,LEV},{pnc,nlev}), molmol, pgn, ps); + add_field(e, FieldLayout({COL,LEV},{pnc,nlev}), mol/mol, pgn, ps); } trace_gases_workaround.set_remapper(gm->create_remapper(m_cgll_grid, m_dyn_grid)); } diff --git a/components/eamxx/src/dynamics/homme/eamxx_homme_process_interface.cpp b/components/eamxx/src/dynamics/homme/eamxx_homme_process_interface.cpp index dfd116b0832..5c71bf92244 100644 --- a/components/eamxx/src/dynamics/homme/eamxx_homme_process_interface.cpp +++ b/components/eamxx/src/dynamics/homme/eamxx_homme_process_interface.cpp @@ -115,10 +115,6 @@ void HommeDynamics::set_grids (const std::shared_ptr grids_m constexpr int QTL = HOMMEXX_Q_NUM_TIME_LEVELS; constexpr int N = HOMMEXX_PACK_SIZE; - // Some units - auto Q = kg/kg; - Q.set_string("kg/kg"); - const int nelem = m_dyn_grid->get_num_local_dofs()/(NGP*NGP); const int nlev_mid = m_dyn_grid->get_num_vertical_levels(); const int nlev_int = nlev_mid+1; @@ -161,8 +157,8 @@ void HommeDynamics::set_grids (const std::shared_ptr grids_m // into the n0 time-slice of Homme's vtheta_dp, and then do the conversion // T_mid->VTheta_dp in place. - const auto m2 = m*m; - const auto s2 = s*s; + const auto m2 = pow(m,2); + const auto s2 = pow(s,2); // Note: qv is needed to transform T<->Theta @@ -176,7 +172,7 @@ void HommeDynamics::set_grids (const std::shared_ptr grids_m add_field("pseudo_density", pg_scalar3d_mid, Pa, pgn,N); add_field("pseudo_density_dry", pg_scalar3d_mid, Pa, pgn,N); add_field ("ps", pg_scalar2d , Pa, pgn); - add_field("qv", pg_scalar3d_mid, Q, pgn,"tracers",N); + add_field("qv", pg_scalar3d_mid, kg/kg, pgn,"tracers",N); add_field("phis", pg_scalar2d , m2/s2, pgn); add_field("p_int", pg_scalar3d_int, Pa, pgn,N); add_field("p_mid", pg_scalar3d_mid, Pa, pgn,N); diff --git a/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp b/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp index 270f1ffbdda..87009c7d074 100644 --- a/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp +++ b/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp @@ -140,6 +140,7 @@ void HommeGridsManager::build_dynamics_grid () { } using gid_type = AbstractGrid::gid_type; + using namespace ekat::units; // Get dimensions and create "empty" grid const int nlelem = get_num_local_elems_f90(); @@ -149,7 +150,7 @@ void HommeGridsManager::build_dynamics_grid () { dyn_grid->setSelfPointer(dyn_grid); const auto layout2d = dyn_grid->get_2d_scalar_layout(); - const auto rad = ekat::units::Units::nondimensional(); + const Units rad (Units::nondimensional(),"rad"); // Filling the cg/dg gids, elgpgp, coords, lat/lon views auto dg_dofs = dyn_grid->get_dofs_gids(); @@ -218,8 +219,9 @@ build_physics_grid (const ci_string& type, const ci_string& rebalance) { // Create the gids, coords, area views using namespace ShortFieldTagsNames; + using namespace ekat::units; const auto layout2d = phys_grid->get_2d_scalar_layout(); - const auto rad = ekat::units::Units::nondimensional(); + const Units rad (Units::nondimensional(),"rad"); auto dofs = phys_grid->get_dofs_gids(); auto lat = phys_grid->create_geometry_data("lat",layout2d,rad); @@ -260,15 +262,15 @@ build_physics_grid (const ci_string& type, const ci_string& rebalance) { if (get_grid("Dynamics")->has_geometry_data("hyam")) { auto layout_mid = phys_grid->get_vertical_layout(true); auto layout_int = phys_grid->get_vertical_layout(false); - const auto nondim = ekat::units::Units::nondimensional(); - auto lev_unit = ekat::units::Units::nondimensional();; - lev_unit.set_string("mb"); + using namespace ekat::units; + Units nondim = Units::nondimensional(); + Units mbar(bar/1000,"mb"); auto hyai = phys_grid->create_geometry_data("hyai",layout_int,nondim); auto hybi = phys_grid->create_geometry_data("hybi",layout_int,nondim); auto hyam = phys_grid->create_geometry_data("hyam",layout_mid,nondim); auto hybm = phys_grid->create_geometry_data("hybm",layout_mid,nondim); - auto lev = phys_grid->create_geometry_data("lev", layout_mid, lev_unit); + auto lev = phys_grid->create_geometry_data("lev", layout_mid,mbar); for (auto f : {hyai, hybi, hyam, hybm}) { auto f_d = get_grid("Dynamics")->get_geometry_data(f.name()); diff --git a/components/eamxx/src/physics/cld_fraction/eamxx_cld_fraction_process_interface.cpp b/components/eamxx/src/physics/cld_fraction/eamxx_cld_fraction_process_interface.cpp index 28015bc7e9a..6a7b2bf04e8 100644 --- a/components/eamxx/src/physics/cld_fraction/eamxx_cld_fraction_process_interface.cpp +++ b/components/eamxx/src/physics/cld_fraction/eamxx_cld_fraction_process_interface.cpp @@ -24,8 +24,6 @@ void CldFraction::set_grids(const std::shared_ptr grids_mana // The units of mixing ratio Q are technically non-dimensional. // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Q = kg/kg; - Q.set_string("kg/kg"); auto nondim = Units::nondimensional(); m_grid = grids_manager->get_grid("Physics"); @@ -40,7 +38,7 @@ void CldFraction::set_grids(const std::shared_ptr grids_mana // Set of fields used strictly as input constexpr int ps = Pack::n; - add_field("qi", scalar3d_layout_mid, Q, grid_name,"tracers",ps); + add_field("qi", scalar3d_layout_mid, kg/kg, grid_name,"tracers",ps); add_field("cldfrac_liq", scalar3d_layout_mid, nondim, grid_name,ps); // Set of fields used strictly as output diff --git a/components/eamxx/src/physics/cosp/eamxx_cosp.cpp b/components/eamxx/src/physics/cosp/eamxx_cosp.cpp index d3d146797d1..0f4b9f1559e 100644 --- a/components/eamxx/src/physics/cosp/eamxx_cosp.cpp +++ b/components/eamxx/src/physics/cosp/eamxx_cosp.cpp @@ -31,16 +31,14 @@ Cosp::Cosp (const ekat::Comm& comm, const ekat::ParameterList& params) void Cosp::set_grids(const std::shared_ptr grids_manager) { using namespace ekat::units; + using namespace ekat::prefixes; using namespace ShortFieldTagsNames; // The units of mixing ratio Q are technically non-dimensional. // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Q = kg/kg; - Q.set_string("kg/kg"); - auto nondim = Units::nondimensional(); - auto percent = Units::nondimensional(); - percent.set_string("%"); - auto micron = m / 1000000; + Units nondim = Units::nondimensional(); + Units percent (nondim,"%"); + auto micron = micro*m; m_grid = grids_manager->get_grid("Physics"); const auto& grid_name = m_grid->name(); @@ -68,9 +66,9 @@ void Cosp::set_grids(const std::shared_ptr grids_manager) //add_field("height_mid", scalar3d_mid, m, grid_name); //add_field("height_int", scalar3d_int, m, grid_name); add_field("T_mid", scalar3d_mid, K, grid_name); - add_field("qv", scalar3d_mid, Q, grid_name, "tracers"); - add_field("qc", scalar3d_mid, Q, grid_name, "tracers"); - add_field("qi", scalar3d_mid, Q, grid_name, "tracers"); + add_field("qv", scalar3d_mid, kg/kg, grid_name, "tracers"); + add_field("qc", scalar3d_mid, kg/kg, grid_name, "tracers"); + add_field("qi", scalar3d_mid, kg/kg, grid_name, "tracers"); add_field("cldfrac_rad", scalar3d_mid, nondim, grid_name); // Optical properties, should be computed in radiation interface add_field("dtau067", scalar3d_mid, nondim, grid_name); // 0.67 micron optical depth diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp index 4ad61b96fe0..8bc727c325e 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp @@ -91,13 +91,10 @@ void MAMMicrophysics::configure(const ekat::ParameterList& params) { void MAMMicrophysics::set_grids(const std::shared_ptr grids_manager) { using namespace ekat::units; - auto q_unit = kg/kg; // mass mixing ratios [kg stuff / kg air] - q_unit.set_string("kg/kg"); - auto n_unit = 1/kg; // number mixing ratios [# / kg air] - n_unit.set_string("#/kg"); - Units nondim(0,0,0,0,0,0,0); - const auto m2 = m*m; - const auto s2 = s*s; + Units nondim = Units::nondimensional(); + Units n_unit (1/kg,"#/kg"); // number mixing ratios [# / kg air] + const auto m2 = pow(m,2); + const auto s2 = pow(s,2); grid_ = grids_manager->get_grid("Physics"); const auto& grid_name = grid_->name(); @@ -125,8 +122,8 @@ void MAMMicrophysics::set_grids(const std::shared_ptr grids_ add_field("omega", scalar3d_layout_mid, Pa/s, grid_name); // vertical pressure velocity add_field("T_mid", scalar3d_layout_mid, K, grid_name); // Temperature add_field("p_mid", scalar3d_layout_mid, Pa, grid_name); // total pressure - add_field("qv", scalar3d_layout_mid, q_unit, grid_name, "tracers"); // specific humidity - add_field("qi", scalar3d_layout_mid, q_unit, grid_name, "tracers"); // ice wet mixing ratio + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, "tracers"); // specific humidity + add_field("qi", scalar3d_layout_mid, kg/kg, grid_name, "tracers"); // ice wet mixing ratio add_field("ni", scalar3d_layout_mid, n_unit, grid_name, "tracers"); // ice number mixing ratio add_field("pbl_height", scalar2d_layout_col, m, grid_name); // planetary boundary layer height add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name); // p_del, hydrostatic pressure @@ -134,7 +131,7 @@ void MAMMicrophysics::set_grids(const std::shared_ptr grids_ add_field("cldfrac_tot", scalar3d_layout_mid, nondim, grid_name); // cloud fraction // droplet activation can alter cloud liquid and number mixing ratios - add_field("qc", scalar3d_layout_mid, q_unit, grid_name, "tracers"); // cloud liquid wet mixing ratio + add_field("qc", scalar3d_layout_mid, kg/kg, grid_name, "tracers"); // cloud liquid wet mixing ratio add_field("nc", scalar3d_layout_mid, n_unit, grid_name, "tracers"); // cloud liquid wet number mixing ratio // (interstitial) aerosol tracers of interest: mass (q) and number (n) mixing ratios @@ -144,7 +141,7 @@ void MAMMicrophysics::set_grids(const std::shared_ptr grids_ for (int a = 0; a < mam_coupling::num_aero_species(); ++a) { const char* int_mmr_field_name = mam_coupling::int_aero_mmr_field_name(m, a); if (strlen(int_mmr_field_name) > 0) { - add_field(int_mmr_field_name, scalar3d_layout_mid, q_unit, grid_name, "tracers"); + add_field(int_mmr_field_name, scalar3d_layout_mid, kg/kg, grid_name, "tracers"); } } } @@ -152,7 +149,7 @@ void MAMMicrophysics::set_grids(const std::shared_ptr grids_ // aerosol-related gases: mass mixing ratios for (int g = 0; g < mam_coupling::num_aero_gases(); ++g) { const char* gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g); - add_field(gas_mmr_field_name, scalar3d_layout_mid, q_unit, grid_name, "tracers"); + add_field(gas_mmr_field_name, scalar3d_layout_mid, kg/kg, grid_name, "tracers"); } // Tracers group -- do we need this in addition to the tracers above? In any diff --git a/components/eamxx/src/physics/mam/eamxx_mam_optics_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_optics_process_interface.cpp index d818890a9b4..a55bf84ca17 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_optics_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_optics_process_interface.cpp @@ -25,12 +25,9 @@ void MAMOptics::set_grids( grid_ = grids_manager->get_grid("Physics"); const auto &grid_name = grid_->name(); - auto q_unit = kg / kg; // mass mixing ratios [kg stuff / kg air] - q_unit.set_string("kg/kg"); - auto n_unit = 1 / kg; // number mixing ratios [# / kg air] - n_unit.set_string("#/kg"); - const auto m2 = m * m; - const auto s2 = s * s; + Units n_unit (1 / kg, "#/kg"); // number mixing ratios [# / kg air] + const auto m2 = pow(m,2); + const auto s2 = pow(s,2); ncol_ = grid_->get_num_local_dofs(); // number of columns on this rank nlev_ = grid_->get_num_vertical_levels(); // number of levels per column @@ -58,12 +55,12 @@ void MAMOptics::set_grids( add_field("p_int", scalar3d_int, Pa, grid_name); // total pressure add_field("pseudo_density", scalar3d_mid, Pa, grid_name); add_field("pseudo_density_dry", scalar3d_mid, Pa, grid_name); - add_field("qv", scalar3d_mid, q_unit, grid_name,"tracers"); // specific humidity - add_field("qi", scalar3d_mid, q_unit, grid_name,"tracers"); // ice wet mixing ratio + add_field("qv", scalar3d_mid, kg/kg, grid_name,"tracers"); // specific humidity + add_field("qi", scalar3d_mid, kg/kg, grid_name,"tracers"); // ice wet mixing ratio add_field("ni", scalar3d_mid, n_unit, grid_name,"tracers"); // ice number mixing ratio // droplet activation can alter cloud liquid and number mixing ratios - add_field("qc", scalar3d_mid, q_unit, grid_name,"tracers"); // cloud liquid wet mixing ratio + add_field("qc", scalar3d_mid, kg/kg, grid_name,"tracers"); // cloud liquid wet mixing ratio add_field("nc", scalar3d_mid, n_unit, grid_name,"tracers"); // cloud liquid wet number mixing ratio add_field("phis", scalar2d, m2 / s2, grid_name); @@ -94,7 +91,7 @@ void MAMOptics::set_grids( const char *int_mmr_field_name = mam_coupling::int_aero_mmr_field_name(m, a); if(strlen(int_mmr_field_name) > 0) { - add_field(int_mmr_field_name, scalar3d_mid, q_unit,grid_name, "tracers"); + add_field(int_mmr_field_name, scalar3d_mid, kg/kg,grid_name, "tracers"); } } } @@ -108,7 +105,7 @@ void MAMOptics::set_grids( mam_coupling::cld_aero_mmr_field_name(m, a); if(strlen(cld_mmr_field_name) > 0) { - add_field(cld_mmr_field_name, scalar3d_mid, q_unit, grid_name); + add_field(cld_mmr_field_name, scalar3d_mid, kg/kg, grid_name); } } } @@ -116,7 +113,7 @@ void MAMOptics::set_grids( // aerosol-related gases: mass mixing ratios for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) { const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g); - add_field(gas_mmr_field_name, scalar3d_mid, q_unit, grid_name, "tracers"); + add_field(gas_mmr_field_name, scalar3d_mid, kg/kg, grid_name, "tracers"); } } diff --git a/components/eamxx/src/physics/ml_correction/eamxx_ml_correction_process_interface.cpp b/components/eamxx/src/physics/ml_correction/eamxx_ml_correction_process_interface.cpp index 171e3486ba4..6047188735a 100644 --- a/components/eamxx/src/physics/ml_correction/eamxx_ml_correction_process_interface.cpp +++ b/components/eamxx/src/physics/ml_correction/eamxx_ml_correction_process_interface.cpp @@ -24,8 +24,6 @@ void MLCorrection::set_grids( // The units of mixing ratio Q are technically non-dimensional. // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Q = kg / kg; - Q.set_string("kg/kg"); constexpr int ps = Pack::n; m_grid = grids_manager->get_grid("Physics"); const auto &grid_name = m_grid->name(); @@ -40,16 +38,15 @@ void MLCorrection::set_grids( FieldLayout scalar3d_mid = m_grid->get_3d_scalar_layout(true); FieldLayout scalar3d_int = m_grid->get_3d_scalar_layout(false); FieldLayout vector3d_mid = m_grid->get_3d_vector_layout(true,2); - const auto m2 = m*m; + const auto m2 = pow(m,2); if (not m_ML_correction_unit_test) { - const auto s2 = s*s; - auto Wm2 = W / m / m; - auto nondim = m/m; + const auto s2 = pow(s,2); + auto nondim = Units::nondimensional(); add_field("phis", scalar2d, m2/s2, grid_name); add_field("sfc_alb_dif_vis", scalar2d, nondim, grid_name); - add_field("SW_flux_dn", scalar3d_int, Wm2, grid_name, ps); - add_field("sfc_flux_sw_net", scalar2d, Wm2, grid_name); - add_field("sfc_flux_lw_dn", scalar2d, Wm2, grid_name); + add_field("SW_flux_dn", scalar3d_int, W/m2, grid_name, ps); + add_field("sfc_flux_sw_net", scalar2d, W/m2, grid_name); + add_field("sfc_flux_lw_dn", scalar2d, W/m2, grid_name); m_lat = m_grid->get_geometry_data("lat"); m_lon = m_grid->get_geometry_data("lon"); } @@ -60,9 +57,9 @@ void MLCorrection::set_grids( * is adapting the infrastructure to allow for a generic "add_field" call * to be used here which we can then setup using the m_fields_ml_output_variables variable */ - add_field("T_mid", scalar3d_mid, K, grid_name, ps); - add_field("qv", scalar3d_mid, Q, grid_name, "tracers", ps); - add_field("horiz_winds", vector3d_mid, m/s, grid_name, ps); + add_field("T_mid", scalar3d_mid, K, grid_name, ps); + add_field("qv", scalar3d_mid, kg/kg, grid_name, "tracers", ps); + add_field("horiz_winds", vector3d_mid, m/s, grid_name, ps); /* Note: we also need to update the precipitation after ML commits any column drying */ add_field("pseudo_density", scalar3d_mid, Pa, grid_name, ps); add_field("precip_liq_surf_mass", scalar2d, kg/m2, grid_name); @@ -107,7 +104,6 @@ void MLCorrection::run_impl(const double dt) { host_view2d_type qv_told("",qv.extent(0),qv.extent(1)); Kokkos::deep_copy(qv_told,qv); - auto h_lat = m_lat.get_view(); auto h_lon = m_lon.get_view(); diff --git a/components/eamxx/src/physics/nudging/eamxx_nudging_process_interface.cpp b/components/eamxx/src/physics/nudging/eamxx_nudging_process_interface.cpp index 832c030e97b..3af33eaea16 100644 --- a/components/eamxx/src/physics/nudging/eamxx_nudging_process_interface.cpp +++ b/components/eamxx/src/physics/nudging/eamxx_nudging_process_interface.cpp @@ -68,8 +68,6 @@ void Nudging::set_grids(const std::shared_ptr grids_manager) FieldLayout horiz_wind_layout = m_grid->get_3d_vector_layout(true,2); constexpr int ps = 1; - auto Q = kg/kg; - Q.set_string("kg/kg"); add_field("p_mid", scalar3d_layout_mid, Pa, grid_name, ps); /* ----------------------- WARNING --------------------------------*/ @@ -85,7 +83,7 @@ void Nudging::set_grids(const std::shared_ptr grids_manager) add_field("T_mid", scalar3d_layout_mid, K, grid_name, ps); } if (ekat::contains(m_fields_nudge,"qv")) { - add_field("qv", scalar3d_layout_mid, Q, grid_name, "tracers", ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); } if (ekat::contains(m_fields_nudge,"U") or ekat::contains(m_fields_nudge,"V")) { add_field("horiz_winds", horiz_wind_layout, m/s, grid_name, ps); diff --git a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp index d6264c38b8b..d886478ac2a 100644 --- a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp +++ b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp @@ -25,14 +25,13 @@ P3Microphysics::P3Microphysics (const ekat::Comm& comm, const ekat::ParameterLis void P3Microphysics::set_grids(const std::shared_ptr grids_manager) { using namespace ekat::units; + using namespace ekat::prefixes; // The units of mixing ratio Q are technically non-dimensional. // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Q = kg/kg; - Q.set_string("kg/kg"); auto nondim = Units::nondimensional(); - auto micron = m / 1000000; - auto m2 = m * m; + auto micron = micro*m; + auto m2 = pow(m,2); m_grid = grids_manager->get_grid("Physics"); const auto& grid_name = m_grid->name(); @@ -73,27 +72,27 @@ void P3Microphysics::set_grids(const std::shared_ptr grids_m add_field ("T_mid", scalar3d_layout_mid, K, grid_name, ps); // T_mid is the only one of these variables that is also updated. // Prognostic State: (all fields are both input and output) - add_field("qv", scalar3d_layout_mid, Q, grid_name, "tracers", ps); - add_field("qc", scalar3d_layout_mid, Q, grid_name, "tracers", ps); - add_field("qr", scalar3d_layout_mid, Q, grid_name, "tracers", ps); - add_field("qi", scalar3d_layout_mid, Q, grid_name, "tracers", ps); - add_field("qm", scalar3d_layout_mid, Q, grid_name, "tracers", ps); - add_field("nc", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); - add_field("nr", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); - add_field("ni", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); - add_field("bm", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); + add_field("qv", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); + add_field("qc", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); + add_field("qr", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); + add_field("qi", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); + add_field("qm", scalar3d_layout_mid, kg/kg, grid_name, "tracers", ps); + add_field("nc", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); + add_field("nr", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); + add_field("ni", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); + add_field("bm", scalar3d_layout_mid, 1/kg, grid_name, "tracers", ps); // Diagnostic Inputs: (only the X_prev fields are both input and output, all others are just inputs) add_field("nc_nuceat_tend", scalar3d_layout_mid, 1/(kg*s), grid_name, ps); if (infrastructure.prescribedCCN) { add_field("nccn", scalar3d_layout_mid, 1/kg, grid_name, ps); } - add_field("ni_activated", scalar3d_layout_mid, 1/kg, grid_name, ps); - add_field("inv_qc_relvar", scalar3d_layout_mid, Q*Q, grid_name, ps); - add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); - add_field("pseudo_density_dry", scalar3d_layout_mid, Pa, grid_name, ps); - add_field ("qv_prev_micro_step", scalar3d_layout_mid, Q, grid_name, ps); - add_field ("T_prev_micro_step", scalar3d_layout_mid, K, grid_name, ps); + add_field("ni_activated", scalar3d_layout_mid, 1/kg, grid_name, ps); + add_field("inv_qc_relvar", scalar3d_layout_mid, pow(kg/kg,2), grid_name, ps); + add_field("pseudo_density", scalar3d_layout_mid, Pa, grid_name, ps); + add_field("pseudo_density_dry", scalar3d_layout_mid, Pa, grid_name, ps); + add_field ("qv_prev_micro_step", scalar3d_layout_mid, kg/kg, grid_name, ps); + add_field ("T_prev_micro_step", scalar3d_layout_mid, K, grid_name, ps); // Diagnostic Outputs: (all fields are just outputs w.r.t. P3) add_field("precip_liq_surf_mass", scalar2d_layout, kg/m2, grid_name, "ACCUMULATED"); @@ -106,9 +105,9 @@ void P3Microphysics::set_grids(const std::shared_ptr grids_m // TODO: These should be averaged over subcycle as well. But there is no simple mechanism // yet to reset these values at the beginning of the atmosphere timestep. When this // mechanism is developed we should add these variables to the accumulated variables. - add_field("micro_liq_ice_exchange", scalar3d_layout_mid, Q, grid_name, ps); - add_field("micro_vap_liq_exchange", scalar3d_layout_mid, Q, grid_name, ps); - add_field("micro_vap_ice_exchange", scalar3d_layout_mid, Q, grid_name, ps); + add_field("micro_liq_ice_exchange", scalar3d_layout_mid, kg/kg, grid_name, ps); + add_field("micro_vap_liq_exchange", scalar3d_layout_mid, kg/kg, grid_name, ps); + add_field("micro_vap_ice_exchange", scalar3d_layout_mid, kg/kg, grid_name, ps); add_field("rainfrac", scalar3d_layout_mid, nondim, grid_name, ps); // Boundary flux fields for energy and mass conservation checks diff --git a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp index 256174baef6..88f7cdc68ed 100644 --- a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp +++ b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp @@ -42,17 +42,12 @@ RRTMGPRadiation (const ekat::Comm& comm, const ekat::ParameterList& params) void RRTMGPRadiation::set_grids(const std::shared_ptr grids_manager) { using namespace ekat::units; + using namespace ekat::prefixes; // Declare the set of fields used by rrtmgp - auto kgkg = kg/kg; - kgkg.set_string("kg/kg"); - auto m2 = m * m; - auto Wm2 = W / m / m; - Wm2.set_string("W/m2"); - auto nondim = m/m; // dummy unit for non-dimensional fields - auto micron = m / 1000000; - auto molmol = mol/mol; - molmol.set_string("mol/mol"); + Units m2(m*m,"m2"); + auto nondim = Units::nondimensional(); + auto micron = micro*m; m_grid = grids_manager->get_grid("Physics"); const auto& grid_name = m_grid->name(); @@ -92,24 +87,24 @@ void RRTMGPRadiation::set_grids(const std::shared_ptr grids_ add_field("sfc_alb_dir_nir", scalar2d, nondim, grid_name); add_field("sfc_alb_dif_vis", scalar2d, nondim, grid_name); add_field("sfc_alb_dif_nir", scalar2d, nondim, grid_name); - add_field("qc", scalar3d_mid, kgkg, grid_name); + add_field("qc", scalar3d_mid, kg/kg, grid_name); add_field("nc", scalar3d_mid, 1/kg, grid_name); - add_field("qi", scalar3d_mid, kgkg, grid_name); + add_field("qi", scalar3d_mid, kg/kg, grid_name); add_field("cldfrac_tot", scalar3d_mid, nondim, grid_name); add_field("eff_radius_qc", scalar3d_mid, micron, grid_name); add_field("eff_radius_qi", scalar3d_mid, micron, grid_name); - add_field("qv",scalar3d_mid,kgkg,grid_name); + add_field("qv",scalar3d_mid,kg/kg,grid_name); add_field("surf_lw_flux_up",scalar2d,W/(m*m),grid_name); // Set of required gas concentration fields for (auto& it : m_gas_names) { // Add gas VOLUME mixing ratios (moles of gas / moles of air; what actually gets input to RRTMGP) if (it == "o3") { // o3 is read from file, or computed by chemistry - add_field(it + "_volume_mix_ratio", scalar3d_mid, molmol, grid_name); + add_field(it + "_volume_mix_ratio", scalar3d_mid, mol/mol, grid_name); } else { // the rest are computed by RRTMGP from prescribed surface values // NOTE: this may change at some point - add_field(it + "_volume_mix_ratio", scalar3d_mid, molmol, grid_name); + add_field(it + "_volume_mix_ratio", scalar3d_mid, mol/mol, grid_name); } } // Required aerosol optical properties from SPA @@ -127,26 +122,26 @@ void RRTMGPRadiation::set_grids(const std::shared_ptr grids_ // Set computed (output) fields add_field("T_mid" , scalar3d_mid, K , grid_name); - add_field("SW_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("SW_flux_up", scalar3d_int, Wm2, grid_name); - add_field("SW_flux_dn_dir", scalar3d_int, Wm2, grid_name); - add_field("LW_flux_up", scalar3d_int, Wm2, grid_name); - add_field("LW_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("SW_clnclrsky_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("SW_clnclrsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("SW_clnclrsky_flux_dn_dir", scalar3d_int, Wm2, grid_name); - add_field("SW_clrsky_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("SW_clrsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("SW_clrsky_flux_dn_dir", scalar3d_int, Wm2, grid_name); - add_field("SW_clnsky_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("SW_clnsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("SW_clnsky_flux_dn_dir", scalar3d_int, Wm2, grid_name); - add_field("LW_clnclrsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("LW_clnclrsky_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("LW_clrsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("LW_clrsky_flux_dn", scalar3d_int, Wm2, grid_name); - add_field("LW_clnsky_flux_up", scalar3d_int, Wm2, grid_name); - add_field("LW_clnsky_flux_dn", scalar3d_int, Wm2, grid_name); + add_field("SW_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("SW_flux_up", scalar3d_int, W/m2, grid_name); + add_field("SW_flux_dn_dir", scalar3d_int, W/m2, grid_name); + add_field("LW_flux_up", scalar3d_int, W/m2, grid_name); + add_field("LW_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("SW_clnclrsky_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("SW_clnclrsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("SW_clnclrsky_flux_dn_dir", scalar3d_int, W/m2, grid_name); + add_field("SW_clrsky_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("SW_clrsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("SW_clrsky_flux_dn_dir", scalar3d_int, W/m2, grid_name); + add_field("SW_clnsky_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("SW_clnsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("SW_clnsky_flux_dn_dir", scalar3d_int, W/m2, grid_name); + add_field("LW_clnclrsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("LW_clnclrsky_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("LW_clrsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("LW_clrsky_flux_dn", scalar3d_int, W/m2, grid_name); + add_field("LW_clnsky_flux_up", scalar3d_int, W/m2, grid_name); + add_field("LW_clnsky_flux_dn", scalar3d_int, W/m2, grid_name); add_field("rad_heating_pdel", scalar3d_mid, Pa*K/s, grid_name); // Cloud properties added as computed fields for diagnostic purposes add_field("cldlow" , scalar2d, nondim, grid_name); @@ -179,12 +174,12 @@ void RRTMGPRadiation::set_grids(const std::shared_ptr grids_ // netsw sfc_flux_sw_net net (down - up) SW flux at surface // flwds sfc_flux_lw_dn downwelling LW flux at surface // -------------------------------------------------------------- - add_field("sfc_flux_dir_nir", scalar2d, Wm2, grid_name); - add_field("sfc_flux_dir_vis", scalar2d, Wm2, grid_name); - add_field("sfc_flux_dif_nir", scalar2d, Wm2, grid_name); - add_field("sfc_flux_dif_vis", scalar2d, Wm2, grid_name); - add_field("sfc_flux_sw_net" , scalar2d, Wm2, grid_name); - add_field("sfc_flux_lw_dn" , scalar2d, Wm2, grid_name); + add_field("sfc_flux_dir_nir", scalar2d, W/m2, grid_name); + add_field("sfc_flux_dir_vis", scalar2d, W/m2, grid_name); + add_field("sfc_flux_dif_nir", scalar2d, W/m2, grid_name); + add_field("sfc_flux_dif_vis", scalar2d, W/m2, grid_name); + add_field("sfc_flux_sw_net" , scalar2d, W/m2, grid_name); + add_field("sfc_flux_lw_dn" , scalar2d, W/m2, grid_name); // Boundary flux fields for energy and mass conservation checks if (has_column_conservation_check()) { diff --git a/components/eamxx/src/physics/shoc/eamxx_shoc_process_interface.cpp b/components/eamxx/src/physics/shoc/eamxx_shoc_process_interface.cpp index 2504c7ddd8a..6204421c1ea 100644 --- a/components/eamxx/src/physics/shoc/eamxx_shoc_process_interface.cpp +++ b/components/eamxx/src/physics/shoc/eamxx_shoc_process_interface.cpp @@ -23,12 +23,6 @@ void SHOCMacrophysics::set_grids(const std::shared_ptr grids { using namespace ekat::units; - // The units of mixing ratio Q are technically non-dimensional. - // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Qunit = kg/kg; - Qunit.set_string("kg/kg"); - auto nondim = Units::nondimensional(); - m_grid = grids_manager->get_grid("Physics"); const auto& grid_name = m_grid->name(); @@ -56,21 +50,22 @@ void SHOCMacrophysics::set_grids(const std::shared_ptr grids constexpr int ps = Spack::n; - const auto m2 = m*m; - const auto s2 = s*s; + const auto nondim = Units::nondimensional(); + const auto m2 = pow(m,2); + const auto s2 = pow(s,2); // These variables are needed by the interface, but not actually passed to shoc_main. add_field("omega", scalar3d_mid, Pa/s, grid_name, ps); add_field("surf_sens_flux", scalar2d , W/m2, grid_name); add_field("surf_mom_flux", vector2d , N/m2, grid_name); - add_field("surf_evap", scalar2d , kg/m2/s, grid_name); - add_field ("T_mid", scalar3d_mid, K, grid_name, ps); - add_field ("qv", scalar3d_mid, Qunit, grid_name, "tracers", ps); + add_field("surf_evap", scalar2d , kg/(m2*s), grid_name); + add_field ("T_mid", scalar3d_mid, K, grid_name, ps); + add_field ("qv", scalar3d_mid, kg/kg, grid_name, "tracers", ps); // If TMS is a process, add surface drag coefficient to required fields if (m_params.get("apply_tms", false)) { - add_field("surf_drag_coeff_tms", scalar2d, kg/s/m2, grid_name); + add_field("surf_drag_coeff_tms", scalar2d, kg/(m2*s), grid_name); } // Input variables @@ -84,19 +79,19 @@ void SHOCMacrophysics::set_grids(const std::shared_ptr grids add_field("horiz_winds", vector3d_mid, m/s, grid_name, ps); add_field("sgs_buoy_flux", scalar3d_mid, K*(m/s), grid_name, ps); add_field("eddy_diff_mom", scalar3d_mid, m2/s, grid_name, ps); - add_field("qc", scalar3d_mid, Qunit, grid_name, "tracers", ps); + add_field("qc", scalar3d_mid, kg/kg, grid_name, "tracers", ps); add_field("cldfrac_liq", scalar3d_mid, nondim, grid_name, ps); // Output variables - add_field("pbl_height", scalar2d , m, grid_name); - add_field("inv_qc_relvar", scalar3d_mid, Qunit*Qunit, grid_name, ps); + add_field("pbl_height", scalar2d , m, grid_name); + add_field("inv_qc_relvar", scalar3d_mid, pow(kg/kg,2), grid_name, ps); // Tracer group add_group("tracers", grid_name, ps, Bundling::Required); // Boundary flux fields for energy and mass conservation checks if (has_column_conservation_check()) { - add_field("vapor_flux", scalar2d, kg/m2/s, grid_name); + add_field("vapor_flux", scalar2d, kg/(m2*s), grid_name); add_field("water_flux", scalar2d, m/s, grid_name); add_field("ice_flux", scalar2d, m/s, grid_name); add_field("heat_flux", scalar2d, W/m2, grid_name); diff --git a/components/eamxx/src/physics/spa/eamxx_spa_process_interface.cpp b/components/eamxx/src/physics/spa/eamxx_spa_process_interface.cpp index 89f521e3d96..61c61b878c2 100644 --- a/components/eamxx/src/physics/spa/eamxx_spa_process_interface.cpp +++ b/components/eamxx/src/physics/spa/eamxx_spa_process_interface.cpp @@ -26,10 +26,6 @@ void SPA::set_grids(const std::shared_ptr grids_manager) using namespace ekat::units; using namespace ShortFieldTagsNames; - // The units of mixing ratio Q are technically non-dimensional. - // Nevertheless, for output reasons, we like to see 'kg/kg'. - auto Q = kg/kg; - Q.set_string("kg/kg"); auto nondim = Units::nondimensional(); m_grid = grids_manager->get_grid("Physics"); diff --git a/components/eamxx/src/physics/tms/eamxx_tms_process_interface.cpp b/components/eamxx/src/physics/tms/eamxx_tms_process_interface.cpp index 87e14591798..a8996c3dd40 100644 --- a/components/eamxx/src/physics/tms/eamxx_tms_process_interface.cpp +++ b/components/eamxx/src/physics/tms/eamxx_tms_process_interface.cpp @@ -26,10 +26,8 @@ void TurbulentMountainStress::set_grids(const std::shared_ptrget_grid("Physics"); @@ -52,12 +50,12 @@ void TurbulentMountainStress::set_grids(const std::shared_ptr("T_mid", scalar3d_mid, K, grid_name, ps); add_field("p_mid", scalar3d_mid, Pa, grid_name, ps); add_field("pseudo_density", scalar3d_mid, Pa, grid_name, ps); - add_field("qv", scalar3d_mid, Qunit, grid_name, "tracers", ps); + add_field("qv", scalar3d_mid, kg/kg, grid_name, "tracers", ps); add_field("sgh30", scalar2d , m, grid_name); add_field("landfrac", scalar2d , nondim, grid_name); - add_field("surf_drag_coeff_tms", scalar2d, kg/s/m2, grid_name); - add_field("wind_stress_tms", vector2d, N/m2, grid_name); + add_field("surf_drag_coeff_tms", scalar2d, kg/(m2*s), grid_name); + add_field("wind_stress_tms", vector2d, N/m2, grid_name); } // ========================================================================================= diff --git a/components/eamxx/src/physics/zm/eamxx_zm_process_interface.cpp b/components/eamxx/src/physics/zm/eamxx_zm_process_interface.cpp index 2dbb048957e..f36aac6133d 100644 --- a/components/eamxx/src/physics/zm/eamxx_zm_process_interface.cpp +++ b/components/eamxx/src/physics/zm/eamxx_zm_process_interface.cpp @@ -29,12 +29,7 @@ ZMDeepConvection::ZMDeepConvection (const ekat::Comm& comm,const ekat::Parameter void ZMDeepConvection::set_grids(const std::shared_ptr grids_manager) { using namespace std; - using namespace ekat; - using namespace units; - - auto Q = kg/kg; - auto nondim = m/m; - Q.set_string("kg/kg"); + using namespace ekat::units; constexpr int NVL = 72; /* TODO THIS NEEDS TO BE CHANGED TO A CONFIGURABLE */ constexpr int QSZ = 35; /* TODO THIS NEEDS TO BE CHANGED TO A CONFIGURABLE */ @@ -57,9 +52,9 @@ void ZMDeepConvection::set_grids(const std::shared_ptr grids set_grid_opts(opt_map); for ( auto i = opt_map.begin(); i != opt_map.end(); ++i) { - add_required_field((i->second).name, layout_opts[((i->second).field_idx)], Q, grid->name()); + add_required_field((i->second).name, layout_opts[((i->second).field_idx)], kg/kg, grid->name()); if ( (i->second).isOut == true ) { - add_computed_field((i->second).name, layout_opts[((i->second).field_idx)], Q, grid->name()); + add_computed_field((i->second).name, layout_opts[((i->second).field_idx)], kg/kg, grid->name()); } } diff --git a/components/eamxx/src/share/atm_process/atmosphere_process_dag.cpp b/components/eamxx/src/share/atm_process/atmosphere_process_dag.cpp index a77dd6e4c56..7b6fc218a0b 100644 --- a/components/eamxx/src/share/atm_process/atmosphere_process_dag.cpp +++ b/components/eamxx/src/share/atm_process/atmosphere_process_dag.cpp @@ -146,7 +146,7 @@ void AtmProcDAG::write_dag (const std::string& fname, const int verbosity) const s.back() = ')'; if (verbosity>2) { - s += " [" + fid.get_units().get_string() + "]"; + s += " [" + fid.get_units().to_string() + "]"; } } return s; diff --git a/components/eamxx/src/share/field/field_identifier.cpp b/components/eamxx/src/share/field/field_identifier.cpp index 56974aa0696..7430ffa892e 100644 --- a/components/eamxx/src/share/field/field_identifier.cpp +++ b/components/eamxx/src/share/field/field_identifier.cpp @@ -48,7 +48,7 @@ void FieldIdentifier::update_identifier () { m_identifier += ">"; m_identifier += "(" + ekat::join(m_layout.dims(),",") + ")"; - m_identifier += " [" + m_units.get_string() + "]"; + m_identifier += " [" + m_units.to_string() + "]"; } // Free functions for identifiers comparison diff --git a/components/eamxx/src/share/field/field_manager.cpp b/components/eamxx/src/share/field/field_manager.cpp index 4db9fd0fa15..311a0a6b14b 100644 --- a/components/eamxx/src/share/field/field_manager.cpp +++ b/components/eamxx/src/share/field/field_manager.cpp @@ -46,8 +46,8 @@ void FieldManager::register_field (const FieldRequest& req) const auto id0 = m_fields[id.name()]->get_header().get_identifier(); EKAT_REQUIRE_MSG(id.get_units()==id0.get_units(), "Error! Field '" + id.name() + "' already registered with different units:\n" - " - input field units: " + to_string(id.get_units()) + "\n" - " - stored field units: " + to_string(id0.get_units()) + "\n" + " - input field units: " + id.get_units().to_string() + "\n" + " - stored field units: " + id0.get_units().to_string() + "\n" " Please, check and make sure all atmosphere processes use the same units.\n"); EKAT_REQUIRE_MSG(id.get_layout()==id0.get_layout(), diff --git a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp index e0f78e10cf0..e7e11ef20e2 100644 --- a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp +++ b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp @@ -230,14 +230,15 @@ load_vertical_coordinates (const nonconstgrid_ptr_type& grid, const std::string& using geo_view_host = AtmosphereInput::view_1d_host; using namespace ShortFieldTagsNames; + using namespace ekat::units; + FieldLayout layout_mid ({LEV},{grid->get_num_vertical_levels()}); - const auto units = ekat::units::Units::nondimensional(); - auto lev_unit = ekat::units::Units::nondimensional();; - lev_unit.set_string("mb"); + Units nondim = Units::nondimensional(); + Units mbar (100*Pa,"mb"); - auto hyam = grid->create_geometry_data("hyam", layout_mid, units); - auto hybm = grid->create_geometry_data("hybm", layout_mid, units); - auto lev = grid->create_geometry_data("lev", layout_mid, lev_unit); + auto hyam = grid->create_geometry_data("hyam", layout_mid, nondim); + auto hybm = grid->create_geometry_data("hybm", layout_mid, nondim); + auto lev = grid->create_geometry_data("lev", layout_mid, mbar); // Create host mirrors for reading in data std::map host_views = { diff --git a/components/eamxx/src/share/io/scorpio_output.cpp b/components/eamxx/src/share/io/scorpio_output.cpp index 3db201f424b..1852785eeac 100644 --- a/components/eamxx/src/share/io/scorpio_output.cpp +++ b/components/eamxx/src/share/io/scorpio_output.cpp @@ -953,7 +953,7 @@ register_variables(const std::string& filename, // in the simulation and not the one used in the output file. const auto& layout = fid.get_layout(); auto vec_of_dims = set_vec_of_dims(layout); - std::string units = fid.get_units().get_string(); + std::string units = fid.get_units().to_string(); // Gather longname auto longname = m_longnames.get_longname(name);