Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify FM over all grids #6981

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
368 changes: 135 additions & 233 deletions components/eamxx/src/control/atmosphere_driver.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions components/eamxx/src/control/atmosphere_driver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class AtmosphereDriver
// NOTE: if already finalized, this is a no-op
void finalize ();

field_mgr_ptr get_field_mgr (const std::string& grid_name) const;
field_mgr_ptr get_field_mgr () const { return m_field_mgr; }

// Get atmosphere time stamp
const util::TimeStamp& get_atm_time_stamp () const { return m_current_ts; }
Expand Down Expand Up @@ -191,7 +191,7 @@ class AtmosphereDriver
const std::string& file_name);
void register_groups ();

std::map<std::string,field_mgr_ptr> m_field_mgrs;
field_mgr_ptr m_field_mgr;

std::shared_ptr<AtmosphereProcessGroup> m_atm_process_group;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool approx(const T a, const T b) {
if (std::abs(a-b)>eps) {
printf("approx violated with std::abs(%e - %e) = %e > %e\n",a,b,std::abs(a-b),eps);
}
return std::abs(a-b)<=eps;
return std::abs(a-b)<=eps;
}

struct PressureBnds
Expand All @@ -54,7 +54,7 @@ TEST_CASE("field_at_pressure_level_p2")
ekat::Comm comm(MPI_COMM_WORLD);

// For any random case, set a number of iterations of that test
int num_checks = 10;
int num_checks = 10;

// Create a grids manager w/ a point grid
int ncols = 3;
Expand All @@ -73,7 +73,7 @@ TEST_CASE("field_at_pressure_level_p2")
Real p_mid_bnds_dz = pressure_bounds.p_surf/nlevs; // Note, p_mid will actually never make it to p_top or p_surf in all columns, so we offset the bounds.
RPDF pdf_pmid(pressure_bounds.p_top+p_mid_bnds_dz,pressure_bounds.p_surf-p_mid_bnds_dz);
RPDF pdf_pint(pressure_bounds.p_top,pressure_bounds.p_surf);

