KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
model_part_operation_utilities.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Suneth Warnakulasuriya
11 //
12 
13 #pragma once
14 
15 // System includes
16 #include <string>
17 #include <vector>
18 
19 // External includes
20 
21 // Project includes
22 #include "includes/key_hash.h"
23 #include "includes/model_part.h"
25 
26 namespace Kratos {
27 
30 
31 class KRATOS_API(KRATOS_CORE) ModelPartOperationUtilities {
32 public:
35 
36  using IndexType = std::size_t;
37 
38  using CNodePointersType = std::vector<ModelPart::NodeType const*>;
39 
40  template<class KeyType, class ValueType>
41  using RangedKeyMapType = std::unordered_map<KeyType, ValueType, KeyHasherRange<KeyType>, KeyComparorRange<KeyType>>;
42 
46 
61  static bool CheckValidityOfModelPartsForOperations(
62  const ModelPart& rMainModelPart,
63  const std::vector<ModelPart const*>& rCheckModelParts,
64  const bool ThrowError = false);
65 
91  template<class TModelPartOperation>
92  static void FillSubModelPart(
93  ModelPart& rOutputSubModelPart,
94  const ModelPart& rMainModelPart,
95  const std::vector<ModelPart const*>& rOperands,
96  const bool AddNeighbourEntities)
97  {
98  std::vector<ModelPart::NodeType*> output_nodes;
99  std::vector<ModelPart::ConditionType*> output_conditions;
100  std::vector<ModelPart::ElementType*> output_elements;
101 
102  // check whether the given rOutputSubModelPart is a sub model part of rMainModelPart
103  // This is done based on pointers to avoid having same names in model parts
104  // which are within two different models.
105  ModelPart* p_parent_model_part = &rOutputSubModelPart.GetParentModelPart();
106  while (p_parent_model_part != &rMainModelPart && p_parent_model_part != &p_parent_model_part->GetParentModelPart()) {
107  p_parent_model_part = &p_parent_model_part->GetParentModelPart();
108  }
109 
110  KRATOS_ERROR_IF_NOT(p_parent_model_part == &rMainModelPart)
111  << "The given sub model part " << rOutputSubModelPart.FullName()
112  << " is not a sub model part of " << rMainModelPart.FullName() << ".\n";
113 
114  // fill vectors
115  ModelPartOperation<TModelPartOperation>(output_nodes, output_conditions, output_elements, *p_parent_model_part, rOperands, AddNeighbourEntities);
116 
117  // now fill the sub model part
118  FillOutputSubModelPart(rOutputSubModelPart, *p_parent_model_part, output_nodes, output_conditions, output_elements);
119  }
120 
132  static bool HasIntersection(const std::vector<ModelPart*>& rIntersectionModelParts);
133 
135 private:
138 
139  template<class TUnaryFunc>
140  static void AddNodes(
141  std::vector<ModelPart::NodeType*>& rNodesOutput,
142  ModelPart::NodesContainerType& rNodesContainer,
143  TUnaryFunc&& rIsValidEntity)
144  {
145  using p_entity_type = ModelPart::NodeType*;
146 
147  const auto& result = block_for_each<AccumReduction<p_entity_type>>(rNodesContainer, [&rIsValidEntity](auto& rMainEntity) -> p_entity_type {
148  ModelPart::NodeType const* p_entity = &rMainEntity;
149  if (rIsValidEntity(p_entity)) {
150  return &rMainEntity;
151  } else {
152  return nullptr;
153  }
154  });
155 
156  std::for_each(result.begin(), result.end(), [&rNodesOutput](auto pEntity) {
157  if (pEntity != nullptr) {
158  rNodesOutput.push_back(pEntity);
159  }
160  });
161  }
162 
163  template<class TContainerType, class TUnaryFunc>
164  static void AddEntities(
165  std::vector<typename TContainerType::value_type*>& rEntitiesOutput,
166  TContainerType& rMainEntityContainer,
167  TUnaryFunc&& rIsValidEntity)
168  {
169  using p_entity_type = typename TContainerType::value_type*;
170  const auto& result = block_for_each<AccumReduction<p_entity_type>>(rMainEntityContainer, CNodePointersType(), [&rIsValidEntity](auto& rMainEntity, CNodePointersType& rTLS) -> p_entity_type {
171  const auto& r_geometry = rMainEntity.GetGeometry();
172  const IndexType number_of_nodes = r_geometry.size();
173 
174  if (rTLS.size() != number_of_nodes) {
175  rTLS.resize(number_of_nodes);
176  }
177 
178  for (IndexType i = 0; i < number_of_nodes; ++i) {
179  rTLS[i] = &r_geometry[i];
180  }
181 
182  std::sort(rTLS.begin(), rTLS.end());
183 
184  if (rIsValidEntity(rTLS)) {
185  return &rMainEntity;
186  } else {
187  return nullptr;
188  }
189  });
190 
191  std::for_each(result.begin(), result.end(), [&rEntitiesOutput](auto pEntity) {
192  if (pEntity != nullptr) {
193  rEntitiesOutput.push_back(pEntity);
194  }
195  });
196  }
197 
198  template<class TModelPartOperation>
199  static void ModelPartOperation(
200  std::vector<ModelPart::NodeType*>& rOutputNodes,
201  std::vector<ModelPart::ConditionType*>& rOutputConditions,
202  std::vector<ModelPart::ElementType*>& rOutputElements,
203  ModelPart& rMainModelPart,
204  const std::vector<ModelPart const*>& rOperands,
205  const bool AddNeighbourEntities)
206  {
207  const IndexType number_of_operation_model_parts = rOperands.size();
208 
209  std::vector<std::set<ModelPart::NodeType const*>> set_operation_node_sets(number_of_operation_model_parts);
210  std::vector<std::set<CNodePointersType>> set_operation_condition_sets(number_of_operation_model_parts);
211  std::vector<std::set<CNodePointersType>> set_operation_element_sets(number_of_operation_model_parts);
212 
213  // now iterate through model parts' conditions/elements containers and get available main model part entities.
214  for (IndexType i = 0; i < number_of_operation_model_parts; ++i) {
215  auto p_model_part = rOperands[i];
216 
217  // fill the set_operation nodes
218  FillNodesPointerSet(set_operation_node_sets[i], p_model_part->Nodes());
219 
220  // fill the set_operation conditions
221  FillNodePointersForEntities(set_operation_condition_sets[i], p_model_part->Conditions());
222 
223  // fill the set_operation elements
224  FillNodePointersForEntities(set_operation_element_sets[i], p_model_part->Elements());
225  }
226 
227  AddNodes(rOutputNodes, rMainModelPart.Nodes(), [&set_operation_node_sets](auto& rEntity) {
228  return TModelPartOperation::IsValid(rEntity, set_operation_node_sets);
229  });
230 
231  AddEntities(rOutputConditions, rMainModelPart.Conditions(), [&set_operation_condition_sets](auto& rEntity) {
232  return TModelPartOperation::IsValid(rEntity, set_operation_condition_sets);
233  });
234 
235  AddEntities(rOutputElements, rMainModelPart.Elements(), [&set_operation_element_sets](auto& rEntity) {
236  return TModelPartOperation::IsValid(rEntity, set_operation_element_sets);
237  });
238 
239  // now we have all the nodes to find and add neighbour entities.
240  if (AddNeighbourEntities) {
241  // we need to fill the boundary nodes for elements and conditions
242  FillNodesFromEntities<ModelPart::ConditionType>(rOutputNodes, rOutputConditions.begin(), rOutputConditions.end());
243  FillNodesFromEntities<ModelPart::ElementType>(rOutputNodes, rOutputElements.begin(), rOutputElements.end());
244 
245  // now add all the neighbours
246  AddNeighbours(rOutputNodes, rOutputConditions, rOutputElements, rMainModelPart);
247  }
248  }
249 
250  static void FillNodesPointerSet(
251  std::set<ModelPart::NodeType const*>& rOutput,
252  const ModelPart::NodesContainerType& rNodes);
253 
254  template <class TContainerType>
255  static void FillNodePointersForEntities(
256  std::set<CNodePointersType>& rOutput,
257  const TContainerType& rEntityContainer);
258 
259  static void FillCommonNodes(
261  ModelPart::NodesContainerType& rMainNodes,
262  const std::set<ModelPart::NodeType const*>& rNodesSet);
263 
264  template<class TEntityType>
265  static void FillNodesFromEntities(
266  std::vector<ModelPart::NodeType*>& rOutput,
267  typename std::vector<TEntityType*>::iterator pEntityBegin,
268  typename std::vector<TEntityType*>::iterator pEntityEnd);
269 
270  template<class TContainerType>
271  static void FindNeighbourEntities(
272  std::vector<typename TContainerType::value_type*>& rOutputEntities,
273  const Flags& rNodeSelectionFlag,
274  TContainerType& rMainEntities);
275 
276  static void AddNeighbours(
277  std::vector<ModelPart::NodeType*>& rOutputNodes,
278  std::vector<ModelPart::ConditionType*>& rOutputConditions,
279  std::vector<ModelPart::ElementType*>& rOutputElements,
280  ModelPart& rMainModelPart);
281 
282  static void FillWithMainNodesFromSearchNodes(
284  ModelPart::NodesContainerType& rMainNodes,
285  ModelPart::NodesContainerType& rSearchedNodes);
286 
287  static void SetCommunicator(
288  ModelPart& rOutputModelPart,
289  ModelPart& rMainModelPart);
290 
291  static void FillOutputSubModelPart(
292  ModelPart& rOutputSubModelPart,
293  ModelPart& rMainModelPart,
294  std::vector<ModelPart::NodeType*>& rOutputNodes,
295  std::vector<ModelPart::ConditionType*>& rOutputConditions,
296  std::vector<ModelPart::ElementType*>& rOutputElements);
297 
298  static void CheckNodes(
299  std::vector<IndexType>& rNodeIdsWithIssues,
300  const ModelPart::NodesContainerType& rCheckNodes,
301  const std::set<ModelPart::NodeType const*>& rMainNodes);
302 
303  template<class TContainerType>
304  static void CheckEntities(
305  std::vector<IndexType>& rEntityIdsWithIssues,
306  const TContainerType& rCheckEntities,
307  const std::set<CNodePointersType>& rMainEntities);
308 
310 };
311 
313 
314 } // namespace Kratos
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
std::string FullName() const
This method returns the full name of the model part (including the parents model parts)
Definition: model_part.h:1850
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
ModelPart & GetParentModelPart()
Definition: model_part.cpp:2124
Definition: model_part_operation_utilities.h:31
std::unordered_map< KeyType, ValueType, KeyHasherRange< KeyType >, KeyComparorRange< KeyType > > RangedKeyMapType
Definition: model_part_operation_utilities.h:41
std::vector< ModelPart::NodeType const * > CNodePointersType
Definition: model_part_operation_utilities.h:38
std::size_t IndexType
Definition: model_part_operation_utilities.h:36
static void FillSubModelPart(ModelPart &rOutputSubModelPart, const ModelPart &rMainModelPart, const std::vector< ModelPart const * > &rOperands, const bool AddNeighbourEntities)
Fill a sub model part with the specified operation.
Definition: model_part_operation_utilities.h:92
This class defines the node.
Definition: node.h:65
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
integer i
Definition: TensorModule.f:17
This is a key comparer of general pourpose between two classes.
Definition: key_hash.h:100