OGS
ApplicationUtils Namespace Reference

Classes

struct  ConfigOffsets
 
struct  NodeStruct
 
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 nodeIdBulkMesh (MeshLib::Node const &node, std::vector< std::size_t > const *node_id_mapping=nullptr)
 
std::size_t partitionLookup (MeshLib::Node const &node, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const *node_id_mapping=nullptr)
 
std::pair< std::vector< MeshLib::Node * >, std::vector< MeshLib::Node * > > findRegularNodesInPartition (std::size_t const part_id, std::vector< MeshLib::Node * > const &nodes, std::vector< std::size_t > const &partition_ids, MeshLib::Mesh const &mesh, std::vector< std::size_t > const *node_id_mapping=nullptr)
 
std::ptrdiff_t numberOfRegularNodes (MeshLib::Element const &e, std::size_t const part_id, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const *node_id_mapping=nullptr)
 
std::tuple< std::vector< MeshLib::Element const * >, std::vector< MeshLib::Element const * > > findElementsInPartition (std::size_t const part_id, std::vector< MeshLib::Element * > const &elements, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const *node_id_mapping=nullptr)
 
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=nullptr)
 
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 >
bool copyPropertyVector (MeshLib::Properties &partitioned_properties, std::vector< Partition > const &partitions, MeshLib::PropertyVector< T > const *const pv, std::map< MeshLib::MeshItemType, std::size_t > const &total_number_of_tuples)
 
template<typename Function >
void applyToPropertyVectors (MeshLib::Properties const &properties, Function f)
 
void addVtkGhostTypeProperty (MeshLib::Properties &partitioned_properties, std::vector< Partition > const &partitions, std::size_t const total_number_of_cells)
 
MeshLib::Properties partitionProperties (MeshLib::Properties const &properties, std::vector< Partition > const &partitions)
 Partition existing properties and add vtkGhostType cell data array property. More...
 
void markDuplicateGhostCells (MeshLib::Mesh const &mesh, std::vector< Partition > &partitions)
 
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 &nodes)
 Generates a mapping of given node ids to a new local (renumbered) node ids. More...
 
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 440 of file NodeWiseMeshPartitioner.cpp.

443{
444 auto* vtk_ghost_type =
445 partitioned_properties.createNewPropertyVector<unsigned char>(
446 "vtkGhostType", MeshLib::MeshItemType::Cell);
447 if (vtk_ghost_type == nullptr)
448 {
449 OGS_FATAL("Could not create vtkGhostType cell data array.");
450 }
451
452 vtk_ghost_type->resize(total_number_of_cells);
453 std::size_t offset = 0;
454 for (auto const& partition : partitions)
455 {
456 offset += partition.regular_elements.size();
457 for (std::size_t i = 0; i < partition.ghost_elements.size(); ++i)
458 {
459 if (partition.duplicate_ghost_cell[i])
460 {
461 (*vtk_ghost_type)[offset + i] |=
462 vtkDataSetAttributes::DUPLICATECELL;
463 }
464 }
465 offset += partition.ghost_elements.size();
466 }
467}
#define OGS_FATAL(...)
Definition: Error.h:26
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)

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

Referenced by partitionProperties().

◆ applyToPropertyVectors()

template<typename Function >
void ApplicationUtils::applyToPropertyVectors ( MeshLib::Properties const &  properties,
Function  f 
)

Applies a function of the form f(type, name) -> bool for each of the properties names. The type argument is used to call f<decltype(type)>(name). At least one of the functions must return the 'true' value, but at most one is executed.

Definition at line 417 of file NodeWiseMeshPartitioner.cpp.

