OGS
ApplicationUtils Namespace Reference

Classes

struct  ConfigOffsets
 
class  NodeWiseMeshPartitioner
 Mesh partitioner. More...
 
struct  Partition
 A subdomain mesh. More...
 
struct  PartitionOffsets
 

Functions

void writeMETIS (std::vector< MeshLib::Element * > const &elements, const std::string &file_name)
 
std::vector< std::size_t > readMetisData (const std::string &file_name_base, long const number_of_partitions, std::size_t const number_of_nodes)
 
void removeMetisPartitioningFiles (std::string const &file_name_base, long const number_of_partitions)
 
NodeWiseMeshPartitioner::IntegerType getNumberOfIntegerVariablesOfElements (std::vector< const MeshLib::Element * > const &elements)
 
std::size_t partitionLookup (std::size_t const &node_id, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const &node_id_mapping)
 
std::pair< std::vector< MeshLib::Node const * >, std::vector< MeshLib::Node const * > > splitIntoBaseAndHigherOrderNodes (std::vector< MeshLib::Node const * > const &nodes, MeshLib::Mesh const &mesh)
 
std::tuple< std::vector< MeshLib::Node * >, std::vector< MeshLib::Node * > > findGhostNodesInPartition (std::size_t const part_id, std::vector< MeshLib::Node * > const &nodes, std::vector< MeshLib::Element const * > const &ghost_elements, std::vector< std::size_t > const &partition_ids, MeshLib::Mesh const &mesh, std::vector< std::size_t > const &node_id_mapping)
 
template<typename T >
std::size_t copyNodePropertyVectorValues (Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
 
template<typename T >
std::size_t copyCellPropertyVectorValues (Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
 
template<typename T >
std::size_t copyFieldPropertyDataToPartitions (MeshLib::Properties const &properties, Partition const &p, std::size_t const id_offset_partition, std::vector< std::size_t > const &element_ip_data_offsets, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
 
void setIntegrationPointNumberOfPartition (MeshLib::Properties const &properties, std::vector< Partition > &partitions)
 
template<typename T >
bool copyPropertyVector (std::vector< MeshLib::Element * > const &global_mesh_elements, MeshLib::Properties &partitioned_properties, MeshLib::Properties const &properties, std::vector< Partition > const &partitions, MeshLib::PropertyVector< T > const *const pv, std::map< MeshLib::MeshItemType, std::size_t > const &total_number_of_tuples)
 
void addVtkGhostTypeProperty (MeshLib::Properties &partitioned_properties, std::vector< Partition > const &partitions, std::size_t const total_number_of_cells)
 
MeshLib::Properties partitionProperties (std::unique_ptr< MeshLib::Mesh > const &mesh, std::vector< Partition > &partitions)
 Partition existing properties and add vtkGhostType cell data array property.
 
void markDuplicateGhostCells (MeshLib::Mesh const &mesh, std::vector< Partition > &partitions)
 
void checkFieldPropertyVectorSize (std::vector< MeshLib::Element * > const &global_mesh_elements, MeshLib::Properties const &properties)
 
std::vector< std::vector< std::size_t > > computePartitionIDPerElement (std::vector< std::size_t > const &node_partition_map, std::vector< MeshLib::Element * > const &elements, std::vector< std::size_t > const &bulk_node_ids)
 
void distributeNodesToPartitions (std::vector< Partition > &partitions, std::vector< std::size_t > const &nodes_partition_ids, std::vector< MeshLib::Node * > const &nodes, std::vector< std::size_t > const &bulk_node_ids)
 
void reorderNodesIntoBaseAndHigherOrderNodes (Partition &partition, MeshLib::Mesh const &mesh)
 
void reorderNodesIntoBaseAndHigherOrderNodesPerPartition (std::vector< Partition > &partitions, MeshLib::Mesh const &mesh)
 
void setNumberOfNodesInPartitions (std::vector< Partition > &partitions, MeshLib::Mesh const &mesh)
 
void distributeElementsIntoPartitions (std::vector< Partition > &partitions, MeshLib::Mesh const &mesh, std::vector< std::vector< std::size_t > > const &partition_ids_per_element)
 
void determineAndAppendGhostNodesToPartitions (std::vector< Partition > &partitions, MeshLib::Mesh const &mesh, std::vector< std::size_t > const &nodes_partition_ids, std::vector< std::size_t > const &node_id_mapping)
 
void partitionMesh (std::vector< Partition > &partitions, MeshLib::Mesh const &mesh, std::vector< std::size_t > const &nodes_partition_ids, std::vector< std::size_t > const &bulk_node_ids)
 
template<typename T >
void writePropertyVectorValues (std::ostream &os, MeshLib::PropertyVector< T > const &pv)
 
template<typename T >
bool writePropertyVector (MeshLib::PropertyVector< T > const *const pv, MeshLib::MeshItemType const mesh_item_type, std::ostream &out_val, std::ostream &out_meta)
 
void writeProperties (const std::string &file_name_base, MeshLib::Properties const &partitioned_properties, std::vector< Partition > const &partitions, MeshLib::MeshItemType const mesh_item_type)
 
PartitionOffsets computePartitionOffsets (Partition const &partition)
 
ConfigOffsets incrementConfigOffsets (ConfigOffsets const &oldConfig, PartitionOffsets const &offsets)
 
std::tuple< std::vector< long >, std::vector< long > > writeConfigData (const std::string &file_name_base, std::vector< Partition > const &partitions)
 
void getElementIntegerVariables (const MeshLib::Element &elem, const std::unordered_map< std::size_t, long > &local_node_ids, std::vector< long > &elem_info, long &counter)
 
std::unordered_map< std::size_t, long > enumerateLocalNodeIds (std::vector< MeshLib::Node const * > const &nodes)
 Generates a mapping of given node ids to a new local (renumbered) node ids.
 
void writeElements (std::string const &file_name_base, std::vector< Partition > const &partitions, std::vector< long > const &regular_element_offsets, std::vector< long > const &ghost_element_offsets)
 
void writeNodes (const std::string &file_name_base, std::vector< Partition > const &partitions, std::vector< std::size_t > const &global_node_ids)
 

Function Documentation

◆ addVtkGhostTypeProperty()

void ApplicationUtils::addVtkGhostTypeProperty ( MeshLib::Properties & partitioned_properties,
std::vector< Partition > const & partitions,
std::size_t const total_number_of_cells )

Definition at line 407 of file NodeWiseMeshPartitioner.cpp.

410{
411 auto* vtk_ghost_type =
412 partitioned_properties.createNewPropertyVector<unsigned char>(
413 "vtkGhostType", MeshLib::MeshItemType::Cell);
414 if (vtk_ghost_type == nullptr)
415 {
416 OGS_FATAL("Could not create vtkGhostType cell data array.");
417 }
418
419 vtk_ghost_type->resize(total_number_of_cells);
420 std::size_t offset = 0;
421 for (auto const& partition : partitions)
422 {
423 offset += partition.regular_elements.size();
424 for (std::size_t i = 0; i < partition.ghost_elements.size(); ++i)
425 {
426 if (partition.duplicate_ghost_cell[i])
427 {
428 (*vtk_ghost_type)[offset + i] |=
429 vtkDataSetAttributes::DUPLICATECELL;
430 }
431 }
432 offset += partition.ghost_elements.size();
433 }
434}
#define OGS_FATAL(...)
Definition Error.h:26
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)

References MeshLib::Cell, MeshLib::Properties::createNewPropertyVector(), and OGS_FATAL.

Referenced by partitionProperties().

◆ checkFieldPropertyVectorSize()

void ApplicationUtils::checkFieldPropertyVectorSize ( std::vector< MeshLib::Element * > const & global_mesh_elements,
MeshLib::Properties const & properties )

Definition at line 513 of file NodeWiseMeshPartitioner.cpp.

516{
517 for (auto const& [name, property] : properties)
518 {
519 auto const item_type = property->getMeshItemType();
520
522 {
523 continue;
524 }
525
526 // For special field data such as OGS_VERSION, IntegrationPointMetaData,
527 // etc., which are not "real" integration points:
528 if (property->getPropertyName().find("_ip") == std::string::npos)
529 {
530 continue;
531 }
532
533 std::size_t number_of_total_integration_points = 0;
534 auto const ip_meta_data = MeshLib::getIntegrationPointMetaData(
535 properties, property->getPropertyName());
536 for (auto const element : global_mesh_elements)
537 {
538 int const number_of_integration_points =
540 *element);
541 number_of_total_integration_points += number_of_integration_points;
542 }
543
544 const auto pv =
545 dynamic_cast<MeshLib::PropertyVector<double> const*>(property);
546 std::size_t const component_number = pv->getNumberOfGlobalComponents();
547 if (pv->size() != number_of_total_integration_points * component_number)
548 {
549 OGS_FATAL(
550 "The property vector's size {:d} for integration point data "
551 "{:s} does not match its actual size {:d}. The field data in "
552 "the vtu file are wrong.",
553 pv->size(), name,
554 number_of_total_integration_points * component_number);
555 }
556 }
557}
int getNumberOfGlobalComponents() const
IntegrationPointMetaData getIntegrationPointMetaData(MeshLib::Properties const &properties, std::string const &name)
int getNumberOfElementIntegrationPoints(MeshLib::IntegrationPointMetaData const &ip_meta_data, MeshLib::Element const &e)

References MeshLib::getIntegrationPointMetaData(), MeshToolsLib::getNumberOfElementIntegrationPoints(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::IntegrationPoint, and OGS_FATAL.

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::partitionByMETIS().

◆ computePartitionIDPerElement()

std::vector< std::vector< std::size_t > > ApplicationUtils::computePartitionIDPerElement ( std::vector< std::size_t > const & node_partition_map,
std::vector< MeshLib::Element * > const & elements,
std::vector< std::size_t > const & bulk_node_ids )

Definition at line 559 of file NodeWiseMeshPartitioner.cpp.

563{
564 auto node_partition_ids = ranges::views::transform(
565 [&](MeshLib::Element const* const element)
566 {
567 auto node_lookup = ranges::views::transform(
568 [&](std::size_t const i)
569 { return node_partition_map[bulk_node_ids[i]]; });
570
571 return element->nodes() | MeshLib::views::ids | node_lookup |
572 ranges::to<std::vector>;
573 });
574
575 return elements | node_partition_ids | ranges::to<std::vector>;
576}
constexpr std::span< Node *const > nodes() const
Span of element's nodes, their pointers actually.
Definition Element.h:72
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
Definition Mesh.h:225

References MeshLib::views::ids, and MeshLib::Element::nodes().

Referenced by partitionMesh().

◆ computePartitionOffsets()

PartitionOffsets ApplicationUtils::computePartitionOffsets ( Partition const & partition)

Definition at line 1029 of file NodeWiseMeshPartitioner.cpp.

1030{
1031 return {static_cast<long>(partition.nodes.size()),
1032 static_cast<long>(partition.regular_elements.size() +
1034 partition.regular_elements)),
1035 static_cast<long>(partition.ghost_elements.size() +
1037 partition.ghost_elements))};
1038}
NodeWiseMeshPartitioner::IntegerType getNumberOfIntegerVariablesOfElements(std::vector< const MeshLib::Element * > const &elements)

