OGS
PVD2XDMF.cpp File Reference

Detailed Description

Definition in file PVD2XDMF.cpp.

#include <tclap/CmdLine.h>
#include <array>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include "BaseLib/FileTools.h"
#include "BaseLib/Logging.h"
#include "BaseLib/MPI.h"
#include "BaseLib/MemWatch.h"
#include "BaseLib/RunTime.h"
#include "BaseLib/StringTools.h"
#include "InfoLib/GitInfo.h"
#include "MeshLib/Elements/Element.h"
#include "MeshLib/IO/XDMF/XdmfHdfWriter.h"
#include "MeshLib/IO/readMeshFromFile.h"
#include "MeshLib/Mesh.h"
Include dependency graph for PVD2XDMF.cpp:

Go to the source code of this file.

Functions

std::vector< std::pair< double, std::string > > readPvd (std::string const &pvd_filename)
 
template<typename T >
bool copyPropertyVector (MeshLib::Properties const &properties, MeshLib::PropertyVectorBase *destination_pv)
 
void testIfMeshesAreEqual (MeshLib::Mesh const &mesh, MeshLib::Mesh const &main_mesh, std::string error_message)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ copyPropertyVector()

template<typename T >
bool copyPropertyVector ( MeshLib::Properties const & properties,
MeshLib::PropertyVectorBase * destination_pv )

Definition at line 56 of file PVD2XDMF.cpp.

58{
59 if (!dynamic_cast<MeshLib::PropertyVector<T>*>(destination_pv))
60 {
61 return false;
62 }
63
64 auto const* pv = properties.getPropertyVector<T>(
65 destination_pv->getPropertyName(), destination_pv->getMeshItemType(),
66 destination_pv->getNumberOfGlobalComponents());
67
68 assert(pv != nullptr);
69
70 std::copy(
71 std::begin(*pv), std::end(*pv),
72 std::begin(dynamic_cast<MeshLib::PropertyVector<T>&>(*destination_pv)));
73
74 return true;
75}
MeshItemType getMeshItemType() const
int getNumberOfGlobalComponents() const
std::string const & getPropertyName() const

References MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::PropertyVectorBase::getPropertyName(), and MeshLib::Properties::getPropertyVector().

Referenced by main().

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 106 of file PVD2XDMF.cpp.

107{
108 TCLAP::CmdLine cmd(
109 "Converts a time series from PVD to XDMF format.\n\n"
110 "OpenGeoSys-6 software, version " +
112 ".\n"
113 "Copyright (c) 2012-2024, OpenGeoSys Community "
114 "(http://www.opengeosys.org)",
116
117 TCLAP::ValueArg<std::string> log_level_arg(
118 "l", "log-level",
119 "the verbosity of logging messages: none, error, warn, info, "
120 "debug, "
121 "all",
122 false,
123#ifdef NDEBUG
124 "info",
125#else
126 "all",
127#endif
128 "LOG_LEVEL");
129 cmd.add(log_level_arg);
130
131 TCLAP::UnlabeledValueArg<std::string> pvd_file_arg("pvd-file", "pvd file",
132 true, "", "file");
133 cmd.add(pvd_file_arg);
134
135 TCLAP::ValueArg<std::string> outdir_arg("o", "output-directory",
136 "the output directory to write to",
137 false, ".", "PATH");
138 cmd.add(outdir_arg);
139
140 cmd.parse(argc, argv);
141 BaseLib::MPI::Setup mpi_setup(argc, argv);
142 BaseLib::setConsoleLogLevel(log_level_arg.getValue());
143
144 auto const pvd_file_dir = BaseLib::extractPath(pvd_file_arg.getValue());
145
146 auto const timeseries = readPvd(pvd_file_arg.getValue());
147
148 if (timeseries.empty())
149 {
150 OGS_FATAL("Empty time series.");
151 }
152
153 // Initialized from the first timeseries entry and data is updated for each
154 // subsequent time step.
155 std::unique_ptr<MeshLib::Mesh> main_mesh;
156
157 std::filesystem::path const output_file{
158 BaseLib::extractBaseNameWithoutExtension(pvd_file_arg.getValue()) +
159 ".xdmf"};
160 std::filesystem::path output_file_path{outdir_arg.getValue()};
161 if (outdir_arg.getValue() != "")
162 {
163 output_file_path =
164 BaseLib::joinPaths(outdir_arg.getValue(), output_file.string());
165 }
166 std::set<std::string> variable_output_names;
167 std::unique_ptr<MeshLib::IO::XdmfHdfWriter> mesh_xdmf_hdf_writer;
168 // read first file in the time series; it is determining variables.
169 {
170 auto [time, filename] = timeseries[0];
171 DBUG("{} - {}", time, filename);
172
173 main_mesh.reset(MeshLib::IO::readMeshFromFile(
174 BaseLib::joinPaths(pvd_file_dir, filename)));
175 if (main_mesh == nullptr)
176 {
177 OGS_FATAL("Could not read mesh from '{:s}'.",
178 BaseLib::joinPaths(pvd_file_dir, filename));
179 }
180
181 for (auto const& p : main_mesh->getProperties())
182 {
183 variable_output_names.insert(std::string(p.first));
184 }
185 mesh_xdmf_hdf_writer = std::make_unique<MeshLib::IO::XdmfHdfWriter>(
186 std::vector{std::cref(*main_mesh)}, output_file_path,
187 0 /*timestep*/, time, variable_output_names,
188 true /*output_file.compression*/, 1 /*output_file.n_files*/,
189 1048576 /*chunk_size_bytes*/);
190 }
191
192 for (std::size_t timestep = 1; timestep < timeseries.size(); ++timestep)
193 {
194 auto [time, filename] = timeseries[timestep];
195 DBUG("{} - {}", time, filename);
196
197 std::unique_ptr<MeshLib::Mesh> mesh{MeshLib::IO::readMeshFromFile(
198 BaseLib::joinPaths(pvd_file_dir, filename))};
199 if (mesh == nullptr)
200 {
201 OGS_FATAL("Could not read mesh from '{:s}'.",
202 BaseLib::joinPaths(pvd_file_dir, filename));
203 }
204
206 *mesh, *main_mesh,
207 fmt::format("Error in comparison of mesh from file '{:s}' to the "
208 "main mesh:\n",
209 BaseLib::joinPaths(pvd_file_dir, filename)));
210
211 // We have to copy the values because the xdmf writer remembers the data
212 // pointers. Therefore replacing the properties will not work.
213 for (auto& [name, pv] : main_mesh->getProperties())
214 {
215 if (copyPropertyVector<double>(mesh->getProperties(), pv) ||
216 copyPropertyVector<float>(mesh->getProperties(), pv) ||
217 copyPropertyVector<int>(mesh->getProperties(), pv) ||
218 copyPropertyVector<long>(mesh->getProperties(), pv) ||
219 copyPropertyVector<unsigned>(mesh->getProperties(), pv) ||
220 copyPropertyVector<unsigned long>(mesh->getProperties(), pv) ||
221 copyPropertyVector<std::size_t>(mesh->getProperties(), pv) ||
222 copyPropertyVector<char>(mesh->getProperties(), pv) ||
223 copyPropertyVector<unsigned char>(mesh->getProperties(), pv))
224 {
225 continue;
226 }
227 OGS_FATAL(
228 "Could not copy property vector '{:s}' from '{:s}' mesh to the "
229 "main_mesh.",
230 name, BaseLib::joinPaths(pvd_file_dir, filename));
231 }
232
233 mesh_xdmf_hdf_writer->writeStep(time);
234 }
235 return EXIT_SUCCESS;
236}
#define OGS_FATAL(...)
Definition Error.h:26
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void testIfMeshesAreEqual(MeshLib::Mesh const &mesh, MeshLib::Mesh const &main_mesh, std::string error_message)
Definition PVD2XDMF.cpp:77
std::vector< std::pair< double, std::string > > readPvd(std::string const &pvd_filename)
Definition PVD2XDMF.cpp:30
bool copyPropertyVector(MeshLib::Properties const &properties, MeshLib::PropertyVectorBase *destination_pv)
Definition PVD2XDMF.cpp:56
void setConsoleLogLevel(std::string const &level_string)
Definition Logging.cpp:37
std::string extractPath(std::string const &pathname)
std::string extractBaseNameWithoutExtension(std::string const &pathname)
std::string joinPaths(std::string const &pathA, std::string const &pathB)
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)

