From 2f4be63d7ede318fae8b458902d1b934bd7333ac Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Mon, 20 May 2024 17:25:57 -0600 Subject: [PATCH] EAMxx: cleanup the VerticalLayer diagnostic * Rename altitude with height * Clean up includes * Clean up unit tests --- .../src/diagnostics/register_diagnostics.hpp | 4 +- .../tests/vertical_layer_tests.cpp | 176 +++++++++--------- .../eamxx/src/diagnostics/vertical_layer.cpp | 176 ++++++++++++------ .../eamxx/src/diagnostics/vertical_layer.hpp | 23 +-- .../eamxx/src/share/io/scorpio_output.cpp | 2 +- 5 files changed, 215 insertions(+), 166 deletions(-) diff --git a/components/eamxx/src/diagnostics/register_diagnostics.hpp b/components/eamxx/src/diagnostics/register_diagnostics.hpp index efb55980a2f..21d82b045da 100644 --- a/components/eamxx/src/diagnostics/register_diagnostics.hpp +++ b/components/eamxx/src/diagnostics/register_diagnostics.hpp @@ -36,9 +36,11 @@ inline void register_diagnostics () { diag_factory.register_product("Exner",&create_atmosphere_diagnostic); diag_factory.register_product("VirtualTemperature",&create_atmosphere_diagnostic); diag_factory.register_product("z_int",&create_atmosphere_diagnostic); - diag_factory.register_product("geopotential_int",&create_atmosphere_diagnostic); diag_factory.register_product("z_mid",&create_atmosphere_diagnostic); + diag_factory.register_product("geopotential_int",&create_atmosphere_diagnostic); diag_factory.register_product("geopotential_mid",&create_atmosphere_diagnostic); + diag_factory.register_product("height_int",&create_atmosphere_diagnostic); + diag_factory.register_product("height_mid",&create_atmosphere_diagnostic); diag_factory.register_product("dz",&create_atmosphere_diagnostic); diag_factory.register_product("DryStaticEnergy",&create_atmosphere_diagnostic); diag_factory.register_product("SeaLevelPressure",&create_atmosphere_diagnostic); diff --git a/components/eamxx/src/diagnostics/tests/vertical_layer_tests.cpp b/components/eamxx/src/diagnostics/tests/vertical_layer_tests.cpp index fc90c1a56f8..a3a8f2a93ce 100644 --- a/components/eamxx/src/diagnostics/tests/vertical_layer_tests.cpp +++ b/components/eamxx/src/diagnostics/tests/vertical_layer_tests.cpp @@ -1,20 +1,8 @@ #include "catch2/catch.hpp" -#include "share/grid/mesh_free_grids_manager.hpp" -#include "diagnostics/vertical_layer.hpp" #include "diagnostics/register_diagnostics.hpp" - #include "physics/share/physics_constants.hpp" - -#include "share/util/scream_setup_random_test.hpp" -#include "share/util/scream_common_physics_functions.hpp" -#include "share/field/field_utils.hpp" - -#include "ekat/ekat_pack.hpp" -#include "ekat/kokkos/ekat_kokkos_utils.hpp" -#include "ekat/util/ekat_test_utils.hpp" - -#include +#include "share/grid/mesh_free_grids_manager.hpp" namespace scream { @@ -39,24 +27,13 @@ create_gm (const ekat::Comm& comm, const int ncols, const int nlevs) { } //-----------------------------------------------------------------------------------------------// -template -void run( Engine& engine, - std::string diag_name, - const std::string& location) +template +void run (const std::string& diag_name, const std::string& location) { - using PC = scream::physics::Constants; - using Pack = ekat::Pack; - using KT = ekat::KokkosTypes; - using ExecSpace = typename KT::ExeSpace; - using MemberType = typename KT::MemberType; - using view_1d = typename KT::template view_1d; - using rview_1d = typename KT::template view_1d; - using view_2d = typename KT::template view_2d; - - const int packsize = SCREAM_PACK_SIZE; + using PC = scream::physics::Constants; + + const int packsize = N; constexpr int num_levs = packsize*2 + 1; // Number of levels to use for tests, make sure the last pack can also have some empty slots (packsize>1). - const int num_mid_packs = ekat::npack(num_levs); - const int num_mid_packs_p1 = ekat::npack(num_levs+1); // A world comm ekat::Comm comm(MPI_COMM_WORLD); @@ -68,31 +45,19 @@ void run( Engine& engine, // A time stamp util::TimeStamp t0 ({2022,1,1},{0,0,0}); - // Kokkos Policy - auto policy = ekat::ExeSpaceUtils::get_default_team_policy(ncols, num_mid_packs); - - // Input (randomized) views - view_1d temperature("temperature",num_mid_packs), - pseudodensity("pseudo_density",num_mid_packs), - pressure("pressure",num_mid_packs), - watervapor("watervapor",num_mid_packs); - - auto dview_as_real = [&] (const view_1d& v) -> rview_1d { - return rview_1d(reinterpret_cast(v.data()),v.size()*packsize); - }; - register_diagnostics(); auto& diag_factory = AtmosphereDiagnosticFactory::instance(); // Construct the Diagnostic ekat::ParameterList params; + std::string name = diag_name; if (location=="midpoints") { - diag_name += "_mid"; + name += "_mid"; } else if (location=="interfaces") { - diag_name += "_int"; + name += "_int"; } - params.set("diag_name", diag_name); - auto diag = diag_factory.create(diag_name,comm,params); + params.set("diag_name", name); + auto diag = diag_factory.create(name,comm,params); diag->set_grids(gm); const bool needs_phis = diag_name=="z" or diag_name=="geopotential"; @@ -107,21 +72,31 @@ void run( Engine& engine, const auto name = f.name(); f.get_header().get_tracking().update_time_stamp(t0); diag->set_required_field(f.get_const()); - REQUIRE_THROWS(diag->set_computed_field(f)); input_fields.emplace(name,f); } + // Can't set computed fields in the diag + REQUIRE_THROWS(diag->set_computed_field(input_fields.begin()->second)); + // Note: we are not testing the calculate_dz utility. We are testing // the diag class, so use some inputs that make checking results easier // With these inputs, T_virt=T, and dz=8*rd/g - const Real dz = PC::RD/PC::gravit; - const Real phis = 3; - input_fields["T_mid"].deep_copy(Real(4)); - input_fields["p_mid"].deep_copy(Real(2)); - input_fields["pseudo_density"].deep_copy(Real(4)); - input_fields["qv"].deep_copy(Real(0)); + const Real g = PC::gravit; + const Real rho_val = 4; + const Real qv_val = 0; + const Real p_val = 2; + const Real T_val = 4; + const Real c1 = -PC::ONE + PC::ONE / PC::ep_2; + const Real Tvirt_val = T_val*(PC::ONE + c1*qv_val); + const Real dz_val = (PC::RD/g) * rho_val*Tvirt_val / p_val; + const Real phis_val = 3; + + input_fields["T_mid"].deep_copy(T_val); + input_fields["p_mid"].deep_copy(p_val); + input_fields["pseudo_density"].deep_copy(rho_val); + input_fields["qv"].deep_copy(qv_val); if (needs_phis) { - input_fields["phis"].deep_copy(phis); + input_fields["phis"].deep_copy(phis_val); } // Initialize and run the diagnostic @@ -132,28 +107,43 @@ void run( Engine& engine, auto d_h = diag_out.get_view(); // Compare against expecte value - const auto last_lev = location=="interfaces" ? num_levs : num_levs-1; + const auto last_int = num_levs; + const auto last_mid = last_int-1; + + // Precompute surface value and increment depending on the diag type + Real delta, surf_val; + if (diag_name=="altitude") { + surf_val = 0; + delta = dz_val; + } else if (diag_name=="z") { + surf_val = phis_val/g; + delta = dz_val; + } else { + surf_val = phis_val; + delta = dz_val*g; + } + for (int icol=0; icol=0; --ilev) { - int num_mid_levs_below = ilev-last_lev; - Real tgt_mid, tgt_int; - if (diag_name=="dz") { - tgt_mid = dz; - } else if (diag_name=="altitude") { - tgt_int = phis/PC::gravit + num_mid_levs_below*dz; - tgt_mid = tgt_int + dz/2; - } else if (diag_name=="geopotential") { - tgt_int = phis + num_mid_levs_below*dz*PC::gravit; - tgt_mid = tgt_int + PC::gravit*dz/2; - } else { - tgt_int = num_mid_levs_below*dz; - tgt_mid = tgt_int + dz/2; - } + Real prev_int_val = surf_val; - if (location=="interfaces") { - REQUIRE (d_h(icol,ilev)==tgt_int); + if (location=="interfaces") { + // Check surface value + REQUIRE (d_h(icol,num_levs)==prev_int_val); + } + + for (int ilev=last_mid; ilev>=0; --ilev) { + if (diag_name=="dz") { + REQUIRE (d_h(icol,ilev)==dz_val); } else { - REQUIRE (d_h(icol,ilev)==tgt_mid); + // If interface, check value, otherwise perform int->mid averaging and check value + auto int_val = prev_int_val + delta; + if (location=="interfaces") { + REQUIRE_THAT(d_h(icol,ilev), Catch::Matchers::WithinRel(int_val,1e-5)); + } else { + auto mid_val = (int_val + prev_int_val) / 2; + REQUIRE_THAT(d_h(icol,ilev), Catch::Matchers::WithinRel(mid_val,1e-5)); + } + prev_int_val = int_val; } } } @@ -168,26 +158,36 @@ TEST_CASE("vertical_layer_test", "vertical_layer_test]"){ using scream::Real; using Device = scream::DefaultDevice; - constexpr int num_runs = 5; - - auto engine = scream::setup_random_test(); - - printf("Test specs\n"); - printf(" - number of randomized runs: %d\n",num_runs); - printf(" - scalar type: Pack\n\n", SCREAM_PACK_SIZE); - - for (int irun=0; irun Testing diagnostic for pack_size=" + std::to_string(N) + "\n"); for (std::string loc : {"midpoints","interfaces"}) { for (std::string diag : {"geopotential","altitude","z"}) { - printf(" -> Testing diag=%s at %s ...\n",diag.c_str(),loc.c_str()); - run(engine, loc, diag); - printf(" -> Testing diag=%s at %s ... PASS!\n",diag.c_str(),loc.c_str()); + std::string msg = " -> Testing diag=" + diag + " at " + loc + " "; + std::string dots (50-msg.size(),'.'); + root_print (msg + dots + "\n"); + run(diag, loc); + root_print (msg + dots + " PASS!\n"); } } - printf(" -> Testing diag=dz ...\n"); - run(engine, "", "dz"); - printf(" -> Testing diag=dz ... PASS!\n"); + std::string msg = " -> Testing diag=dz "; + std::string dots (50-msg.size(),'.'); + root_print (msg + dots + "\n"); + run("dz", "UNUSED"); + root_print (msg + dots + " PASS!\n"); + }; + + if (SCREAM_PACK_SIZE!=1) { + do_run(std::integral_constant()); } + do_run(std::integral_constant()); } // TEST_CASE diff --git a/components/eamxx/src/diagnostics/vertical_layer.cpp b/components/eamxx/src/diagnostics/vertical_layer.cpp index 4dae513893b..262aae90e9f 100644 --- a/components/eamxx/src/diagnostics/vertical_layer.cpp +++ b/components/eamxx/src/diagnostics/vertical_layer.cpp @@ -1,5 +1,9 @@ #include "diagnostics/vertical_layer.hpp" +#include "physics/share/physics_constants.hpp" +#include "share/util/scream_common_physics_functions.hpp" +#include "share/util/scream_column_ops.hpp" + namespace scream { @@ -9,11 +13,20 @@ VerticalLayerDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& para : AtmosphereDiagnostic(comm,params) { m_diag_name = params.get("diag_name"); - EKAT_REQUIRE_MSG(m_diag_name == "z_int" or m_diag_name == "z_mid" or - m_diag_name == "geopotential_int" or m_diag_name == "geopotential_mid" or - m_diag_name == "altitude_int" or m_diag_name == "altitude_mid" or - m_diag_name == "dz", - "Error! VerticalLayerDiagnostic has been given an unknown name: "+m_diag_name+".\n"); + std::vector supported = { + "z_int", + "z_mid", + "geopotential_int", + "geopotential_mid", + "height_int", + "height_mid", + "dz" + }; + + EKAT_REQUIRE_MSG(ekat::contains(supported,m_diag_name), + "[VerticalLayerDiagnostic] Error! Invalid diag_name.\n" + " - diag_name : " + m_diag_name + "\n" + " - valid names: " + ekat::join(supported,", ") + "\n"); m_is_interface_layout = m_diag_name.find("_int") != std::string::npos; @@ -38,25 +51,52 @@ set_grids(const std::shared_ptr grids_manager) const auto scalar2d = grid->get_2d_scalar_layout(); const auto scalar3d_mid = grid->get_3d_scalar_layout(true); const auto scalar3d_int = grid->get_3d_scalar_layout(false); - constexpr int ps = Pack::n; // The fields required for this diagnostic to be computed - add_field("T_mid", scalar3d_mid, K, grid_name, ps); - add_field("pseudo_density", scalar3d_mid, Pa, grid_name, ps); - add_field("p_mid", scalar3d_mid, Pa, grid_name, ps); - add_field("qv", scalar3d_mid, kg/kg, grid_name, ps); + add_field("T_mid", scalar3d_mid, K, grid_name); + add_field("pseudo_density", scalar3d_mid, Pa, grid_name); + add_field("p_mid", scalar3d_mid, Pa, grid_name); + add_field("qv", scalar3d_mid, kg/kg, grid_name); // Only need phis if computing geopotential_* - if (not m_geopotential) { + if (m_from_sea_level) { add_field("phis", scalar2d, m2/s2, grid_name); } +} + +void VerticalLayerDiagnostic:: +initialize_impl (const RunType /*run_type*/) +{ + using namespace ShortFieldTagsNames; + using namespace ekat::units; + + auto m2 = pow(m,2); + auto s2 = pow(s,2); - // Construct and allocate the diagnostic field based on the diagnostic name. - const auto diag_layout = m_is_interface_layout ? scalar3d_int : scalar3d_mid; + const auto& T = get_field_in("T_mid"); + const auto& rho = get_field_in("pseudo_density"); + const auto& p = get_field_in("p_mid"); + const auto& qv = get_field_in("qv"); + const auto& phis = m_from_sea_level ? get_field_in("phis") : T; // unused if m_from_sea_level=false + + // Construct and allocate the diagnostic field. + // Notes: + // - consider diag name to set long name + // - check input fields alloc props to set alloc props for output + + const auto& grid_name = T.get_header().get_identifier().get_grid_name(); + const auto VLEV = m_is_interface_layout ? ILEV : LEV; + const auto nlevs = m_is_interface_layout ? m_num_levs+1 : m_num_levs; + FieldLayout diag_layout ({COL,VLEV},{m_num_cols,nlevs}); FieldIdentifier fid (name(), diag_layout, m_geopotential ? m2/s2 : m, grid_name); + m_diagnostic_output = Field(fid); - auto& fap = m_diagnostic_output.get_header().get_alloc_properties(); - fap.request_allocation(ps); + auto& diag_fap = m_diagnostic_output.get_header().get_alloc_properties(); + for (const auto& f : {T,rho,p,qv,phis}) { + const auto& fap = f.get_header().get_alloc_properties(); + const auto& ps = fap.get_largest_pack_size(); + diag_fap.request_allocation(ps); + } m_diagnostic_output.allocate_view(); using stratts_t = std::map; @@ -68,9 +108,9 @@ set_grids(const std::shared_ptr grids_manager) long_name = "elevation above sealevel at level midpoints"; } else if (m_diag_name=="z_int") { long_name = "elevation above sealevel at level interfaces"; - } else if (m_diag_name=="altitude_mid") { + } else if (m_diag_name=="height_mid") { long_name= "elevation above surface at level midpoints"; - } else if (m_diag_name=="altitude_int") { + } else if (m_diag_name=="height_int") { long_name = "elevation above surface at level interfaces"; } else if (m_diag_name=="geopotential_mid") { long_name = "geopotential height relative to sealevel at level midpoints"; @@ -78,68 +118,81 @@ set_grids(const std::shared_ptr grids_manager) long_name = "geopotential height relative to sealevel at level interfaces"; } - // Initialize temporary views based on need. - if (m_diag_name!="dz") { - if (m_is_interface_layout) { - const auto npacks = ekat::npack(m_num_levs); - m_tmp_midpoint_view = view_2d("tmp_mid",m_num_cols,npacks); - } else { - const auto npacks_p1 = ekat::npack(m_num_levs+1); - m_tmp_interface_view = view_2d("tmp_int",m_num_cols,npacks_p1); - } + // Initialize temporary views based on need. Can alias the diag if a temp is not needed + auto create_temp = [&](const std::string& name, int levs) { + auto u = Units::nondimensional(); + auto ps = diag_fap.get_largest_pack_size(); + FieldLayout fl({COL,LEV},{m_num_cols,levs}); + FieldIdentifier fid (name,fl,u,grid_name); + Field f = Field(fid); + f.get_header().get_alloc_properties().request_allocation(ps); + f.allocate_view(); + return f; + }; + if (m_diag_name == "dz") { + m_tmp_midpoint = m_diagnostic_output; + m_tmp_interface = m_diagnostic_output; // Not really used + } else if (m_is_interface_layout) { + m_tmp_midpoint = create_temp("tmp_mid",m_num_levs); + m_tmp_interface = m_diagnostic_output; + } else { + m_tmp_interface = create_temp("tmp_int",m_num_levs+1); + m_tmp_midpoint = m_diagnostic_output; } } // ========================================================================================= void VerticalLayerDiagnostic::compute_diagnostic_impl() +{ + const auto& fap = m_diagnostic_output.get_header().get_alloc_properties(); + if (fap.get_largest_pack_size()==SCREAM_PACK_SIZE) { + do_compute_diagnostic_impl(); + } else { + do_compute_diagnostic_impl<1>(); + } +} + +template +void VerticalLayerDiagnostic::do_compute_diagnostic_impl() { using column_ops = ColumnOps; + using PackT = ekat::Pack; + using KT = KokkosTypes; + using MemberType = typename KT::MemberType; + using PF = PhysicsFunctions; + // To use in column_ops, since we integrate from surface constexpr bool FromTop = false; - const auto npacks = ekat::npack(m_num_levs); - const auto default_policy = ekat::ExeSpaceUtils::get_thread_range_parallel_scan_team_policy(m_num_cols, npacks); - - const auto& T_mid = get_field_in("T_mid").get_view(); - const auto& p_mid = get_field_in("p_mid").get_view(); - const auto& qv_mid = get_field_in("qv").get_view(); - const auto& pseudo_density_mid = get_field_in("pseudo_density").get_view(); + const auto npacks = ekat::npack(m_num_levs); + const auto policy = ekat::ExeSpaceUtils::get_thread_range_parallel_scan_team_policy(m_num_cols, npacks); - view_1d_const phis; - if (m_from_sea_level) { - phis = get_field_in("phis").get_view(); - } + const auto& T = get_field_in("T_mid").get_view(); + const auto& p = get_field_in("p_mid").get_view(); + const auto& qv = get_field_in("qv").get_view(); + const auto& rho = get_field_in("pseudo_density").get_view(); + const auto phis = m_from_sea_level ? get_field_in("phis").get_view() : typename KT::view_1d(); const bool only_compute_dz = m_diag_name=="dz"; const bool is_interface_layout = m_is_interface_layout; const bool from_sea_level = m_from_sea_level; - const bool do_geopotential = m_geopotential; + const bool geopotential = m_geopotential; const int num_levs = m_num_levs; constexpr auto g = scream::physics::Constants::gravit; // Alias correct view for diagnostic output and for tmp class views - view_2d interface_view; - view_2d midpoint_view; - if (only_compute_dz) { - midpoint_view = m_diagnostic_output.get_view(); - } else if (is_interface_layout) { - interface_view = m_diagnostic_output.get_view(); - midpoint_view = m_tmp_midpoint_view; - } else { - midpoint_view = m_diagnostic_output.get_view(); - interface_view = m_tmp_interface_view; - } + auto tmp_mid = m_tmp_midpoint.get_view(); + auto tmp_int = m_tmp_interface.get_view(); - Kokkos::parallel_for("VerticalLayerDiagnostic", - default_policy, - KOKKOS_LAMBDA(const MemberType& team) { + // Define the lambda, then dispatch the ||for + auto lambda = KOKKOS_LAMBDA(const MemberType& team) { const int icol = team.league_rank(); // Whatever the output needs, the first thing to compute is dz. - const auto& dz = ekat::subview(midpoint_view, icol); - PF::calculate_dz(team,ekat::subview(pseudo_density_mid,icol), - ekat::subview(p_mid,icol), - ekat::subview(T_mid,icol), - ekat::subview(qv_mid,icol), + const auto& dz = ekat::subview(tmp_mid, icol); + PF::calculate_dz(team,ekat::subview(rho,icol), + ekat::subview(p,icol), + ekat::subview(T,icol), + ekat::subview(qv,icol), dz); team.team_barrier(); @@ -147,10 +200,10 @@ void VerticalLayerDiagnostic::compute_diagnostic_impl() if (only_compute_dz) { return; } // Now integrate to compute quantity at interfaces - const auto& v_int = ekat::subview(interface_view, icol); + const auto& v_int = ekat::subview(tmp_int, icol); // phi and z are related by phi=z*g, so dphi=dz*g, and z_surf = phis/g - if (do_geopotential) { + if (geopotential) { auto dphi = [&](const int ilev) { return dz(ilev) * g; }; @@ -163,10 +216,11 @@ void VerticalLayerDiagnostic::compute_diagnostic_impl() // If we need quantity at midpoints, simply do int->mid averaging if (not is_interface_layout) { team.team_barrier(); - const auto& v_mid = ekat::subview(midpoint_view, icol); + const auto& v_mid = ekat::subview(tmp_mid, icol); column_ops::compute_midpoint_values(team,num_levs,v_int,v_mid); } - }); + }; + Kokkos::parallel_for(m_diag_name, policy, lambda); } } //namespace scream diff --git a/components/eamxx/src/diagnostics/vertical_layer.hpp b/components/eamxx/src/diagnostics/vertical_layer.hpp index 0a511303d52..53a482ce060 100644 --- a/components/eamxx/src/diagnostics/vertical_layer.hpp +++ b/components/eamxx/src/diagnostics/vertical_layer.hpp @@ -2,8 +2,6 @@ #define EAMXX_VERTICAL_LAY_MID_DIAGNOSTIC_HPP #include "share/atm_process/atmosphere_diagnostic.hpp" -#include "share/util/scream_common_physics_functions.hpp" -#include "ekat/kokkos/ekat_subview_utils.hpp" namespace scream { @@ -22,13 +20,6 @@ namespace scream class VerticalLayerDiagnostic : public AtmosphereDiagnostic { public: - using Pack = ekat::Pack; - using PF = scream::PhysicsFunctions; - using KT = KokkosTypes; - using MemberType = typename KT::MemberType; - using view_1d_const = typename KT::template view_1d; - using view_2d = typename KT::template view_2d; - // Constructors VerticalLayerDiagnostic (const ekat::Comm& comm, const ekat::ParameterList& params); @@ -39,19 +30,22 @@ class VerticalLayerDiagnostic : public AtmosphereDiagnostic void set_grids (const std::shared_ptr grids_manager); protected: + void compute_diagnostic_impl (); + void initialize_impl (const RunType /* run_type */); #ifdef KOKKOS_ENABLE_CUDA public: #endif - void compute_diagnostic_impl (); + template + void do_compute_diagnostic_impl (); protected: // Keep track of field dimensions Int m_num_cols; Int m_num_levs; - // Temporary view to set dz, z_mid, and z_int - view_2d m_tmp_interface_view; - view_2d m_tmp_midpoint_view; + // Temporaries to use for calculation of dz, z_int, and z_mid + Field m_tmp_interface; + Field m_tmp_midpoint; // The diagnostic name. This will dictate which // field in the computation is output (dz, z_int, or z_mid). @@ -65,8 +59,7 @@ class VerticalLayerDiagnostic : public AtmosphereDiagnostic // If true, output is a geopotential (units m2/s2), otherwise an elevation bool m_geopotential; - -}; // class VerticalLayerDiagnostic +}; } //namespace scream diff --git a/components/eamxx/src/share/io/scorpio_output.cpp b/components/eamxx/src/share/io/scorpio_output.cpp index b3ed08496df..e79d75e97b1 100644 --- a/components/eamxx/src/share/io/scorpio_output.cpp +++ b/components/eamxx/src/share/io/scorpio_output.cpp @@ -1394,7 +1394,7 @@ AtmosphereOutput::create_diagnostic (const std::string& diag_field_name) { // The diagnostics requires the name to be given as param value. if (diag_name == "z_int" or diag_name == "z_mid" or diag_name == "geopotential_int" or diag_name == "geopotential_mid" or - diag_name == "altitude_int" or diag_name == "altitude_mid" or + diag_name == "height_int" or diag_name == "height_mid" or diag_name == "dz") { params.set("diag_name", diag_name); }