References getNumberOfIntegerVariablesOfElements(), ApplicationUtils::Partition::ghost_elements, ApplicationUtils::Partition::nodes, and ApplicationUtils::Partition::regular_elements.

Referenced by writeConfigData().

◆ copyCellPropertyVectorValues()

template<typename T >
std::size_t ApplicationUtils::copyCellPropertyVectorValues ( Partition const & p,
std::size_t const offset,
MeshLib::PropertyVector< T > const & pv,
MeshLib::PropertyVector< T > & partitioned_pv )

Copies the properties from global property vector pv to the partition-local one partitioned_pv. Regular elements' and ghost elements' values are copied.

Definition at line 207 of file NodeWiseMeshPartitioner.cpp.

212{
213 std::size_t const n_regular(p.regular_elements.size());
214 auto const n_components = pv.getNumberOfGlobalComponents();
215 for (std::size_t i = 0; i < n_regular; ++i)
216 {
217 const auto id = p.regular_elements[i]->getID();
218 std::copy_n(&pv[n_components * id], n_components,
219 &partitioned_pv[offset + n_components * i]);
220 }
221
222 std::size_t const n_ghost(p.ghost_elements.size());
223 for (std::size_t i = 0; i < n_ghost; ++i)
224 {
225 const auto id = p.ghost_elements[i]->getID();
226 std::copy_n(&pv[n_components * id], n_components,
227 &partitioned_pv[offset + n_components * (n_regular + i)]);
228 }
229 return n_components * (n_regular + n_ghost);
230}

References MeshLib::PropertyVectorBase::getNumberOfGlobalComponents().

Referenced by copyPropertyVector().

◆ copyFieldPropertyDataToPartitions()

template<typename T >
std::size_t ApplicationUtils::copyFieldPropertyDataToPartitions ( MeshLib::Properties const & properties,
Partition const & p,
std::size_t const id_offset_partition,
std::vector< std::size_t > const & element_ip_data_offsets,
MeshLib::PropertyVector< T > const & pv,
MeshLib::PropertyVector< T > & partitioned_pv )

Copies the data from the property vector pv belonging to the given Partition p to the property vector partitioned_pv. partitioned_pv is ordered by partition. Regular elements' and ghost elements' values are copied.

Definition at line 237 of file NodeWiseMeshPartitioner.cpp.

244{
245 // Special field data such as OGS_VERSION, IntegrationPointMetaData,
246 // etc., which are not "real" integration points, are copied "as is"
247 // (i.e. fully) for every partition.
248 if (pv.getPropertyName().find("_ip") == std::string::npos)
249 {
250 std::copy_n(&pv[0], pv.size(), &partitioned_pv[id_offset_partition]);
251 return pv.size();
252 }
253
254 auto const n_components = pv.getNumberOfGlobalComponents();
255
256 std::size_t id_offset = 0;
257
258 auto copyFieldData =
259 [&](std::vector<const MeshLib::Element*> const& elements)
260 {
261 auto const ip_meta_data = MeshLib::getIntegrationPointMetaData(
262 properties, pv.getPropertyName());
263
264 for (auto const element : elements)
265 {
266 int const number_of_element_field_data =
268 *element) *
269 n_components;
270 // The original element ID is not changed.
271 auto const element_id = element->getID();
272 int const begin_pos = element_ip_data_offsets[element_id];
273 int const end_pos = element_ip_data_offsets[element_id + 1];
274
275 std::copy(pv.begin() + begin_pos, pv.begin() + end_pos,
276 &partitioned_pv[id_offset + id_offset_partition]);
277 id_offset += number_of_element_field_data;
278 }
279 };
280
281 copyFieldData(p.regular_elements);
282 copyFieldData(p.ghost_elements);
283
284 return id_offset;
285}
std::string const & getPropertyName() const
std::size_t size() const