References copyPropertyVector(), DBUG(), BaseLib::extractBaseNameWithoutExtension(), BaseLib::extractPath(), BaseLib::joinPaths(), OGS_FATAL, GitInfoLib::GitInfo::ogs_version, MeshLib::IO::readMeshFromFile(), readPvd(), BaseLib::setConsoleLogLevel(), and testIfMeshesAreEqual().

◆ readPvd()

std::vector< std::pair< double, std::string > > readPvd ( std::string const & pvd_filename)

Definition at line 30 of file PVD2XDMF.cpp.

32{
33 DBUG("Start reading the PVD file {:s}", pvd_filename);
34 boost::property_tree::ptree pvd;
35 read_xml(pvd_filename, pvd,
36 boost::property_tree::xml_parser::trim_whitespace);
37
38 std::vector<std::pair<double, std::string>> timeseries;
39 for (auto const& dataset : pvd.get_child("VTKFile.Collection"))
40 {
41 if (dataset.first != "DataSet")
42 {
43 OGS_FATAL("Expected DataSet tag but got '{:s}'", dataset.first);
44 }
45
46 auto const time = dataset.second.get<double>("<xmlattr>.timestep");
47 auto const file = dataset.second.get<std::string>("<xmlattr>.file");
48 timeseries.emplace_back(time, file);
49 }
50 DBUG("Finished reading the PVD file {:s}", pvd_filename);
51
52 return timeseries;
53}

References DBUG(), and OGS_FATAL.

Referenced by main().

◆ testIfMeshesAreEqual()

void testIfMeshesAreEqual ( MeshLib::Mesh const & mesh,
MeshLib::Mesh const & main_mesh,
std::string error_message )

Definition at line 77 of file PVD2XDMF.cpp.

80{
81 if (mesh.getDimension() != main_mesh.getDimension())
82 {
84 "{:s}The mesh has dimension {} which is different from the "
85 "dimension {} of in the main mesh.",
86 error_message, mesh.getDimension(), main_mesh.getDimension());
87 }
88 if (mesh.getNumberOfElements() != main_mesh.getNumberOfElements())
89 {
91 "{:s}The mesh has {} elements which is different from the number "
92 "of elements ({}) in the main mesh.",
93 error_message, mesh.getNumberOfElements(),
94 main_mesh.getNumberOfElements());
95 }
96 if (mesh.getNumberOfNodes() != main_mesh.getNumberOfNodes())
97 {
99 "{:s}The mesh has {} nodes which is different from the number of "
100 "nodes ({}) in the main mesh.",
101 error_message, mesh.getNumberOfNodes(),
102 main_mesh.getNumberOfNodes());
103 }
104}

References MeshLib::Mesh::getDimension(), MeshLib::Mesh::getNumberOfElements(), MeshLib::Mesh::getNumberOfNodes(), and OGS_FATAL.

Referenced by main().