OGS 6.3.0-179-g962fdcd4e.dirty.20200403132553
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 * > > findNonGhostNodesInPartition (std::size_t const part_id, const bool is_mixed_high_order_linear_elems, std::size_t const n_base_nodes, std::vector< MeshLib::Node *> const &nodes, std::vector< std::size_t > const &partition_ids, 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::size_t const number_of_base_nodes, std::vector< MeshLib::Node *> const &nodes, std::vector< MeshLib::Element const *> const &ghost_elements, std::vector< std::size_t > const &partition_ids, 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 const &original_properties, MeshLib::Properties &partitioned_properties, std::vector< Partition > const &partitions, std::string const &name, std::size_t const total_number_of_tuples)
 
template<typename Function >
void applyToPropertyVectors (std::vector< std::string > const &property_names, Function f)
 
void processProperties (MeshLib::Properties const &properties, MeshLib::MeshItemType const mesh_item_type, std::vector< Partition > const &partitions, MeshLib::Properties &partitioned_properties)
 
MeshLib::Properties partitionProperties (MeshLib::Properties const &properties, std::vector< Partition > const &partitions)
 Creates partitioned mesh properties for nodes and cells. More...
 
template<typename T >
void writePropertyVectorValuesBinary (std::ostream &os, MeshLib::PropertyVector< T > const &pv)
 
template<typename T >
bool writePropertyVectorBinary (MeshLib::Properties const &partitioned_properties, std::string const &name, std::ostream &out_val, std::ostream &out_meta)
 
void writePropertiesBinary (const std::string &file_name_base, MeshLib::Properties const &partitioned_properties, std::vector< Partition > const &partitions, MeshLib::MeshItemType const mesh_item_type)
 
PartitionOffsets computePartitionElementOffsets (Partition const &partition)
 
ConfigOffsets incrementConfigOffsets (ConfigOffsets const &oldConfig, PartitionOffsets const &offsets)
 
std::tuple< std::vector< long >, std::vector< long > > writeConfigDataBinary (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 writeElementsBinary (std::string const &file_name_base, std::vector< Partition > const &partitions, std::vector< long > const &num_elem_integers, std::vector< long > const &num_g_elem_integers)
 
void writeNodesBinary (const std::string &file_name_base, std::vector< Partition > const &partitions, std::vector< std::size_t > const &global_node_ids)
 

Function Documentation

◆ applyToPropertyVectors()

template<typename Function >
void ApplicationUtils::applyToPropertyVectors ( std::vector< std::string > const &  property_names,
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 425 of file NodeWiseMeshPartitioner.cpp.

References MaterialPropertyLib::name, and OGS_FATAL.

Referenced by processProperties(), and writePropertiesBinary().

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

◆ computePartitionElementOffsets()

PartitionOffsets ApplicationUtils::computePartitionElementOffsets ( Partition const &  partition)

Definition at line 807 of file NodeWiseMeshPartitioner.cpp.

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

Referenced by writeConfigDataBinary().

808 {
809  return {static_cast<long>(partition.nodes.size()),
810  static_cast<long>(partition.regular_elements.size() +
812  partition.regular_elements)),
813  static_cast<long>(partition.ghost_elements.size() +
815  partition.ghost_elements))};
816 }
NodeWiseMeshPartitioner::IntegerType getNumberOfIntegerVariablesOfElements(std::vector< const MeshLib::Element *> const &elements)

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

References ApplicationUtils::Partition::ghost_elements, ApplicationUtils::NodeStruct::id, and ApplicationUtils::Partition::regular_elements.

Referenced by copyPropertyVector().

358 {
359  std::size_t const n_regular(p.regular_elements.size());
360  for (std::size_t i = 0; i < n_regular; ++i)
361  {
362  const auto id = p.regular_elements[i]->getID();
363  partitioned_pv[offset + i] = pv[id];
364  }
365 
366  std::size_t const n_ghost(p.ghost_elements.size());
367  for (std::size_t i = 0; i < n_ghost; ++i)
368  {
369  const auto id = p.ghost_elements[i]->getID();
370  partitioned_pv[offset + n_regular + i] = pv[id];
371  }
372  return n_regular + n_ghost;
373 }
static const double p

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

References ApplicationUtils::Partition::nodes.

Referenced by copyPropertyVector().

338 {
339  auto const& nodes = p.nodes;
340  auto const nnodes = nodes.size();
341  for (std::size_t i = 0; i < nnodes; ++i)
342  {
343  const auto global_id = nodes[i]->getID();
344  partitioned_pv[offset + i] = pv[global_id];
345  }
346  return nnodes;
347 }
static const double p

