4#include <tclap/CmdLine.h>
25 std::string
const& val_name,
29 std::size_t start(line.find(val_name));
30 std::size_t end(std::string::npos);
33 ERR(
"Value not found.");
36 value = line.substr(start + 1, std::string::npos);
39 start = value.find(
"\"");
40 value = value.substr(start + 1, std::string::npos);
41 end = value.find(
"\"");
45 start = value.find_first_not_of(
" ");
46 value = value.substr(start + 1, std::string::npos);
48 end = value.find_first_of(
" ");
50 value = value.substr(0, end);
56std::string
getName(std::string
const& line)
63 auto start = line.find(
"ZONETYPE=");
64 if (start == std::string::npos)
67 "A required 'ZONETYPE=' substring is not available in the ZONE "
68 "description: '{:s}'.",
71 start += std::size(
"ZONETYPE=") - 1;
73 auto end = line.find(
',', start);
74 if (end == std::string::npos)
77 "Expected the 'ZONETYPE=type' to be followed by a comma in the "
78 "ZONE description '{:s}'. The zone type starts at position {:d}.",
83 ERR(
"ZONETYPE string is empty in ZONE description '{:s}'.", line);
85 return std::string_view(&line[start], end - start);
89std::pair<std::size_t, std::size_t>
getDimensions(std::string
const& line)
91 std::pair<std::size_t, std::size_t> dims;
92 std::stringstream start(
getValue(line,
"I=",
false));
94 std::stringstream end(
getValue(line,
"J=",
false));
102 std::size_t
const start = var.find_first_not_of(
"\"");
103 var = var.substr(start, std::string::npos);
104 std::size_t
const end = var.find_first_of(
"\"");
105 return var.substr(0, end);
111 std::string
const var_str(
"VARIABLES");
112 std::size_t start(line.find(var_str));
113 std::string all_vars =
114 line.substr(start + var_str.length(), std::string::npos);
115 start = all_vars.find(
"=");
116 all_vars = all_vars.substr(start + 1, std::string::npos);
119 std::vector<std::string> variables;
121 while (end != std::string::npos)
123 end = all_vars.find_first_of(
" ");
124 std::string var = all_vars.substr(0, end);
126 all_vars = all_vars.substr(end + 1, std::string::npos);
135 std::size_t
const& current,
136 std::size_t
const& total)
138 if (current != total)
140 ERR(
"Data rows found do not fit specified dimensions for section "
151 std::string
const& name,
152 std::size_t
const& current,
153 std::size_t
const& total)
165 std::vector<std::vector<double>>& scalars,
166 std::size_t& val_count)
169 scalars.reserve(n_scalars);
170 for (std::size_t i = 0; i < n_scalars; ++i)
172 scalars.emplace_back(0);
179 std::string
const& file_name,
180 std::size_t& write_count,
181 std::size_t& val_count,
182 std::size_t& val_total)
184 if (write_count == 0 || val_total != 0)
186 std::size_t
const delim_pos(file_name.find_last_of(
"."));
187 std::string
const base_name(file_name.substr(0, delim_pos + 1));
188 std::string
const extension(
189 file_name.substr(delim_pos, std::string::npos));
193 INFO(
"Writing section #{}", write_count);
195 out.open(base_name + std::to_string(write_count++) + extension);
201 std::size_t& write_count,
202 std::vector<std::string>
const& vec_names,
203 std::vector<std::vector<double>>
const& scalars,
204 std::pair<std::size_t, std::size_t>
const& dims)
207 for (std::size_t i = 0; i < vec_names.size(); ++i)
209 if (vec_names[i] ==
"x" || vec_names[i] ==
"X")
211 cellsize = scalars[i][1] - scalars[i][0];
218 ERR(
"Cell size not found. Aborting...");
224 origin, cellsize, -9999};
226 std::unique_ptr<MeshLib::Mesh> mesh(
233 for (std::size_t i = 1; i < vec_names.size(); ++i)
239 ERR(
"Error creating array '{:s}'.", vec_names[i]);
245 std::size_t
const delim_pos(file_name.find_last_of(
"."));
246 std::string
const base_name(file_name.substr(0, delim_pos + 1));
247 std::string
const extension(file_name.substr(delim_pos, std::string::npos));
249 INFO(
"Writing section #{}", write_count);
251 vtu.
writeToFile(base_name + std::to_string(write_count++) + extension);
258 while (std::getline(in, line))
260 if ((line.find(
"TITLE") != std::string::npos) ||
261 (line.find(
"VARIABLES") != std::string::npos) ||
262 (line.find(
"ZONE") != std::string::npos))
270int splitFile(std::ifstream& in, std::string
const& file_name)
275 std::size_t val_count(0);
276 std::size_t val_total(0);
277 std::size_t write_count(0);
278 while (std::getline(in, line))
280 if (line.find(
"TITLE") != std::string::npos)
291 if (line.find(
"VARIABLES") != std::string::npos)
302 if (line.find(
"ZONE") != std::string::npos)
312 std::pair<std::size_t, std::size_t> dims =
getDimensions(line);
313 val_total = dims.first * dims.second;
325 INFO(
"Writing time step #{}", write_count);
327 INFO(
"Finished split.");
337 std::pair<std::size_t, std::size_t> dims(0, 0);
338 std::vector<std::string> var_names;
339 std::vector<std::vector<double>> scalars;
340 std::size_t val_count(0);
341 std::size_t val_total(0);
342 std::size_t write_count(0);
343 while (std::getline(in, line))
345 if (line.find(
"GEOMETRY") != std::string::npos)
354 if (line.find(
"TITLE") != std::string::npos)
368 if (line.find(
"VARIABLES") != std::string::npos)
384 if (line.find(
"ZONE") != std::string::npos)
397 if (
auto const zonetype =
getZonetype(line); zonetype !=
"ORDERED")
399 ERR(
"Given zonetype '{:s}' is not supported. Only 'ORDERED' "
400 "zonetype data can be converted.",
405 val_total = dims.first * dims.second;
411 std::stringstream iss(line);
413 std::size_t
const n_scalars(scalars.size());
416 if (i > n_scalars - 1)
418 ERR(
"Too much data for existing scalar arrays");
421 scalars[i++].push_back(x);
425 ERR(
"Not enough data for existing scalar arrays");
435 INFO(
"Finished conversion.");
450int main(
int argc,
char* argv[])
454 "OpenGeoSys-6 software, version " +
457 "Copyright (c) 2012-2026, OpenGeoSys Community "
458 "(http://www.opengeosys.org)",
460 TCLAP::SwitchArg split_arg(
"s",
"split",
461 "split time steps into separate files");
463 TCLAP::SwitchArg convert_arg(
"c",
"convert",
464 "convert TecPlot data into OGS meshes");
465 cmd.add(convert_arg);
466 TCLAP::ValueArg<std::string> output_arg(
"o",
"output-file",
467 "Output (.vtu). Output mesh file",
468 false,
"",
"OUTPUT_FILE");
470 TCLAP::ValueArg<std::string> input_arg(
"i",
"input-file",
471 "Input (.plt). TecPlot input file",
472 true,
"",
"INPUT_FILE");
475 cmd.add(log_level_arg);
476 cmd.parse(argc, argv);
481 if (!input_arg.isSet())
483 ERR(
"No input file given. Please specify TecPlot (*.plt) file");
487 if (convert_arg.getValue() && !output_arg.isSet())
489 ERR(
"No output file given. Please specify OGS mesh (*.vtu) file");
493 std::ifstream in(input_arg.getValue().c_str());
496 ERR(
"Could not open file {:s}.", input_arg.getValue());
500 if (!convert_arg.isSet() && !split_arg.isSet())
502 INFO(
"Nothing to do. Use -s to split or -c to convert.");
506 std::string
const filename =
507 (output_arg.isSet()) ? output_arg.getValue() : input_arg.getValue();
509 if (split_arg.getValue())
513 else if (convert_arg.getValue())
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
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)
constexpr void assign(R &&r)
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