OGS
ProcessLib/Output/CreateOutput.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "CreateOutput.h"
5
6#include <spdlog/fmt/ranges.h>
7
8#include <memory>
9#include <range/v3/algorithm/find.hpp>
10#include <tuple>
11
12#include "BaseLib/Algorithm.h"
13#include "BaseLib/ConfigTree.h"
14#include "BaseLib/Logging.h"
15#include "BaseLib/cpp23.h"
16#include "MeshLib/Mesh.h"
18
19namespace
20{
23int convertVtkDataMode(std::string_view const& data_mode)
24{
25 using namespace std::string_view_literals;
26 constexpr std::array data_mode_lookup_table{"Ascii"sv, "Binary"sv,
27 "Appended"sv};
28 auto res = ranges::find(begin(data_mode_lookup_table),
29 end(data_mode_lookup_table), data_mode);
30 if (res == data_mode_lookup_table.end())
31 {
33 "Unsupported vtk output file data mode '{:s}'. Expected Ascii, "
34 "Binary, or Appended.",
35 data_mode);
36 }
37 return static_cast<int>(std::distance(begin(data_mode_lookup_table), res));
38}
39
40std::vector<std::string> getDuplicateOutputNames(
41 std::vector<ProcessLib::Output> const& outputs)
42{
43 std::vector<std::string> output_names;
44 for (auto const& output : outputs)
45 {
46 auto output_mesh_names = output.getFileNamesForOutput();
47 output_names.insert(output_names.end(), output_mesh_names.begin(),
48 output_mesh_names.end());
49 }
50 return BaseLib::getDuplicates(output_names);
51}
52} // namespace
53
54namespace ProcessLib
55{
56std::unique_ptr<OutputFormat> createOutputFormat(
57 std::string const& output_directory, OutputType const output_type,
58 std::string prefix, std::string suffix, std::string const& data_mode,
59 bool const compress_output, unsigned int const number_of_files,
60 unsigned int const chunk_size_bytes,
61 bool const store_static_data_separately,
62 std::set<std::string> static_variables)
63{
64 switch (output_type)
65 {
66 case OutputType::vtk:
67 return std::make_unique<OutputVTKFormat>(
68 output_directory, std::move(prefix), std::move(suffix),
69 compress_output, convertVtkDataMode(data_mode));
71 return std::make_unique<OutputXDMFHDF5Format>(
72 output_directory, std::move(prefix), std::move(suffix),
73 compress_output, number_of_files, chunk_size_bytes,
74 store_static_data_separately, std::move(static_variables));
75 default:
77 "No supported file type provided. Read '{}' from "
78 "<output><type> in prj file. Supported: VTK, XDMF.",
79 BaseLib::to_underlying(output_type));
80 }
81}
82
83Output createOutput(OutputConfig&& oc, std::string const& output_directory,
84 std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
85{
86 auto output_format = createOutputFormat(
87 output_directory, oc.output_type, std::move(oc.prefix),
88 std::move(oc.suffix), oc.data_mode, oc.compress_output,
89 oc.number_of_files, oc.chunk_size_bytes,
90 oc.store_static_data_separately, std::move(oc.static_output_variables));
91
92 OutputDataSpecification output_data_specification{
93 std::move(oc.output_variables), std::move(oc.fixed_output_times),
94 std::move(oc.repeats_each_steps), oc.output_extrapolation_residuals};
95
96 return {std::move(output_format), oc.output_iteration_results,
97 std::move(output_data_specification),
98 std::move(oc.mesh_names_for_output), meshes};
99}
100
101std::vector<Output> createOutput(
102 const BaseLib::ConfigTree& config,
103 std::string const& output_directory,
104 std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes)
105{
106 std::vector<Output> outputs;
107 auto oc = createOutputConfig(config, meshes);
108 outputs.push_back(createOutput(std::move(oc), output_directory, meshes));
109 return outputs;
110}
111
112std::vector<Output> createOutputs(
113 const BaseLib::ConfigTree& output_configs,
114 std::string const& output_directory,
115 std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes)
116{
117 DBUG("Parse outputs configuration:");
118 std::vector<Output> outputs;
119 for (auto const& output_config :
121 output_configs.getConfigSubtreeList("output"))
122 {
123 auto oc = createOutputConfig(output_config, meshes);
124 outputs.push_back(
125 createOutput(std::move(oc), output_directory, meshes));
126 }
127 auto const duplicates = getDuplicateOutputNames(outputs);
128 if (duplicates.empty())
129 {
130 return outputs;
131 }
132
133 OGS_FATAL(
134 "Output configuration paths are not unique. This will lead to "
135 "overwritten results or invalid / corrupted data within the "
136 "files. Duplicate paths: {:s}.",
137 fmt::join(duplicates, ", "));
138}
139} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:10
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
std::vector< ranges::range_value_t< Range > > getDuplicates(Range &&range)
Definition Algorithm.h:178
constexpr auto to_underlying(E e) noexcept
Converts an enumeration to its underlying type.
Definition cpp23.h:22
OutputConfig createOutputConfig(const BaseLib::ConfigTree &config, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)
Output createOutput(OutputConfig &&oc, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
std::unique_ptr< OutputFormat > createOutputFormat(std::string const &output_directory, OutputType const output_type, std::string prefix, std::string suffix, std::string const &data_mode, bool const compress_output, unsigned int const number_of_files, unsigned int const chunk_size_bytes, bool const store_static_data_separately, std::set< std::string > static_variables)
std::vector< Output > createOutputs(const BaseLib::ConfigTree &output_configs, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)
std::vector< std::string > getDuplicateOutputNames(std::vector< ProcessLib::Output > const &outputs)
int convertVtkDataMode(std::string_view const &data_mode)
Holds information about which variables to write to output files.