418{
419 for (auto [name, property] : properties)
420 {
421 // Open question, why is the 'unsigned long' case not compiling giving
422 // an error "expected '(' for function-style cast or type construction"
423 // with clang-7, and "error C4576: a parenthesized type followed by an
424 // initializer list is a non-standard explicit type conversion syntax"
425 // with MSVC-15.
426 bool success = f(double{}, property) || f(float{}, property) ||
427 f(int{}, property) || f(long{}, property) ||
428 f(unsigned{}, property) || f(long{}, property) ||
429 f(static_cast<unsigned long>(0), property) ||
430 f(std::size_t{}, property) || f(char{}, property) ||
431 f(static_cast<unsigned char>(0), property);
432 if (!success)
433 {
434 OGS_FATAL("Could not apply function to PropertyVector '{:s}'.",
435 property->getPropertyName());
436 }
437 }
438}

References MaterialPropertyLib::name, and OGS_FATAL.

Referenced by partitionProperties(), and writeProperties().

◆ computePartitionOffsets()

PartitionOffsets ApplicationUtils::computePartitionOffsets ( Partition const &  partition)

Definition at line 839 of file NodeWiseMeshPartitioner.cpp.

840{
841 return {static_cast<long>(partition.nodes.size()),
842 static_cast<long>(partition.regular_elements.size() +
844 partition.regular_elements)),
845 static_cast<long>(partition.ghost_elements.size() +
847 partition.ghost_elements))};
848}
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 333 of file NodeWiseMeshPartitioner.cpp.

338{
339 std::size_t const n_regular(p.regular_elements.size());
340 auto const n_components = pv.getNumberOfGlobalComponents();
341 for (std::size_t i = 0; i < n_regular; ++i)
342 {
343 const auto id = p.regular_elements[i]->getID();
344 std::copy_n(&pv[n_components * id], n_components,
345 &partitioned_pv[offset + n_components * i]);
346 }
347
348 std::size_t const n_ghost(p.ghost_elements.size());
349 for (std::size_t i = 0; i < n_ghost; ++i)
350 {
351 const auto id = p.ghost_elements[i]->getID();
352 std::copy_n(&pv[n_components * id], n_components,
353 &partitioned_pv[offset + n_components * (n_regular + i)]);
354 }
355 return n_components * (n_regular + n_ghost);
356}
int getNumberOfGlobalComponents() const
static const double p

References MeshLib::PropertyVectorBase::getNumberOfGlobalComponents().

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 311 of file NodeWiseMeshPartitioner.cpp.

316{
317 auto const& nodes = p.nodes;
318 auto const nnodes = nodes.size();
319 auto const n_components = pv.getNumberOfGlobalComponents();
320 for (std::size_t i = 0; i < nnodes; ++i)
321 {
322 const auto global_id = nodes[i]->getID();
323 std::copy_n(&pv[n_components * global_id], n_components,
324 &partitioned_pv[offset + n_components * i]);
325 }
326 return n_components * nnodes;
327}

References MeshLib::PropertyVectorBase::getNumberOfGlobalComponents().

Referenced by copyPropertyVector().

◆ copyPropertyVector()

