OGS
CreateOutput.cpp
Go to the documentation of this file.
1 
11 #include "CreateOutput.h"
12 
13 #include <memory>
14 #include <tuple>
15 
16 #include "BaseLib/Algorithm.h"
17 #include "BaseLib/ConfigTree.h"
18 #include "BaseLib/FileTools.h"
19 #include "BaseLib/Logging.h"
20 #include "MeshLib/Mesh.h"
21 #include "Output.h"
22 
23 namespace ProcessLib
24 {
25 std::unique_ptr<Output> createOutput(
26  const BaseLib::ConfigTree& config,
27  std::string const& output_directory,
28  std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
29 {
30  DBUG("Parse output configuration:");
31  OutputType const output_type = [](auto output_type)
32  {
33  try
34  {
35  const std::map<std::string, OutputType> outputType_to_enum = {
36  {"VTK", OutputType::vtk}, {"XDMF", OutputType::xdmf}};
37  auto type = outputType_to_enum.at(output_type);
38 
39  return type;
40  }
41  catch (std::out_of_range&)
42  {
43  OGS_FATAL(
44  "No supported file type provided. Read `{:s}' from <output><type> \
45  in prj File. Supported: VTK, XDMF.",
46  output_type);
47  }
49  }(config.getConfigParameter<std::string>("type"));
50 
51  auto const prefix =
53  config.getConfigParameter<std::string>("prefix", "{:meshname}");
54 
55  auto const suffix =
57  config.getConfigParameter<std::string>("suffix",
58  "_ts_{:timestep}_t_{:time}");
59 
60  auto const compress_output =
62  config.getConfigParameter("compress_output", true);
63 
64  auto const hdf =
66  config.getConfigSubtreeOptional("hdf");
67 
68  auto number_of_files = [&hdf]() -> unsigned int
69  {
70  if (hdf)
71  {
73  return hdf->getConfigParameter<unsigned int>("number_of_files");
74  }
75  else
76  {
77  return 1;
78  }
79  }();
80 
81  auto const data_mode =
83  config.getConfigParameter<std::string>("data_mode", "Appended");
84 
85  // Construction of output times
86  std::vector<Output::PairRepeatEachSteps> repeats_each_steps;
87 
89  if (auto const timesteps = config.getConfigSubtreeOptional("timesteps"))
90  {
92  for (auto pair : timesteps->getConfigSubtreeList("pair"))
93  {
95  auto repeat = pair.getConfigParameter<unsigned>("repeat");
97  auto each_steps = pair.getConfigParameter<unsigned>("each_steps");
98 
99  assert(repeat != 0 && each_steps != 0);
100  repeats_each_steps.emplace_back(repeat, each_steps);
101  }
102 
103  if (repeats_each_steps.empty())
104  {
105  OGS_FATAL(
106  "You have not given any pair (<repeat/>, <each_steps/>) that "
107  "defines at which timesteps output shall be written. "
108  "Aborting.");
109  }
110  }
111  else
112  {
113  repeats_each_steps.emplace_back(1, 1);
114  }
115 
117  auto const out_vars = config.getConfigSubtree("variables");
118 
119  std::set<std::string> output_variables;
120  for (auto out_var :
122  out_vars.getConfigParameterList<std::string>("variable"))
123  {
124  if (output_variables.find(out_var) != output_variables.cend())
125  {
126  OGS_FATAL("output variable `{:s}' specified more than once.",
127  out_var);
128  }
129 
130  DBUG("adding output variable `{:s}'", out_var);
131  output_variables.insert(out_var);
132  }
133 
135  bool const output_residuals = config.getConfigParameter<bool>(
136  "output_extrapolation_residuals", false);
137 
138  OutputDataSpecification output_data_specification{output_variables,
139  output_residuals};
140 
141  std::vector<std::string> mesh_names_for_output;
143  if (auto const meshes_config = config.getConfigSubtreeOptional("meshes"))
144  {
145  if (prefix.find("{:meshname}") == std::string::npos)
146  {
147  OGS_FATAL(
148  "There are multiple meshes defined in the output section of "
149  "the project file, but the prefix doesn't contain "
150  "'{{:meshname}}'. Thus the names for the files, the simulation "
151  "results should be written to, would not be distinguishable "
152  "for different meshes.");
153  }
155  for (auto mesh_config : meshes_config->getConfigParameterList("mesh"))
156  {
157  mesh_names_for_output.push_back(
158  mesh_config.getValue<std::string>());
159  INFO("Configure mesh '{:s}' for output.",
160  mesh_names_for_output.back());
161  }
162  }
163 
164  std::vector<double> fixed_output_times =
166  config.getConfigParameter<std::vector<double>>("fixed_output_times",
167  {});
168  // Remove possible duplicated elements and sort.
169  BaseLib::makeVectorUnique(fixed_output_times);
170 
171  bool const output_iteration_results =
173  config.getConfigParameter<bool>("output_iteration_results", false);
174 
175  return std::make_unique<Output>(
176  output_directory, output_type, prefix, suffix, compress_output,
177  number_of_files, data_mode, output_iteration_results,
178  std::move(repeats_each_steps), std::move(fixed_output_times),
179  std::move(output_data_specification), std::move(mesh_names_for_output),
180  meshes);
181 }
182 
183 } // namespace ProcessLib
#define OGS_FATAL(...)
Definition: Error.h:26
Filename manipulation routines.
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:32
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
Definition of the Mesh class.
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:155
T getConfigParameter(std::string const &param) const
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:146
void makeVectorUnique(std::vector< T > &v)
Definition: Algorithm.h:209
std::unique_ptr< Output > createOutput(const BaseLib::ConfigTree &config, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes)
Holds information about which variables to write to output files.
Definition: ProcessOutput.h:23