OGS
ApplicationUtils Namespace Reference

Classes

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

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, const bool is_mixed_high_order_linear_elems, 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, const bool is_mixed_high_order_linear_elems, 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 450 of file NodeWiseMeshPartitioner.cpp.

453 {
454  auto* vtk_ghost_type =
455  partitioned_properties.createNewPropertyVector<unsigned char>(
456  "vtkGhostType", MeshLib::MeshItemType::Cell);
457  if (vtk_ghost_type == nullptr)
458  {
459  OGS_FATAL("Could not create vtkGhostType cell data array.");
460  }
461 
462  vtk_ghost_type->resize(total_number_of_cells);
463  std::size_t offset = 0;
464  for (auto const& partition : partitions)
465  {
466  offset += partition.regular_elements.size();
467  for (std::size_t i = 0; i < partition.ghost_elements.size(); ++i)
468  {
469  if (partition.duplicate_ghost_cell[i])
470  {
471  (*vtk_ghost_type)[offset + i] |=
472  vtkDataSetAttributes::DUPLICATECELL;
473  }
474  }
475  offset += partition.ghost_elements.size();
476  }
477 }
#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 427 of file NodeWiseMeshPartitioner.cpp.

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

References MaterialPropertyLib::name, and OGS_FATAL.

Referenced by partitionProperties(), and writeProperties().

◆ computePartitionOffsets()

PartitionOffsets ApplicationUtils::computePartitionOffsets ( Partition const &  partition)

Definition at line 877 of file NodeWiseMeshPartitioner.cpp.

878 {
879  return {static_cast<long>(partition.nodes.size()),
880  static_cast<long>(partition.regular_elements.size() +
882  partition.regular_elements)),
883  static_cast<long>(partition.ghost_elements.size() +
885  partition.ghost_elements))};
886 }
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 343 of file NodeWiseMeshPartitioner.cpp.

348 {
349  std::size_t const n_regular(p.regular_elements.size());
350  auto const n_components = pv.getNumberOfGlobalComponents();
351  for (std::size_t i = 0; i < n_regular; ++i)
352  {
353  const auto id = p.regular_elements[i]->getID();
354  std::copy_n(&pv[n_components * id], n_components,
355  &partitioned_pv[offset + n_components * i]);
356  }
357 
358  std::size_t const n_ghost(p.ghost_elements.size());
359  for (std::size_t i = 0; i < n_ghost; ++i)
360  {
361  const auto id = p.ghost_elements[i]->getID();
362  std::copy_n(&pv[n_components * id], n_components,
363  &partitioned_pv[offset + n_components * (n_regular + i)]);
364  }
365  return n_components * (n_regular + n_ghost);
366 }
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 321 of file NodeWiseMeshPartitioner.cpp.

326 {
327  auto const& nodes = p.nodes;
328  auto const nnodes = nodes.size();
329  auto const n_components = pv.getNumberOfGlobalComponents();
330  for (std::size_t i = 0; i < nnodes; ++i)
331  {
332  const auto global_id = nodes[i]->getID();
333  std::copy_n(&pv[n_components * global_id], n_components,
334  &partitioned_pv[offset + n_components * i]);
335  }
336  return n_components * nnodes;
337 }

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

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

976 {
977  std::unordered_map<std::size_t, long> local_ids;
978  local_ids.reserve(nodes.size());
979 
980  long local_node_id = 0;
981  for (const auto* node : nodes)
982  {
983  local_ids[node->getID()] = local_node_id++;
984  }
985  return local_ids;
986 }

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

198 {
199  std::vector<MeshLib::Element const*> regular_elements;
200  std::vector<MeshLib::Element const*> ghost_elements;
201 
202  for (auto elem : elements)
203  {
204  auto const regular_nodes = numberOfRegularNodes(
205  *elem, part_id, partition_ids, node_id_mapping);
206 
207  if (regular_nodes == 0)
208  {
209  continue;
210  }
211 
212  if (regular_nodes ==
213  static_cast<std::ptrdiff_t>(elem->getNumberOfNodes()))
214  {
215  regular_elements.push_back(elem);
216  }
217  else
218  {
219  ghost_elements.push_back(elem);
220  }
221  }
222  return std::tuple<std::vector<MeshLib::Element const*>,
223  std::vector<MeshLib::Element const*>>{regular_elements,
224  ghost_elements};
225 }
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,
const bool  is_mixed_high_order_linear_elems,
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 232 of file NodeWiseMeshPartitioner.cpp.

