@@ -58,9 +58,7 @@ namespace control {
58
58
* Note: at this stage, atm procs that act on non-ref grid(s) should be able to create their
59
59
* remappers. The AD will *not* take care of remapping inputs/outputs of the process.
60
60
* 4) Register all fields and all groups from all atm procs inside the field managers, and proceed
61
- * to allocate fields. Each field manager (there is one FM per grid) will take care of
62
- * accommodating all requests for packing as well as (if possible) bundling of groups.
63
- * For more details, see the documentation in the share/field/field_request.hpp header.
61
+ * to allocate fields. For more details, see the documentation in the share/field/field_request.hpp header.
64
62
* 5) Set all the fields into the atm procs. Before this point, all the atm procs had were the
65
63
* FieldIdentifiers for their input/output fields and FieldGroupInfo for their input/output
66
64
* field groups. Now, we pass actual Field and FieldGroup objects to them, where both the
@@ -405,7 +403,7 @@ void AtmosphereDriver::reset_accumulated_fields ()
405
403
}
406
404
407
405
auto accum_group = m_field_mgr->get_field_group (" ACCUMULATED" , grid_name);
408
- for (auto f_it : accum_group.m_fields ) {
406
+ for (auto f_it : accum_group.m_individual_fields ) {
409
407
auto & track = f_it.second ->get_header ().get_tracking ();
410
408
f_it.second ->deep_copy (zero);
411
409
track.set_accum_start_time (m_current_ts);
@@ -535,8 +533,54 @@ void AtmosphereDriver::create_fields()
535
533
m_field_mgr = std::make_shared<field_mgr_type>(m_grids_manager);
536
534
m_field_mgr->registration_begins ();
537
535
538
- // By now, the processes should have fully built the ids of their
539
- // required/computed fields and groups. Let them register them in the FM
536
+ // Before registering fields, check that Field Requests for tracers are compatible
537
+ {
538
+ // Create map from tracer name to a vector which contains the field requests for that tracer.
539
+ std::map<std::string, std::set<FieldRequest>> tracer_requests;
540
+ auto gather_tracer_requests = [&] (FieldRequest req) {
541
+ if (not ekat::contains (req.groups , " tracers" )) return ;
542
+
543
+ std::string fname = req.fid .name ();
544
+ if (tracer_requests.find (fname) == tracer_requests.end ()) {
545
+ tracer_requests[fname] = {req};
546
+ } else {
547
+ tracer_requests[fname].emplace (req);
548
+ }
549
+ };
550
+ for (const auto & req : m_atm_process_group->get_required_field_requests ()){
551
+ gather_tracer_requests (req);
552
+ }
553
+ for (const auto & req : m_atm_process_group->get_computed_field_requests ()) {
554
+ gather_tracer_requests (req);
555
+ }
556
+
557
+ // Go through the map entry for each tracer and check that every one
558
+ // has the same request for turbulence advection.
559
+ for (auto fr : tracer_requests) {
560
+ const auto reqs = fr.second ;
561
+
562
+ std::set<bool > turb_advect_types;
563
+ for (auto req : reqs) {
564
+ turb_advect_types.emplace (ekat::contains (req.groups , " turbulence_advected_tracers" ));
565
+ }
566
+
567
+ if (turb_advect_types.size ()!=1 ) {
568
+ std::ostringstream ss;
569
+ ss << " Error! Incompatible tracer request. Turbulence advection requests not consistent among processes.\n "
570
+ " - Tracer name: " + fr.first + " \n "
571
+ " - Requests (process name, grid name, is tracers turbulence advected):\n " ;
572
+ for (auto req : reqs) {
573
+ const auto grid_name = req.fid .get_grid_name ();
574
+ const bool turb_advect = ekat::contains (req.groups , " turbulence_advected_tracers" );
575
+ ss << " - (" + req.calling_process + " , " + grid_name + " , " + (turb_advect ? " true" : " false" ) + " )\n " ;
576
+ }
577
+ EKAT_ERROR_MSG (ss.str ());
578
+ }
579
+ }
580
+ }
581
+
582
+ // Register required/computed fields. By now, the processes should have
583
+ // fully built the ids of their required/computed fields and groups
540
584
for (const auto & req : m_atm_process_group->get_required_field_requests ()) {
541
585
m_field_mgr->register_field (req);
542
586
}
@@ -599,8 +643,8 @@ void AtmosphereDriver::create_fields()
599
643
m_field_mgr->add_to_group (fid, " RESTART" );
600
644
}
601
645
for (const auto & g : m_atm_process_group->get_groups_in ()) {
602
- if (g.m_bundle ) {
603
- m_field_mgr->add_to_group (g.m_bundle ->get_header ().get_identifier (), " RESTART" );
646
+ if (g.m_monolithic_field ) {
647
+ m_field_mgr->add_to_group (g.m_monolithic_field ->get_header ().get_identifier (), " RESTART" );
604
648
} else {
605
649
for (const auto & fn : g.m_info ->m_fields_names ) {
606
650
m_field_mgr->add_to_group (fn, g.grid_name (), " RESTART" );
@@ -1128,19 +1172,19 @@ void AtmosphereDriver::set_initial_conditions ()
1128
1172
// ...then the input groups
1129
1173
m_atm_logger->debug (" [EAMxx] Processing input groups ..." );
1130
1174
for (const auto & g : m_atm_process_group->get_groups_in ()) {
1131
- if (g.m_bundle ) {
1132
- process_ic_field (*g.m_bundle );
1175
+ if (g.m_monolithic_field ) {
1176
+ process_ic_field (*g.m_monolithic_field );
1133
1177
}
1134
- for (auto it : g.m_fields ) {
1178
+ for (auto it : g.m_individual_fields ) {
1135
1179
process_ic_field (*it.second );
1136
1180
}
1137
1181
}
1138
1182
m_atm_logger->debug (" [EAMxx] Processing input groups ... done!" );
1139
1183
1140
- // Some fields might be the subfield of a group's bundled field. In that case,
1141
- // we only need to init one: either the bundled field, or all the individual subfields.
1184
+ // Some fields might be the subfield of a group's monolithic field. In that case,
1185
+ // we only need to init one: either the monolithic field, or all the individual subfields.
1142
1186
// So loop over the fields that appear to require loading from file, and remove
1143
- // them from the list if they are the subfield of a bundled field already inited
1187
+ // them from the list if they are the subfield of a groups monolithic field already inited
1144
1188
// (perhaps via initialize_constant_field, or copied from another field).
1145
1189
for (auto & it1 : ic_fields_names) {
1146
1190
const auto & grid_name = it1.first ;
@@ -1244,17 +1288,17 @@ void AtmosphereDriver::set_initial_conditions ()
1244
1288
}
1245
1289
m_atm_logger->debug (" [EAMxx] Processing fields to copy ... done!" );
1246
1290
1247
- // It is possible to have a bundled group G1=(f1,f2,f3),
1291
+ // It is possible to have a monolithically allocated group G1=(f1,f2,f3),
1248
1292
// where the IC are read from file for f1, f2, and f3. In that case,
1249
- // the time stamp for the bundled G1 has not be inited, but the data
1293
+ // the time stamp for the monolithic field of G1 has not be inited, but the data
1250
1294
// is valid (all entries have been inited). Let's fix that.
1251
1295
m_atm_logger->debug (" [EAMxx] Processing subfields ..." );
1252
1296
for (const auto & g : m_atm_process_group->get_groups_in ()) {
1253
- if (g.m_bundle ) {
1254
- auto & track = g.m_bundle ->get_header ().get_tracking ();
1297
+ if (g.m_monolithic_field ) {
1298
+ auto & track = g.m_monolithic_field ->get_header ().get_tracking ();
1255
1299
if (not track.get_time_stamp ().is_valid ()) {
1256
- // The bundled field has not been inited. Check if all the subfields
1257
- // have been inited. If so, init the timestamp of the bundled field too.
1300
+ // The groups monolithic field has not been inited. Check if all the subfields
1301
+ // have been inited. If so, init the timestamp of the monlithic field too.
1258
1302
const auto & children = track.get_children ();
1259
1303
bool all_inited = children.size ()>0 ; // If no children, then something is off, so mark as not good
1260
1304
for (auto wp : children) {
@@ -1632,7 +1676,7 @@ void AtmosphereDriver::run (const int dt) {
1632
1676
}
1633
1677
1634
1678
auto rescale_group = m_field_mgr->get_field_group (" DIVIDE_BY_DT" , gname);
1635
- for (auto f_it : rescale_group.m_fields ) {
1679
+ for (auto f_it : rescale_group.m_individual_fields ) {
1636
1680
f_it.second ->scale (Real (1 ) / dt);
1637
1681
}
1638
1682
}
0 commit comments