// Get a diagnostic factory
auto& diag_factory = AtmosphereDiagnosticFactory::instance();
diag_factory.register_product("FieldAtPressureLevel",&create_atmosphere_diagnostic<FieldAtPressureLevel>);
Expand All @@ -92,7 +92,7 @@ TEST_CASE("field_at_pressure_level_p2")
REQUIRE(approx(test1_diag_v(icol),get_test_data(plevel)));
}
}
}
}
{
// Test 2: Take a slice at a random value for variable defined at interface.
for (int test_itr=0;test_itr<num_checks;test_itr++) {
Expand All @@ -113,7 +113,7 @@ TEST_CASE("field_at_pressure_level_p2")
REQUIRE(approx(test2_mask_v(icol),Real(1.0)));
}
}
}
}
{
// Test 3: Take a slice at a value outside the bounds, which should return the default masked value
for (int test_itr=0;test_itr<num_checks;test_itr++) {
Expand All @@ -135,8 +135,8 @@ TEST_CASE("field_at_pressure_level_p2")
REQUIRE(approx(test2_mask_v(icol),Real(0.0)));
}
}
}
}

} // TEST_CASE("field_at_pressure_level")
/*==========================================================================================================*/
std::shared_ptr<FieldManager> get_test_fm(std::shared_ptr<const AbstractGrid> grid)
Expand Down Expand Up @@ -191,21 +191,21 @@ std::shared_ptr<FieldManager> get_test_fm(std::shared_ptr<const AbstractGrid> gr
int ivec = jj % packsize;
Real p_mid = (get_test_pres(ii,jj,num_levs,num_lcols) + get_test_pres(ii,jj+1,num_levs,num_lcols)) / 2;
Real p_int = get_test_pres(ii,jj,num_levs,num_lcols);
f1_host(ii,ipack)[ivec] = get_test_data(p_mid);
f2_host(ii,ipack)[ivec] = get_test_data(p_int);
f3_host(ii,ipack)[ivec] = p_mid;
f1_host(ii,ipack)[ivec] = get_test_data(p_mid);
f2_host(ii,ipack)[ivec] = get_test_data(p_int);
f3_host(ii,ipack)[ivec] = p_mid;
f4_host(ii,ipack)[ivec] = p_int;
}
// The interface values have one more vertical level
int ipack = num_levs / packsize;
int ivec = num_levs % packsize;
Real p_int = get_test_pres(ii,num_levs,num_levs,num_lcols);
f2_host(ii,ipack)[ivec] = get_test_data(p_int);
f2_host(ii,ipack)[ivec] = get_test_data(p_int);
f4_host(ii,ipack)[ivec] = p_int;
}
// Update timestamp
util::TimeStamp time ({2000,1,1},{0,0,0});
fm->init_fields_time_stamp(time);
fm->init_fields_time_stamp(time, grid->name());
// Sync back to device
f1.sync_to_dev();
f2.sync_to_dev();
Expand All @@ -219,11 +219,12 @@ std::shared_ptr<FieldAtPressureLevel>
get_test_diag(const ekat::Comm& comm, std::shared_ptr<const FieldManager> fm, std::shared_ptr<const GridsManager> gm, const std::string& type, const Real plevel)
{
std::string fname = "V_"+type;
auto field = fm->get_field(fname);
const auto gn = gm->get_repo().begin()->second->name();
auto field = fm->get_field(fname, gn);
auto fid = field.get_header().get_identifier();
ekat::ParameterList params;
params.set("field_name",field.name());
params.set("grid_name",fm->get_grid()->name());
params.set("grid_name",gn);
params.set("pressure_value",std::to_string(plevel));
params.set("pressure_units",std::string("Pa"));
auto diag = std::make_shared<FieldAtPressureLevel>(comm,params);
Expand All @@ -238,8 +239,8 @@ get_test_diag(const ekat::Comm& comm, std::shared_ptr<const FieldManager> fm, st
Real get_test_pres(const int col, const int lev, const int num_lev, const int num_cols)
{
PressureBnds pressure_bounds;
Real p_surf = pressure_bounds.p_surf;
Real p_top = pressure_bounds.p_top;
Real p_surf = pressure_bounds.p_surf;
Real p_top = pressure_bounds.p_top;
Real dp_dx = p_top/(num_cols); // Make sure that 1 column hits the min pressure of 0 at tom
Real dp_dz = (p_surf-(p_top-(col+1)*dp_dx))/(num_lev); // Make sure the max pressure at surface is the surf pressure
return (p_top - (col+1)*dp_dx) + lev*dp_dz;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ void HommeDynamics::set_grids (const std::shared_ptr<const GridsManager> grids_m
add_field<Required>("T_mid", rg_scalar3d_mid,K, rgn,N);
add_field<Required>("ps", rg_scalar2d ,Pa, rgn);
add_field<Required>("phis", rg_scalar2d ,m2/s2, rgn);
add_group<Required>("tracers",rgn,N, Bundling::Required, DerivationType::Import, "tracers", pgn);
add_group<Required>("tracers",rgn,N, Bundling::Required);
fv_phys_rrtmgp_active_gases_init(grids_manager);
// This is needed for the dp_ref init in initialize_homme_state.
add_field<Computed>("pseudo_density",rg_scalar3d_mid,Pa, rgn,N);
Expand Down
46 changes: 20 additions & 26 deletions components/eamxx/src/dynamics/homme/tests/dyn_grid_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,40 +86,34 @@ TEST_CASE("dyn_grid_io")
FieldIdentifier fid_phys_2 ("field_2",phys_vector3d_mid,nondim,phys_grid->name());
FieldIdentifier fid_phys_3 ("field_3",phys_scalar2d ,nondim,phys_grid->name());

// The starting FM
auto fm_dyn = std::make_shared<FieldManager> (dyn_grid);
// FM with dyn and phys where we read into
auto fm = std::make_shared<FieldManager> (gm);

// The FM we will manually remap onto
auto fm_ctrl= std::make_shared<FieldManager> (phys_grid);

// The FM we will read into, and compare against the previous
auto fm_phys= std::make_shared<FieldManager> (phys_grid);

fm_dyn->registration_begins();
fm_phys->registration_begins();
fm->registration_begins();
fm_ctrl->registration_begins();

const int ps = HOMMEXX_PACK_SIZE;
util::TimeStamp t0({2000,1,1},{0,0,0});

fm_dyn->register_field(FieldRequest(fid_dyn_1,ps));
fm_dyn->register_field(FieldRequest(fid_dyn_2,ps));
fm_dyn->register_field(FieldRequest(fid_dyn_3));

fm_phys->register_field(FieldRequest(fid_phys_1,ps));
fm_phys->register_field(FieldRequest(fid_phys_2,ps));
fm_phys->register_field(FieldRequest(fid_phys_3));
fm->register_field(FieldRequest(fid_dyn_1,ps));
fm->register_field(FieldRequest(fid_dyn_2,ps));
fm->register_field(FieldRequest(fid_dyn_3));
fm->register_field(FieldRequest(fid_phys_1,ps));
fm->register_field(FieldRequest(fid_phys_2,ps));
fm->register_field(FieldRequest(fid_phys_3));

fm_ctrl->register_field(FieldRequest(fid_phys_1,ps));
fm_ctrl->register_field(FieldRequest(fid_phys_2,ps));
fm_ctrl->register_field(FieldRequest(fid_phys_3));

fm_dyn->registration_ends();
fm_phys->registration_ends();
fm->registration_ends();
fm_ctrl->registration_ends();
fm_dyn->init_fields_time_stamp(t0);
fm_phys->init_fields_time_stamp(t0);
fm_ctrl->init_fields_time_stamp(t0);
fm->init_fields_time_stamp(t0,dyn_grid->name());
fm->init_fields_time_stamp(t0, phys_grid->name());
fm_ctrl->init_fields_time_stamp(t0, phys_grid->name());

std::vector<std::string> fnames = {"field_1", "field_2", "field_3"};

Expand All @@ -129,13 +123,13 @@ TEST_CASE("dyn_grid_io")
auto dyn2ctrl = gm->create_remapper(dyn_grid,phys_grid);
dyn2ctrl->registration_begins();
for (const auto& fn : fnames) {
auto fd = fm_dyn->get_field(fn);
auto fc = fm_ctrl->get_field(fn);
auto fd = fm->get_field(fn,dyn_grid->name());
auto fc = fm_ctrl->get_field(fn,phys_grid->name());
dyn2ctrl->register_field(fd,fc);
randomize(fd,engine,pdf);

// Init phys field to something obviously wrong
auto fp = fm_phys->get_field(fn);
auto fp = fm->get_field(fn,phys_grid->name());
fp.deep_copy(-1.0);
}
dyn2ctrl->registration_ends();
Expand All @@ -155,7 +149,7 @@ TEST_CASE("dyn_grid_io")

OutputManager output;
output.initialize(comm, out_params, t0, false);
output.setup (fm_dyn, gm);
output.setup (fm, {dyn_grid->name()});
output.run(t0);
output.finalize();

Expand All @@ -166,14 +160,14 @@ TEST_CASE("dyn_grid_io")
ekat::ParameterList in_params;
in_params.set<std::string>("Filename",filename);
in_params.set<std::vector<std::string>>("Field Names",fnames);
AtmosphereInput input (in_params,fm_phys);
AtmosphereInput input (in_params,fm,phys_grid->name());
input.read_variables();
input.finalize();

// Compare against ctrl fields
for (const auto& fn : fnames) {
auto fp = fm_phys->get_field(fn);
auto fc = fm_ctrl->get_field(fn);
auto fp = fm->get_field(fn,phys_grid->name());
auto fc = fm_ctrl->get_field(fn,phys_grid->name());
REQUIRE(views_are_equal(fp,fc));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ inline std::shared_ptr<AtmosphereInput> create_tracer_data_reader(
// we must rename this tag.
// We need to perform a shallow clone of io_grid because tags are const in this object.
auto horiz_interp_src_grid =
io_grid->clone("tracer_horiz_interp_src_grid", true);
io_grid->clone(io_grid->name(), true);
tcclevenger marked this conversation as resolved.
Show resolved Hide resolved
horiz_interp_src_grid->reset_field_tag_name(LEV, "altitude");
horiz_interp_src_grid->reset_field_tag_name(ILEV, "altitude_int");
return std::make_shared<AtmosphereInput>(tracer_data_file, horiz_interp_src_grid, io_fields,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ TEST_CASE("create_nudging_data") {
// Create a grids manager
const auto gm = create_gm(comm,ngcols,nlevs);
const auto grid = gm->get_grid("Point Grid");
const auto gn = grid->name();

// Create a field manager, and init fields (since OM's need t0 values)
const auto fm1 = create_fm(grid);
const auto fm2 = create_fm(grid);
const auto fm3 = create_fm(grid);
compute_fields(fm1,t0,comm,0);
compute_fields(fm2,t0,comm,nlevs_filled);
compute_fields(fm3,t0,comm,0);
compute_fields(fm1,gn,t0,comm,0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment on FM header: if we allow querying for a field without passing the grid name (if there's only 1 grid), we can revert these changes (here, as in many other unit tests)...

compute_fields(fm2,gn,t0,comm,nlevs_filled);
compute_fields(fm3,gn,t0,comm,0);

// Create output manager
const auto om1 = create_om("nudging_data",fm1,gm,t0,comm);
Expand All @@ -44,9 +45,9 @@ TEST_CASE("create_nudging_data") {
time += dt;

// Compute fields, but keep p_mid constnat in fm1 and fm2, to avoid vinterp
compute_fields(fm1,time,comm,0,false);
compute_fields(fm2,time,comm,nlevs_filled,false);
compute_fields(fm3,time,comm,0);
compute_fields(fm1,gn,time,comm,0,false);
compute_fields(fm2,gn,time,comm,nlevs_filled,false);
compute_fields(fm3,gn,time,comm,0);

om1->run(time);
om2->run(time);
Expand Down
26 changes: 13 additions & 13 deletions components/eamxx/src/physics/nudging/tests/nudging_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ create_nudging (const ekat::Comm& comm,
auto nudging = std::make_shared<Nudging>(comm,params);
nudging->set_grids(gm);
for (const auto& req : nudging->get_required_field_requests()) {
auto f = fm->get_field(req.fid.name());
auto f = fm->get_field(req.fid);
nudging->set_required_field(f);
}
for (const auto& req : nudging->get_computed_field_requests()) {
auto f = fm->get_field(req.fid.name());
auto f = fm->get_field(req.fid);
nudging->set_computed_field(f);
}
nudging->initialize(t0,RunType::Initial);
Expand Down Expand Up @@ -68,7 +68,7 @@ TEST_CASE("nudging_tests") {
auto grid_fine_h = gm_fine_h->get_grid("Point Grid");
auto grid_fine_v = gm_fine_v->get_grid("Point Grid");
auto grid_fine = gm_fine->get_grid("Point Grid");

const int ncols_data = grid_data->get_num_local_dofs();

// First section tests nudging when there is no horiz-vert interp
Expand All @@ -81,9 +81,9 @@ TEST_CASE("nudging_tests") {

// Create fm. Init p_mid, since it's constant in this file
auto fm = create_fm(grid_data);
compute_field(fm->get_field("p_mid"),get_t0(),comm,0);
compute_field(fm->get_field("p_mid",grid_data->name()),get_t0(),comm,0);

auto U = fm->get_field("U");
auto U = fm->get_field("U",grid_data->name());
SECTION ("same-time") {
std::string msg = " -> Testing same time/horiz/vert grid as data ...........";
root_print (msg + "\n");
Expand Down Expand Up @@ -204,8 +204,8 @@ TEST_CASE("nudging_tests") {

// Create fm
auto fm = create_fm(grid_fine_v);
auto U = fm->get_field("U");
auto p_mid = fm->get_field("p_mid");
auto U = fm->get_field("U",grid_fine_v->name());
auto p_mid = fm->get_field("p_mid",grid_fine_v->name());

// Create and init nudging process
auto nudging = create_nudging(comm,params,fm,gm_fine_v,get_t0());
Expand Down Expand Up @@ -244,8 +244,8 @@ TEST_CASE("nudging_tests") {

// Create fm
auto fm = create_fm(grid_fine_v);
auto U = fm->get_field("U");
auto p_mid = fm->get_field("p_mid");
auto U = fm->get_field("U",grid_fine_v->name());
auto p_mid = fm->get_field("p_mid",grid_fine_v->name());

// Create and init nudging process
auto nudging = create_nudging(comm,params,fm,gm_fine_v,get_t0());
Expand Down Expand Up @@ -373,8 +373,8 @@ TEST_CASE("nudging_tests") {

// Create fm
auto fm = create_fm(grid_fine_h);
auto U = fm->get_field("U");
auto p_mid = fm->get_field("p_mid");
auto U = fm->get_field("U",grid_fine_h->name());
auto p_mid = fm->get_field("p_mid",grid_fine_h->name());

// Create and init nudging process
auto nudging = create_nudging(comm,params,fm,gm_fine_h,get_t0());
Expand Down Expand Up @@ -437,8 +437,8 @@ TEST_CASE("nudging_tests") {

// Create fm. Init p_mid, since it's constant in this file
auto fm = create_fm(grid_data);
auto U = fm->get_field("U");
auto p_mid = fm->get_field("p_mid");
auto U = fm->get_field("U",grid_data->name());
auto p_mid = fm->get_field("p_mid",grid_data->name());
compute_field(p_mid,get_t0(),comm,0);

// Create and init nudging process
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ create_fm (const std::shared_ptr<const AbstractGrid>& grid)
fm->register_field(FR(fid2));
fm->registration_ends();

auto U = fm->get_field("horiz_winds").subfield("U",1,0);
auto V = fm->get_field("horiz_winds").subfield("V",1,1);
auto U = fm->get_field("horiz_winds",gn).subfield("U",1,0);
auto V = fm->get_field("horiz_winds",gn).subfield("V",1,1);
fm->add_field(U);
fm->add_field(V);

Expand Down Expand Up @@ -119,20 +119,21 @@ void compute_field (Field f,
}

void compute_fields (const std::shared_ptr<FieldManager>& fm,
const std::string& grid_name,
const util::TimeStamp& time,
const ekat::Comm& comm,
const int num_masked_levs = 0,
const bool update_p_mid = true)
{
if (update_p_mid) {
// Don't mask pressure
compute_field(fm->get_field("p_mid"),time,comm,0);
compute_field(fm->get_field("p_mid",grid_name),time,comm,0);
}
compute_field(fm->get_field("U"),time,comm,num_masked_levs);
compute_field(fm->get_field("V"),time,comm,num_masked_levs);
compute_field(fm->get_field("U",grid_name),time,comm,num_masked_levs);
compute_field(fm->get_field("V",grid_name),time,comm,num_masked_levs);

// Not sure if we need it, since we don't handle horiz_winds directly, I think
fm->get_field("horiz_winds").get_header().get_tracking().update_time_stamp(time);
fm->get_field("horiz_winds", grid_name).get_header().get_tracking().update_time_stamp(time);
}

std::shared_ptr<OutputManager>
Expand Down Expand Up @@ -160,7 +161,7 @@ create_om (const std::string& filename_prefix,

auto om = std::make_shared<OutputManager>();
om->initialize(comm,params,t0,false);
om->setup(fm,gm);
om->setup(fm,gm->get_grid_names());
return om;
}

Expand Down
Loading
Loading