Chi-Tech
AggregateNodalValuePostProcessor.cc
Go to the documentation of this file.
2
3#include "ChiObjectFactory.h"
4
10
11namespace chi
12{
13
15
17{
21
23 "Gets the max/min/avg nodal value of a field function "
24 "among nodal values.");
25 params.SetDocGroup("doc_PostProcessors");
26
27 params.AddRequiredParameter<std::string>(
28 "operation", "The required operation to be performed.");
29
30 using namespace chi_data_types;
32 "operation", AllowableRangeList::New({"max", "min", "avg"}));
33
34 return params;
35}
36
38 const InputParameters& params)
39 : PostProcessor(params, PPType::SCALAR),
40 chi_physics::GridBasedFieldFunctionInterface(params),
41 chi_mesh::LogicalVolumeInterface(params),
42 operation_(params.GetParamValue<std::string>("operation"))
43{
44}
45
46// ##################################################################
48{
49 const auto* grid_field_function = GetGridBasedFieldFunction();
50
51 ChiLogicalErrorIf(not grid_field_function,
52 "Attempted to access invalid field"
53 "function");
54
55 const auto& grid = grid_field_function->GetSpatialDiscretization().Grid();
56
57 const auto* logical_volume_ptr_ = GetLogicalVolume();
58 if (logical_volume_ptr_ == nullptr)
59 {
60 cell_local_ids_.reserve(grid.local_cells.size());
61 for (const auto& cell : grid.local_cells)
62 cell_local_ids_.push_back(cell.local_id_);
63 }
64 else
65 {
66 for (const auto& cell : grid.local_cells)
67 if (logical_volume_ptr_->Inside(cell.centroid_))
68 cell_local_ids_.push_back(cell.local_id_);
69 }
70
71 initialized_ = true;
72}
73
74// ##################################################################
76{
77 if (not initialized_) Initialize();
78
79 const auto* grid_field_function = GetGridBasedFieldFunction();
80
81 ChiLogicalErrorIf(not grid_field_function,
82 "Attempted to access invalid field"
83 "function");
84
85 const auto& ref_ff = *grid_field_function;
86 const auto& sdm = ref_ff.GetSpatialDiscretization();
87 const auto& grid = sdm.Grid();
88
89 const auto& uk_man = ref_ff.GetUnknownManager();
90 const auto uid = 0;
91 const auto cid = 0;
92
93 const auto field_data = ref_ff.GetGhostedFieldVector();
94 const size_t num_local_dofs =
95 ref_ff.GetSpatialDiscretization().GetNumLocalDOFs(
96 ref_ff.GetUnknownManager());
97
98 double local_max_value = 0.0;
99 double local_min_value = 0.0;
100 double local_accumulation = 0.0;
101 bool first_local = true;
102 for (const uint64_t cell_local_id : cell_local_ids_)
103 {
104 const auto& cell = grid.local_cells[cell_local_id];
105 const auto& cell_mapping = sdm.GetCellMapping(cell);
106 const size_t num_nodes = cell_mapping.NumNodes();
107
108 for (size_t i = 0; i < num_nodes; ++i)
109 {
110 const int64_t imap = sdm.MapDOFLocal(cell, i, uk_man, uid, cid);
111 if (imap >= 0 and imap < num_local_dofs)
112 {
113 const double field_value = field_data[imap];
114 if (first_local)
115 {
116 local_max_value = field_value;
117 local_min_value = field_value;
118 first_local = false;
119 }
120
121 local_max_value = std::max(local_max_value, field_value);
122 local_min_value = std::min(local_min_value, field_value);
123 local_accumulation += field_value;
124 }
125 } // for i
126 } // for cell-id
127
128 if (operation_ == "max")
129 {
130 double globl_max_value;
131 MPI_Allreduce(&local_max_value, // sendbuf
132 &globl_max_value, // recvbuf
133 1,
134 MPI_DOUBLE, // count + datatype
135 MPI_MAX, // op
136 Chi::mpi.comm); // communicator
137
138 value_ = ParameterBlock("", globl_max_value);
139 }
140 else if (operation_ == "min")
141 {
142 double globl_min_value;
143 MPI_Allreduce(&local_min_value, // sendbuf
144 &globl_min_value, // recvbuf
145 1,
146 MPI_DOUBLE, // count + datatype
147 MPI_MIN, // op
148 Chi::mpi.comm); // communicator
149
150 value_ = ParameterBlock("", globl_min_value);
151 }
152 else if (operation_ == "avg")
153 {
154 double globl_accumulation;
155 MPI_Allreduce(&local_accumulation, // sendbuf
156 &globl_accumulation, // recvbuf
157 1,
158 MPI_DOUBLE, // count + datatype
159 MPI_SUM, // op
160 Chi::mpi.comm); // communicator
161
162 const size_t num_globl_dofs =
163 ref_ff.GetSpatialDiscretization().GetNumGlobalDOFs(
164 ref_ff.GetUnknownManager());
165 value_ = ParameterBlock("", globl_accumulation / double(num_globl_dofs));
166 }
167 else
168 ChiLogicalError("Unsupported operation type \"" + operation_ + "\".");
169
170 const int event_code = event_context.Code();
171 if (event_code == 32 /*SolverInitialized*/ or
172 event_code == 38 /*SolverAdvanced*/)
173 {
174 const auto& event_params = event_context.Parameters();
175
176 if (event_params.Has("timestep_index") and event_params.Has("time"))
177 {
178 const size_t index = event_params.GetParamValue<size_t>("timestep_index");
179 const double time = event_params.GetParamValue<double>("time");
180 TimeHistoryEntry entry{index, time, value_};
181 time_history_.push_back(std::move(entry));
182 }
183 }
184}
185
186} // namespace chi
#define ChiLogicalErrorIf(condition, message)
#define ChiLogicalError(message)
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
static InputParameters GetInputParameters()
bool initialized_
std::vector< uint64_t > cell_local_ids_
AggregateNodalValuePostProcessor(const InputParameters &params)
void Initialize()
void Execute(const Event &event_context) override
const std::string operation_
int Code() const
Definition: Event.cc:19
const ParameterBlock & Parameters() const
Definition: Event.cc:20
void SetDocGroup(const std::string &doc_group)
void AddRequiredParameter(const std::string &name, const std::string &doc_string)
void ConstrainParameterRange(const std::string &param_name, AllowableRangePtr allowable_range)
void SetGeneralDescription(const std::string &description)
T GetParamValue(const std::string &param_name) const
Definition: PostProcessor.h:28
ParameterBlock value_
Definition: PostProcessor.h:88
std::vector< TimeHistoryEntry > time_history_
Definition: PostProcessor.h:90
static InputParameters GetInputParameters()
static chi::InputParameters GetInputParameters()
const LogicalVolume * GetLogicalVolume() const
RegisterChiObject(chi, KBAGraphPartitioner)
Definition: PostProcessor.h:31