Skip to content

Commit fd74424

Browse files
committed
EAMxx: correctly handle mask fields in VerticalRemapper
1 parent fa8839e commit fd74424

File tree

3 files changed

+30
-61
lines changed

3 files changed

+30
-61
lines changed

components/eamxx/src/share/grid/remap/vertical_remapper.cpp

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ registration_ends_impl ()
160160
const auto& src = m_src_fields[i];
161161
auto& tgt = m_tgt_fields[i];
162162

163-
// Clone src layout, since we may strip dims later for mask creation
164-
auto src_layout = src.get_header().get_identifier().get_layout().clone();
163+
const auto& src_layout = src.get_header().get_identifier().get_layout().clone();
165164

166165
if (src_layout.has_tag(LEV) or src_layout.has_tag(ILEV)) {
167166
// Determine if this field can be handled with packs, and whether it's at midpoints
@@ -185,47 +184,27 @@ registration_ends_impl ()
185184
// NOTE: for now we assume that masking is determined only by the COL,LEV location in space
186185
// and that fields with multiple components will have the same masking for each component
187186
// at a specific COL,LEV
188-
src_layout.strip_dims({CMP});
187+
188+
auto tgt_layout = create_tgt_layout(src_layout);
189+
tgt_layout.strip_dims({CMP});
189190

190191
// I this mask has already been created, retrieve it, otherwise create it
191-
const auto mask_name = m_tgt_grid->name() + "_" + ekat::join(src_layout.names(),"_") + "_mask";
192-
Field tgt_mask;
193-
if (m_field2type.count(mask_name)==0) {
192+
const auto mask_name = m_tgt_grid->name() + "_" + ekat::join(tgt_layout.names(),"_") + "_mask";
193+
auto& mask = m_masks[mask_name];
194+
if (not mask.is_allocated()) {
194195
auto nondim = ekat::units::Units::nondimensional();
195196
// Create this src/tgt mask fields, and assign them to these src/tgt fields extra data
196197

197-
FieldIdentifier src_mask_fid (mask_name, src_layout, nondim, m_src_grid->name() );
198-
FieldIdentifier tgt_mask_fid = create_tgt_fid(src_mask_fid);
199-
200-
Field src_mask (src_mask_fid);
201-
src_mask.allocate_view();
202-
203-
tgt_mask = Field (tgt_mask_fid);
204-
tgt_mask.allocate_view();
205-
206-
// Initialize the src mask values to 1.0
207-
src_mask.deep_copy(1.0);
208-
209-
m_src_masks.push_back(src_mask);
210-
m_tgt_masks.push_back(tgt_mask);
211-
212-
auto& mt = m_field2type[src_mask_fid.name()];
213-
mt.packed = false;
214-
mt.midpoints = src_layout.has_tag(LEV);
215-
} else {
216-
for (size_t i=0; i<m_tgt_masks.size(); ++i) {
217-
if (m_tgt_masks[i].name()==mask_name) {
218-
tgt_mask = m_tgt_masks[i];
219-
break;
220-
}
221-
}
198+
FieldIdentifier mask_fid (mask_name, tgt_layout, nondim, m_tgt_grid->name() );
199+
mask = Field (mask_fid);
200+
mask.allocate_view();
222201
}
223202

224203
EKAT_REQUIRE_MSG(not tgt.get_header().has_extra_data("mask_field"),
225204
"[VerticalRemapper::registration_ends_impl] Error! Target field already has mask data assigned.\n"
226205
" - tgt field name: " + tgt.name() + "\n");
227206

228-
tgt.get_header().set_extra_data("mask_field",tgt_mask);
207+
tgt.get_header().set_extra_data("mask_field",mask);
229208

230209
// Since we do mask (at top and/or bot), the tgt field MAY be contain fill_value entries
231210
tgt.get_header().set_may_be_filled(true);
@@ -383,6 +362,8 @@ create_layout (const FieldLayout& from_layout,
383362

384363
void VerticalRemapper::remap_fwd_impl ()
385364
{
365+
using namespace ShortFieldTagsNames;
366+
386367
// 1. Setup any interp object that was created (if nullptr, no fields need it)
387368
if (m_lin_interp_mid_packed) {
388369
setup_lin_interp(*m_lin_interp_mid_packed,m_src_pmid,m_tgt_pmid);
@@ -397,9 +378,12 @@ void VerticalRemapper::remap_fwd_impl ()
397378
setup_lin_interp(*m_lin_interp_int_scalar,m_src_pint,m_tgt_pint);
398379
}
399380

400-
using namespace ShortFieldTagsNames;
381+
// 2. Init all masks fields (if any) to 1 (signaling no masked entries)
382+
for (auto& [name, mask] : m_masks) {
383+
mask.deep_copy(1);
384+
}
401385

402-
// 2. Interpolate the fields
386+
// 3. Interpolate the fields
403387
for (int i=0; i<m_num_fields; ++i) {
404388
const auto& f_src = m_src_fields[i];
405389
auto& f_tgt = m_tgt_fields[i];
@@ -435,29 +419,6 @@ void VerticalRemapper::remap_fwd_impl ()
435419
}
436420
}
437421

438-
// 3. Interpolate the mask fields
439-
for (unsigned i=0; i<m_tgt_masks.size(); ++i) {
440-
auto& f_src = m_src_masks[i];
441-
auto& f_tgt = m_tgt_masks[i];
442-
const auto& type = m_field2type.at(f_src.name());
443-
444-
// Dispatch interpolation to the proper lin interp object
445-
if (type.midpoints) {
446-
if (type.packed) {
447-
apply_vertical_interpolation(*m_lin_interp_mid_packed,f_src,f_tgt,m_src_pmid,m_tgt_pmid);
448-
} else {
449-
apply_vertical_interpolation(*m_lin_interp_mid_scalar,f_src,f_tgt,m_src_pmid,m_tgt_pmid);
450-
}
451-
extrapolate(f_src,f_tgt,m_src_pmid,m_tgt_pmid);
452-
} else {
453-
if (type.packed) {
454-
apply_vertical_interpolation(*m_lin_interp_int_packed,f_src,f_tgt,m_src_pint,m_tgt_pint);
455-
} else {
456-
apply_vertical_interpolation(*m_lin_interp_int_scalar,f_src,f_tgt,m_src_pint,m_tgt_pint);
457-
}
458-
extrapolate(f_src,f_tgt,m_src_pint,m_tgt_pint);
459-
}
460-
}
461422
}
462423

463424
template<int Packsize>
@@ -641,6 +602,12 @@ extrapolate (const Field& f_src,
641602
auto etop = m_etype_top;
642603
auto ebot = m_etype_bot;
643604
auto mid = nlevs_tgt / 2;
605+
auto do_mask = etop==Mask or ebot==Mask;
606+
decltype(f_tgt.get_view<Real**>()) mask_v;
607+
if (do_mask) {
608+
mask_v = f_tgt.get_header().get_extra_data<Field>("mask_field").get_view<Real**>();
609+
}
610+
644611
switch(f_src.rank()) {
645612
case 2:
646613
{
@@ -674,6 +641,7 @@ extrapolate (const Field& f_src,
674641
y_tgt[ilev] = y_src[nlevs_src-1];
675642
} else {
676643
y_tgt[ilev] = fill_val;
644+
mask_v(icol,ilev) = 0;
677645
}
678646
}
679647
} else {
@@ -683,6 +651,7 @@ extrapolate (const Field& f_src,
683651
y_tgt[ilev] = y_src[0];
684652
} else {
685653
y_tgt[ilev] = fill_val;
654+
mask_v(icol,ilev) = 0;
686655
}
687656
}
688657
}
@@ -725,6 +694,7 @@ extrapolate (const Field& f_src,
725694
y_tgt[ilev] = y_src[nlevs_src-1];
726695
} else {
727696
y_tgt[ilev] = fill_val;
697+
mask_v(icol,ilev) = 0;
728698
}
729699
}
730700
} else {
@@ -734,6 +704,7 @@ extrapolate (const Field& f_src,
734704
y_tgt[ilev] = y_src[0];
735705
} else {
736706
y_tgt[ilev] = fill_val;
707+
mask_v(icol,ilev) = 0;
737708
}
738709
}
739710
}

components/eamxx/src/share/grid/remap/vertical_remapper.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ class VerticalRemapper : public AbstractRemapper
112112

113113
ekat::Comm m_comm;
114114

115-
// Source and target fields
116-
std::vector<Field> m_src_masks;
117-
std::vector<Field> m_tgt_masks;
115+
// Tgt grid masks (in case extrap type at top or bot is Mask)
116+
std::map<std::string,Field> m_masks;
118117

119118
// Vertical profile fields, both for source and target
120119
Field m_src_pmid;

components/eamxx/src/share/io/tests/io_remap_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,6 @@ ekat::ParameterList set_output_params(const std::string& name, const std::string
675675

676676
params.set<std::string>("filename_prefix",name);
677677
params.set<std::string>("averaging_type","instant");
678-
params.set<int>("max_snapshots_per_file",1);
679678
params.set<std::string>("floating_point_precision","real");
680679
auto& oc = params.sublist("output_control");
681680
oc.set<int>("frequency",1);

0 commit comments

Comments
 (0)