template<typename T >
bool ApplicationUtils::copyPropertyVector ( MeshLib::Properties partitioned_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 359 of file NodeWiseMeshPartitioner.cpp.

364{
365 if (pv == nullptr)
366 {
367 return false;
368 }
369 auto const item_type = pv->getMeshItemType();
370
372 {
373 return true; // Skip integration point data. Requires parsing of json
374 // for the integration point data. Return true, because
375 // the property was "successfully" parsed.
376 }
377
378 auto partitioned_pv = partitioned_properties.createNewPropertyVector<T>(
379 pv->getPropertyName(), pv->getMeshItemType(),
381 partitioned_pv->resize(total_number_of_tuples.at(item_type) *
383
384 auto copy_property_vector_values =
385 [&](Partition const& p, std::size_t offset)
386 {
387 if (item_type == MeshLib::MeshItemType::Node)
388 {
389 return copyNodePropertyVectorValues(p, offset, *pv,
390 *partitioned_pv);
391 }
392 if (item_type == MeshLib::MeshItemType::Cell)
393 {
394 return copyCellPropertyVectorValues(p, offset, *pv,
395 *partitioned_pv);
396 }
397 OGS_FATAL(
398 "Copying of property vector values for mesh item type {:s} is not "
399 "implemented.",
400 item_type);
401 };
402
403 std::size_t position_offset(0);
404 for (auto p : partitions)
405 {
406 position_offset += copy_property_vector_values(p, position_offset);
407 }
408 return true;
409}
MeshItemType getMeshItemType() const
std::string const & getPropertyName() 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 copyNodePropertyVectorValues(Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)

References MeshLib::Cell, copyCellPropertyVectorValues(), copyNodePropertyVectorValues(), MeshLib::Properties::createNewPropertyVector(), MeshLib::PropertyVectorBase::getMeshItemType(), MeshLib::PropertyVectorBase::getNumberOfGlobalComponents(), MeshLib::PropertyVectorBase::getPropertyName(), MeshLib::IntegrationPoint, MeshLib::Node, and OGS_FATAL.

◆ enumerateLocalNodeIds()

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

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

Definition at line 936 of file NodeWiseMeshPartitioner.cpp.

938{
939 std::unordered_map<std::size_t, long> local_ids;
940 local_ids.reserve(nodes.size());
941
942 long local_node_id = 0;
943 for (const auto* node : nodes)
944 {
945 local_ids[node->getID()] = local_node_id++;
946 }
947 return local_ids;
948}

Referenced by writeElements().

◆ findElementsInPartition()

std::tuple< std::vector< MeshLib::Element const * >, std::vector< MeshLib::Element const * > > ApplicationUtils::findElementsInPartition ( std::size_t const  part_id,
std::vector< MeshLib::Element * > const &  elements,
std::vector< std::size_t > const &  partition_ids,
std::vector< std::size_t > const *  node_id_mapping = nullptr 
)

1 find elements belonging to the partition part_id: fills vector partition.regular_elements 2 find ghost elements belonging to the partition part_id fills vector partition.ghost_elements

Definition at line 189 of file NodeWiseMeshPartitioner.cpp.

194{
195 std::vector<MeshLib::Element const*> regular_elements;
196 std::vector<MeshLib::Element const*> ghost_elements;
197
198 for (auto elem : elements)
199 {
200 auto const regular_nodes = numberOfRegularNodes(
201 *elem, part_id, partition_ids, node_id_mapping);
202
203 if (regular_nodes == 0)
204 {
205 continue;
206 }
207
208 if (regular_nodes ==
209 static_cast<std::ptrdiff_t>(elem->getNumberOfNodes()))
210 {
211 regular_elements.push_back(elem);
212 }
213 else
214 {
215 ghost_elements.push_back(elem);
216 }
217 }
218 return std::tuple<std::vector<MeshLib::Element const*>,
219 std::vector<MeshLib::Element const*>>{regular_elements,
220 ghost_elements};
221}
std::ptrdiff_t numberOfRegularNodes(MeshLib::Element const &e, std::size_t const part_id, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const *node_id_mapping=nullptr)

References numberOfRegularNodes().

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

◆ 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 = nullptr 
)

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

Definition at line 228 of file NodeWiseMeshPartitioner.cpp.

235{
236 std::vector<MeshLib::Node*> base_nodes;
237 std::vector<MeshLib::Node*> ghost_nodes;
238
239 std::vector<bool> is_ghost_node(nodes.size(), false);
240 for (const auto* ghost_elem : ghost_elements)
241 {
242 for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++)
243 {
244 auto const& n = ghost_elem->getNode(i);
245 if (is_ghost_node[n->getID()])
246 {
247 continue;
248 }
249
250 if (partitionLookup(*n, partition_ids, node_id_mapping) != part_id)
251 {
252 if (isBaseNode(*n, mesh.getElementsConnectedToNode(*n)))
253 {
254 base_nodes.push_back(nodes[n->getID()]);
255 }
256 else
257 {
258 ghost_nodes.push_back(nodes[n->getID()]);
259 }
260 is_ghost_node[n->getID()] = true;
261 }
262 }
263 }
264 return std::tuple<std::vector<MeshLib::Node*>, std::vector<MeshLib::Node*>>{
265 base_nodes, ghost_nodes};
266}
std::size_t partitionLookup(MeshLib::Node const &node, std::vector< std::size_t > const &partition_ids, std::vector< std::size_t > const *node_id_mapping=nullptr)
bool isBaseNode(Node const &node, std::vector< Element const * > const &elements_connected_to_node)
Definition: Mesh.cpp:365

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

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

◆ findRegularNodesInPartition()

std::pair< std::vector< MeshLib::Node * >, std::vector< MeshLib::Node * > > ApplicationUtils::findRegularNodesInPartition ( std::size_t const  part_id,
std::vector< MeshLib::Node * > const &  nodes,
std::vector< std::size_t > const &  partition_ids,
MeshLib::Mesh const &  mesh,
std::vector< std::size_t > const *  node_id_mapping = nullptr 
)

1 copy pointers to nodes belonging to the partition part_id into base nodes vector, and 2 collect non-linear element nodes belonging to the partition part_id in extra nodes vector. If node_id_mapping is given, it will be used to map the mesh node ids to other ids; used by boundary meshes, for example.

Returns
a pair of base node and extra nodes.

Definition at line 135 of file NodeWiseMeshPartitioner.cpp.

141{
142 // Find nodes belonging to a given partition id.
143 std::vector<MeshLib::Node*> partition_nodes;
144 copy_if(begin(nodes), end(nodes), std::back_inserter(partition_nodes),
145 [&](auto const& n) {
146 return partitionLookup(*n, partition_ids, node_id_mapping) ==
147 part_id;
148 });
149
150 // Space for resulting vectors.
151 std::vector<MeshLib::Node*> base_nodes;
152 base_nodes.reserve(partition_nodes.size() /
153 2); // if linear mesh, then one reallocation, no realloc
154 // for higher order elements meshes.
155 std::vector<MeshLib::Node*> higher_order_nodes;
156 higher_order_nodes.reserve(
157 partition_nodes.size() /
158 2); // if linear mesh, then wasted space, good estimate for quadratic
159 // order mesh, and realloc needed for higher order element meshes.
160
161 // Split the nodes into base nodes and extra nodes.
162 std::partition_copy(
163 begin(partition_nodes), end(partition_nodes),
164 std::back_inserter(base_nodes), std::back_inserter(higher_order_nodes),
165 [&](MeshLib::Node* const n)
166 { return isBaseNode(*n, mesh.getElementsConnectedToNode(*n)); });
167
168 return {base_nodes, higher_order_nodes};
169}

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

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

◆ 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 915 of file NodeWiseMeshPartitioner.cpp.

920{
921 constexpr unsigned mat_id =
922 0; // TODO: Material ID to be set from the mesh data
923 const long nn = elem.getNumberOfNodes();
924 elem_info[counter++] = mat_id;
925 elem_info[counter++] = static_cast<long>(elem.getCellType());
926 elem_info[counter++] = nn;
927
928 for (long i = 0; i < nn; i++)
929 {
930 auto const& n = *elem.getNode(i);
931 elem_info[counter++] = local_node_ids.at(n.getID());
932 }
933}
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 80 of file NodeWiseMeshPartitioner.cpp.

82{
83 return 3 * elements.size() +
84 std::accumulate(begin(elements), end(elements), 0,
85 [](auto const nnodes, auto const* e)
86 { return nnodes + e->getNumberOfNodes(); });
87}

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

◆ incrementConfigOffsets()

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

Definition at line 850 of file NodeWiseMeshPartitioner.cpp.

852{
853 return {
854 static_cast<long>(oldConfig.node_rank_offset +
855 offsets.node * sizeof(NodeStruct)),
856 // Offset the ending entry of the element integer variables of
857 // the non-ghost elements of this partition in the vector of elem_info.
858 static_cast<long>(oldConfig.element_rank_offset +
859 offsets.regular_elements * sizeof(long)),
860
861 // Offset the ending entry of the element integer variables of
862 // the ghost elements of this partition in the vector of elem_info.
863 static_cast<long>(oldConfig.ghost_element_rank_offset +
864 offsets.ghost_elements * sizeof(long))};
865}

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 515 of file NodeWiseMeshPartitioner.cpp.

517{
518 std::vector<bool> cell_visited(mesh.getElements().size(), false);
519
520 for (auto& partition : partitions)
521 {
522 partition.duplicate_ghost_cell.resize(partition.ghost_elements.size(),
523 true);
524
525 for (std::size_t i = 0; i < partition.ghost_elements.size(); i++)
526 {
527 const auto& ghost_element = *partition.ghost_elements[i];
528 if (!cell_visited[ghost_element.getID()])
529 {
530 cell_visited[ghost_element.getID()] = true;
531 partition.duplicate_ghost_cell[i] = false;
532 }
533 }
534 }
535}

References MeshLib::Mesh::getElements().

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

◆ nodeIdBulkMesh()

std::size_t ApplicationUtils::nodeIdBulkMesh ( MeshLib::Node const &  node,
std::vector< std::size_t > const *  node_id_mapping = nullptr 
)

Definition at line 109 of file NodeWiseMeshPartitioner.cpp.

112{
113 return node_id_mapping ? (*node_id_mapping)[node.getID()] : node.getID();
114}

References MathLib::Point3dWithID::getID().

Referenced by partitionLookup().

◆ numberOfRegularNodes()

std::ptrdiff_t ApplicationUtils::numberOfRegularNodes ( MeshLib::Element const &  e,
std::size_t const  part_id,
std::vector< std::size_t > const &  partition_ids,
std::vector< std::size_t > const *  node_id_mapping = nullptr 
)

Definition at line 171 of file NodeWiseMeshPartitioner.cpp.

175{
176 return std::count_if(e.getNodes(), e.getNodes() + e.getNumberOfNodes(),
177 [&](MeshLib::Node* const n) {
178 return partitionLookup(*n, partition_ids,
179 node_id_mapping) == part_id;
180 });
181}

References MeshLib::Element::getNodes(), and MeshLib::Element::getNumberOfNodes().

Referenced by findElementsInPartition().

◆ partitionLookup()

std::size_t ApplicationUtils::partitionLookup ( MeshLib::Node const &  node,
std::vector< std::size_t > const &  partition_ids,
std::vector< std::size_t > const *  node_id_mapping = nullptr 
)

Definition at line 116 of file NodeWiseMeshPartitioner.cpp.

120{
121 auto node_id = [&node_id_mapping](MeshLib::Node const& n)
122 { return nodeIdBulkMesh(n, node_id_mapping); };
123
124 return partition_ids[node_id(node)];
125}
std::size_t nodeIdBulkMesh(MeshLib::Node const &node, std::vector< std::size_t > const *node_id_mapping=nullptr)

References nodeIdBulkMesh().

Referenced by findGhostNodesInPartition(), and findRegularNodesInPartition().

◆ partitionProperties()

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

Partition existing properties and add vtkGhostType cell data array property.

Creates partitioned mesh properties for nodes and cells.

Definition at line 470 of file NodeWiseMeshPartitioner.cpp.

473{
474 using namespace MeshLib;
475
476 Properties partitioned_properties;
477
478 auto count_tuples = [&](MeshItemType const mesh_item_type)
479 {
480 return std::accumulate(
481 begin(partitions), end(partitions), 0,
482 [&](std::size_t const sum, Partition const& p)
483 { return sum + p.numberOfMeshItems(mesh_item_type); });
484 };
485 std::map<MeshItemType, std::size_t> const total_number_of_tuples = {
486 {MeshItemType::Cell, count_tuples(MeshItemType::Cell)},
487 {MeshItemType::Node, count_tuples(MeshItemType::Node)}};
488
489 DBUG(
490 "total number of tuples after partitioning defined for cells is {:d} "
491 "and for nodes {:d}.",
492 total_number_of_tuples.at(MeshItemType::Cell),
493 total_number_of_tuples.at(MeshItemType::Node));
494
495 // 1 create new PV
496 // 2 resize the PV with total_number_of_tuples
497 // 3 copy the values according to the partition info
499 properties,
500 [&](auto type, auto const property)
501 {
502 return copyPropertyVector<decltype(type)>(
503 partitioned_properties, partitions,
504 dynamic_cast<PropertyVector<decltype(type)> const*>(property),
505 total_number_of_tuples);
506 });
507
508 addVtkGhostTypeProperty(partitioned_properties,
509 partitions,
510 total_number_of_tuples.at(MeshItemType::Cell));
511
512 return partitioned_properties;
513}
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:29
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 applyToPropertyVectors(MeshLib::Properties const &properties, Function f)
MeshItemType
Definition: Location.h:21

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

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().