References MeshLib::getIntegrationPointMetaData(), MeshToolsLib::getNumberOfElementIntegrationPoints(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::PropertyVectorBase::getPropertyName(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by copyPropertyVector().

◆ copyNodePropertyVectorValues()

template<typename T >
std::size_t ApplicationUtils::copyNodePropertyVectorValues ( Partition const & p,
std::size_t const offset,
MeshLib::PropertyVector< T > const & pv,
MeshLib::PropertyVector< T > & partitioned_pv )

Copies the properties from global property vector pv to the partition-local one partitioned_pv.

Definition at line 185 of file NodeWiseMeshPartitioner.cpp.

190{
191 auto const& nodes = p.nodes;
192 auto const nnodes = nodes.size();
193 auto const n_components = pv.getNumberOfGlobalComponents();
194 for (std::size_t i = 0; i < nnodes; ++i)
195 {
196 const auto global_id = nodes[i]->getID();
197 std::copy_n(&pv[n_components * global_id], n_components,
198 &partitioned_pv[offset + n_components * i]);
199 }
200 return n_components * nnodes;
201}

References MeshLib::PropertyVectorBase::getNumberOfGlobalComponents().

Referenced by copyPropertyVector().

◆ copyPropertyVector()

template<typename T >
bool ApplicationUtils::copyPropertyVector ( std::vector< MeshLib::Element * > const & global_mesh_elements,
MeshLib::Properties & partitioned_properties,
MeshLib::Properties const & properties,
std::vector< Partition > const & partitions,
MeshLib::PropertyVector< T > const *const pv,
std::map< MeshLib::MeshItemType, std::size_t > const & total_number_of_tuples )

Definition at line 334 of file NodeWiseMeshPartitioner.cpp.

341{
342 if (pv == nullptr)
343 {
344 return false;
345 }
346 auto const item_type = pv->getMeshItemType();
347
348 std::size_t partitioned_pv_size = total_number_of_tuples.at(item_type) *
350
351 std::vector<std::size_t> element_ip_data_offsets;
353 {
354 // Special field data such as OGS_VERSION, IntegrationPointMetaData,
355 // etc., which are not "real" integration points, are copied "as is"
356 // (i.e. fully) for every partition.
357 if (pv->getPropertyName().find("_ip") == std::string::npos)
358 {
359 partitioned_pv_size = pv->size() * partitions.size();
360 }
361
362 element_ip_data_offsets =
364 global_mesh_elements, *pv, properties);
365 }
366
367 auto partitioned_pv = partitioned_properties.createNewPropertyVector<T>(
368 pv->getPropertyName(), pv->getMeshItemType(),
370 partitioned_pv->resize(partitioned_pv_size);
371
372 auto copy_property_vector_values =
373 [&](Partition const& p, std::size_t offset)
374 {
376 {
377 return copyFieldPropertyDataToPartitions(properties, p, offset,
378 element_ip_data_offsets,
379 *pv, *partitioned_pv);
380 }
381
382 if (item_type == MeshLib::MeshItemType::Node)
383 {
384 return copyNodePropertyVectorValues(p, offset, *pv,
385 *partitioned_pv);
386 }
387 if (item_type == MeshLib::MeshItemType::Cell)
388 {
389 return copyCellPropertyVectorValues(p, offset, *pv,
390 *partitioned_pv);
391 }
392
393 OGS_FATAL(
394 "Copying of property vector values for mesh item type {:s} is not "
395 "implemented.",
396 toString(item_type));
397 };
398
399 std::size_t position_offset(0);
400 for (auto p : partitions)
401 {
402 position_offset += copy_property_vector_values(p, position_offset);
403 }
404 return true;
405}
MeshItemType getMeshItemType() const
std::size_t copyCellPropertyVectorValues(Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
std::size_t copyFieldPropertyDataToPartitions(MeshLib::Properties const &properties, Partition const &p, std::size_t const id_offset_partition, std::vector< std::size_t > const &element_ip_data_offsets, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
std::size_t copyNodePropertyVectorValues(Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
std::vector< std::size_t > getIntegrationPointDataOffsetsOfMeshElements(std::vector< MeshLib::Element * > const &mesh_elements, MeshLib::PropertyVectorBase const &pv, MeshLib::Properties const &properties)
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)

References MeshLib::Cell, copyCellPropertyVectorValues(), copyFieldPropertyDataToPartitions(), copyNodePropertyVectorValues(), MeshLib::Properties::createNewPropertyVector(), MeshToolsLib::getIntegrationPointDataOffsetsOfMeshElements(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::IntegrationPoint, MeshLib::Node, OGS_FATAL, and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

◆ determineAndAppendGhostNodesToPartitions()

void ApplicationUtils::determineAndAppendGhostNodesToPartitions ( std::vector< Partition > & partitions,
MeshLib::Mesh const & mesh,
std::vector< std::size_t > const & nodes_partition_ids,
std::vector< std::size_t > const & node_id_mapping )

Definition at line 661 of file NodeWiseMeshPartitioner.cpp.

665{
666 for (std::size_t part_id = 0; part_id < partitions.size(); part_id++)
667 {
668 auto& partition = partitions[part_id];
669 std::vector<MeshLib::Node*> base_ghost_nodes;
670 std::vector<MeshLib::Node*> higher_order_ghost_nodes;
671 std::tie(base_ghost_nodes, higher_order_ghost_nodes) =
673 part_id, mesh.getNodes(), partition.ghost_elements,
674 nodes_partition_ids, mesh, node_id_mapping);
675
676 std::copy(begin(base_ghost_nodes), end(base_ghost_nodes),
677 std::back_inserter(partition.nodes));
678
679 partition.number_of_base_nodes =
680 partition.number_of_regular_base_nodes + base_ghost_nodes.size();
681
682 std::copy(begin(higher_order_ghost_nodes),
683 end(higher_order_ghost_nodes),
684 std::back_inserter(partition.nodes));
685 }
686}
std::tuple< std::vector< MeshLib::Node * >, std::vector< MeshLib::Node * > > findGhostNodesInPartition(std::size_t const part_id, std::vector< MeshLib::Node * > const &nodes, std::vector< MeshLib::Element const * > const &ghost_elements, std::vector< std::size_t > const &partition_ids, MeshLib::Mesh const &mesh, std::vector< std::size_t > const &node_id_mapping)

References findGhostNodesInPartition(), and MeshLib::Mesh::getNodes().

Referenced by partitionMesh().

◆ distributeElementsIntoPartitions()

void ApplicationUtils::distributeElementsIntoPartitions ( std::vector< Partition > & partitions,
MeshLib::Mesh const & mesh,
std::vector< std::vector< std::size_t > > const & partition_ids_per_element )

Definition at line 627 of file NodeWiseMeshPartitioner.cpp.

631{
632 for (auto const& element : mesh.getElements())
633 {
634 auto const element_id = element->getID();
635 auto node_partition_ids = partition_ids_per_element[element_id];
636 // make partition ids unique
637 std::sort(node_partition_ids.begin(), node_partition_ids.end());
638 auto last =
639 std::unique(node_partition_ids.begin(), node_partition_ids.end());
640 node_partition_ids.erase(last, node_partition_ids.end());
641
642 // all element nodes belong to the same partition => regular element
643 if (node_partition_ids.size() == 1)
644 {
645 partitions[node_partition_ids[0]].regular_elements.push_back(
646 element);
647 }
648 else
649 {
650 for (auto const partition_id : node_partition_ids)
651 {
652 partitions[partition_id].ghost_elements.push_back(element);
653 }
654 }
655 }
656}

References MeshLib::Mesh::getElements().

Referenced by partitionMesh().

◆ distributeNodesToPartitions()

void ApplicationUtils::distributeNodesToPartitions ( std::vector< Partition > & partitions,
std::vector< std::size_t > const & nodes_partition_ids,
std::vector< MeshLib::Node * > const & nodes,
std::vector< std::size_t > const & bulk_node_ids )

Definition at line 578 of file NodeWiseMeshPartitioner.cpp.

583{
584 for (auto const* const node : nodes)
585 {
586 partitions[nodes_partition_ids[bulk_node_ids[node->getID()]]]
587 .nodes.push_back(node);
588 }
589}

Referenced by partitionMesh().

◆ enumerateLocalNodeIds()

std::unordered_map< std::size_t, long > ApplicationUtils::enumerateLocalNodeIds ( std::vector< MeshLib::Node const * > const & nodes)

Generates a mapping of given node ids to a new local (renumbered) node ids.

Definition at line 1126 of file NodeWiseMeshPartitioner.cpp.

1128{
1129 std::unordered_map<std::size_t, long> local_ids;
1130 local_ids.reserve(nodes.size());
1131
1132 long local_node_id = 0;
1133 for (const auto* node : nodes)
1134 {
1135 local_ids[node->getID()] = local_node_id++;
1136 }
1137 return local_ids;
1138}

Referenced by writeElements().

◆ findGhostNodesInPartition()

std::tuple< std::vector< MeshLib::Node * >, std::vector< MeshLib::Node * > > ApplicationUtils::findGhostNodesInPartition ( std::size_t const part_id,
std::vector< MeshLib::Node * > const & nodes,
std::vector< MeshLib::Element const * > const & ghost_elements,
std::vector< std::size_t > const & partition_ids,
MeshLib::Mesh const & mesh,
std::vector< std::size_t > const & node_id_mapping )

Prerequisite: the ghost elements has to be found Finds ghost nodes and non-linear element ghost nodes by walking over ghost elements.

Definition at line 140 of file NodeWiseMeshPartitioner.cpp.

147{
148 std::vector<MeshLib::Node*> base_ghost_nodes;
149 std::vector<MeshLib::Node*> higher_order_ghost_nodes;
150
151 std::vector<bool> is_ghost_node(nodes.size(), false);
152 for (const auto* ghost_elem : ghost_elements)
153 {
154 for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++)
155 {
156 auto const& n = ghost_elem->getNode(i);
157 auto const node_id = n->getID();
158 if (is_ghost_node[node_id])
159 {
160 continue;
161 }
162
163 if (partitionLookup(node_id, partition_ids, node_id_mapping) !=
164 part_id)
165 {
166 if (isBaseNode(*n, mesh.getElementsConnectedToNode(*n)))
167 {
168 base_ghost_nodes.push_back(nodes[node_id]);
169 }
170 else
171 {
172 higher_order_ghost_nodes.push_back(nodes[node_id]);
173 }
174 is_ghost_node[node_id] = true;
175 }
176 }
177 }
178 return std::tuple<std::vector<MeshLib::Node*>, std::vector<MeshLib::Node*>>{
179 base_ghost_nodes, higher_order_ghost_nodes};
180}

References MeshLib::Mesh::getElementsConnectedToNode(), and partitionLookup().

Referenced by determineAndAppendGhostNodesToPartitions().

◆ getElementIntegerVariables()

void ApplicationUtils::getElementIntegerVariables ( const MeshLib::Element & elem,
const std::unordered_map< std::size_t, long > & local_node_ids,
std::vector< long > & elem_info,
long & counter )

Get integer variables, which are used to define an element

Parameters
elemElement
local_node_idsLocal node indices of a partition
elem_infoA vector holds all integer variables of element definitions
counterRecorder of the number of integer variables.

Definition at line 1105 of file NodeWiseMeshPartitioner.cpp.

1110{
1111 constexpr unsigned mat_id =
1112 0; // TODO: Material ID to be set from the mesh data
1113 const long nn = elem.getNumberOfNodes();
1114 elem_info[counter++] = mat_id;
1115 elem_info[counter++] = static_cast<long>(elem.getCellType());
1116 elem_info[counter++] = nn;
1117
1118 for (long i = 0; i < nn; i++)
1119 {
1120 auto const& n = *elem.getNode(i);
1121 elem_info[counter++] = local_node_ids.at(n.getID());
1122 }
1123}
virtual CellType getCellType() const =0
virtual unsigned getNumberOfNodes() const =0
virtual const Node * getNode(unsigned idx) const =0

References MeshLib::Element::getCellType(), MeshLib::Element::getNode(), and MeshLib::Element::getNumberOfNodes().

Referenced by writeElements().

◆ getNumberOfIntegerVariablesOfElements()

NodeWiseMeshPartitioner::IntegerType ApplicationUtils::getNumberOfIntegerVariablesOfElements ( std::vector< const MeshLib::Element * > const & elements)

Calculate the total number of integer variables of an element vector. Each element has three integer variables for element ID, element type, number of nodes of the element. Therefore the total number of the integers in elements is 3 * elements.size() + sum (number of nodes of each element).

Definition at line 76 of file NodeWiseMeshPartitioner.cpp.

78{
79 return 3 * elements.size() +
80 std::accumulate(begin(elements), end(elements), 0,
81 [](auto const nnodes, auto const* e)
82 { return nnodes + e->getNumberOfNodes(); });
83}

Referenced by computePartitionOffsets(), and ApplicationUtils::Partition::writeConfig().

◆ incrementConfigOffsets()

ConfigOffsets ApplicationUtils::incrementConfigOffsets ( ConfigOffsets const & oldConfig,
PartitionOffsets const & offsets )

Definition at line 1040 of file NodeWiseMeshPartitioner.cpp.

1042{
1043 return {
1044 static_cast<long>(oldConfig.node_rank_offset +
1045 offsets.node * sizeof(MeshLib::IO::NodeData)),
1046 // Offset the ending entry of the element integer variables of
1047 // the non-ghost elements of this partition in the vector of elem_info.
1048 static_cast<long>(oldConfig.element_rank_offset +
1049 offsets.regular_elements * sizeof(long)),
1050
1051 // Offset the ending entry of the element integer variables of
1052 // the ghost elements of this partition in the vector of elem_info.
1053 static_cast<long>(oldConfig.ghost_element_rank_offset +
1054 offsets.ghost_elements * sizeof(long))};
1055}
struct NodeData used for parallel reading and also partitioning
Definition NodeData.h:18

References ApplicationUtils::ConfigOffsets::element_rank_offset, ApplicationUtils::ConfigOffsets::ghost_element_rank_offset, ApplicationUtils::PartitionOffsets::ghost_elements, ApplicationUtils::PartitionOffsets::node, ApplicationUtils::ConfigOffsets::node_rank_offset, and ApplicationUtils::PartitionOffsets::regular_elements.

Referenced by writeConfigData().

◆ markDuplicateGhostCells()

void ApplicationUtils::markDuplicateGhostCells ( MeshLib::Mesh const & mesh,
std::vector< Partition > & partitions )

Definition at line 491 of file NodeWiseMeshPartitioner.cpp.

493{
494 std::vector<bool> cell_visited(mesh.getElements().size(), false);
495
496 for (auto& partition : partitions)
497 {
498 partition.duplicate_ghost_cell.resize(partition.ghost_elements.size(),
499 true);
500
501 for (std::size_t i = 0; i < partition.ghost_elements.size(); i++)
502 {
503 const auto& ghost_element = *partition.ghost_elements[i];
504 if (!cell_visited[ghost_element.getID()])
505 {
506 cell_visited[ghost_element.getID()] = true;
507 partition.duplicate_ghost_cell[i] = false;
508 }
509 }
510 }
511}

References MeshLib::Mesh::getElements().

Referenced by partitionMesh().

◆ partitionLookup()

std::size_t ApplicationUtils::partitionLookup ( std::size_t const & node_id,
std::vector< std::size_t > const & partition_ids,
std::vector< std::size_t > const & node_id_mapping )

Definition at line 105 of file NodeWiseMeshPartitioner.cpp.

108{
109 return partition_ids[node_id_mapping[node_id]];
110}

Referenced by findGhostNodesInPartition().

◆ partitionMesh()

void ApplicationUtils::partitionMesh ( std::vector< Partition > & partitions,
MeshLib::Mesh const & mesh,
std::vector< std::size_t > const & nodes_partition_ids,
std::vector< std::size_t > const & bulk_node_ids )

Definition at line 688 of file NodeWiseMeshPartitioner.cpp.

692{
693 BaseLib::RunTime run_timer;
694 run_timer.start();
695 auto const partition_ids_per_element = computePartitionIDPerElement(
696 nodes_partition_ids, mesh.getElements(), bulk_node_ids);
697 INFO("partitionMesh(): Partition IDs per element computed in {:g} s",
698 run_timer.elapsed());
699
700 run_timer.start();
701 distributeNodesToPartitions(partitions, nodes_partition_ids,
702 mesh.getNodes(), bulk_node_ids);
703 INFO("partitionMesh(): distribute nodes to partitions took {:g} s",
704 run_timer.elapsed());
705
706 run_timer.start();
708 INFO(
709 "partitionMesh(): sorting [base nodes | higher order nodes] took {:g} "
710 "s",
711 run_timer.elapsed());
712
713 run_timer.start();
714 setNumberOfNodesInPartitions(partitions, mesh);
715 INFO(
716 "partitionMesh(): setting number of nodes and of all mesh base nodes "
717 "took {:g} s",
718 run_timer.elapsed());
719
720 run_timer.start();
721 distributeElementsIntoPartitions(partitions, mesh,
722 partition_ids_per_element);
723 INFO("partitionMesh(): distribute elements into partitions took {:g} s",
724 run_timer.elapsed());
725
726 run_timer.start();
728 partitions, mesh, nodes_partition_ids, bulk_node_ids);
729 INFO("partitionMesh(): determine / append ghost nodes took {:g} s",
730 run_timer.elapsed());
731
732 run_timer.start();
733 markDuplicateGhostCells(mesh, partitions);
734 INFO("partitionMesh(): markDuplicateGhostCells took {:g} s",
735 run_timer.elapsed());
736}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
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
void distributeNodesToPartitions(std::vector< Partition > &partitions, std::vector< std::size_t > const &nodes_partition_ids, std::vector< MeshLib::Node * > const &nodes, std::vector< std::size_t > const &bulk_node_ids)
void reorderNodesIntoBaseAndHigherOrderNodesPerPartition(std::vector< Partition > &partitions, MeshLib::Mesh const &mesh)
void setNumberOfNodesInPartitions(std::vector< Partition > &partitions, MeshLib::Mesh const &mesh)
void determineAndAppendGhostNodesToPartitions(std::vector< Partition > &partitions, MeshLib::Mesh const &mesh, std::vector< std::size_t > const &nodes_partition_ids, std::vector< std::size_t > const &node_id_mapping)
void markDuplicateGhostCells(MeshLib::Mesh const &mesh, std::vector< Partition > &partitions)
void distributeElementsIntoPartitions(std::vector< Partition > &partitions, MeshLib::Mesh const &mesh, std::vector< std::vector< std::size_t > > const &partition_ids_per_element)
std::vector< std::vector< std::size_t > > computePartitionIDPerElement(std::vector< std::size_t > const &node_partition_map, std::vector< MeshLib::Element * > const &elements, std::vector< std::size_t > const &bulk_node_ids)

References computePartitionIDPerElement(), determineAndAppendGhostNodesToPartitions(), distributeElementsIntoPartitions(), distributeNodesToPartitions(), BaseLib::RunTime::elapsed(), MeshLib::Mesh::getElements(), MeshLib::Mesh::getNodes(), INFO(), markDuplicateGhostCells(), reorderNodesIntoBaseAndHigherOrderNodesPerPartition(), setNumberOfNodesInPartitions(), and BaseLib::RunTime::start().

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::partitionByMETIS(), and ApplicationUtils::NodeWiseMeshPartitioner::partitionOtherMesh().

◆ partitionProperties()

MeshLib::Properties ApplicationUtils::partitionProperties ( std::unique_ptr< MeshLib::Mesh > const & mesh,
std::vector< Partition > & partitions )

Partition existing properties and add vtkGhostType cell data array property.

Creates partitioned mesh properties for nodes and cells.

Definition at line 437 of file NodeWiseMeshPartitioner.cpp.

440{
441 using namespace MeshLib;
442
443 MeshLib::Properties const& properties = mesh->getProperties();
444
445 // Count the number of integration point data of all partitions:
446 setIntegrationPointNumberOfPartition(properties, partitions);
447
448 Properties partitioned_properties;
449 auto count_tuples = [&](MeshItemType const mesh_item_type)
450 {
451 return std::accumulate(
452 begin(partitions), end(partitions), 0,
453 [&](std::size_t const sum, Partition const& p)
454 { return sum + p.numberOfMeshItems(mesh_item_type); });
455 };
456
457 std::map<MeshItemType, std::size_t> const total_number_of_tuples = {
458 {MeshItemType::Cell, count_tuples(MeshItemType::Cell)},
459 {MeshItemType::Node, count_tuples(MeshItemType::Node)},
460 {MeshItemType::IntegrationPoint,
461 count_tuples(MeshItemType::IntegrationPoint)}};
462
463 DBUG(
464 "total number of tuples after partitioning defined for cells is {:d} "
465 "and for nodes {:d} and for integration points {:d}.",
466 total_number_of_tuples.at(MeshItemType::Cell),
467 total_number_of_tuples.at(MeshItemType::Node),
468 total_number_of_tuples.at(MeshItemType::IntegrationPoint));
469
470 // 1 create new PV
471 // 2 resize the PV with total_number_of_tuples
472 // 3 copy the values according to the partition info
474 properties,
475 [&](auto type, auto const property)
476 {
477 return copyPropertyVector<decltype(type)>(
478 mesh->getElements(), partitioned_properties, properties,
479 partitions,
480 dynamic_cast<PropertyVector<decltype(type)> const*>(property),
481 total_number_of_tuples);
482 });
483
484 addVtkGhostTypeProperty(partitioned_properties,
485 partitions,
486 total_number_of_tuples.at(MeshItemType::Cell));
487
488 return partitioned_properties;
489}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void applyToPropertyVectors(Properties const &properties, Function f)
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition Properties.h:36
void addVtkGhostTypeProperty(MeshLib::Properties &partitioned_properties, std::vector< Partition > const &partitions, std::size_t const total_number_of_cells)
void setIntegrationPointNumberOfPartition(MeshLib::Properties const &properties, std::vector< Partition > &partitions)
MeshItemType
Definition Location.h:21

References addVtkGhostTypeProperty(), applyToPropertyVectors(), DBUG(), and setIntegrationPointNumberOfPartition().

Referenced by main(), and ApplicationUtils::NodeWiseMeshPartitioner::partitionByMETIS().

◆ readMetisData()

std::vector< std::size_t > ApplicationUtils::readMetisData ( const std::string & file_name_base,
long number_of_partitions,
std::size_t number_of_nodes )

Read metis data

Parameters
file_name_baseThe prefix of the filename.
number_of_partitionsThe number is used to compose the full filename and forms the postfix.
number_of_nodesExpected/required number of nodes to be read.

Definition at line 45 of file Metis.cpp.

48{
49 const std::string npartitions_str = std::to_string(number_of_partitions);
50
51 // Read partitioned mesh data from METIS
52 const std::string fname_parts =
53 file_name_base + ".mesh.npart." + npartitions_str;
54
55 std::ifstream npart_in(fname_parts);
56 if (!npart_in.is_open())
57 {
59 "Error: cannot open file {:s}. It may not exist!\n"
60 "Run mpmetis beforehand or use option -m",
61 fname_parts.data());
62 }
63
64 std::vector<std::size_t> partition_ids(number_of_nodes);
65
66 std::size_t counter = 0;
67 while (!npart_in.eof())
68 {
69 npart_in >> partition_ids[counter++] >> std::ws;
70 if (counter == number_of_nodes)
71 {
72 break;
73 }
74 }
75
76 if (npart_in.bad())
77 {
78 OGS_FATAL("Error while reading file {:s}.", fname_parts.data());
79 }
80
81 if (counter != number_of_nodes)
82 {
83 OGS_FATAL("Error: data in {:s} are less than expected.",
84 fname_parts.data());
85 }
86
87 return partition_ids;
88}