◆ copyPropertyVector()

template<typename T >
bool ApplicationUtils::copyPropertyVector ( MeshLib::Properties const &  original_properties,
MeshLib::Properties partitioned_properties,
std::vector< Partition > const &  partitions,
std::string const &  name,
std::size_t const  total_number_of_tuples 
)

Definition at line 376 of file NodeWiseMeshPartitioner.cpp.

References MeshLib::Cell, copyCellPropertyVectorValues(), copyNodePropertyVectorValues(), MeshLib::Properties::createNewPropertyVector(), MeshLib::Properties::existsPropertyVector(), MeshLib::Properties::getPropertyVector(), MaterialPropertyLib::name, MeshLib::Node, and OGS_FATAL.

381 {
382  if (!original_properties.existsPropertyVector<T>(name))
383  {
384  return false;
385  }
386 
387  auto const& pv = original_properties.getPropertyVector<T>(name);
388  auto partitioned_pv = partitioned_properties.createNewPropertyVector<T>(
389  name, pv->getMeshItemType(), pv->getNumberOfComponents());
390  partitioned_pv->resize(total_number_of_tuples *
391  pv->getNumberOfComponents());
392 
393  auto copy_property_vector_values = [&](Partition const& p,
394  std::size_t offset) {
395  if (pv->getMeshItemType() == MeshLib::MeshItemType::Node)
396  {
397  return copyNodePropertyVectorValues(p, offset, *pv,
398  *partitioned_pv);
399  }
400  if (pv->getMeshItemType() == MeshLib::MeshItemType::Cell)
401  {
402  return copyCellPropertyVectorValues(p, offset, *pv,
403  *partitioned_pv);
404  }
405  OGS_FATAL(
406  "Copying of property vector values for mesh item type %s is "
407  "not implemented.",
408  pv->getMeshItemType());
409  };
410 
411  std::size_t position_offset(0);
412  for (auto p : partitions)
413  {
414  position_offset += copy_property_vector_values(p, position_offset);
415  }
416  return true;
417 }
std::size_t copyNodePropertyVectorValues(Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)
Definition: Properties.h:15
static const double p
#define OGS_FATAL(fmt,...)
Definition: Error.h:64
std::size_t copyCellPropertyVectorValues(Partition const &p, std::size_t const offset, MeshLib::PropertyVector< T > const &pv, MeshLib::PropertyVector< T > &partitioned_pv)

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

Referenced by writeElementsBinary().

902 {
903  std::unordered_map<std::size_t, long> local_ids;
904  local_ids.reserve(nodes.size());
905 
906  long local_node_id = 0;
907  for (const auto* node : nodes)
908  {
909  local_ids[node->getID()] = local_node_id++;
910  }
911  return local_ids;
912 }

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

References numberOfRegularNodes().

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

204 {
205  std::vector<MeshLib::Element const*> regular_elements;
206  std::vector<MeshLib::Element const*> ghost_elements;
207 
208  for (auto elem : elements)
209  {
210  auto const regular_nodes = numberOfRegularNodes(
211  *elem, part_id, partition_ids, node_id_mapping);
212 
213  if (regular_nodes == 0)
214  {
215  continue;
216  }
217 
218  if (regular_nodes ==
219  static_cast<std::ptrdiff_t>(elem->getNumberOfNodes()))
220  {
221  regular_elements.push_back(elem);
222  }
223  else
224  {
225  ghost_elements.push_back(elem);
226  }
227  }
228  return std::tuple<std::vector<MeshLib::Element const*>,
229  std::vector<MeshLib::Element const*>>{regular_elements,
230  ghost_elements};
231 }
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)

◆ 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::size_t const  number_of_base_nodes,
std::vector< MeshLib::Node *> const &  nodes,
std::vector< MeshLib::Element const *> const &  ghost_elements,
std::vector< std::size_t > const &  partition_ids,
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 238 of file NodeWiseMeshPartitioner.cpp.

References nodeIdBulkMesh(), and partitionLookup().

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