◆ 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 872 of file NodeWiseMeshPartitioner.cpp.

874{
875 auto const file_name_cfg = file_name_base + "_partitioned_msh_cfg" +
876 std::to_string(partitions.size()) + ".bin";
877 std::ofstream of_bin_cfg(file_name_cfg, std::ios::binary);
878 if (!of_bin_cfg)
879 {
880 OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
881 }
882
883 std::vector<long> partitions_element_offsets;
884 partitions_element_offsets.reserve(partitions.size());
885 std::vector<long> partitions_ghost_element_offsets;
886 partitions_ghost_element_offsets.reserve(partitions.size());
887
888 ConfigOffsets config_offsets = {0, 0, 0}; // 0 for first partition.
889 for (const auto& partition : partitions)
890 {
891 partition.writeConfig(of_bin_cfg);
892
893 config_offsets.writeConfig(of_bin_cfg);
894 auto const& partition_offsets = computePartitionOffsets(partition);
895 config_offsets =
896 incrementConfigOffsets(config_offsets, partition_offsets);
897
898 partitions_element_offsets.push_back(
899 partition_offsets.regular_elements);
900 partitions_ghost_element_offsets.push_back(
901 partition_offsets.ghost_elements);
902 }
903
904 return std::make_tuple(partitions_element_offsets,
905 partitions_ghost_element_offsets);
906}
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 956 of file NodeWiseMeshPartitioner.cpp.