References OGS_FATAL.

Referenced by main().

◆ removeMetisPartitioningFiles()

void ApplicationUtils::removeMetisPartitioningFiles ( std::string const & file_name_base,
long number_of_partitions )

Removes the F.mesh.npart.P and F.mesh.epart.P files, where F is file name base and P is the number of partitions.

Definition at line 90 of file Metis.cpp.

92{
93 const std::string npartitions_str = std::to_string(number_of_partitions);
94
95 std::remove((file_name_base + ".mesh.npart." + npartitions_str).c_str());
96 std::remove((file_name_base + ".mesh.epart." + npartitions_str).c_str());
97}

Referenced by main().

◆ reorderNodesIntoBaseAndHigherOrderNodes()

void ApplicationUtils::reorderNodesIntoBaseAndHigherOrderNodes ( Partition & partition,
MeshLib::Mesh const & mesh )

Definition at line 591 of file NodeWiseMeshPartitioner.cpp.

593{
594 std::vector<MeshLib::Node const*> higher_order_nodes;
595 // after splitIntoBaseAndHigherOrderNodes() partition.nodes contains only
596 // base nodes
597 std::tie(partition.nodes, higher_order_nodes) =
599 partition.number_of_regular_base_nodes = partition.nodes.size();
600 std::copy(begin(higher_order_nodes), end(higher_order_nodes),
601 std::back_inserter(partition.nodes));
602 partition.number_of_regular_nodes = partition.nodes.size();
603}
std::pair< std::vector< MeshLib::Node const * >, std::vector< MeshLib::Node const * > > splitIntoBaseAndHigherOrderNodes(std::vector< MeshLib::Node const * > const &nodes, MeshLib::Mesh const &mesh)
std::vector< MeshLib::Node const * > nodes
nodes.

