PRISMS-PF Manual
Loading...
Searching...
No Matches
io_parameters.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
2// SPDX-License-Identifier: GNU Lesser General Public Version 2.1
3
4#pragma once
5
6#include <deal.II/base/data_out_base.h>
7#include <deal.II/base/utilities.h>
8
12#include <prismspf/core/types.h>
13#include <prismspf/core/variable_attributes.h>
14
15#include <prismspf/user_inputs/parameter_base.h>
16
18
19#include <prismspf/config.h>
20
21#include <climits>
22#include <execution>
23#include <set>
24#include <string>
25#include <unordered_map>
26
28
33{
37 enum OutputType : std::uint8_t
38 {
42 };
43
53
62 unsigned int patch_subdivisions = 0;
63
71 dealii::DataOutBase::CompressionLevel compression_level =
72 dealii::DataOutBase::CompressionLevel::default_compression;
73
79 std::string folder;
80
87 std::string file_name;
88
95 std::set<unsigned int> output_list;
96
109 std::set<std::pair<Types::Index, DependencyType>> output_fields;
110};
111
115class FieldOutputParameterLoader : ParameterBase
116{
117public:
121 void
122 declare(dealii::ParameterHandler &parameter_handler) const override
123 {
124 parameter_handler.enter_subsection("field output");
125
126 parameter_handler.declare_entry("folder",
127 "",
128 dealii::Patterns::Anything(),
129 "The folder where output files are stored.");
130 parameter_handler.declare_entry("file name",
131 "solution",
132 dealii::Patterns::Anything(),
133 "The base name for the output file, before the time "
134 "step and processor info are added.");
135 parameter_handler.declare_entry(
136 "file type",
137 "vtu",
138 dealii::Patterns::Selection("vtu|vtk|pvtu|xdmf"),
139 "The output file type (either vtu, pvtu, vtk, or xdmf).");
140 parameter_handler.declare_entry(
141 "subdivisions",
142 "0",
143 dealii::Patterns::Integer(0, INT_MAX),
144 "The number of subdivisions to apply to the mesh when building output patches. If "
145 "0, the degree is used.");
146 parameter_handler.declare_entry("compression level",
147 "default",
148 dealii::Patterns::Selection(
149 "default|best speed|best size|none"),
150 "The compression level of the output (either "
151 "default, best speed, best size, or none).");
152
153 parameter_handler.declare_entry(
154 "condition",
155 "EQUAL_SPACING",
156 dealii::Patterns::Selection("EQUAL_SPACING|LOG_SPACING|N_PER_DECADE|LIST"),
157 "The spacing type for outputting the solution fields (either EQUAL_SPACING, "
158 "LOG_SPACING, N_PER_DECADE, or LIST).");
159 parameter_handler.declare_entry(
160 "list",
161 "0",
162 dealii::Patterns::List(dealii::Patterns::Integer(0, INT_MAX), 0, INT_MAX, ","),
163 "The list of time steps to output. Used for the LIST type only and must be comma "
164 "delimited.");
165 parameter_handler.declare_entry("number",
166 "10",
167 dealii::Patterns::Integer(0, INT_MAX),
168 "The number of outputs (or number of outputs "
169 "per decade for the N_PER_DECADE type).");
170
171 parameter_handler.declare_entry(
172 "fields",
173 "",
174 dealii::Patterns::List(dealii::Patterns::Anything(), 0, INT_MAX, ","),
175 "The list of fields to output. Must be comma delimited. Additionally, for the "
176 "output of change and old fields, they must follow the same delimiters in "
177 "VariableAttributes. In other words, something like `set fields = n1, old_1(n1), "
178 "change(n1)`.");
179
180 parameter_handler.leave_subsection();
181 }
182
186 void
187 read(dealii::ParameterHandler &parameter_handler) override
188 {
189 const std::unordered_map<std::string, FieldOutputParameters::OutputType>
190 output_type_table = {
194 };
195 const std::unordered_map<std::string, dealii::DataOutBase::CompressionLevel>
196 compression_level_table = {
197 {"default", dealii::DataOutBase::CompressionLevel::default_compression},
198 {"best speed", dealii::DataOutBase::CompressionLevel::best_speed },
199 {"best size", dealii::DataOutBase::CompressionLevel::best_compression },
200 {"none", dealii::DataOutBase::CompressionLevel::no_compression }
201 };
202
203 parameter_handler.enter_subsection("field output");
204
205 parameters.folder = parameter_handler.get("folder");
206 parameters.file_name = parameter_handler.get("file name");
207 parameters.file_type =
208 string_to_type(parameter_handler.get("file type"), output_type_table);
209 parameters.patch_subdivisions = parameter_handler.get_integer("subdivisions");
210 parameters.compression_level =
211 string_to_type(parameter_handler.get("compression level"), compression_level_table);
212
213 condition = parameter_handler.get("condition");
214 user_output_list = dealii::Utilities::string_to_int(
215 dealii::Utilities::split_string_list(parameter_handler.get("list")));
216 n_outputs = parameter_handler.get_integer("number");
217 field_list = dealii::Utilities::split_string_list(parameter_handler.get("fields"));
218
219 parameter_handler.leave_subsection();
220 }
221
225 void
226 postprocess(unsigned int n_increments)
227 {
228 fill_out_output_list(n_increments);
229
230 // Determine which fields we are outputting.
231 }
232
236 void
237 validate(const std::vector<VariableAttributes> &field_attributes) const override
238 {}
239
243 [[nodiscard]] FieldOutputParameters
244 package() const
245 {
246 return parameters;
247 }
248
252 void
253 print_parameter_summary() const override
254 {
256 << "================================================\n"
257 << " Field Output Parameter Class\n"
258 << "================================================\n"
259 << std::flush;
260 }
261
262private:
263 void
264 fill_out_output_list(unsigned int n_increments)
265 {
266 // If the user has specified a list and we have list output use that and return early
267 if (condition == "LIST")
268 {
269 for (const auto &increment : user_output_list)
270 {
271 parameters.output_list.insert(static_cast<unsigned int>(increment));
272 }
273 return;
274 }
275
276 // If the number of outputs is 0 return early
277 if (n_outputs == 0)
278 {
279 return;
280 }
281
282 // If the number of outputs is greater than the number of increments, force them to be
283 // equivalent
284 n_outputs = std::min(n_outputs, n_increments);
285
286 // If the number of increments is 0, we only output the initial condition. We can set
287 // that and return early.
288 if (n_increments == 0)
289 {
290 parameters.output_list.insert(0);
291 return;
292 }
293
294 // Determine the output list from the other criteria
295 if (condition == "EQUAL_SPACING")
296 {
297 for (unsigned int iteration = 0; iteration <= n_increments;
298 iteration += n_increments / n_outputs)
299 {
300 parameters.output_list.insert(iteration);
301 }
302 }
303 else if (condition == "LOG_SPACING")
304 {
305 parameters.output_list.insert(0);
306 for (unsigned int output = 1; output <= n_outputs; output++)
307 {
308 parameters.output_list.insert(static_cast<unsigned int>(std::round(
309 std::pow(static_cast<double>(n_increments),
310 static_cast<double>(output) / static_cast<double>(n_outputs)))));
311 }
312 }
313 else if (condition == "N_PER_DECADE")
314 {
315 AssertThrow(n_increments > 1,
316 dealii::ExcMessage("For n per decaded spaced outputs, the number of "
317 "increments must be greater than 1."));
318 parameters.output_list.insert(0);
319 parameters.output_list.insert(1);
320 for (unsigned int iteration = 2; iteration <= n_increments; iteration++)
321 {
322 const auto decade =
323 static_cast<unsigned int>(std::ceil(std::log10(iteration)));
324 const auto step_size =
325 static_cast<unsigned int>(std::pow(10, decade) / n_outputs);
326 if (iteration % step_size == 0)
327 {
328 parameters.output_list.insert(iteration);
329 }
330 }
331 }
332 else
333 {
334 AssertThrow(false, UnreachableCode());
335 }
336 }
337
339
340 std::string condition;
341
342 std::vector<int> user_output_list;
343
344 unsigned int n_outputs = 0;
345
346 std::vector<std::string> field_list;
347};
348
349PRISMS_PF_END_NAMESPACE
static dealii::ConditionalOStream & pout_summary()
Log output stream for writing a summary.log file.
Definition conditional_ostreams.cc:35
A class that determines how often and what fields are output.
Definition io_parameters.h:116
void validate(const std::vector< VariableAttributes > &field_attributes) const override
Validate parameters.
Definition io_parameters.h:237
unsigned int n_outputs
Definition io_parameters.h:344
std::vector< std::string > field_list
Definition io_parameters.h:346
void read(dealii::ParameterHandler &parameter_handler) override
Read parameters.
Definition io_parameters.h:187
void postprocess(unsigned int n_increments)
Postprocess parameters.
Definition io_parameters.h:226
void print_parameter_summary() const override
Print parameters to summary.log.
Definition io_parameters.h:253
void fill_out_output_list(unsigned int n_increments)
Definition io_parameters.h:264
std::string condition
Definition io_parameters.h:340
void declare(dealii::ParameterHandler &parameter_handler) const override
Declare parameters.
Definition io_parameters.h:122
std::vector< int > user_output_list
Definition io_parameters.h:342
FieldOutputParameters package() const
Package parameters.
Definition io_parameters.h:244
FieldOutputParameters parameters
Definition io_parameters.h:338
Definition conditional_ostreams.cc:20
Simple struct for field output.
Definition io_parameters.h:33
OutputType
VTK output types.
Definition io_parameters.h:38
@ VTU
Definition io_parameters.h:39
@ PVTU
Definition io_parameters.h:41
@ VTK
Definition io_parameters.h:40
dealii::DataOutBase::CompressionLevel compression_level
Compression level for output.
Definition io_parameters.h:71
unsigned int patch_subdivisions
Number of subdivisions to apply when building patches.
Definition io_parameters.h:62
OutputType file_type
File type for field output.
Definition io_parameters.h:52
std::string folder
Folder for field output.
Definition io_parameters.h:79
std::set< std::pair< Types::Index, DependencyType > > output_fields
A list of fields that are output.
Definition io_parameters.h:109
std::string file_name
Base filename for field output.
Definition io_parameters.h:87
std::set< unsigned int > output_list
A list of output steps.
Definition io_parameters.h:95
Type string_to_type(const std::string &string, const std::unordered_map< std::string, Type > &table)
Helper function that converts a string to some type, given a mapping.
Definition utilities.h:71