960{
961 const std::string npartitions_str = std::to_string(partitions.size());
962
963 auto const file_name_ele =
964 file_name_base + "_partitioned_msh_ele" + npartitions_str + ".bin";
965 std::ofstream element_info_os(file_name_ele, std::ios::binary);
966 if (!element_info_os)
967 {
968 OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele);
969 }
970
971 auto const file_name_ele_g =
972 file_name_base + "_partitioned_msh_ele_g" + npartitions_str + ".bin";
973 std::ofstream ghost_element_info_os(file_name_ele_g, std::ios::binary);
974 if (!ghost_element_info_os)
975 {
976 OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele_g);
977 }
978
979 for (std::size_t i = 0; i < partitions.size(); i++)
980 {
981 const auto& partition = partitions[i];
982 auto const local_node_ids = enumerateLocalNodeIds(partition.nodes);
983
984 // Vector containing the offsets of the regular elements of this
985 // partition
986 std::vector<long> ele_info(regular_element_offsets[i]);
987
988 auto writeElementData =
989 [&local_node_ids](
990 std::vector<MeshLib::Element const*> const& elements,
991 long const element_offsets,
992 std::ofstream& output_stream)
993 {
994 long counter = elements.size();
995 std::vector<long> ele_info(element_offsets);
996
997 for (std::size_t j = 0; j < elements.size(); j++)
998 {
999 const auto* elem = elements[j];
1000 ele_info[j] = counter;
1001 getElementIntegerVariables(*elem, local_node_ids, ele_info,
1002 counter);
1003 }
1004 // Write vector data of regular elements
1005 output_stream.write(reinterpret_cast<const char*>(ele_info.data()),
1006 ele_info.size() * sizeof(long));
1007 };
1008
1009 // regular elements.
1010 writeElementData(partition.regular_elements, regular_element_offsets[i],
1011 element_info_os);
1012 // Ghost elements
1013 writeElementData(partition.ghost_elements, ghost_element_offsets[i],
1014 ghost_element_info_os);
1015 }
1016}
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 &nodes)
Generates a mapping of given node ids to a new local (renumbered) node ids.

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 MeshLib::getNodeIndex(), and 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 1022 of file NodeWiseMeshPartitioner.cpp.

