Chi-Tech
PostProcessor.cc
Go to the documentation of this file.
1#include "PostProcessor.h"
2
6
7#include "chi_log.h"
8#include "ChiObjectFactory.h"
9
10namespace chi
11{
12
14
16{
18
20 "Base class for Post-Processors. For more general"
21 "information see \\ref doc_PostProcessors");
22 params.SetDocGroup("doc_PostProcessors");
23
24 params.AddRequiredParameter<std::string>(
25 "name",
26 "Name of the post processor. This name will be used in many places so make "
27 "sure it's a useful name.");
29 "execute_on",
30 std::vector<std::string>{"SolverInitialized",
31 "SolverAdvanced",
32 "SolverExecuted",
33 "ProgramExecuted"},
34 "List of events at which the post-processor will execute.");
35
37 "print_on",
38 std::vector<std::string>{"SolverInitialized",
39 "SolverAdvanced",
40 "SolverExecuted",
41 "ProgramExecuted"},
42 "List of events at which the post-processor will print. Make sure that "
43 "these "
44 "events are also set for the `PostProcessorPrinter` otherwise it wont "
45 "print.");
46
48 "initial_value", ParameterBlock{}, "An initial value.");
49
51 "print_numeric_format", "general", "Numeric format to use.");
52
53 using namespace chi_data_types;
55 "print_numeric_format",
56 AllowableRangeList::New(
57 {"fixed", "floating_point", "scientific", "general"}));
58
60 "print_precision", 6, "Number of digits to display after decimal point");
61
63 "solvername_filter",
64 "",
65 "Controls update events to only execute on the relevant solver's"
66 "event calls.");
67
68 return params;
69}
70
72 : ChiObject(params),
73 name_(params.GetParamValue<std::string>("name")),
74 subscribed_events_for_execution_(
75 params.GetParamVectorValue<std::string>("execute_on")),
76 subscribed_events_for_printing_(
77 params.GetParamVectorValue<std::string>("print_on")),
78 type_(type),
79 print_numeric_format_(ConstructNumericFormat(
80 params.GetParamValue<std::string>("print_numeric_format"))),
81 print_precision_(params.GetParamValue<size_t>("print_precision")),
82 solvername_filter_(params.GetParamValue<std::string>("solvername_filter"))
83{
84 const auto& user_params = params.ParametersAtAssignment();
85 if (user_params.Has("initial_value"))
86 {
87 value_ = params.GetParam("initial_value");
89 }
90}
91
93PostProcessor::ConstructNumericFormat(const std::string& format_string)
94{
95 if (format_string == "fixed") return PPNumericFormat::FIXED;
96 else if (format_string == "floating_point")
98 else if (format_string == "scientific")
100 else if (format_string == "general")
102 else
103 ChiLogicalError("Invalid numeric format string \"" + format_string + "\"");
104}
105
106const std::string& PostProcessor::Name() const { return name_; }
108
110{
112}
113
115
116/**Pushes onto the post-processor stack and adds a subscription to
117 * `chi_physics::PhysicsEventPublisher` singleton.*/
118void PostProcessor::PushOntoStack(std::shared_ptr<ChiObject>& new_object)
119{
120
121 auto pp_ptr = std::dynamic_pointer_cast<PostProcessor>(new_object);
122 ChiLogicalErrorIf(not pp_ptr,
123 "Failure to cast new object to chi::PostProcessor");
124
125 Chi::postprocessor_stack.push_back(pp_ptr);
126 new_object->SetStackID(Chi::postprocessor_stack.size() - 1);
127
128 auto new_subscriber = std::dynamic_pointer_cast<chi::EventSubscriber>(pp_ptr);
129
131 not new_subscriber,
132 "Failure to cast chi::PostProcessor to chi::EventSubscriber");
133
135 publisher.AddSubscriber(new_subscriber);
136}
137
139{
140 auto it = std::find(subscribed_events_for_execution_.begin(),
142 event.Name());
143
144 if (it != subscribed_events_for_execution_.end())
145 {
146 if (event.Code() >= 31 and event.Code() <= 38 and
147 not solvername_filter_.empty())
148 {
149 if (event.Parameters().GetParamValue<std::string>("solver_name") !=
151 return;
152 }
153
154 Execute(event);
155 if (Chi::log.GetVerbosity() >= 1)
156 Chi::log.Log0Verbose1() << "Post processor \"" << Name()
157 << "\" executed on "
158 "event \""
159 << event.Name() << "\".";
160 }
161}
162
164
165const std::vector<PostProcessor::TimeHistoryEntry>&
167{
168 return time_history_;
169}
170
171const std::vector<std::string>& PostProcessor::PrintScope() const
172{
174}
175
176/**Converts a scalar value into a string format based on this post-processor's
177 * numeric specifications.*/
178std::string
180{
181 std::string value_string;
182 if (value.Type() == ParameterBlockType::BOOLEAN)
183 {
184 value_string = value.GetValue<bool>() ? "true" : "false";
185 }
186 else if (value.Type() == ParameterBlockType::FLOAT)
187 {
188 const auto dblval = value.GetValue<double>();
189 char buffer[30];
190 const auto numeric_format = NumericFormat();
191 const size_t precision = NumericPrecision();
192 if (numeric_format == PPNumericFormat::SCIENTIFIC)
193 {
194 const std::string format_spec = "%." + std::to_string(precision) + "e";
195 snprintf(buffer, 30, format_spec.c_str(), dblval);
196 }
197 else if (numeric_format == PPNumericFormat::FLOATING_POINT)
198 {
199 const std::string format_spec = "%." + std::to_string(precision) + "f";
200 snprintf(buffer, 30, format_spec.c_str(), dblval);
201 }
202 else // GENERAL
203 {
204 if (dblval < 1.0e-4)
205 {
206 const std::string format_spec = "%." + std::to_string(precision) + "e";
207 snprintf(buffer, 30, format_spec.c_str(), dblval);
208 }
209 else if (dblval >= 1.0e-4 and dblval < 1.0e6)
210 {
211 const std::string format_spec = "%." + std::to_string(precision) + "f";
212 snprintf(buffer, 30, format_spec.c_str(), dblval);
213 }
214 else
215 {
216 const std::string format_spec = "%." + std::to_string(precision) + "e";
217 snprintf(buffer, 30, format_spec.c_str(), dblval);
218 }
219 } // if num_format
220
221 value_string = buffer;
222 }
223 else if (value.Type() == ParameterBlockType::STRING)
224 {
225 value_string = value.GetValue<std::string>();
226 }
227 else if (value.Type() == ParameterBlockType::INTEGER)
228 {
229 const auto intval = value.GetValue<int64_t>();
230 char buffer[30];
231 snprintf(buffer, 30, "%lld", intval);
232 value_string = buffer;
233 }
234
235 return value_string;
236}
237
238std::string
240{
241 const PPType type = FigureTypeFromValue(value);
242 if (type == PPType::SCALAR) return ConvertScalarValueToString(value);
243 else if (type == PPType::VECTOR)
244 {
245 if (value.NumParameters() == 0) return "";
246 const auto& first_entry = value.GetParam(0);
247 const auto first_entry_type = first_entry.Type();
248
250 "The entries of the vector value of post-processor \"" +
251 Name() + "\" must all be SCALAR.");
252
253 std::string output;
254 for (const auto& entry : value)
255 {
257 entry.Type() != first_entry_type,
258 "Mixed typed encountered in the vector values of post-processor \"" +
259 Name() + "\"");
260 output.append(ConvertScalarValueToString(entry) + " ");
261 }
262
263 return output;
264 }
265 else
266 {
267 std::string outstr;
268 value.RecursiveDumpToString(outstr);
269 std::replace(outstr.begin(), outstr.end(), '\n', ' ');
270 return outstr;
271 }
272}
273
275{
276 const std::vector<ParameterBlockType> scalar_types = {
281
282 /**Lambda to check if this is a scalar*/
283 auto IsScalar = [&scalar_types](const ParameterBlockType& block_type)
284 {
285 return std::find(scalar_types.begin(), scalar_types.end(), block_type) !=
286 scalar_types.end();
287 };
288
289 if (not value.HasValue() and value.NumParameters() == 0)
290 return PPType::NO_VALUE;
291 else if (IsScalar(value.Type()))
292 return PPType::SCALAR;
293 else if (value.Type() == ParameterBlockType::ARRAY)
294 {
295 if (value.NumParameters() == 0) return PPType::NO_VALUE;
296 else
297 {
298 if (IsScalar(value.GetParam(0).Type())) return PPType::VECTOR;
299 else
300 return PPType::ARBITRARY;
301 }
302 }
303 else if (value.Type() == ParameterBlockType::BLOCK)
304 return PPType::ARBITRARY;
305 else
306 ChiLogicalError("Unsupported type");
307}
308
309void PostProcessor::SetType(PPType type) { type_ = type; }
310
311} // namespace chi
#define ChiLogicalErrorIf(condition, message)
#define ChiLogicalError(message)
static chi::ChiLog & log
Definition: chi_runtime.h:81
static std::vector< chi::PostProcessorPtr > postprocessor_stack
Definition: chi_runtime.h:98
static chi::InputParameters GetInputParameters()
Definition: ChiObject.cc:4
LogStream Log0Verbose1()
Definition: chi_log.h:234
int Code() const
Definition: Event.cc:19
const ParameterBlock & Parameters() const
Definition: Event.cc:20
const std::string & Name() const
Definition: Event.cc:18
void SetDocGroup(const std::string &doc_group)
void AddRequiredParameter(const std::string &name, const std::string &doc_string)
const ParameterBlock & ParametersAtAssignment() const
void ConstrainParameterRange(const std::string &param_name, AllowableRangePtr allowable_range)
void AddOptionalParameter(const std::string &name, T value, const std::string &doc_string)
void AddOptionalParameterBlock(const std::string &name, const ParameterBlock &block, const std::string &doc_string)
void SetGeneralDescription(const std::string &description)
void AddOptionalParameterArray(const std::string &name, const std::vector< T > &array, const std::string &doc_string)
size_t NumParameters() const
void RecursiveDumpToString(std::string &outstr, const std::string &offset="") const
T GetParamValue(const std::string &param_name) const
ParameterBlockType Type() const
ParameterBlock & GetParam(const std::string &param_name)
Definition: PostProcessor.h:28
static PPNumericFormat ConstructNumericFormat(const std::string &format_string)
const size_t print_precision_
Definition: PostProcessor.h:93
PostProcessor(const InputParameters &params, PPType type)
virtual const std::vector< TimeHistoryEntry > & GetTimeHistory() const
std::vector< std::string > subscribed_events_for_printing_
Definition: PostProcessor.h:86
static PPType FigureTypeFromValue(const ParameterBlock &value)
const PPNumericFormat print_numeric_format_
Definition: PostProcessor.h:92
ParameterBlock value_
Definition: PostProcessor.h:88
virtual const ParameterBlock & GetValue() const
std::vector< std::string > subscribed_events_for_execution_
Definition: PostProcessor.h:85
void ReceiveEventUpdate(const Event &event) override
const std::string & Name() const
virtual void Execute(const Event &event_context)=0
size_t NumericPrecision() const
void SetType(PPType type)
std::string solvername_filter_
Definition: PostProcessor.h:94
void PushOntoStack(std::shared_ptr< ChiObject > &new_object) override
std::vector< TimeHistoryEntry > time_history_
Definition: PostProcessor.h:90
PPType Type() const
PPType type_
Definition: PostProcessor.h:87
std::string ConvertValueToString(const ParameterBlock &value) const
std::string ConvertScalarValueToString(const ParameterBlock &value) const
static InputParameters GetInputParameters()
PPNumericFormat NumericFormat() const
const std::string name_
Definition: PostProcessor.h:84
const std::vector< std::string > & PrintScope() const
static PhysicsEventPublisher & GetInstance()
PPNumericFormat
Definition: PostProcessor.h:19
ParameterBlockType
RegisterChiObjectParametersOnly(chi, PostProcessor)