References ApplicationUtils::Partition::nodes, ApplicationUtils::Partition::number_of_regular_base_nodes, ApplicationUtils::Partition::number_of_regular_nodes, and splitIntoBaseAndHigherOrderNodes().

Referenced by reorderNodesIntoBaseAndHigherOrderNodesPerPartition().

◆ reorderNodesIntoBaseAndHigherOrderNodesPerPartition()

void ApplicationUtils::reorderNodesIntoBaseAndHigherOrderNodesPerPartition ( std::vector< Partition > & partitions,
MeshLib::Mesh const & mesh )

Definition at line 605 of file NodeWiseMeshPartitioner.cpp.

607{
608 for (auto& partition : partitions)
609 {
611 }
612}
void reorderNodesIntoBaseAndHigherOrderNodes(Partition &partition, MeshLib::Mesh const &mesh)

References reorderNodesIntoBaseAndHigherOrderNodes().

Referenced by partitionMesh().

◆ setIntegrationPointNumberOfPartition()

void ApplicationUtils::setIntegrationPointNumberOfPartition ( MeshLib::Properties const & properties,
std::vector< Partition > & partitions )

Definition at line 287 of file NodeWiseMeshPartitioner.cpp.

289{
290 for (auto const& [name, property] : properties)
291 {
292 auto const item_type = property->getMeshItemType();
293
295 {
296 continue;
297 }
298
299 // For special field data such as OGS_VERSION, IntegrationPointMetaData,
300 // etc., which are not "real" integration points:
301 if (property->getPropertyName().find("_ip") == std::string::npos)
302 {
303 continue;
304 }
305
306 std::string const property_name = property->getPropertyName();
307 auto countIntegrationPoints =
308 [&](std::vector<const MeshLib::Element*> const& elements)
309 {
310 auto const ip_meta_data =
311 MeshLib::getIntegrationPointMetaData(properties, property_name);
312 std::size_t counter = 0;
313 for (auto const element : elements)
314 {
315 int const number_of_integration_points =
317 ip_meta_data, *element);
318 counter += number_of_integration_points;
319 }
320 return counter;
321 };
322
323 for (auto& p : partitions)
324 {
325 p.number_of_integration_points =
326 countIntegrationPoints(p.regular_elements) +
327 countIntegrationPoints(p.ghost_elements);
328 }
329 return;
330 }
331}

