OGS
CreateOutputConfig.cpp
Go to the documentation of this file.
1
11#include "CreateOutputConfig.h"
12
13#include <spdlog/fmt/bundled/ranges.h>
14
15#include <map>
16
17#include "BaseLib/Algorithm.h"
18#include "BaseLib/ConfigTree.h"
19#include "BaseLib/FileTools.h" // required for reading output_times from binary file
20#include "MaterialLib/Utils/MediaCreation.h" // required for splitMaterialIDString
21#include "MeshLib/Mesh.h"
24#ifdef USE_PETSC
26#endif // USE_PETSC
27
28std::string createMeshOutputName(std::vector<int> const& material_ids,
29 std::string const& mesh_name)
30{
31 if (material_ids.empty())
32 {
33 return mesh_name;
34 }
35 return mesh_name + "_" + fmt::format("{}", fmt::join(material_ids, "_"));
36}
37
39 BaseLib::ConfigTree const& output_mesh_config,
40 std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes)
41{
42 auto const mesh_name = output_mesh_config.getValue<std::string>();
43 auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
44
45 auto material_id_string =
47 output_mesh_config.getConfigAttributeOptional<std::string>(
48 "material_ids");
49
50 if (!material_id_string)
51 {
52 return mesh_name;
53 }
54
55 auto const material_ids_for_output =
56 MaterialLib::splitMaterialIdString(*material_id_string);
57#ifdef USE_PETSC
58 // this mesh isn't yet a NodePartitionedMesh
59 auto subdomain_mesh = MeshLib::createMaterialIDsBasedSubMesh(
60 mesh, material_ids_for_output,
61 createMeshOutputName(material_ids_for_output, mesh_name));
62 auto const* bulk_mesh =
63 dynamic_cast<MeshLib::NodePartitionedMesh const*>(&mesh);
65 bulk_mesh, subdomain_mesh.get()));
66#else
68 mesh, material_ids_for_output,
69 createMeshOutputName(material_ids_for_output, mesh_name)));
70#endif
71
72 return meshes.back()->getName();
73}
74
75namespace ProcessLib
76{
78 const BaseLib::ConfigTree& config,
79 std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes)
80{
81 OutputConfig output_config;
82
83 output_config.output_type = [](auto output_type)
84 {
85 try
86 {
87 const std::map<std::string, OutputType> outputType_to_enum = {
88 {"VTK", OutputType::vtk}, {"XDMF", OutputType::xdmf}};
89 auto type = outputType_to_enum.at(output_type);
90
91 return type;
92 }
93 catch (std::out_of_range&)
94 {
96 "No supported file type provided. Read `{:s}' from <output><type> \
97 in prj File. Supported: VTK, XDMF.",
98 output_type);
99 }
101 }(config.getConfigParameter<std::string>("type"));
102
103 output_config.prefix =
105 config.getConfigParameter<std::string>("prefix", "{:meshname}");
106
107 output_config.suffix =
109 config.getConfigParameter<std::string>("suffix",
110 "_ts_{:timestep}_t_{:time}");
111
112 output_config.compress_output =
114 config.getConfigParameter("compress_output", true);
115
116 auto const hdf =
118 config.getConfigSubtreeOptional("hdf");
119
120 output_config.number_of_files = [&hdf]() -> unsigned int
121 {
122 if (hdf)
123 {
125 return hdf->getConfigParameter<unsigned int>("number_of_files");
126 }
127 return 1;
128 }();
129 output_config.chunk_size_bytes = [&hdf]() -> unsigned int
130 {
131 if (hdf)
132 {
134 return hdf->getConfigParameter<unsigned int>("chunk_size_bytes");
135 }
136 return 1048576; // default chunk size in bytes according to
137 // https://www.hdfgroup.org/2022/10/improve-hdf5-performance-using-caching/
138 }();
139
140 output_config.data_mode =
142 config.getConfigParameter<std::string>("data_mode", "Appended");
143
144 //
145 // Construction of output times
146 //
147
148 output_config.fixed_output_times =
150 config.getConfigParameter<std::vector<double>>("fixed_output_times",
151 {});
152 if (output_config.fixed_output_times.empty())
153 {
155 std::string filename = config.getConfigParameter<std::string>(
156 "fixed_output_times_from_file", "no_file");
157
158 if (filename != "no_file")
159 {
160 output_config.fixed_output_times =
162 }
163 }
164 // Remove possible duplicated elements and sort.
166
167 auto& repeats_each_steps = output_config.repeats_each_steps;
168
170 if (auto const timesteps = config.getConfigSubtreeOptional("timesteps"))
171 {
173 for (auto pair : timesteps->getConfigSubtreeList("pair"))
174 {
176 auto repeat = pair.getConfigParameter<unsigned>("repeat");
178 auto each_steps = pair.getConfigParameter<unsigned>("each_steps");
179
180 assert(repeat != 0 && each_steps != 0);
181 repeats_each_steps.emplace_back(repeat, each_steps);
182 }
183
184 if (repeats_each_steps.empty())
185 {
186 OGS_FATAL(
187 "You have not given any pair (<repeat/>, <each_steps/>) that "
188 "defines at which timesteps output shall be written. "
189 "Aborting.");
190 }
191 }
192 // In case nothing was specified, i.e. no explicit time steps or fixed
193 // output times, every time step will be written.
194 if (output_config.fixed_output_times.empty() &&
195 output_config.repeats_each_steps.empty())
196 {
197 repeats_each_steps.emplace_back(1, 1);
198 }
199
201 auto const out_vars = config.getConfigSubtree("variables");
202
203 auto& output_variables = output_config.output_variables;
204 for (auto out_var :
206 out_vars.getConfigParameterList<std::string>("variable"))
207 {
208 if (output_variables.find(out_var) != output_variables.cend())
209 {
210 OGS_FATAL("output variable `{:s}' specified more than once.",
211 out_var);
212 }
213
214 DBUG("adding output variable `{:s}'", out_var);
215 output_variables.insert(out_var);
216 }
217
218 output_config.output_extrapolation_residuals =
220 config.getConfigParameter<bool>("output_extrapolation_residuals",
221 false);
222
223 auto& mesh_names_for_output = output_config.mesh_names_for_output;
225 if (auto const meshes_config = config.getConfigSubtreeOptional("meshes"))
226 {
227 if (output_config.prefix.find("{:meshname}") == std::string::npos)
228 {
229 OGS_FATAL(
230 "There are multiple meshes defined in the output section of "
231 "the project file, but the prefix doesn't contain "
232 "'{{:meshname}}'. Thus the names for the files, the simulation "
233 "results should be written to, would not be distinguishable "
234 "for different meshes.");
235 }
237 for (auto mesh_config : meshes_config->getConfigParameterList("mesh"))
238 {
239 mesh_names_for_output.push_back(
240 parseOutputMeshConfig(mesh_config, meshes));
241 INFO("Configure mesh '{:s}' for output.",
242 mesh_names_for_output.back());
243 }
244 }
245
246 if (auto const geometrical_sets_config =
248 config.getConfigSubtreeOptional("geometrical_sets"))
249 {
250 for (
251 auto geometrical_set_config :
253 geometrical_sets_config->getConfigSubtreeList("geometrical_set"))
254 {
255 auto const geometrical_set_name =
257 geometrical_set_config.getConfigParameter<std::string>("name",
258 "");
259 auto const geometry_name =
261 geometrical_set_config.getConfigParameter<std::string>(
262 "geometry");
263 mesh_names_for_output.push_back(geometrical_set_name + "_" +
264 geometry_name);
265 }
266 }
267
268 output_config.output_iteration_results =
270 config.getConfigParameter<bool>("output_iteration_results", false);
271
272 return output_config;
273}
274} // namespace ProcessLib
std::string createMeshOutputName(std::vector< int > const &material_ids, std::string const &mesh_name)
std::string parseOutputMeshConfig(BaseLib::ConfigTree const &output_mesh_config, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)
#define OGS_FATAL(...)
Definition Error.h:26
Filename manipulation routines.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
Definition of the Mesh class.
Definition of mesh class for partitioned mesh (by node) for parallel computing within the framework o...
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
T getConfigParameter(std::string const &param) const
ConfigTree getConfigSubtree(std::string const &root) const
std::optional< T > getConfigAttributeOptional(std::string const &attr) const
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:103
std::vector< double > readDoublesFromBinaryFile(const std::string &filename)
void makeVectorUnique(std::vector< T > &v)
Definition Algorithm.h:180
std::vector< int > splitMaterialIdString(std::string const &material_id_string)
Mesh & findMeshByName(std::vector< std::unique_ptr< Mesh > > const &meshes, std::string_view const name)
Definition Mesh.cpp:364
std::unique_ptr< MeshLib::Mesh > createMaterialIDsBasedSubMesh(MeshLib::Mesh const &mesh, std::vector< int > const &material_ids, std::string const &name_for_created_mesh)
std::unique_ptr< NodePartitionedMesh > transformMeshToNodePartitionedMesh(NodePartitionedMesh const *const bulk_mesh, Mesh const *const subdomain_mesh)
OutputConfig createOutputConfig(const BaseLib::ConfigTree &config, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)
std::vector< PairRepeatEachSteps > repeats_each_steps
std::vector< double > fixed_output_times
unsigned int number_of_files
unsigned int chunk_size_bytes
std::set< std::string > output_variables
std::vector< std::string > mesh_names_for_output