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