References MeshLib::getIntegrationPointMetaData(), MeshToolsLib::getNumberOfElementIntegrationPoints(), and MeshLib::IntegrationPoint.

Referenced by partitionProperties().

◆ setNumberOfNodesInPartitions()

void ApplicationUtils::setNumberOfNodesInPartitions ( std::vector< Partition > & partitions,
MeshLib::Mesh const & mesh )

Definition at line 614 of file NodeWiseMeshPartitioner.cpp.

616{
617 auto const number_of_mesh_base_nodes = mesh.computeNumberOfBaseNodes();
618 auto const number_of_mesh_all_nodes = mesh.getNumberOfNodes();
619 for (auto& partition : partitions)
620 {
621 partition.number_of_regular_nodes = partition.nodes.size();
622 partition.number_of_mesh_base_nodes = number_of_mesh_base_nodes;
623 partition.number_of_mesh_all_nodes = number_of_mesh_all_nodes;
624 }
625}

References MeshLib::Mesh::computeNumberOfBaseNodes(), and MeshLib::Mesh::getNumberOfNodes().

Referenced by partitionMesh().

◆ splitIntoBaseAndHigherOrderNodes()

std::pair< std::vector< MeshLib::Node const * >, std::vector< MeshLib::Node const * > > ApplicationUtils::splitIntoBaseAndHigherOrderNodes ( std::vector< MeshLib::Node const * > const & nodes,
MeshLib::Mesh const & mesh )