240 {
241  std::vector<MeshLib::Node*> base_nodes;
242  std::vector<MeshLib::Node*> ghost_nodes;
243 
244  std::vector<bool> is_ghost_node(nodes.size(), false);
245  for (const auto* ghost_elem : ghost_elements)
246  {
247  for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++)
248  {
249  auto const& n = ghost_elem->getNode(i);
250  if (is_ghost_node[n->getID()])
251  {
252  continue;
253  }
254 
255  if (partitionLookup(*n, partition_ids, node_id_mapping) != part_id)
256  {
257  if (!is_mixed_high_order_linear_elems ||
258  isBaseNode(*n, mesh.getElementsConnectedToNode(*n)))
259  {
260  base_nodes.push_back(nodes[n->getID()]);
261  }
262  else
263  {
264  ghost_nodes.push_back(nodes[n->getID()]);
265  }
266  is_ghost_node[n->getID()] = true;
267  }
268  }
269  }
270  return std::tuple<std::vector<MeshLib::Node*>, std::vector<MeshLib::Node*>>{
271  base_nodes, ghost_nodes};
272 }
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:370

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,
const bool  is_mixed_high_order_linear_elems,
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.

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

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

958 {
959  constexpr unsigned mat_id =
960  0; // TODO: Material ID to be set from the mesh data
961  const long nn = elem.getNumberOfNodes();
962  elem_info[counter++] = mat_id;
963  elem_info[counter++] = static_cast<long>(elem.getCellType());
964  elem_info[counter++] = nn;
965 
966  for (long i = 0; i < nn; i++)
967  {
968  auto const& n = *elem.getNode(i);
969  elem_info[counter++] = local_node_ids.at(n.getID());
970  }
971 }
virtual CellType getCellType() const =0
virtual const Node * getNode(unsigned idx) const =0
virtual unsigned getNumberOfNodes() 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 888 of file NodeWiseMeshPartitioner.cpp.

890 {
891  return {
892  static_cast<long>(oldConfig.node_rank_offset +
893  offsets.node * sizeof(NodeStruct)),
894  // Offset the ending entry of the element integer variables of
895  // the non-ghost elements of this partition in the vector of elem_info.
896  static_cast<long>(oldConfig.element_rank_offset +
897  offsets.regular_elements * sizeof(long)),
898 
899  // Offset the ending entry of the element integer variables of
900  // the ghost elements of this partition in the vector of elem_info.
901  static_cast<long>(oldConfig.ghost_element_rank_offset +
902  offsets.ghost_elements * sizeof(long))};
903 }

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

527 {
528  std::vector<bool> cell_visited(mesh.getElements().size(), false);
529 
530  for (auto& partition : partitions)
531  {
532  partition.duplicate_ghost_cell.resize(partition.ghost_elements.size(),
533  true);
534 
535  for (std::size_t i = 0; i < partition.ghost_elements.size(); i++)
536  {
537  const auto& ghost_element = *partition.ghost_elements[i];
538  if (!cell_visited[ghost_element.getID()])
539  {
540  cell_visited[ghost_element.getID()] = true;
541  partition.duplicate_ghost_cell[i] = false;
542  }
543  }
544  }
545 }

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

179 {
180  return std::count_if(e.getNodes(), e.getNodes() + e.getNumberOfNodes(),
181  [&](MeshLib::Node* const n) {
182  return partitionLookup(*n, partition_ids,
183  node_id_mapping) == part_id;
184  });
185 }

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

