Skip to content

Commit 02458d5

Browse files
authored
Merge remote-tracking branch 'tcclevenger/eamxx/turb_advect_default_mode' (PR #7173)
If all processes register a tracer with "NoPreference", the tracer will be both dynamics and shoc advected. Also, moves tracer consistency check to AtmosphereProcessGroup. [BFB]
2 parents 7be7a3c + 1df8dd3 commit 02458d5

File tree

5 files changed

+104
-64
lines changed

5 files changed

+104
-64
lines changed

components/eamxx/src/control/atmosphere_driver.cpp

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -534,50 +534,8 @@ void AtmosphereDriver::create_fields()
534534
m_field_mgr->registration_begins();
535535

536536
// 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-
}
537+
// and store the correct type of turbulence advection for each tracer
538+
m_atm_process_group->pre_process_tracer_requests();
581539

582540
// Register required/computed fields. By now, the processes should have
583541
// fully built the ids of their required/computed fields and groups

components/eamxx/src/share/atm_process/atmosphere_process.hpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
176176
// These methods allow the AD to figure out what each process needs, with very fine
177177
// grain detail. See field_request.hpp for more info on what FieldRequest and GroupRequest
178178
// are, and field_group.hpp for what groups of fields are.
179-
const std::set<FieldRequest>& get_required_field_requests () const { return m_required_field_requests; }
180-
const std::set<FieldRequest>& get_computed_field_requests () const { return m_computed_field_requests; }
181-
const std::set<GroupRequest>& get_required_group_requests () const { return m_required_group_requests; }
182-
const std::set<GroupRequest>& get_computed_group_requests () const { return m_computed_group_requests; }
179+
const std::list<FieldRequest>& get_required_field_requests () const { return m_required_field_requests; }
180+
const std::list<FieldRequest>& get_computed_field_requests () const { return m_computed_field_requests; }
181+
const std::list<GroupRequest>& get_required_group_requests () const { return m_required_group_requests; }
182+
const std::list<GroupRequest>& get_computed_group_requests () const { return m_computed_group_requests; }
183183

184184
// These sets allow to get all the actual in/out fields stored by the atm proc
185185
// Note: if an atm proc requires a group, then all the fields in the group, as well as
@@ -356,12 +356,14 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
356356
void add_tracer (const std::string& name, std::shared_ptr<const AbstractGrid> grid,
357357
const ekat::units::Units& u,
358358
const int ps = 1,
359-
const TracerAdvection tracer_advection = TracerAdvection::DynamicsAndTurbulence)
359+
const TracerAdvection tracer_advection = TracerAdvection::NoPreference)
360360
{
361361
std::list<std::string> tracer_groups;
362362
tracer_groups.push_back("tracers");
363363
if (tracer_advection==TracerAdvection::DynamicsAndTurbulence) {
364364
tracer_groups.push_back("turbulence_advected_tracers");
365+
} else if (tracer_advection==TracerAdvection::DynamicsOnly) {
366+
tracer_groups.push_back("non_turbulence_advected_tracers");
365367
}
366368

367369
FieldIdentifier fid(name, grid->get_3d_scalar_layout(true), u, grid->name());
@@ -391,14 +393,14 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
391393

392394
switch (RT) {
393395
case Required:
394-
m_required_field_requests.emplace(req);
396+
m_required_field_requests.push_back(req);
395397
break;
396398
case Computed:
397-
m_computed_field_requests.emplace(req);
399+
m_computed_field_requests.push_back(req);
398400
break;
399401
case Updated:
400-
m_required_field_requests.emplace(req);
401-
m_computed_field_requests.emplace(req);
402+
m_required_field_requests.push_back(req);
403+
m_computed_field_requests.push_back(req);
402404
break;
403405
}
404406
}
@@ -411,14 +413,14 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
411413
"Error! Invalid request type in call to add_group.\n");
412414
switch (RT) {
413415
case Required:
414-
m_required_group_requests.emplace(req);
416+
m_required_group_requests.push_back(req);
415417
break;
416418
case Computed:
417-
m_computed_group_requests.emplace(req);
419+
m_computed_group_requests.push_back(req);
418420
break;
419421
case Updated:
420-
m_required_group_requests.emplace(req);
421-
m_computed_group_requests.emplace(req);
422+
m_required_group_requests.push_back(req);
423+
m_computed_group_requests.push_back(req);
422424
break;
423425
}
424426
}
@@ -558,12 +560,6 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
558560
strmap_t<strmap_t<Field*>> m_fields_out_pointers;
559561
strmap_t<strmap_t<Field*>> m_internal_fields_pointers;
560562

561-
// The list of in/out field/group requests.
562-
std::set<FieldRequest> m_required_field_requests;
563-
std::set<FieldRequest> m_computed_field_requests;
564-
std::set<GroupRequest> m_required_group_requests;
565-
std::set<GroupRequest> m_computed_group_requests;
566-
567563
// List of property checks for fields
568564
std::list<std::pair<CheckFailHandling,prop_check_ptr>> m_precondition_checks;
569565
std::list<std::pair<CheckFailHandling,prop_check_ptr>> m_postcondition_checks;
@@ -608,6 +604,12 @@ class AtmosphereProcess : public ekat::enable_shared_from_this<AtmosphereProcess
608604