Definition at line 113 of file NodeWiseMeshPartitioner.cpp.

115{
116 // Space for resulting vectors.
117 std::vector<MeshLib::Node const*> base_nodes;
118 // if linear mesh, then one reallocation, no realloc for higher order
119 // elements meshes.
120 base_nodes.reserve(nodes.size() / 2);
121 std::vector<MeshLib::Node const*> higher_order_nodes;
122 // if linear mesh, then wasted space, good estimate for quadratic
123 // order mesh, and realloc needed for higher order element meshes.
124 higher_order_nodes.reserve(nodes.size() / 2);
125
126 // Split the nodes into base nodes and extra nodes.
127 std::partition_copy(
128 begin(nodes), end(nodes), std::back_inserter(base_nodes),
129 std::back_inserter(higher_order_nodes),
130 [&](MeshLib::Node const* const n)
131 { return isBaseNode(*n, mesh.getElementsConnectedToNode(*n)); });
132
133 return {base_nodes, higher_order_nodes};
134}

References MeshLib::Mesh::getElementsConnectedToNode().

Referenced by reorderNodesIntoBaseAndHigherOrderNodes().

◆ writeConfigData()

std::tuple< std::vector< long >, std::vector< long > > ApplicationUtils::writeConfigData ( const std::string & file_name_base,
std::vector< Partition > const & partitions )

Write the configuration data of the partition data in binary files.

Returns
a pair of vectors for:
  1. The number of all non-ghost element integer variables for each partition.
  2. The number of all ghost element integer variables for each partition.

Definition at line 1062 of file NodeWiseMeshPartitioner.cpp.

1064{
1065 auto const file_name_cfg = file_name_base + "_partitioned_msh_cfg" +
1066 std::to_string(partitions.size()) + ".bin";
1067 std::ofstream of_bin_cfg(file_name_cfg, std::ios::binary);
1068 if (!of_bin_cfg)
1069 {
1070 OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
1071 }
1072
1073 std::vector<long> partitions_element_offsets;
1074 partitions_element_offsets.reserve(partitions.size());
1075 std::vector<long> partitions_ghost_element_offsets;
1076 partitions_ghost_element_offsets.reserve(partitions.size());
1077
1078 ConfigOffsets config_offsets = {0, 0, 0}; // 0 for first partition.
1079 for (const auto& partition : partitions)
1080 {
1081 partition.writeConfig(of_bin_cfg);
1082
1083 config_offsets.writeConfig(of_bin_cfg);
1084 auto const& partition_offsets = computePartitionOffsets(partition);
1085 config_offsets =
1086 incrementConfigOffsets(config_offsets, partition_offsets);
1087
1088 partitions_element_offsets.push_back(
1089 partition_offsets.regular_elements);
1090 partitions_ghost_element_offsets.push_back(
1091 partition_offsets.ghost_elements);
1092 }
1093
1094 return std::make_tuple(partitions_element_offsets,
1095 partitions_ghost_element_offsets);
1096}
ConfigOffsets incrementConfigOffsets(ConfigOffsets const &oldConfig, PartitionOffsets const &offsets)
PartitionOffsets computePartitionOffsets(Partition const &partition)

References computePartitionOffsets(), incrementConfigOffsets(), OGS_FATAL, and ApplicationUtils::ConfigOffsets::writeConfig().

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::write(), and ApplicationUtils::NodeWiseMeshPartitioner::writeOtherMesh().

◆ writeElements()

void ApplicationUtils::writeElements ( std::string const & file_name_base,
std::vector< Partition > const & partitions,
std::vector< long > const & regular_element_offsets,
std::vector< long > const & ghost_element_offsets )

Write the element integer variables of all partitions into binary files.

Parameters
file_name_baseThe prefix of the file name.
partitionsPartitions vector.
regular_element_offsetsThe numbers of all non-ghost element integer variables of each partitions.
ghost_element_offsetsThe numbers of all ghost element

Definition at line 1146 of file NodeWiseMeshPartitioner.cpp.

1150{
1151 const std::string npartitions_str = std::to_string(partitions.size());
1152
1153 auto const file_name_ele =
1154 file_name_base + "_partitioned_msh_ele" + npartitions_str + ".bin";
1155 std::ofstream element_info_os(file_name_ele, std::ios::binary);
1156 if (!element_info_os)
1157 {
1158 OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele);
1159 }
1160
1161 auto const file_name_ele_g =
1162 file_name_base + "_partitioned_msh_ele_g" + npartitions_str + ".bin";
1163 std::ofstream ghost_element_info_os(file_name_ele_g, std::ios::binary);
1164 if (!ghost_element_info_os)
1165 {
1166 OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele_g);
1167 }
1168
1169 for (std::size_t i = 0; i < partitions.size(); i++)
1170 {
1171 const auto& partition = partitions[i];
1172 auto const local_node_ids = enumerateLocalNodeIds(partition.nodes);
1173
1174 // Vector containing the offsets of the regular elements of this
1175 // partition
1176 std::vector<long> ele_info(regular_element_offsets[i]);
1177
1178 auto writeElementData =
1179 [&local_node_ids](
1180 std::vector<MeshLib::Element const*> const& elements,
1181 long const element_offsets,
1182 std::ofstream& output_stream)
1183 {
1184 long counter = elements.size();
1185 std::vector<long> ele_info(element_offsets);
1186
1187 for (std::size_t j = 0; j < elements.size(); j++)
1188 {
1189 const auto* elem = elements[j];
1190 ele_info[j] = counter;
1191 getElementIntegerVariables(*elem, local_node_ids, ele_info,
1192 counter);
1193 }
1194 // Write vector data of regular elements
1195 output_stream.write(reinterpret_cast<const char*>(ele_info.data()),
1196 ele_info.size() * sizeof(long));
1197 };
1198
1199 // regular elements.
1200 writeElementData(partition.regular_elements, regular_element_offsets[i],
1201 element_info_os);
1202 // Ghost elements
1203 writeElementData(partition.ghost_elements, ghost_element_offsets[i],
1204 ghost_element_info_os);
1205 }
1206}
std::unordered_map< std::size_t, long > enumerateLocalNodeIds(std::vector< MeshLib::Node const * > const &nodes)
Generates a mapping of given node ids to a new local (renumbered) node ids.
void getElementIntegerVariables(const MeshLib::Element &elem, const std::unordered_map< std::size_t, long > &local_node_ids, std::vector< long > &elem_info, long &counter)