1025{
1026 auto const file_name = file_name_base + "_partitioned_msh_nod" +
1027 std::to_string(partitions.size()) + ".bin";
1028 std::ofstream os(file_name, std::ios::binary);
1029 if (!os)
1030 {
1031 OGS_FATAL("Could not open file '{:s}' for output.", file_name);
1032 }
1033
1034 for (const auto& partition : partitions)
1035 {
1036 partition.writeNodes(os, global_node_ids);
1037 }
1038}

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 755 of file NodeWiseMeshPartitioner.cpp.

759{
760 auto const number_of_properties =
761 partitioned_properties.size(mesh_item_type);
762 if (number_of_properties == 0)
763 {
764 return;
765 }
766
767 auto const file_name_infix = toString(mesh_item_type);
768
769 auto const file_name_cfg = file_name_base + "_partitioned_" +
770 file_name_infix + "_properties_cfg" +
771 std::to_string(partitions.size()) + ".bin";
772 std::ofstream out(file_name_cfg, std::ios::binary);
773 if (!out)
774 {
775 OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
776 }
777
778 auto const file_name_val = file_name_base + "_partitioned_" +
779 file_name_infix + "_properties_val" +
780 std::to_string(partitions.size()) + ".bin";
781 std::ofstream out_val(file_name_val, std::ios::binary);
782 if (!out_val)
783 {
784 OGS_FATAL("Could not open file '{:s}' for output.", file_name_val);
785 }
786
788
790 partitioned_properties,
791 [&](auto type, auto const& property)
792 {
793 return writePropertyVector<decltype(type)>(
794 dynamic_cast<MeshLib::PropertyVector<decltype(type)> const*>(
795 property),
796 mesh_item_type, out_val, out);
797 });
798
799 unsigned long offset = 0;
800 for (const auto& partition : partitions)
801 {
803 offset, static_cast<unsigned long>(
804 partition.numberOfMeshItems(mesh_item_type))};
805 DBUG(
806 "Write meta data for node-based PropertyVector: global offset "
807 "{:d}, number of tuples {:d}",
808 pvpmd.offset, pvpmd.number_of_tuples);
810 offset += pvpmd.number_of_tuples;
811 }
812}
void writeValueBinary(std::ostream &out, T const &val)
write value as binary into the given output stream
Definition: FileTools.h:63
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)
Converts MGIS kinematic to a string representation.
Definition: MFront.cpp:103
void writePropertyVectorPartitionMetaData(std::ostream &os, PropertyVectorPartitionMetaData const &pvpmd)

References applyToPropertyVectors(), DBUG(), MaterialPropertyLib::number_of_properties, OGS_FATAL, MeshLib::Properties::size(), MaterialLib::Solids::MFront::toString(), 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 730 of file NodeWiseMeshPartitioner.cpp.

733{
734 if (pv == nullptr)
735 {
736 return false;
737 }
738 // skip property of different mesh item type. Return true, because this
739 // operation was successful.
740 if (pv->getMeshItemType() != mesh_item_type)
741 {
742 return true;
743 }
744
746 pvmd.property_name = pv->getPropertyName();
750 writePropertyVectorValues(out_val, *pv);
752 return true;
753}
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 723 of file NodeWiseMeshPartitioner.cpp.

725{
726 os.write(reinterpret_cast<const char*>(pv.data()), pv.size() * sizeof(T));
727}
std::size_t size() const

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

Referenced by writePropertyVector().