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