246 {
247  auto node_id = [&node_id_mapping](MeshLib::Node const& n) {
248  return nodeIdBulkMesh(n, node_id_mapping);
249  };
250 
251  std::vector<MeshLib::Node*> base_nodes;
252  std::vector<MeshLib::Node*> ghost_nodes;
253 
254  std::vector<bool> nodes_reserved(nodes.size(), false);
255  for (const auto* ghost_elem : ghost_elements)
256  {
257  for (unsigned i = 0; i < ghost_elem->getNumberOfNodes(); i++)
258  {
259  auto const& n = ghost_elem->getNode(i);
260  if (nodes_reserved[n->getID()])
261  {
262  continue;
263  }
264 
265  if (partitionLookup(*n, partition_ids, node_id_mapping) != part_id)
266  {
267  if (!is_mixed_high_order_linear_elems ||
268  node_id(*n) > number_of_base_nodes)
269  {
270  base_nodes.push_back(nodes[n->getID()]);
271  }
272  else
273  {
274  ghost_nodes.push_back(nodes[n->getID()]);
275  }
276  nodes_reserved[n->getID()] = true;
277  }
278  }
279  }
280  return std::tuple<std::vector<MeshLib::Node*>, std::vector<MeshLib::Node*>>{
281  base_nodes, ghost_nodes};
282 }
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::size_t nodeIdBulkMesh(MeshLib::Node const &node, std::vector< std::size_t > const *node_id_mapping=nullptr)

◆ findNonGhostNodesInPartition()

std::pair<std::vector<MeshLib::Node*>, std::vector<MeshLib::Node*> > ApplicationUtils::findNonGhostNodesInPartition ( std::size_t const  part_id,
const bool  is_mixed_high_order_linear_elems,
std::size_t const  n_base_nodes,
std::vector< MeshLib::Node *> const &  nodes,
std::vector< std::size_t > const &  partition_ids,
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 138 of file NodeWiseMeshPartitioner.cpp.

References nodeIdBulkMesh(), and partitionLookup().

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

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

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

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

Referenced by writeElementsBinary().

885 {
886  unsigned mat_id = 0; // TODO: Material ID to be set from the mesh data
887  const long nn = elem.getNumberOfNodes();
888  elem_info[counter++] = mat_id;
889  elem_info[counter++] = static_cast<long>(elem.getCellType());
890  elem_info[counter++] = nn;
891 
892  for (long i = 0; i < nn; i++)
893  {
894  auto const& n = *elem.getNode(i);
895  elem_info[counter++] = local_node_ids.at(n.getID());
896  }
897 }
virtual CellType getCellType() const =0
virtual unsigned getNumberOfNodes() const =0
Returns the number of all nodes including both linear and nonlinear nodes.
const Node * getNode(unsigned i) const
Definition: Element.cpp:158

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

Referenced by computePartitionElementOffsets(), ApplicationUtils::Partition::writeConfigBinary(), and ApplicationUtils::NodeWiseMeshPartitioner::writeConfigDataASCII().

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

◆ incrementConfigOffsets()

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

Definition at line 818 of file NodeWiseMeshPartitioner.cpp.

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

Referenced by writeConfigDataBinary().

820 {
821  return {
822  static_cast<long>(oldConfig.node_rank_offset +
823  offsets.node * sizeof(NodeStruct)),
824  // Offset the ending entry of the element integer variales of
825  // the non-ghost elements of this partition in the vector of elem_info.
826  static_cast<long>(oldConfig.element_rank_offset +
827  offsets.regular_elements * sizeof(long)),
828 
829  // Offset the ending entry of the element integer variales of
830  // the ghost elements of this partition in the vector of elem_info.
831  static_cast<long>(oldConfig.ghost_element_rank_offset +
832  offsets.ghost_elements * sizeof(long))};
833 }

◆ nodeIdBulkMesh()

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

Definition at line 111 of file NodeWiseMeshPartitioner.cpp.

References MathLib::Point3dWithID::getID().

Referenced by findGhostNodesInPartition(), findNonGhostNodesInPartition(), and partitionLookup().

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

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

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

Referenced by findElementsInPartition().

185 {
186  return std::count_if(e.getNodes(), e.getNodes() + e.getNumberOfNodes(),
187  [&](MeshLib::Node* const n) {
188  return partitionLookup(*n, partition_ids,
189  node_id_mapping) == part_id;
190  });
191 }
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)

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

References nodeIdBulkMesh().

Referenced by findGhostNodesInPartition(), findNonGhostNodesInPartition(), and numberOfRegularNodes().

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

◆ partitionProperties()

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

Creates partitioned mesh properties for nodes and cells.

Definition at line 474 of file NodeWiseMeshPartitioner.cpp.

References MeshLib::Cell, MeshLib::Node, and processProperties().

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

