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