@@ -160,8 +160,7 @@ registration_ends_impl ()
160
160
const auto & src = m_src_fields[i];
161
161
auto & tgt = m_tgt_fields[i];
162
162
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 ();
165
164
166
165
if (src_layout.has_tag (LEV) or src_layout.has_tag (ILEV)) {
167
166
// Determine if this field can be handled with packs, and whether it's at midpoints
@@ -185,47 +184,27 @@ registration_ends_impl ()
185
184
// NOTE: for now we assume that masking is determined only by the COL,LEV location in space
186
185
// and that fields with multiple components will have the same masking for each component
187
186
// 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});
189
190
190
191
// 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 () ) {
194
195
auto nondim = ekat::units::Units::nondimensional ();
195
196
// Create this src/tgt mask fields, and assign them to these src/tgt fields extra data
196
197
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 ();
222
201
}
223
202
224
203
EKAT_REQUIRE_MSG (not tgt.get_header ().has_extra_data (" mask_field" ),
225
204
" [VerticalRemapper::registration_ends_impl] Error! Target field already has mask data assigned.\n "
226
205
" - tgt field name: " + tgt.name () + " \n " );
227
206
228
- tgt.get_header ().set_extra_data (" mask_field" ,tgt_mask );
207
+ tgt.get_header ().set_extra_data (" mask_field" ,mask );
229
208
230
209
// Since we do mask (at top and/or bot), the tgt field MAY be contain fill_value entries
231
210
tgt.get_header ().set_may_be_filled (true );
@@ -383,6 +362,8 @@ create_layout (const FieldLayout& from_layout,
383
362
384
363
void VerticalRemapper::remap_fwd_impl ()
385
364
{
365
+ using namespace ShortFieldTagsNames ;
366
+
386
367
// 1. Setup any interp object that was created (if nullptr, no fields need it)
387
368
if (m_lin_interp_mid_packed) {
388
369
setup_lin_interp (*m_lin_interp_mid_packed,m_src_pmid,m_tgt_pmid);
@@ -397,9 +378,12 @@ void VerticalRemapper::remap_fwd_impl ()
397
378
setup_lin_interp (*m_lin_interp_int_scalar,m_src_pint,m_tgt_pint);
398
379
}
399
380
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
+ }
401
385
402
- // 2 . Interpolate the fields
386
+ // 3 . Interpolate the fields
403
387
for (int i=0 ; i<m_num_fields; ++i) {
404
388
const auto & f_src = m_src_fields[i];
405
389
auto & f_tgt = m_tgt_fields[i];
@@ -435,29 +419,6 @@ void VerticalRemapper::remap_fwd_impl ()
435
419
}
436
420
}
437
421
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
- }
461
422
}
462
423
463
424
template <int Packsize>
@@ -641,6 +602,12 @@ extrapolate (const Field& f_src,
641
602
auto etop = m_etype_top;
642
603
auto ebot = m_etype_bot;
643
604
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
+
644
611
switch (f_src.rank ()) {
645
612
case 2 :
646
613
{
@@ -674,6 +641,7 @@ extrapolate (const Field& f_src,
674
641
y_tgt[ilev] = y_src[nlevs_src-1 ];
675
642
} else {
676
643
y_tgt[ilev] = fill_val;
644
+ mask_v (icol,ilev) = 0 ;
677
645
}
678
646
}
679
647
} else {
@@ -683,6 +651,7 @@ extrapolate (const Field& f_src,
683
651
y_tgt[ilev] = y_src[0 ];
684
652
} else {
685
653
y_tgt[ilev] = fill_val;
654
+ mask_v (icol,ilev) = 0 ;
686
655
}
687
656
}
688
657
}
@@ -725,6 +694,7 @@ extrapolate (const Field& f_src,
725
694
y_tgt[ilev] = y_src[nlevs_src-1 ];
726
695
} else {
727
696
y_tgt[ilev] = fill_val;
697
+ mask_v (icol,ilev) = 0 ;
728
698
}
729
699
}
730
700
} else {
@@ -734,6 +704,7 @@ extrapolate (const Field& f_src,
734
704
y_tgt[ilev] = y_src[0 ];
735
705
} else {
736
706
y_tgt[ilev] = fill_val;
707
+ mask_v (icol,ilev) = 0 ;
737
708
}
738
709
}
739
710
}
0 commit comments