477 {
478  MeshLib::Properties partitioned_properties;
479  processProperties(properties, MeshLib::MeshItemType::Node, partitions,
480  partitioned_properties);
481  processProperties(properties, MeshLib::MeshItemType::Cell, partitions,
482  partitioned_properties);
483  return partitioned_properties;
484 }
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties...
Definition: Properties.h:36
void processProperties(MeshLib::Properties const &properties, MeshLib::MeshItemType const mesh_item_type, std::vector< Partition > const &partitions, MeshLib::Properties &partitioned_properties)

◆ processProperties()

void ApplicationUtils::processProperties ( MeshLib::Properties const &  properties,
MeshLib::MeshItemType const  mesh_item_type,
std::vector< Partition > const &  partitions,
MeshLib::Properties partitioned_properties 
)

Definition at line 447 of file NodeWiseMeshPartitioner.cpp.

References applyToPropertyVectors(), MeshLib::Properties::getPropertyVectorNames(), MaterialPropertyLib::name, ApplicationUtils::Partition::numberOfMeshItems(), and MaterialLib::Solids::MFront::toString().

Referenced by partitionProperties().

451 {
452  std::size_t const total_number_of_tuples =
453  std::accumulate(begin(partitions), end(partitions), 0,
454  [&](std::size_t const sum, Partition const& p) {
455  return sum + p.numberOfMeshItems(mesh_item_type);
456  });
457 
458  DBUG(
459  "total number of tuples define on mesh item type '%s' after "
460  "partitioning: %d ",
461  toString(mesh_item_type), total_number_of_tuples);
462 
463  // 1 create new PV
464  // 2 resize the PV with total_number_of_tuples
465  // 3 copy the values according to the partition info
466  applyToPropertyVectors(properties.getPropertyVectorNames(mesh_item_type),
467  [&](auto type, std::string const& name) {
468  return copyPropertyVector<decltype(type)>(
469  properties, partitioned_properties,
470  partitions, name, total_number_of_tuples);
471  });
472 }
void applyToPropertyVectors(std::vector< std::string > const &property_names, Function f)
static const double p
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)
Converts MGIS kinematic to a string representation.
Definition: MFront.cpp:97

◆ 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.

References OGS_FATAL.

Referenced by main().

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 
67  std::size_t counter = 0;
68  while (!npart_in.eof())
69  {
70  npart_in >> partition_ids[counter++] >> std::ws;
71  if (counter == number_of_nodes)
72  {
73  break;
74  }
75  }
76 
77  if (npart_in.bad())
78  {
79  OGS_FATAL("Error while reading file %s.", fname_parts.data());
80  }
81 
82  if (counter != number_of_nodes)
83  {
84  OGS_FATAL("Error: data in %s are less than expected.",
85  fname_parts.data());
86  }
87 
88  return partition_ids;
89 }
#define OGS_FATAL(fmt,...)
Definition: Error.h:64

◆ 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 91 of file Metis.cpp.

Referenced by main().

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

◆ writeConfigDataBinary()