609605
// IOP object
610606
iop_data_ptr m_iop_data_manager;
607+
608+
// The list of in/out field/group requests.
609+
std::list<FieldRequest> m_required_field_requests;
610+
std::list<FieldRequest> m_computed_field_requests;
611+
std::list<GroupRequest> m_required_group_requests;
612+
std::list<GroupRequest> m_computed_group_requests;
611613
};
612614

613615
// ================= IMPLEMENTATION ================== //

components/eamxx/src/share/atm_process/atmosphere_process_group.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,79 @@ void AtmosphereProcessGroup::add_additional_data_fields_to_property_checks (cons
364364
}
365365
}
366366

367+
void AtmosphereProcessGroup::pre_process_tracer_requests () {
368+
// Create map from tracer name to a vector which contains the field requests for that tracer.
369+
std::map<std::string, std::list<FieldRequest>> tracer_requests;
370+
auto gather_tracer_requests = [&] (FieldRequest& req) {
371+
if (ekat::contains(req.groups, "tracers")) {
372+
tracer_requests[req.fid.name()].push_back(req);
373+
}
374+
};
375+
for (auto& req : m_required_field_requests){
376+
gather_tracer_requests(req);
377+
}
378+
for (auto& req : m_computed_field_requests) {
379+
gather_tracer_requests(req);
380+
}
381+
382+
// Go through the map entry for each tracer and check that every one
383+
// has the same request for turbulence advection, or listed no preference.
384+
std::map<std::string, std::string> tracer_advection_type;
385+
for (auto& fr : tracer_requests) {
386+
auto& reqs = fr.second;
387+
388+
bool turb_advect_req = false;
389+
bool non_turb_advect_req = false;
390+
for (auto& req : reqs) {
391+
if (ekat::contains(req.groups, "turbulence_advected_tracers")) turb_advect_req = true;
392+
if (ekat::contains(req.groups, "non_turbulence_advected_tracers")) non_turb_advect_req = true;
393+
if (turb_advect_req and non_turb_advect_req) {
394+
// All the info we need to error out, just break request loop
395+
break;
396+
}
397+
}
398+
399+
if (turb_advect_req and non_turb_advect_req) {
400+
std::ostringstream ss;
401+
ss << "Error! Incompatible tracer request. Turbulence advection requests not consistent among processes.\n"
402+
" - Tracer name: " + fr.first + "\n"
403+
" - Requests (process name, grid name, turbulence advected request type):\n";
404+
for (auto& req : reqs) {
405+
const auto turb_advect = ekat::contains(req.groups, "turbulence_advected_tracers");
406+
const auto non_turb_advect = ekat::contains(req.groups, "non_turbulence_advected_tracers");
407+
std::string turb_advect_info =
408+
(turb_advect ? "DynamicsAndTurbulence" :
409+
(non_turb_advect ? "DynamicsOnly" :
410+
"NoPreference"));
411+
const auto grid_name = req.fid.get_grid_name();
412+
ss << " - (" + req.calling_process + ", " + grid_name + ", " + turb_advect_info + ")\n";
413+
}
414+
EKAT_ERROR_MSG(ss.str());
415+
} else if (non_turb_advect_req) {
416+
tracer_advection_type[fr.first] = "non_turbulence_advected_tracers";
417+
} else {
418+
tracer_advection_type[fr.first] = "turbulence_advected_tracers";
419+
}
420+
}
421+
422+
// Set correct tracer advection type (if not set)
423+
auto add_correct_tracer_group = [&] (FieldRequest& req, const std::string& advect_type) {
424+
if (not ekat::contains(req.groups, advect_type)) {
425+
req.groups.push_back(advect_type);
426+
}
427+
};
428+
for (auto& req : m_required_field_requests){
429+
if (ekat::contains(req.groups, "tracers")) {
430+
add_correct_tracer_group(req, tracer_advection_type.at(req.fid.name()));
431+
}
432+
}
433+
for (auto& req : m_computed_field_requests) {
434+
if (ekat::contains(req.groups, "tracers")) {
435+
add_correct_tracer_group(req, tracer_advection_type.at(req.fid.name()));
436+
}
437+
}
438+
}
439+
367440
void AtmosphereProcessGroup::initialize_impl (const RunType run_type) {
368441
for (auto& atm_proc : m_atm_processes) {
369442
atm_proc->initialize(timestamp(),run_type);

components/eamxx/src/share/atm_process/atmosphere_process_group.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class AtmosphereProcessGroup : public AtmosphereProcess
112112
}
113113
}
114114

115+
// Pre-process tracer requests by checking for
116+
// consistency among processes and correctly
117+
// determining turbulence advection property
118+
void pre_process_tracer_requests ();
119+
115120
protected:
116121

117122
// Adds fid to the list of required/computed fields of the group (as a whole).

components/eamxx/src/share/field/field_request.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ enum RequestType {
1616
// Whether a tracer should be advected by both Dynamics
1717
// and Turbulance, or only by Dynamics
1818
enum TracerAdvection {
19-
DynamicsAndTurbulence, // Default use case
19+
NoPreference, // Default. In the case that no process gives a preference,
20+
// the tracer is advected by dynamics and turbulence
21+
DynamicsAndTurbulence,
2022
DynamicsOnly,
2123
};
2224

0 commit comments

Comments
 (0)