10#include <tclap/CmdLine.h>
31 std::string
const& val_name,
35 std::size_t start(line.find(val_name));
36 std::size_t end(std::string::npos);
39 ERR(
"Value not found.");
42 value = line.substr(start + 1, std::string::npos);
45 start = value.find(
"\"");
46 value = value.substr(start + 1, std::string::npos);
47 end = value.find(
"\"");
51 start = value.find_first_not_of(
" ");
52 value = value.substr(start + 1, std::string::npos);
54 end = value.find_first_of(
" ");
56 value = value.substr(0, end);
62std::string
getName(std::string
const& line)
69 auto start = line.find(
"ZONETYPE=");
70 if (start == std::string::npos)
73 "A required 'ZONETYPE=' substring is not available in the ZONE "
74 "description: '{:s}'.",
77 start += std::size(
"ZONETYPE=") - 1;
79 auto end = line.find(
',', start);
80 if (end == std::string::npos)
83 "Expected the 'ZONETYPE=type' to be followed by a comma in the "
84 "ZONE description '{:s}'. The zone type starts at position {:d}.",
89 ERR(
"ZONETYPE string is empty in ZONE description '{:s}'.", line);
91 return std::string_view(&line[start], end - start);
95std::pair<std::size_t, std::size_t>
getDimensions(std::string
const& line)
97 std::pair<std::size_t, std::size_t> dims;
98 std::stringstream start(
getValue(line,
"I=",
false));
100 std::stringstream end(
getValue(line,
"J=",
false));
108 std::size_t
const start = var.find_first_not_of(
"\"");
109 var = var.substr(start, std::string::npos);
110 std::size_t
const end = var.find_first_of(
"\"");
111 return var.substr(0, end);
117 std::string
const var_str(
"VARIABLES");
118 std::size_t start(line.find(var_str));
119 std::string all_vars =
120 line.substr(start + var_str.length(), std::string::npos);
121 start = all_vars.find(
"=");
122 all_vars = all_vars.substr(start + 1, std::string::npos);
125 std::vector<std::string> variables;
127 while (end != std::string::npos)
129 end = all_vars.find_first_of(
" ");
130 std::string var = all_vars.substr(0, end);
132 all_vars = all_vars.substr(end + 1, std::string::npos);
141 std::size_t
const& current,
142 std::size_t
const& total)
144 if (current != total)
146 ERR(
"Data rows found do not fit specified dimensions for section "
157 std::string
const& name,
158 std::size_t
const& current,
159 std::size_t
const& total)
171 std::vector<std::vector<double>>& scalars,
172 std::size_t& val_count)
175 scalars.reserve(n_scalars);
176 for (std::size_t i = 0; i < n_scalars; ++i)
178 scalars.emplace_back(0);
185 std::string
const& file_name,
186 std::size_t& write_count,
187 std::size_t& val_count,
188 std::size_t& val_total)
190 if (write_count == 0 || val_total != 0)
192 std::size_t
const delim_pos(file_name.find_last_of(
"."));
193 std::string
const base_name(file_name.substr(0, delim_pos + 1));
194 std::string
const extension(
195 file_name.substr(delim_pos, std::string::npos));
199 INFO(
"Writing section #{}", write_count);
201 out.open(base_name + std::to_string(write_count++) + extension);
207 std::size_t& write_count,
208 std::vector<std::string>
const& vec_names,
209 std::vector<std::vector<double>>
const& scalars,
210 std::pair<std::size_t, std::size_t>
const& dims)
213 for (std::size_t i = 0; i < vec_names.size(); ++i)
215 if (vec_names[i] ==
"x" || vec_names[i] ==
"X")
217 cellsize = scalars[i][1] - scalars[i][0];
224 ERR(
"Cell size not found. Aborting...");
230 origin, cellsize, -9999};
232 std::unique_ptr<MeshLib::Mesh> mesh(
239 for (std::size_t i = 1; i < vec_names.size(); ++i)
245 ERR(
"Error creating array '{:s}'.", vec_names[i]);
248 prop->assign(scalars[i]);
251 std::size_t
const delim_pos(file_name.find_last_of(
"."));
252 std::string
const base_name(file_name.substr(0, delim_pos + 1));
253 std::string
const extension(file_name.substr(delim_pos, std::string::npos));
255 INFO(
"Writing section #{}", write_count);
257 vtu.
writeToFile(base_name + std::to_string(write_count++) + extension);
264 while (std::getline(in, line))
266 if ((line.find(
"TITLE") != std::string::npos) ||
267 (line.find(
"VARIABLES") != std::string::npos) ||
268 (line.find(
"ZONE") != std::string::npos))
276int splitFile(std::ifstream& in, std::string
const& file_name)
281 std::size_t val_count(0);
282 std::size_t val_total(0);
283 std::size_t write_count(0);
284 while (std::getline(in, line))
286 if (line.find(
"TITLE") != std::string::npos)
297 if (line.find(
"VARIABLES") != std::string::npos)
308 if (line.find(
"ZONE") != std::string::npos)
318 std::pair<std::size_t, std::size_t> dims =
getDimensions(line);
319 val_total = dims.first * dims.second;
331 INFO(
"Writing time step #{}", write_count);
333 INFO(
"Finished split.");
343 std::pair<std::size_t, std::size_t> dims(0, 0);
344 std::vector<std::string> var_names;
345 std::vector<std::vector<double>> scalars;
346 std::size_t val_count(0);
347 std::size_t val_total(0);
348 std::size_t write_count(0);
349 while (std::getline(in, line))
351 if (line.find(
"GEOMETRY") != std::string::npos)
360 if (line.find(
"TITLE") != std::string::npos)
374 if (line.find(
"VARIABLES") != std::string::npos)
390 if (line.find(
"ZONE") != std::string::npos)
403 if (
auto const zonetype =
getZonetype(line); zonetype !=
"ORDERED")
405 ERR(
"Given zonetype '{:s}' is not supported. Only 'ORDERED' "
406 "zonetype data can be converted.",
411 val_total = dims.first * dims.second;
417 std::stringstream iss(line);
419 std::size_t
const n_scalars(scalars.size());
422 if (i > n_scalars - 1)
424 ERR(
"Too much data for existing scalar arrays");
427 scalars[i++].push_back(x);
431 ERR(
"Not enough data for existing scalar arrays");
441 INFO(
"Finished conversion.");
456int main(
int argc,
char* argv[])
460 "OpenGeoSys-6 software, version " +
463 "Copyright (c) 2012-2025, OpenGeoSys Community "
464 "(http://www.opengeosys.org)",
466 TCLAP::SwitchArg split_arg(
"s",
"split",
467 "split time steps into separate files");
469 TCLAP::SwitchArg convert_arg(
"c",
"convert",
470 "convert TecPlot data into OGS meshes");
471 cmd.add(convert_arg);
472 TCLAP::ValueArg<std::string> output_arg(
"o",
"output-file",
473 "Output (.vtu). Output mesh file",
474 false,
"",
"OUTPUT_FILE");
476 TCLAP::ValueArg<std::string> input_arg(
"i",
"input-file",
477 "Input (.plt). TecPlot input file",
478 true,
"",
"INPUT_FILE");
481 cmd.add(log_level_arg);
482 cmd.parse(argc, argv);
487 if (!input_arg.isSet())
489 ERR(
"No input file given. Please specify TecPlot (*.plt) file");
493 if (convert_arg.getValue() && !output_arg.isSet())
495 ERR(
"No output file given. Please specify OGS mesh (*.vtu) file");
499 std::ifstream in(input_arg.getValue().c_str());
502 ERR(
"Could not open file {:s}.", input_arg.getValue());
506 if (!convert_arg.isSet() && !split_arg.isSet())
508 INFO(
"Nothing to do. Use -s to split or -c to convert.");
512 std::string
const filename =
513 (output_arg.isSet()) ? output_arg.getValue() : input_arg.getValue();
515 if (split_arg.getValue())
519 else if (convert_arg.getValue())
Definition of the Point class.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition of the Mesh class.
Implementation of the VtuInterface class.
Reads and writes VtkXMLUnstructuredGrid-files (vtu) to and from OGS data structures....
bool writeToFile(std::filesystem::path const &file_path)
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
void trim(std::string &str, char ch)
GITINFOLIB_EXPORT const std::string ogs_version