std::tuple<std::vector<long>, std::vector<long> > ApplicationUtils::writeConfigDataBinary ( 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 840 of file NodeWiseMeshPartitioner.cpp.

References computePartitionElementOffsets(), incrementConfigOffsets(), OGS_FATAL, and ApplicationUtils::ConfigOffsets::writeConfigBinary().

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

842 {
843  auto const file_name_cfg = file_name_base + "_partitioned_msh_cfg" +
844  std::to_string(partitions.size()) + ".bin";
845  std::ofstream of_bin_cfg(file_name_cfg, std::ios::binary);
846  if (!of_bin_cfg)
847  {
848  OGS_FATAL("Could not open file '%s' for output.",
849  file_name_cfg.c_str());
850  }
851 
852  std::vector<long> num_elem_integers;
853  num_elem_integers.reserve(partitions.size());
854  std::vector<long> num_g_elem_integers;
855  num_g_elem_integers.reserve(partitions.size());
856 
857  ConfigOffsets config_offsets = {0, 0, 0}; // 0 for first partition.
858  for (const auto& partition : partitions)
859  {
860  partition.writeConfigBinary(of_bin_cfg);
861 
862  config_offsets.writeConfigBinary(of_bin_cfg);
863  auto const& new_offsets = computePartitionElementOffsets(partition);
864  config_offsets = incrementConfigOffsets(config_offsets, new_offsets);
865 
866  num_elem_integers.push_back(new_offsets.regular_elements);
867  num_g_elem_integers.push_back(new_offsets.ghost_elements);
868  }
869 
870  return std::make_tuple(num_elem_integers, num_g_elem_integers);
871 }
#define OGS_FATAL(fmt,...)
Definition: Error.h:64
ConfigOffsets incrementConfigOffsets(ConfigOffsets const &oldConfig, PartitionOffsets const &offsets)
PartitionOffsets computePartitionElementOffsets(Partition const &partition)

◆ writeElementsBinary()

void ApplicationUtils::writeElementsBinary ( std::string const &  file_name_base,
std::vector< Partition > const &  partitions,
std::vector< long > const &  num_elem_integers,
std::vector< long > const &  num_g_elem_integers 
)

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

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

Definition at line 920 of file NodeWiseMeshPartitioner.cpp.

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

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

924 {
925  const std::string npartitions_str = std::to_string(partitions.size());
926 
927  auto const file_name_ele =
928  file_name_base + "_partitioned_msh_ele" + npartitions_str + ".bin";
929  std::ofstream element_info_os(file_name_ele, std::ios::binary);
930  if (!element_info_os)
931  {
932  OGS_FATAL("Could not open file '%s' for output.",
933  file_name_ele.c_str());
934  }
935 
936  auto const file_name_ele_g =
937  file_name_base + "_partitioned_msh_ele_g" + npartitions_str + ".bin";
938  std::ofstream ghost_element_info_os(file_name_ele_g, std::ios::binary);
939  if (!ghost_element_info_os)
940  {
941  OGS_FATAL("Could not open file '%s' for output.",
942  file_name_ele_g.c_str());
943  }
944 
945  for (std::size_t i = 0; i < partitions.size(); i++)
946  {
947  const auto& partition = partitions[i];
948  auto const local_node_ids = enumerateLocalNodeIds(partition.nodes);
949 
950  // A vector contians all element integer variables of
951  // the non-ghost elements of this partition
952  std::vector<long> ele_info(num_elem_integers[i]);
953 
954  // Non-ghost elements.
955  long counter = partition.regular_elements.size();
956 
957  for (std::size_t j = 0; j < partition.regular_elements.size(); j++)
958  {
959  const auto* elem = partition.regular_elements[j];
960  ele_info[j] = counter;
961  getElementIntegerVariables(*elem, local_node_ids, ele_info,
962  counter);
963  }
964  // Write vector data of non-ghost elements
965  element_info_os.write(reinterpret_cast<const char*>(ele_info.data()),
966  ele_info.size() * sizeof(long));
967 
968  // Ghost elements
969  ele_info.resize(num_g_elem_integers[i]);
970 
971  counter = partition.ghost_elements.size();
972 
973  for (std::size_t j = 0; j < partition.ghost_elements.size(); j++)
974  {
975  const auto* elem = partition.ghost_elements[j];
976  ele_info[j] = counter;
977  getElementIntegerVariables(*elem, local_node_ids, ele_info,
978  counter);
979  }
980  // Write vector data of ghost elements
981  ghost_element_info_os.write(
982  reinterpret_cast<const char*>(ele_info.data()),
983  ele_info.size() * sizeof(long));
984  }
985 }
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)
#define OGS_FATAL(fmt,...)
Definition: Error.h:64

◆ 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.

References OGS_FATAL.

Referenced by main().

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 << elem->getNodeIndex(0) + 1;
37  for (unsigned j = 1; j < elem->getNumberOfNodes(); j++)
38  {
39  os << " " << elem->getNodeIndex(j) + 1;
40  }
41  os << "\n";
42  }
43 }
#define OGS_FATAL(fmt,...)
Definition: Error.h:64

◆ writeNodesBinary()

