OGS
PVTU2VTU.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 <tclap/CmdLine.h>
5
6#include <algorithm>
7#include <boost/property_tree/ptree.hpp>
8#include <boost/property_tree/xml_parser.hpp>
9#include <filesystem>
10#include <fstream>
11#include <memory>
12#include <numeric>
13#include <range/v3/algorithm/copy.hpp>
14#include <range/v3/algorithm/transform.hpp>
15#include <range/v3/numeric/accumulate.hpp>
16#include <range/v3/range/conversion.hpp>
17#include <range/v3/view/filter.hpp>
18#include <string>
19#include <unordered_set>
20#include <vector>
21
23#include "BaseLib/FileTools.h"
24#include "BaseLib/Logging.h"
25#include "BaseLib/MPI.h"
26#include "BaseLib/RunTime.h"
28#include "GeoLib/AABB.h"
29#include "GeoLib/OctTree.h"
30#include "InfoLib/GitInfo.h"
31#include "MathLib/Point3d.h"
35#include "MeshLib/Mesh.h"
36#include "MeshLib/Node.h"
37#include "MeshLib/Properties.h"
41
43{
44 std::size_t partition_id;
45 std::size_t original_id;
46};
47
48template <typename T>
50 MeshLib::Mesh& merged_mesh,
51 std::vector<std::unique_ptr<MeshLib::Mesh>> const& partitioned_meshes,
52 MeshLib::PropertyVector<T> const* const pv,
53 MeshLib::Properties const& properties,
54 std::vector<MeshEntityMapInfo> const& merged_node_map,
55 std::vector<MeshEntityMapInfo> const& merged_element_map)
56{
57 if (pv == nullptr)
58 {
59 return false;
60 }
61
63 {
64 // Do nothing
65 return true;
66 }
67
68 auto const item_type = pv->getMeshItemType();
69
70 auto const pv_name = pv->getPropertyName();
71
72 auto const pv_num_components = pv->getNumberOfGlobalComponents();
73
74 if (pv_name == "OGS_VERSION" || pv_name == "IntegrationPointMetaData")
75 {
77 merged_mesh, pv_name, item_type, pv_num_components);
78 new_pv->assign(*pv);
79
80 return true;
81 }
82
83 std::vector<MeshLib::PropertyVector<T>*> partition_property_vectors;
84 partition_property_vectors.reserve(partitioned_meshes.size());
85 for (auto const& mesh : partitioned_meshes)
86 {
87 partition_property_vectors.emplace_back(
88 mesh->getProperties().getPropertyVector<T>(pv_name, item_type,
89 pv_num_components));
90 }
91
92 auto createNewCellOrNodePropertyVector =
93 [&](std::vector<MeshEntityMapInfo> const& mesh_entity_map)
94 {
96 merged_mesh, pv_name, item_type, pv_num_components);
97 std::size_t counter = 0;
98 for (auto const& entity_info : mesh_entity_map)
99 {
100 auto const& partition_pv =
101 partition_property_vectors[entity_info.partition_id];
102 for (int i_com = 0; i_com < pv_num_components; i_com++)
103 {
104 (*new_pv)[counter * pv_num_components + i_com] =
105 (*partition_pv)[entity_info.original_id *
106 pv_num_components +
107 i_com];
108 }
109 counter++;
110 }
111 };
112
113 if (item_type == MeshLib::MeshItemType::Node)
114 {
115 createNewCellOrNodePropertyVector(merged_node_map);
116 return true;
117 }
118
119 if (item_type == MeshLib::MeshItemType::Cell)
120 {
121 createNewCellOrNodePropertyVector(merged_element_map);
122 return true;
123 }
124
126 {
127 std::vector<std::vector<std::size_t>> partition_element_offsets;
128 partition_element_offsets.reserve(partitioned_meshes.size());
129 for (auto const& mesh : partitioned_meshes)
130 {
131 partition_element_offsets.emplace_back(
133 mesh->getElements(), *pv, properties));
134 }
135
137 merged_mesh, pv_name, item_type, pv_num_components);
138
139 // Count the integration points
140 auto const ip_meta_data =
142 MeshLib::getIntegrationPointMetaData(properties), pv_name);
143
144 auto number_of_integration_points = [&](auto const* element)
145 {
147 ip_meta_data, *element);
148 };
149
150 std::size_t const counter = ranges::accumulate(
151 merged_mesh.getElements() |
152 ranges::views::transform(number_of_integration_points),
153 std::size_t{0});
154 new_pv->resize(counter * pv_num_components);
155
156 auto const global_ip_offsets =
158 merged_mesh.getElements(), *pv, properties);
159
160 std::size_t element_counter = 0;
161 for (auto const& element_info : merged_element_map)
162 {
163 MeshLib::PropertyVector<T> const& partition_pv =
164 *(partition_property_vectors[element_info.partition_id]);
165
166 auto const& offsets =
167 partition_element_offsets[element_info.partition_id];
168
169 int const begin_pos = offsets[element_info.original_id];
170 int const end_pos = offsets[element_info.original_id + 1];
171
172 std::copy(partition_pv.begin() + begin_pos,
173 partition_pv.begin() + end_pos,
174 new_pv->begin() + global_ip_offsets[element_counter]);
175
176 element_counter++;
177 }
178 }
179
180 return true;
181}
182
183std::vector<std::string> readVtuFileNames(std::string const& pvtu_file_name)
184{
185 std::ifstream ins(pvtu_file_name);
186
187 if (!ins)
188 {
189 OGS_FATAL("Could not open pvtu file {:s}.", pvtu_file_name);
190 }
191
192 using boost::property_tree::ptree;
193 ptree pt;
194 read_xml(ins, pt);
195
196 auto root = pt.get_child("VTKFile");
197
198 std::vector<std::string> vtu_file_names;
199
200 std::string file_path = BaseLib::extractPath(pvtu_file_name);
201
202 for (ptree::value_type const& v : root.get_child("PUnstructuredGrid"))
203 {
204 if (v.first == "Piece")
205 {
206 vtu_file_names.push_back(BaseLib::joinPaths(
207 file_path,
208 // only gets the vtu file name:
209 std::filesystem::path(v.second.get("<xmlattr>.Source", ""))
210 .filename()
211 .string()));
212 }
213 }
214
215 if (vtu_file_names.empty())
216 {
217 OGS_FATAL("PVTU file {:s} does not contain any vtu piece",
218 pvtu_file_name);
219 }
220
221 return vtu_file_names;
222}
223
224// all nodes (also 'ghost' nodes) of all meshes sorted by partition
225std::tuple<std::vector<MeshLib::Node*>, std::vector<std::size_t>>
226getMergedNodesVector(std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
227{
228 std::vector<std::size_t> number_of_nodes_per_partition;
229 ranges::transform(meshes, std::back_inserter(number_of_nodes_per_partition),
230 [](auto const& mesh)
231 { return mesh->getNumberOfNodes(); });
232 std::vector<std::size_t> const offsets =
233 BaseLib::sizesToOffsets(number_of_nodes_per_partition);
234
235 std::vector<MeshLib::Node*> all_nodes;
236 all_nodes.reserve(offsets.back());
237 for (auto const& mesh : meshes)
238 {
239 ranges::copy(mesh->getNodes(), std::back_inserter(all_nodes));
240 }
241 return {all_nodes, offsets};
242}
243
244std::tuple<std::vector<MeshLib::Element*>, std::vector<MeshEntityMapInfo>>
245getRegularElements(std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
246{
247 std::vector<MeshLib::Element*> regular_elements;
248
249 std::size_t partition_counter = 0;
250 std::vector<MeshEntityMapInfo> merged_element_map;
251 for (auto const& mesh : meshes)
252 {
253 MeshLib::Properties const& properties = mesh->getProperties();
254
255 auto const* const ghost_id_vector =
256 properties.getPropertyVector<unsigned char>(
258 assert(ghost_id_vector);
259
260 auto const& mesh_elements = mesh->getElements();
261
262 auto const last_element_id_of_previous_partition =
263 regular_elements.size();
264
265 auto is_regular_element = [&](MeshLib::Element const* element)
266 { return (*ghost_id_vector)[element->getID()] == 0; };
267
268 auto regular_mesh_elements =
269 mesh_elements | ranges::views::filter(is_regular_element);
270 regular_elements.insert(regular_elements.end(),
271 regular_mesh_elements.begin(),
272 regular_mesh_elements.end());
273
274 for (auto element_id = last_element_id_of_previous_partition;
275 element_id < regular_elements.size();
276 element_id++)
277 {
278 merged_element_map.push_back(
279 {partition_counter, regular_elements[element_id]->getID()});
280 }
281
282 partition_counter++;
283 }
284
285 return {regular_elements, merged_element_map};
286}
287
289 GeoLib::OctTree<MeshLib::Node, 16>& oct_tree, Eigen::Vector3d const& extent,
290 MeshLib::Node const& node, std::size_t const element_id)
291{
292 std::vector<MeshLib::Node*> query_nodes;
293 auto const eps =
294 std::numeric_limits<double>::epsilon() * extent.squaredNorm();
295 Eigen::Vector3d const min = node.asEigenVector3d().array() - eps;
296 auto constexpr dir = std::numeric_limits<double>::max();
297 Eigen::Vector3d const max = {std::nextafter(node[0] + eps, dir),
298 std::nextafter(node[1] + eps, dir),
299 std::nextafter(node[2] + eps, dir)};
300 oct_tree.getPointsInRange(min, max, query_nodes);
301
302 if (query_nodes.empty())
303 {
304 OGS_FATAL(
305 "query_nodes for node [{}], ({}, {}, {}) of element "
306 "[{}] are empty, eps is {}",
307 node.getID(), node[0], node[1], node[2], element_id, eps);
308 }
309 auto const it =
310 std::find_if(query_nodes.begin(), query_nodes.end(),
311 [&node, eps](auto const* p)
312 {
313 return (p->asEigenVector3d() - node.asEigenVector3d())
314 .squaredNorm() < eps;
315 });
316 if (it == query_nodes.end())
317 {
318 OGS_FATAL(
319 "did not find node: [{}] ({}, {}, {}) of element [{}] in "
320 "query_nodes",
321 node.getID(), node[0], node[1], node[2], element_id);
322 }
323 return *it;
324}
325
327 std::vector<MeshLib::Element*> const& regular_elements,
329 Eigen::Vector3d const& extent)
330{
331 for (auto& e : regular_elements)
332 {
333 for (unsigned i = 0; i < e->getNumberOfNodes(); i++)
334 {
335 auto* const node = e->getNode(i);
336 MeshLib::Node* node_ptr = nullptr;
337 if (!oct_tree.addPoint(node, node_ptr))
338 {
339 auto const node_ptr = getExistingNodeFromOctTree(
340 oct_tree, extent, *node, e->getID());
341 e->setNode(i, node_ptr);
342 }
343 }
344 }
345}
346
347std::pair<std::vector<MeshLib::Node*>, std::vector<MeshEntityMapInfo>>
348makeNodesUnique(std::vector<MeshLib::Node*> const& all_merged_nodes_tmp,
349 std::vector<std::size_t> const& partition_offsets,
351{
352 std::vector<MeshLib::Node*> unique_merged_nodes;
353 unique_merged_nodes.reserve(all_merged_nodes_tmp.size());
354
355 std::vector<MeshEntityMapInfo> merged_node_map;
356 merged_node_map.reserve(all_merged_nodes_tmp.size());
357
358 for (std::size_t i = 0; i < partition_offsets.size() - 1; ++i)
359 {
360 for (std::size_t pos = partition_offsets[i];
361 pos < partition_offsets[i + 1];
362 ++pos)
363 {
364 auto* node = all_merged_nodes_tmp[pos];
365 MeshLib::Node* node_ptr = nullptr;
366 if (oct_tree.addPoint(node, node_ptr))
367 {
368 unique_merged_nodes.push_back(node);
369 merged_node_map.push_back({i, pos - partition_offsets[i]});
370 }
371 }
372 }
373 return {unique_merged_nodes, merged_node_map};
374}
375
376std::unique_ptr<MeshLib::Mesh> mergeSubdomainMeshes(
377 std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
378{
379 BaseLib::RunTime merged_element_timer;
380 merged_element_timer.start();
381 // If structured binding is used for the returned tuple, Mac compiler gives
382 // an error in reference to local binding in calling applyToPropertyVectors.
383 auto [regular_elements, merged_element_map] = getRegularElements(meshes);
384 INFO(
385 "Collection of {} regular elements and computing element map took {} s",
386 regular_elements.size(), merged_element_timer.elapsed());
387
388 // alternative implementation of getNodesOfRegularElements
389 BaseLib::RunTime collect_nodes_timer;
390 collect_nodes_timer.start();
391 auto [all_merged_nodes_tmp, partition_offsets] =
392 getMergedNodesVector(meshes);
393 INFO("Collection of {} nodes and computing offsets took {} s",
394 all_merged_nodes_tmp.size(), collect_nodes_timer.elapsed());
395
396 BaseLib::RunTime merged_nodes_timer;
397 merged_nodes_timer.start();
398 GeoLib::AABB aabb(all_merged_nodes_tmp.begin(), all_merged_nodes_tmp.end());
399 auto oct_tree = std::unique_ptr<GeoLib::OctTree<MeshLib::Node, 16>>(
401 aabb.getMinPoint(), aabb.getMaxPoint(), 1e-16));
402
403 auto [unique_merged_nodes, merged_node_map] =
404 makeNodesUnique(all_merged_nodes_tmp, partition_offsets, *oct_tree);
405 INFO("Make nodes unique ({} unique nodes) / computing map took {} s",
406 unique_merged_nodes.size(), merged_nodes_timer.elapsed());
407
408 BaseLib::RunTime reset_nodes_in_elements_timer;
409 reset_nodes_in_elements_timer.start();
410 auto const extent = aabb.getMaxPoint() - aabb.getMinPoint();
411 resetNodesInRegularElements(regular_elements, *oct_tree, extent);
412 INFO("Reset nodes in regular elements took {} s",
413 reset_nodes_in_elements_timer.elapsed());
414
415 BaseLib::RunTime mesh_creation_timer;
416 mesh_creation_timer.start();
417 // The Node pointers of 'merged_nodes' and Element pointers of
418 // 'regular_elements' are shared with 'meshes', the partitioned meshes.
419 auto merged_mesh = std::make_unique<MeshLib::Mesh>(
420 "pvtu_merged_mesh", unique_merged_nodes, regular_elements,
421 false /* compute_element_neighbors */);
422 INFO("creation of merged mesh took {} s", mesh_creation_timer.elapsed());
423
424 auto const& properties = meshes[0]->getProperties();
425
426 BaseLib::RunTime property_timer;
427 property_timer.start();
428 applyToPropertyVectors(
429 properties,
430 [&, &merged_node_map = merged_node_map,
431 &merged_element_map = merged_element_map](auto type,
432 auto const& property)
433 {
435 *merged_mesh, meshes,
436 dynamic_cast<MeshLib::PropertyVector<decltype(type)> const*>(
437 property),
438 properties, merged_node_map, merged_element_map);
439 });
440 INFO("merge properties into merged mesh took {} s",
441 property_timer.elapsed());
442 return merged_mesh;
443}
444
445template <typename T>
446bool transfer(MeshLib::Properties const& subdomain_properties,
447 MeshLib::Mesh& original_mesh,
448 MeshLib::PropertyVector<std::size_t> const& global_ids,
449 std::string_view const property_name,
450 MeshLib::MeshItemType const mesh_item_type)
451{
452 if (!subdomain_properties.existsPropertyVector<T>(property_name))
453 {
454 INFO("Skipping property '{}' since it is not from type '{}'.",
455 property_name, BaseLib::typeToString<T>());
456 return false;
457 }
458 auto const* subdomain_pv =
459 subdomain_properties.getPropertyVector<T>(property_name);
460 auto const number_of_components =
461 subdomain_pv->getNumberOfGlobalComponents();
462
463 auto* original_pv = MeshLib::getOrCreateMeshProperty<T>(
464 original_mesh, std::string(property_name), mesh_item_type,
465 number_of_components);
466
467 for (std::size_t i = 0; i < global_ids.size(); ++i)
468 {
469 auto const& global_id = global_ids[i];
470 for (std::remove_cvref_t<decltype(number_of_components)>
471 component_number = 0;
472 component_number < number_of_components;
473 ++component_number)
474 {
475 original_pv->getComponent(global_id, component_number) =
476 subdomain_pv->getComponent(i, component_number);
477 }
478 }
479 INFO("Data array {} from data type '{}' transferred.", property_name,
481 return true;
482}
483
485 MeshLib::Mesh const& subdomain_mesh, MeshLib::Mesh& original_mesh,
486 MeshLib::MeshItemType const mesh_item_type)
487{
488 auto const& subdomain_properties = subdomain_mesh.getProperties();
489 if (!subdomain_properties.existsPropertyVector<std::size_t>(
490 MeshLib::globalIDString(mesh_item_type), mesh_item_type, 1))
491 {
492 OGS_FATAL(
493 "The data array '{}' is required for the transfer of data from "
494 "subdomain mesh to the global mesh. But it doesn't exist in "
495 "subdomain mesh '{}'.",
496 MeshLib::globalIDString(mesh_item_type), subdomain_mesh.getName());
497 }
498 auto const* global_ids =
499 subdomain_properties.getPropertyVector<std::size_t>(
500 MeshLib::globalIDString(mesh_item_type), mesh_item_type, 1);
501 if (global_ids == nullptr)
502 {
503 OGS_FATAL("The data array '{}' is not available but required.",
504 MeshLib::globalIDString(mesh_item_type));
505 }
506
507 auto const& property_names =
508 subdomain_properties.getPropertyVectorNames(mesh_item_type);
509
510 for (auto const& property_name : property_names)
511 {
512 if (property_name == MeshLib::globalIDString(mesh_item_type))
513 {
514 continue;
515 }
516 if (property_name == MeshLib::getBulkIDString(mesh_item_type))
517 {
518 INFO(
519 "Skipping property '{}' since it is adjusted locally in "
520 "NodeWiseMeshPartitioner::renumberBulkNodeIdsProperty().",
521 MeshLib::getBulkIDString(mesh_item_type));
522 continue;
523 }
524 if (property_name == MeshLib::vtkGhostTypeString)
525 {
526 INFO(
527 "Skipping property '{}' since it is only required for parallel "
528 "execution.",
530 continue;
531 }
532 if (transfer<double>(subdomain_properties, original_mesh, *global_ids,
533 property_name, mesh_item_type) ||
534 transfer<float>(subdomain_properties, original_mesh, *global_ids,
535 property_name, mesh_item_type) ||
536 transfer<unsigned>(subdomain_properties, original_mesh, *global_ids,
537 property_name, mesh_item_type) ||
538 transfer<unsigned long>(subdomain_properties, original_mesh,
539 *global_ids, property_name,
540 mesh_item_type) ||
541 transfer<std::size_t>(subdomain_properties, original_mesh,
542 *global_ids, property_name, mesh_item_type) ||
543 transfer<int>(subdomain_properties, original_mesh, *global_ids,
544 property_name, mesh_item_type) ||
545 transfer<long>(subdomain_properties, original_mesh, *global_ids,
546 property_name, mesh_item_type))
547 {
548 INFO("Data array {} transferred from '{}' to'{}'", property_name,
549 subdomain_mesh.getName(), original_mesh.getName());
550 }
551 }
552}
553
563
564int main(int argc, char* argv[])
565{
566 TCLAP::CmdLine cmd(
567 "This tool merges VTU files of PVTU into one single VTU file. Apart "
568 "from the mesh data, all property data are merged as well"
569 "\n\nOpenGeoSys-6 software, version " +
571 ".\n"
572 "Copyright (c) 2012-2026, OpenGeoSys Community "
573 "(http://www.opengeosys.org)",
575
576 TCLAP::ValueArg<std::string> output_arg(
577 "o", "output", "Output (.vtu). The output mesh file (format = *.vtu)",
578 true, "", "OUTPUT_FILE");
579 cmd.add(output_arg);
580
581 TCLAP::ValueArg<std::string> input_arg(
582 "i", "input", "Input (.pvtu). The partitioned input mesh file", true,
583 "", "INPUT_FILE");
584 cmd.add(input_arg);
585
586 TCLAP::ValueArg<std::string> original_mesh_input_arg(
587 "m", "original_mesh",
588 "optional, the original unpartitioned input mesh (*.vtu)", false, "",
589 "");
590 cmd.add(original_mesh_input_arg);
591
592 auto log_level_arg = BaseLib::makeLogLevelArg();
593
594 cmd.add(log_level_arg);
595 cmd.parse(argc, argv);
596
597 BaseLib::MPI::Setup mpi_setup(argc, argv);
598 BaseLib::initOGSLogger(log_level_arg.getValue());
599
600 if (BaseLib::getFileExtension(input_arg.getValue()) != ".pvtu")
601 {
602 OGS_FATAL("The extension of input file name {:s} is not \"pvtu\"",
603 input_arg.getValue());
604 }
605 if (BaseLib::getFileExtension(output_arg.getValue()) != ".vtu")
606 {
607 OGS_FATAL("The extension of output file name {:s} is not \"vtu\"",
608 output_arg.getValue());
609 }
610
611 auto const vtu_file_names = readVtuFileNames(input_arg.getValue());
612
613 std::vector<std::unique_ptr<MeshLib::Mesh>> meshes;
614 meshes.reserve(vtu_file_names.size());
615
616 BaseLib::RunTime io_timer;
617 io_timer.start();
618 for (auto const& file_name : vtu_file_names)
619 {
620 auto mesh = std::unique_ptr<MeshLib::Mesh>(
622
623 MeshLib::Properties const& properties = mesh->getProperties();
624
625 if (!properties.existsPropertyVector<unsigned char>(
627 {
628 OGS_FATAL("Property vector '{}' does not exist in mesh {:s}.",
629 MeshLib::vtkGhostTypeString, file_name);
630 }
631
632 meshes.emplace_back(std::move(mesh));
633 }
634 INFO("Reading meshes took {} s", io_timer.elapsed());
635
636 std::unique_ptr<MeshLib::Mesh> merged_mesh;
637 if (original_mesh_input_arg.getValue().empty())
638 {
639 // use old, slow method that generates node and element orderings not
640 // consistent with the original mesh
641 merged_mesh = mergeSubdomainMeshes(meshes);
642 }
643 else
644 {
645 BaseLib::RunTime io_timer;
646 io_timer.start();
647 merged_mesh = std::unique_ptr<MeshLib::Mesh>(
649 original_mesh_input_arg.getValue()));
650 INFO("Reading original unpartitioned mesh took {} s",
651 io_timer.elapsed());
652 for (auto const& subdomain_mesh : meshes)
653 {
655 *(subdomain_mesh.get()), *merged_mesh);
656 }
657 }
658
659 BaseLib::RunTime writing_timer;
660 writing_timer.start();
661 if (MeshLib::IO::writeMeshToFile(*merged_mesh.get(),
662 output_arg.getValue()) != 0)
663 {
664 ERR("Could not write mesh to '{:s}'.", output_arg.getValue());
665 return EXIT_FAILURE;
666 }
667 INFO("writing mesh took {} s", writing_timer.elapsed());
668
669 // Since the Node pointers of 'merged_nodes' and Element pointers of
670 // 'regular_elements' are held by 'meshes', the partitioned meshes, the
671 // memory by these pointers are released by 'meshes' automatically.
672 // Therefore, only node vector and element vector of merged_mesh should be
673 // cleaned.
674 merged_mesh->shallowClean();
675
676 return EXIT_SUCCESS;
677}
#define OGS_FATAL(...)
Definition Error.h:19
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
bool transfer(MeshLib::Properties const &subdomain_properties, MeshLib::Mesh &original_mesh, MeshLib::PropertyVector< std::size_t > const &global_ids, std::string_view const property_name, MeshLib::MeshItemType const mesh_item_type)
Definition PVTU2VTU.cpp:446
int main(int argc, char *argv[])
Definition PVTU2VTU.cpp:564
std::unique_ptr< MeshLib::Mesh > mergeSubdomainMeshes(std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
Definition PVTU2VTU.cpp:376
std::pair< std::vector< MeshLib::Node * >, std::vector< MeshEntityMapInfo > > makeNodesUnique(std::vector< MeshLib::Node * > const &all_merged_nodes_tmp, std::vector< std::size_t > const &partition_offsets, GeoLib::OctTree< MeshLib::Node, 16 > &oct_tree)
Definition PVTU2VTU.cpp:348
MeshLib::Node * getExistingNodeFromOctTree(GeoLib::OctTree< MeshLib::Node, 16 > &oct_tree, Eigen::Vector3d const &extent, MeshLib::Node const &node, std::size_t const element_id)
Definition PVTU2VTU.cpp:288
void transferPropertiesFromPartitionedMeshToUnpartitionedMesh(MeshLib::Mesh const &subdomain_mesh, MeshLib::Mesh &original_mesh, MeshLib::MeshItemType const mesh_item_type)
Definition PVTU2VTU.cpp:484
void resetNodesInRegularElements(std::vector< MeshLib::Element * > const &regular_elements, GeoLib::OctTree< MeshLib::Node, 16 > &oct_tree, Eigen::Vector3d const &extent)
Definition PVTU2VTU.cpp:326
std::tuple< std::vector< MeshLib::Element * >, std::vector< MeshEntityMapInfo > > getRegularElements(std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
Definition PVTU2VTU.cpp:245
std::vector< std::string > readVtuFileNames(std::string const &pvtu_file_name)
Definition PVTU2VTU.cpp:183
bool createPropertyVector(MeshLib::Mesh &merged_mesh, std::vector< std::unique_ptr< MeshLib::Mesh > > const &partitioned_meshes, MeshLib::PropertyVector< T > const *const pv, MeshLib::Properties const &properties, std::vector< MeshEntityMapInfo > const &merged_node_map, std::vector< MeshEntityMapInfo > const &merged_element_map)
Definition PVTU2VTU.cpp:49
std::tuple< std::vector< MeshLib::Node * >, std::vector< std::size_t > > getMergedNodesVector(std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
Definition PVTU2VTU.cpp:226
Count the running time.
Definition RunTime.h:18
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:31
void start()
Start the timer.
Definition RunTime.h:21
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:176
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:169
bool addPoint(POINT *pnt, POINT *&ret_pnt)
void getPointsInRange(T const &min, T const &max, std::vector< POINT * > &pnts) const
static OctTree< POINT, MAX_POINTS > * createOctTree(Eigen::Vector3d ll, Eigen::Vector3d ur, double eps=std::numeric_limits< double >::epsilon())
Definition OctTree-impl.h:7
std::size_t getID() const
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55
static MeshLib::Mesh * readVTUFile(std::string const &file_name, bool const compute_element_neighbors=false)
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:101
Properties & getProperties()
Definition Mesh.h:127
const std::string getName() const
Get name of the mesh.
Definition Mesh.h:95
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > const * getPropertyVector(std::string_view name) const
MeshItemType getMeshItemType() const
int getNumberOfGlobalComponents() const
std::string const & getPropertyName() const
constexpr PROP_VAL_TYPE * begin()
constexpr std::size_t size() const
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:56
std::string getFileExtension(const std::string &path)
std::string typeToString()
std::string extractPath(std::string const &pathname)
std::string joinPaths(std::string const &pathA, std::string const &pathB)
std::vector< ranges::range_value_t< R > > sizesToOffsets(R const &sizes)
Definition Algorithm.h:276
GITINFOLIB_EXPORT const std::string ogs_version
int writeMeshToFile(const MeshLib::Mesh &mesh, std::filesystem::path const &file_path, std::set< std::string > output_variable_names, bool const use_compression, int const data_mode)
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)
std::optional< IntegrationPointMetaData > getIntegrationPointMetaData(MeshLib::Properties const &properties)
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
constexpr std::string vtkGhostTypeString
constexpr std::string_view globalIDString(MeshLib::MeshItemType const mesh_item_type)
IntegrationPointMetaDataSingleField getIntegrationPointMetaDataSingleField(std::optional< IntegrationPointMetaData > const &ip_meta_data, std::string const &field_name)
std::vector< std::size_t > getIntegrationPointDataOffsetsOfMeshElements(std::vector< MeshLib::Element * > const &mesh_elements, MeshLib::PropertyVectorBase const &pv, MeshLib::Properties const &properties)
int getNumberOfElementIntegrationPoints(MeshLib::IntegrationPointMetaDataSingleField const &ip_meta_data, MeshLib::Element const &e)
std::size_t partition_id
Definition PVTU2VTU.cpp:44
std::size_t original_id
Definition PVTU2VTU.cpp:45