References enumerateLocalNodeIds(), getElementIntegerVariables(), and OGS_FATAL.

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::write(), and ApplicationUtils::NodeWiseMeshPartitioner::writeOtherMesh().

◆ writeMETIS()

void ApplicationUtils::writeMETIS ( std::vector< MeshLib::Element * > const & elements,
const std::string & file_name )

Write elements as METIS graph file

Parameters
elementsThe mesh elements.
file_nameFile name with an extension of mesh.

Definition at line 19 of file Metis.cpp.

21{
22 std::ofstream os(file_name, std::ios::trunc);
23 if (!os.is_open())
24 {
25 OGS_FATAL("Error: cannot open file {:s}.", file_name.data());
26 }
27
28 if (!os.good())
29 {
30 OGS_FATAL("Error: Cannot write in file {:s}.", file_name.data());
31 }
32
33 os << elements.size() << " \n";
34 for (const auto* elem : elements)
35 {
36 os << getNodeIndex(*elem, 0) + 1;
37 for (unsigned j = 1; j < elem->getNumberOfNodes(); j++)
38 {
39 os << " " << getNodeIndex(*elem, j) + 1;
40 }
41 os << "\n";
42 }
43}
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:219

References OGS_FATAL.

Referenced by main().

◆ writeNodes()

void ApplicationUtils::writeNodes ( const std::string & file_name_base,
std::vector< Partition > const & partitions,
std::vector< std::size_t > const & global_node_ids )

Write the nodes of all partitions into a binary file.

Parameters
file_name_baseThe prefix of the file name.
partitionsthe list of partitions
global_node_idsglobal numbering of nodes

Definition at line 1212 of file NodeWiseMeshPartitioner.cpp.

1215{
1216 auto const file_name = file_name_base + "_partitioned_msh_nod" +
1217 std::to_string(partitions.size()) + ".bin";
1218 std::ofstream os(file_name, std::ios::binary);
1219 if (!os)
1220 {
1221 OGS_FATAL("Could not open file '{:s}' for output.", file_name);
1222 }
1223
1224 for (const auto& partition : partitions)
1225 {
1226 partition.writeNodes(os, global_node_ids);
1227 }
1228}

References OGS_FATAL.

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::write(), and ApplicationUtils::NodeWiseMeshPartitioner::writeOtherMesh().

◆ writeProperties()

void ApplicationUtils::writeProperties ( const std::string & file_name_base,
MeshLib::Properties const & partitioned_properties,
std::vector< Partition > const & partitions,
MeshLib::MeshItemType const mesh_item_type )

Definition at line 945 of file NodeWiseMeshPartitioner.cpp.

949{
950 auto const number_of_properties =
951 partitioned_properties.size(mesh_item_type);
952 if (number_of_properties == 0)
953 {
954 return;
955 }
956
957 auto const file_name_infix = toString(mesh_item_type);
958
959 auto const file_name_cfg = file_name_base + "_partitioned_" +
960 file_name_infix + "_properties_cfg" +
961 std::to_string(partitions.size()) + ".bin";
962 std::ofstream out(file_name_cfg, std::ios::binary);
963 if (!out)
964 {
965 OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
966 }
967
968 auto const file_name_val = file_name_base + "_partitioned_" +
969 file_name_infix + "_properties_val" +
970 std::to_string(partitions.size()) + ".bin";
971 std::ofstream out_val(file_name_val, std::ios::binary);
972 if (!out_val)
973 {
974 OGS_FATAL("Could not open file '{:s}' for output.", file_name_val);
975 }
976
977 BaseLib::writeValueBinary(out, number_of_properties);
978
980 partitioned_properties,
981 [&](auto type, auto const& property)
982 {
983 return writePropertyVector<decltype(type)>(
984 dynamic_cast<MeshLib::PropertyVector<decltype(type)> const*>(
985 property),
986 mesh_item_type, out_val, out);
987 });
988
989 unsigned long offset = 0;
990 for (const auto& partition : partitions)
991 {
993 offset, static_cast<unsigned long>(
994 partition.numberOfMeshItems(mesh_item_type))};
995 DBUG(
996 "Write meta data for node-based PropertyVector: global offset "
997 "{:d}, number of tuples {:d}",
998 pvpmd.offset, pvpmd.number_of_tuples);
1000 offset += pvpmd.number_of_tuples;
1001 }
1002}
void writeValueBinary(std::ostream &out, T const &val)
write value as binary into the given output stream
void writePropertyVectorPartitionMetaData(std::ostream &os, PropertyVectorPartitionMetaData const &pvpmd)

References applyToPropertyVectors(), DBUG(), OGS_FATAL, MeshLib::Properties::size(), MeshLib::IO::writePropertyVectorPartitionMetaData(), and BaseLib::writeValueBinary().

Referenced by ApplicationUtils::NodeWiseMeshPartitioner::write(), and ApplicationUtils::NodeWiseMeshPartitioner::writeOtherMesh().

◆ writePropertyVector()

template<typename T >
bool ApplicationUtils::writePropertyVector ( MeshLib::PropertyVector< T > const *const pv,
MeshLib::MeshItemType const mesh_item_type,
std::ostream & out_val,
std::ostream & out_meta )

Definition at line 920 of file NodeWiseMeshPartitioner.cpp.

923{
924 if (pv == nullptr)
925 {
926 return false;
927 }
928 // skip property of different mesh item type. Return true, because this
929 // operation was successful.
930 if (pv->getMeshItemType() != mesh_item_type)
931 {
932 return true;
933 }
934
936 pvmd.property_name = pv->getPropertyName();
940 writePropertyVectorValues(out_val, *pv);
942 return true;
943}
std::size_t getNumberOfTuples() const
void writePropertyVectorValues(std::ostream &os, MeshLib::PropertyVector< T > const &pv)
void writePropertyVectorMetaData(std::ostream &os, PropertyVectorMetaData const &pvmd)

References MeshLib::IO::PropertyVectorMetaData::fillPropertyVectorMetaDataTypeInfo(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::PropertyVector< PROP_VAL_TYPE >::getNumberOfTuples(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::IO::PropertyVectorMetaData::number_of_components, MeshLib::IO::PropertyVectorMetaData::number_of_tuples, MeshLib::IO::PropertyVectorMetaData::property_name, MeshLib::IO::writePropertyVectorMetaData(), and writePropertyVectorValues().

◆ writePropertyVectorValues()

template<typename T >
void ApplicationUtils::writePropertyVectorValues ( std::ostream & os,
MeshLib::PropertyVector< T > const & pv )

Definition at line 913 of file NodeWiseMeshPartitioner.cpp.

915{
916 os.write(reinterpret_cast<const char*>(pv.data()), pv.size() * sizeof(T));
917}

References MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by writePropertyVector().