483 {
484  using namespace MeshLib;
485 
486  Properties partitioned_properties;
487 
488  auto count_tuples = [&](MeshItemType const mesh_item_type)
489  {
490  return std::accumulate(
491  begin(partitions), end(partitions), 0,
492  [&](std::size_t const sum, Partition const& p)
493  { return sum + p.numberOfMeshItems(mesh_item_type); });
494  };
495  std::map<MeshItemType, std::size_t> const total_number_of_tuples = {
496  {MeshItemType::Cell, count_tuples(MeshItemType::Cell)},
497  {MeshItemType::Node, count_tuples(MeshItemType::Node)}};
498 
499  DBUG(
500  "total number of tuples after partitioning defined for cells is {:d} "
501  "and for nodes {:d}.",
502  total_number_of_tuples.at(MeshItemType::Cell),
503  total_number_of_tuples.at(MeshItemType::Node));
504 
505  // 1 create new PV
506  // 2 resize the PV with total_number_of_tuples
507  // 3 copy the values according to the partition info
509  properties,
510  [&](auto type, auto const property)
511  {
512  return copyPropertyVector<decltype(type)>(
513  partitioned_properties, partitions,
514  dynamic_cast<PropertyVector<decltype(type)> const*>(property),
515  total_number_of_tuples);
516  });
517 
518  addVtkGhostTypeProperty(partitioned_properties,
519  partitions,
520  total_number_of_tuples.at(MeshItemType::Cell));
521 
522  return partitioned_properties;
523 }
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
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  {
58  OGS_FATAL(
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 910 of file NodeWiseMeshPartitioner.cpp.

912 {
913  auto const file_name_cfg = file_name_base + "_partitioned_msh_cfg" +
914  std::to_string(partitions.size()) + ".bin";
915  std::ofstream of_bin_cfg(file_name_cfg, std::ios::binary);
916  if (!of_bin_cfg)
917  {
918  OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
919  }
920 
921  std::vector<long> partitions_element_offsets;
922  partitions_element_offsets.reserve(partitions.size());
923  std::vector<long> partitions_ghost_element_offsets;
924  partitions_ghost_element_offsets.reserve(partitions.size());
925 
926  ConfigOffsets config_offsets = {0, 0, 0}; // 0 for first partition.
927  for (const auto& partition : partitions)
928  {
929  partition.writeConfig(of_bin_cfg);
930 
931  config_offsets.writeConfig(of_bin_cfg);
932  auto const& partition_offsets = computePartitionOffsets(partition);
933  config_offsets =
934  incrementConfigOffsets(config_offsets, partition_offsets);
935 
936  partitions_element_offsets.push_back(
937  partition_offsets.regular_elements);
938  partitions_ghost_element_offsets.push_back(
939  partition_offsets.ghost_elements);
940  }
941 
942  return std::make_tuple(partitions_element_offsets,
943  partitions_ghost_element_offsets);
944 }
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 994 of file NodeWiseMeshPartitioner.cpp.

998 {
999  const std::string npartitions_str = std::to_string(partitions.size());
1000 
1001  auto const file_name_ele =
1002  file_name_base + "_partitioned_msh_ele" + npartitions_str + ".bin";
1003  std::ofstream element_info_os(file_name_ele, std::ios::binary);
1004  if (!element_info_os)
1005  {
1006  OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele);
1007  }
1008 
1009  auto const file_name_ele_g =
1010  file_name_base + "_partitioned_msh_ele_g" + npartitions_str + ".bin";
1011  std::ofstream ghost_element_info_os(file_name_ele_g, std::ios::binary);
1012  if (!ghost_element_info_os)
1013  {
1014  OGS_FATAL("Could not open file '{:s}' for output.", file_name_ele_g);
1015  }
1016 
1017  for (std::size_t i = 0; i < partitions.size(); i++)
1018  {
1019  const auto& partition = partitions[i];
1020  auto const local_node_ids = enumerateLocalNodeIds(partition.nodes);
1021 
1022  // Vector containing the offsets of the regular elements of this
1023  // partition
1024  std::vector<long> ele_info(regular_element_offsets[i]);
1025 
1026  auto writeElementData =
1027  [&local_node_ids](
1028  std::vector<MeshLib::Element const*> const& elements,
1029  long const element_offsets,
1030  std::ofstream& output_stream)
1031  {
1032  long counter = elements.size();
1033  std::vector<long> ele_info(element_offsets);
1034 
1035  for (std::size_t j = 0; j < elements.size(); j++)
1036  {
1037  const auto* elem = elements[j];
1038  ele_info[j] = counter;
1039  getElementIntegerVariables(*elem, local_node_ids, ele_info,
1040  counter);
1041  }
1042  // Write vector data of regular elements
1043  output_stream.write(reinterpret_cast<const char*>(ele_info.data()),
1044  ele_info.size() * sizeof(long));
1045  };
1046 
1047  // regular elements.
1048  writeElementData(partition.regular_elements, regular_element_offsets[i],
1049  element_info_os);
1050  // Ghost elements
1051  writeElementData(partition.ghost_elements, ghost_element_offsets[i],
1052  ghost_element_info_os);
1053  }
1054 }
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.
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:225

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

1063 {
1064  auto const file_name = file_name_base + "_partitioned_msh_nod" +
1065  std::to_string(partitions.size()) + ".bin";
1066  std::ofstream os(file_name, std::ios::binary);
1067  if (!os)
1068  {
1069  OGS_FATAL("Could not open file '{:s}' for output.", file_name);
1070  }
1071 
1072  for (const auto& partition : partitions)
1073  {
1074  partition.writeNodes(os, global_node_ids);
1075  }
1076 }

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

797 {
798  auto const number_of_properties =
799  partitioned_properties.size(mesh_item_type);
800  if (number_of_properties == 0)
801  {
802  return;
803  }
804 
805  auto const file_name_infix = toString(mesh_item_type);
806 
807  auto const file_name_cfg = file_name_base + "_partitioned_" +
808  file_name_infix + "_properties_cfg" +
809  std::to_string(partitions.size()) + ".bin";
810  std::ofstream out(file_name_cfg, std::ios::binary);
811  if (!out)
812  {
813  OGS_FATAL("Could not open file '{:s}' for output.", file_name_cfg);
814  }
815 
816  auto const file_name_val = file_name_base + "_partitioned_" +
817  file_name_infix + "_properties_val" +
818  std::to_string(partitions.size()) + ".bin";
819  std::ofstream out_val(file_name_val, std::ios::binary);
820  if (!out_val)
821  {
822  OGS_FATAL("Could not open file '{:s}' for output.", file_name_val);
823  }
824 
826 
828  partitioned_properties,
829  [&](auto type, auto const& property)
830  {
831  return writePropertyVector<decltype(type)>(
832  dynamic_cast<MeshLib::PropertyVector<decltype(type)> const*>(
833  property),
834  mesh_item_type, out_val, out);
835  });
836 
837  unsigned long offset = 0;
838  for (const auto& partition : partitions)
839  {
841  offset, static_cast<unsigned long>(
842  partition.numberOfMeshItems(mesh_item_type))};
843  DBUG(
844  "Write meta data for node-based PropertyVector: global offset "
845  "{:d}, number of tuples {:d}",
846  pvpmd.offset, pvpmd.number_of_tuples);
848  offset += pvpmd.number_of_tuples;
849  }
850 }
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 768 of file NodeWiseMeshPartitioner.cpp.

771 {
772  if (pv == nullptr)
773  {
774  return false;
775  }
776  // skip property of different mesh item type. Return true, because this
777  // operation was successful.
778  if (pv->getMeshItemType() != mesh_item_type)
779  {
780  return true;
781  }
782 
784  pvmd.property_name = pv->getPropertyName();
787  pvmd.number_of_tuples = pv->getNumberOfTuples();
788  writePropertyVectorValues(out_val, *pv);
790  return true;
791 }
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 761 of file NodeWiseMeshPartitioner.cpp.

763 {
764  os.write(reinterpret_cast<const char*>(pv.data()), pv.size() * sizeof(T));
765 }
std::size_t size() const

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

Referenced by writePropertyVector().