void ApplicationUtils::writeNodesBinary ( 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 991 of file NodeWiseMeshPartitioner.cpp.

References OGS_FATAL.

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

994 {
995  auto const file_name = file_name_base + "_partitioned_msh_nod" +
996  std::to_string(partitions.size()) + ".bin";
997  std::ofstream os(file_name, std::ios::binary);
998  if (!os)
999  {
1000  OGS_FATAL("Could not open file '%s' for output.", file_name.c_str());
1001  }
1002 
1003  for (const auto& partition : partitions)
1004  {
1005  partition.writeNodesBinary(os, global_node_ids);
1006  }
1007 }
#define OGS_FATAL(fmt,...)
Definition: Error.h:64

◆ writePropertiesBinary()

void ApplicationUtils::writePropertiesBinary ( 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 724 of file NodeWiseMeshPartitioner.cpp.

References applyToPropertyVectors(), MeshLib::Properties::getPropertyVectorNames(), MaterialPropertyLib::name, MaterialPropertyLib::number_of_properties, OGS_FATAL, MaterialLib::Solids::MFront::toString(), MeshLib::IO::writePropertyVectorPartitionMetaData(), and BaseLib::writeValueBinary().

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

728 {
729  auto const& property_names =
730  partitioned_properties.getPropertyVectorNames(mesh_item_type);
731  if (property_names.empty())
732  {
733  return;
734  }
735 
736  auto const file_name_infix = toString(mesh_item_type);
737 
738  auto const file_name_cfg = file_name_base + "_partitioned_" +
739  file_name_infix + "_properties_cfg" +
740  std::to_string(partitions.size()) + ".bin";
741  std::ofstream out(file_name_cfg, std::ios::binary);
742  if (!out)
743  {
744  OGS_FATAL("Could not open file '%s' for output.",
745  file_name_cfg.c_str());
746  }
747 
748  auto const file_name_val = file_name_base + "_partitioned_" +
749  file_name_infix + "_properties_val" +
750  std::to_string(partitions.size()) + ".bin";
751  std::ofstream out_val(file_name_val, std::ios::binary);
752  if (!out_val)
753  {
754  OGS_FATAL("Could not open file '%s' for output.",
755  file_name_val.c_str());
756  }
757 
758  std::size_t const number_of_properties(property_names.size());
760 
761  applyToPropertyVectors(property_names,
762  [&](auto type, std::string const& name) {
763  return writePropertyVectorBinary<decltype(type)>(
764  partitioned_properties, name, out_val, out);
765  });
766 
767  unsigned long offset = 0;
768  for (const auto& partition : partitions)
769  {
771  offset, static_cast<unsigned long>(
772  partition.numberOfMeshItems(mesh_item_type))};
773  DBUG(
774  "Write meta data for node-based PropertyVector: global offset %d, "
775  "number of tuples %d",
776  pvpmd.offset, pvpmd.number_of_tuples);
778  offset += pvpmd.number_of_tuples;
779  }
780 }
void writePropertyVectorPartitionMetaData(std::ostream &os, PropertyVectorPartitionMetaData const &pvpmd)
void applyToPropertyVectors(std::vector< std::string > const &property_names, Function f)
#define OGS_FATAL(fmt,...)
Definition: Error.h:64
void writeValueBinary(std::ostream &out, T const &val)
write value as binary into the given output stream
Definition: FileTools.h:39
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)
Converts MGIS kinematic to a string representation.
Definition: MFront.cpp:97

◆ writePropertyVectorBinary()

template<typename T >
bool ApplicationUtils::writePropertyVectorBinary ( MeshLib::Properties const &  partitioned_properties,
std::string const &  name,
std::ostream &  out_val,
std::ostream &  out_meta 
)

Definition at line 704 of file NodeWiseMeshPartitioner.cpp.

References MeshLib::Properties::existsPropertyVector(), MeshLib::IO::PropertyVectorMetaData::fillPropertyVectorMetaDataTypeInfo(), MeshLib::Properties::getPropertyVector(), MaterialPropertyLib::name, MeshLib::IO::PropertyVectorMetaData::number_of_components, MeshLib::IO::PropertyVectorMetaData::number_of_tuples, MeshLib::IO::PropertyVectorMetaData::property_name, MeshLib::IO::writePropertyVectorMetaDataBinary(), and writePropertyVectorValuesBinary().

707 {
708  if (!partitioned_properties.existsPropertyVector<T>(name))
709  {
710  return false;
711  }
712 
714  pvmd.property_name = name;
715  auto* pv = partitioned_properties.getPropertyVector<T>(name);
717  pvmd.number_of_components = pv->getNumberOfComponents();
718  pvmd.number_of_tuples = pv->getNumberOfTuples();
719  writePropertyVectorValuesBinary(out_val, *pv);
721  return true;
722 }
void writePropertyVectorMetaDataBinary(std::ostream &os, PropertyVectorMetaData const &pvmd)
void writePropertyVectorValuesBinary(std::ostream &os, MeshLib::PropertyVector< T > const &pv)

◆ writePropertyVectorValuesBinary()

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

Definition at line 697 of file NodeWiseMeshPartitioner.cpp.

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

Referenced by writePropertyVectorBinary().

699 {
700  os.write(reinterpret_cast<const char*>(pv.data()), pv.size() * sizeof(T));
701 }
std::size_t size() const