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.
split_elements_process.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosPfemFluidApplication $
3 // Created by: $Author: AFranci $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: June 2017 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined(KRATOS_SPLIT_ELEMENTS_PROCESS_H_INCLUDED)
11 #define KRATOS_SPLIT_ELEMENTS_PROCESS_H_INCLUDED
12 
13 // System includes
14 
15 // External includes
16 
17 // Project includes
18 
20 
23 #include "includes/model_part.h"
24 
26 //Data:
27 //StepData:
28 //Flags: (checked)
29 // (set)
30 // (modified)
31 // (reset)
32 
33 namespace Kratos
34 {
35 
38 
45 
46 typedef GlobalPointersVector<Node> NodeWeakPtrVectorType;
47 typedef GlobalPointersVector<Element> ElementWeakPtrVectorType;
51 
55 
59 
61 
64  : public Process
65 {
66 public:
69 
72 
76 
79  int EchoLevel)
80  : mrModelPart(rModelPart)
81  {
82  mEchoLevel = EchoLevel;
83  }
84 
87  {
88  }
89 
90  void operator()()
91  {
92  Execute();
93  }
94 
98 
99  void Execute() override
100  {
101  std::cout << " Execute() in SplitElementsProcess" << std::endl;
102  };
103 
107 
111 
115 
119 
121  std::string Info() const override
122  {
123  return "SplitElementsProcess";
124  }
125 
127  void PrintInfo(std::ostream &rOStream) const override
128  {
129  rOStream << "SplitElementsProcess";
130  }
131 
132  void ExecuteInitialize() override
133  {
134 
135  KRATOS_TRY
136  const ProcessInfo &rCurrentProcessInfo = mrModelPart.GetProcessInfo();
137 
138  for (ModelPart::SubModelPartIterator i_mp = mrModelPart.SubModelPartsBegin(); i_mp != mrModelPart.SubModelPartsEnd(); i_mp++)
139  {
140  if ((i_mp->Is(ACTIVE) && i_mp->Is(SOLID)) || (i_mp->Is(ACTIVE) && i_mp->Is(FLUID)))
141  {
142 
143  std::string ComputingModelPartName;
144  ComputingModelPartName = i_mp->Name();
145  ModelPart &rComputingModelPart = mrModelPart.GetSubModelPart(ComputingModelPartName);
146  const unsigned int dimension = mrModelPart.ElementsBegin()->GetGeometry().WorkingSpaceDimension();
147  MesherUtilities MesherUtils;
148  double modelPartVolume = MesherUtils.ComputeModelPartVolume(rComputingModelPart);
149  double criticalVolume = 0.5 * modelPartVolume / double(rComputingModelPart.Elements().size());
150 
151  for (ElementsContainerType::iterator i_elem = rComputingModelPart.Elements().begin(); i_elem != rComputingModelPart.Elements().end(); i_elem++)
152  {
153  unsigned int numFreeSurface = 0;
154  unsigned int numRigid = 0;
155  PointsArrayType &vertices = i_elem->GetGeometry().Points();
156  const unsigned int numNodes = i_elem->GetGeometry().size();
157  for (unsigned int i = 0; i < numNodes; i++)
158  {
159  if (vertices[i].Is(FREE_SURFACE) || vertices[i].Is(ISOLATED))
160  {
161  numFreeSurface++;
162  }
163  else if (vertices[i].Is(RIGID))
164  {
165  numRigid++;
166  }
167  }
168 
169  if (dimension == 2)
170  {
171  double elementalVolume = i_elem->GetGeometry().Area();
172  if (numNodes == 3)
173  {
174  // if((numRigid+numFreeSurface)==vertices.size() && vertices.size()>2 && elementalVolume>criticalVolume){
175  if (numRigid > 0 && numFreeSurface == 0 && vertices.size() > 2 && elementalVolume > criticalVolume)
176  {
177  i_elem->Set(ACTIVE, false);
178  }
179  else
180  {
181  i_elem->Set(ACTIVE, true);
182  }
183  }
184  else
185  {
186  std::cout << "split_element_process not yet implemented for quadratic elements" << std::endl;
187  }
188  }
189  else if (dimension == 3)
190  {
191  double elementalVolume = 0;
192  if (i_elem->GetGeometry().WorkingSpaceDimension() == 3)
193  elementalVolume = i_elem->GetGeometry().Volume();
194  if (numNodes == 4)
195  {
196  if (numRigid == 0 && (numRigid + numFreeSurface) == vertices.size() && vertices.size() > 3 && elementalVolume > criticalVolume)
197  {
198  i_elem->Set(ACTIVE, false);
199  }
200  else
201  {
202  i_elem->Set(ACTIVE, true);
203  }
204  }
205  else
206  {
207  std::cout << "split_element_process not yet implemented for quadratic elements" << std::endl;
208  }
209  }
210  }
211 
212  for (ElementsContainerType::iterator i_elem = rComputingModelPart.Elements().begin(); i_elem != rComputingModelPart.Elements().end(); i_elem++)
213  {
214  if (i_elem->IsNot(ACTIVE))
215  {
216  PointsArrayType &vertices = i_elem->GetGeometry().Points();
217  bool addedNode = false;
218  ModelPart::NodeType::Pointer newNode = this->CreateAndAddNewNodeToSubModelPart(i_mp, i_elem, vertices, addedNode);
219  if (addedNode == true)
220  {
221  unsigned int rElementId = 0;
222  ModelPart::PropertiesType::Pointer pProp = i_elem->pGetProperties();
223  if (dimension == 2)
224  {
225 
226  Triangle2D3<Node> firstGeom(newNode, vertices(0), vertices(1));
227  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
228  Element::Pointer newElement = i_elem->Create(rElementId, firstGeom, pProp);
229  newElement->Set(ACTIVE, true);
230  newElement->Set(FLUID);
231  newElement->Set(TO_ERASE);
232  newElement->Initialize(rCurrentProcessInfo);
233  rComputingModelPart.AddElement(newElement);
234 
235  Triangle2D3<Node> secondGeom(newNode, vertices(2), vertices(0));
236  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
237  newElement = i_elem->Create(rElementId, secondGeom, pProp);
238  newElement->Set(ACTIVE, true);
239  newElement->Set(FLUID);
240  newElement->Set(TO_ERASE);
241  newElement->Initialize(rCurrentProcessInfo);
242  rComputingModelPart.AddElement(newElement);
243 
244  Triangle2D3<Node> thirdGeom(newNode, vertices(1), vertices(2));
245  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
246  newElement = i_elem->Create(rElementId, thirdGeom, pProp);
247  newElement->Set(ACTIVE, true);
248  newElement->Set(FLUID);
249  newElement->Set(TO_ERASE);
250  newElement->Initialize(rCurrentProcessInfo);
251  rComputingModelPart.AddElement(newElement);
252  }
253  else if (dimension == 3)
254  {
255 
256  Tetrahedra3D4<Node> firstGeom(newNode, vertices(1), vertices(2), vertices(3));
257  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
258  Element::Pointer newElement = i_elem->Create(rElementId, firstGeom, pProp);
259  newElement->Set(ACTIVE, true);
260  newElement->Set(FLUID);
261  newElement->Set(TO_ERASE);
262  newElement->Initialize(rCurrentProcessInfo);
263  rComputingModelPart.AddElement(newElement);
264 
265  Tetrahedra3D4<Node> secondGeom(vertices(0), newNode, vertices(2), vertices(3));
266  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
267  newElement = i_elem->Create(rElementId, secondGeom, pProp);
268  newElement->Set(ACTIVE, true);
269  newElement->Set(FLUID);
270  newElement->Set(TO_ERASE);
271  newElement->Initialize(rCurrentProcessInfo);
272  rComputingModelPart.AddElement(newElement);
273 
274  Tetrahedra3D4<Node> thirdGeom(vertices(0), vertices(1), newNode, vertices(3));
275  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
276  newElement = i_elem->Create(rElementId, thirdGeom, pProp);
277  newElement->Set(ACTIVE, true);
278  newElement->Set(FLUID);
279  newElement->Set(TO_ERASE);
280  newElement->Initialize(rCurrentProcessInfo);
281  rComputingModelPart.AddElement(newElement);
282 
283  Tetrahedra3D4<Node> fourthGeom(vertices(0), vertices(1), vertices(2), newNode);
284  rElementId = MesherUtilities::GetMaxElementId(mrModelPart) + 1;
285  newElement = i_elem->Create(rElementId, fourthGeom, pProp);
286  newElement->Set(ACTIVE, true);
287  newElement->Set(FLUID);
288  newElement->Set(TO_ERASE);
289  newElement->Initialize(rCurrentProcessInfo);
290  rComputingModelPart.AddElement(newElement);
291  }
292  }
293  else
294  {
295  i_elem->Set(ACTIVE, true);
296  }
297  }
298  }
299 
300  // //Sort
301  // rComputingModelPart.Nodes().Sort();
302  // rComputingModelPart.Elements().Sort();
303 
304  //Unique
305  rComputingModelPart.Nodes().Unique();
306  rComputingModelPart.Elements().Unique();
307  }
308  }
309 
310  // std::cout<<""<<mrModelPart<<std::endl;
311 
312  KRATOS_CATCH(" ")
313  }
314 
315  template <class TDataType>
316  void AddUniquePointer(GlobalPointersVector<TDataType> &v, const typename TDataType::WeakPointer candidate)
317  {
318  typename GlobalPointersVector<TDataType>::iterator i = v.begin();
319  typename GlobalPointersVector<TDataType>::iterator endit = v.end();
320  while (i != endit && (i)->Id() != (candidate)->Id())
321  {
322  i++;
323  }
324  if (i == endit)
325  {
326  v.push_back(candidate);
327  }
328  }
329 
331  ElementsContainerType::iterator i_elem,
332  PointsArrayType vertices,
333  bool &addedNode)
334  {
335 
336  unsigned int numNodes = vertices.size();
337  std::vector<std::vector<double>> ElementPointCoordinates(numNodes);
338  std::vector<double> PointCoordinates(3);
339  array_1d<double, 3> rPoint = ZeroVector(3);
340  unsigned int masterNode = 0;
341  for (unsigned int i = 0; i < vertices.size(); i++)
342  {
343  rPoint += vertices[i].Coordinates() / double(numNodes);
344  PointCoordinates[0] = vertices[i].X();
345  PointCoordinates[1] = vertices[i].Y();
346  PointCoordinates[2] = vertices[i].Z();
347  ElementPointCoordinates[i] = PointCoordinates;
348  if (vertices[i].IsNot(RIGID))
349  {
350  masterNode = i;
351  }
352  }
353  PointCoordinates[0] = rPoint[0];
354  PointCoordinates[1] = rPoint[1];
355  PointCoordinates[2] = rPoint[2];
356  unsigned int rNodeId = MesherUtilities::GetMaxNodeId(mrModelPart) + 1;
357 
358  ModelPart::NodeType::Pointer newNode = i_mp->CreateNewNode(rNodeId, rPoint[0], rPoint[1], rPoint[2]);
359 
360  //generating the dofs
361  ModelPart::NodeType::DofsContainerType &reference_dofs = vertices[masterNode].GetDofs();
362 
363  for (ModelPart::NodeType::DofsContainerType::iterator iii = reference_dofs.begin(); iii != reference_dofs.end(); iii++)
364  {
365  ModelPart::NodeType::DofType &rDof = **iii;
366  Node::DofType::Pointer p_new_dof = newNode->pAddDof(rDof);
367  (p_new_dof)->FreeDof();
368  }
369 
370  MeshDataTransferUtilities DataTransferUtilities;
371  std::vector<double> ShapeFunctionsN;
372  VariablesList &variables_list = i_mp->GetNodalSolutionStepVariablesList();
373 
374  // //giving model part variables list to the node
375  newNode->SetSolutionStepVariablesList(vertices[masterNode].pGetVariablesList());
376 
377  // //set buffer size
378  newNode->SetBufferSize(vertices[masterNode].GetBufferSize());
379  newNode->Set(FLUID);
380  newNode->Reset(FREE_SURFACE);
381  bool is_inside = false;
382  is_inside = MesherUtilities::CalculatePosition(ElementPointCoordinates, PointCoordinates, ShapeFunctionsN);
383  if (is_inside == true)
384  {
385  double alpha = 1; //1 to interpolate, 0 to leave the original data
386  DataTransferUtilities.Interpolate(i_elem->GetGeometry(), ShapeFunctionsN, variables_list, newNode, alpha);
387  newNode->Set(TO_ERASE);
388  newNode->Set(ACTIVE);
389  newNode->Set(FLUID);
390  const array_1d<double, 3> &displacement = newNode->FastGetSolutionStepValue(DISPLACEMENT);
391  newNode->X0() = newNode->X() - displacement[0];
392  newNode->Y0() = newNode->Y() - displacement[1];
393  newNode->Z0() = newNode->Z() - displacement[2];
394 
395  NodeWeakPtrVectorType &rN = newNode->GetValue(NEIGHBOUR_NODES);
396  for (unsigned int spn = 0; spn < numNodes; spn++)
397  {
398  this->AddUniquePointer<Node>(rN, i_elem->GetGeometry()(spn));
399  }
400 
401  i_mp->Nodes().push_back(newNode);
402  addedNode = true;
403  // std::cout<<" NEW NODE "<<rNodeId<<")"<<rPoint[0]<<" "<<rPoint[1]<<" "<<rPoint[2]<<std::endl;
404  }
405  else
406  {
407  addedNode = false;
408  // std::cout<<"NODE IS OUTSIDE "<<rNodeId<<")"<<rPoint[0]<<" "<<rPoint[1]<<" "<<rPoint[2]<<std::endl;
409  }
410  return newNode;
411  }
412 
413  void ExecuteFinalize() override
414  {
415 
416  KRATOS_TRY
417 
418  NodesContainerType temporal_nodes;
419  temporal_nodes.reserve(mrModelPart.Nodes().size());
420  temporal_nodes.swap(mrModelPart.Nodes());
421  mrModelPart.Nodes().clear();
422 
423  for (NodesContainerType::iterator i_node = temporal_nodes.begin(); i_node != temporal_nodes.end(); i_node++)
424  {
425  if (i_node->IsNot(TO_ERASE))
426  {
427  (mrModelPart.Nodes()).push_back(*(i_node.base()));
428  }
429  }
430  mrModelPart.Nodes().Sort();
431 
432  ElementsContainerType temporal_elements;
433  temporal_elements.reserve(mrModelPart.Elements().size());
434  temporal_elements.swap(mrModelPart.Elements());
435  mrModelPart.Elements().clear();
436  for (ElementsContainerType::iterator i_elem = temporal_elements.begin(); i_elem != temporal_elements.end(); i_elem++)
437  {
438  if (i_elem->IsNot(TO_ERASE))
439  {
440  (mrModelPart.Elements()).push_back(*(i_elem.base()));
441  }
442  }
443 
444  mrModelPart.Elements().Sort();
445 
446  KRATOS_CATCH(" ")
447  }
448 
449 protected:
452 
456 
457  //*******************************************************************************************
458  //*******************************************************************************************
459 
463 
467 
471 
473 
474 private:
477  ModelPart &mrModelPart;
478 
479  int mEchoLevel;
480 
484 
488 
492 
496 
500 
504 
506  SplitElementsProcess &operator=(SplitElementsProcess const &rOther);
507 
509  //SplitElementsProcess(SplitElementsProcess const& rOther);
510 
512 
513 }; // Class SplitElementsProcess
514 
516 
519 
523 
525 inline std::istream &operator>>(std::istream &rIStream,
526  SplitElementsProcess &rThis);
527 
529 inline std::ostream &operator<<(std::ostream &rOStream,
530  const SplitElementsProcess &rThis)
531 {
532  rThis.PrintInfo(rOStream);
533  rOStream << std::endl;
534  rThis.PrintData(rOStream);
535 
536  return rOStream;
537 }
539 
540 } // namespace Kratos.
541 
542 #endif // KRATOS_SPLIT_ELEMENTS_PROCESS_H_INCLUDED defined
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
bool Is(Flags const &rOther) const
Definition: flags.h:274
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
PointerVector< TPointType > PointsArrayType
Definition: geometry.h:118
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
Short class definition.
Definition: mesh_data_transfer_utilities.hpp:46
void Interpolate(Geometry< Node > &geom, const std::vector< double > &N, VariablesList &rVariablesList, Node::Pointer pnode, double alpha=1.0)
Definition: mesh_data_transfer_utilities.cpp:1435
Short class definition.
Definition: mesher_utilities.hpp:49
double ComputeModelPartVolume(ModelPart &rModelPart)
Definition: mesher_utilities.cpp:228
static unsigned int GetMaxNodeId(ModelPart &rModelPart)
Definition: mesher_utilities.hpp:1408
static unsigned int GetMaxElementId(ModelPart &rModelPart)
Definition: mesher_utilities.hpp:1481
static bool CalculatePosition(const std::vector< std::vector< double >> &rPointCoordinates, const std::vector< double > &rCenter, std::vector< double > &rShapeFunctionsN)
Definition: mesher_utilities.hpp:1272
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
SubModelPartIterator SubModelPartsEnd()
Definition: model_part.h:1708
SubModelPartIterator SubModelPartsBegin()
Definition: model_part.h:1698
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
SubModelPartsContainerType::iterator SubModelPartIterator
Iterator over the sub model parts of this model part.
Definition: model_part.h:258
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
ModelPart & GetSubModelPart(std::string const &SubModelPartName)
Definition: model_part.cpp:2029
void AddElement(ElementType::Pointer pNewElement, IndexType ThisIndex=0)
Definition: model_part.cpp:917
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
std::vector< std::unique_ptr< Dof< double > >> DofsContainerType
The DoF container type definition.
Definition: node.h:92
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
size_type size() const
Definition: pointer_vector.h:255
The base class for all processes in Kratos.
Definition: process.h:49
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: process.h:210
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Short class definition.
Definition: split_elements_process.hpp:65
void AddUniquePointer(GlobalPointersVector< TDataType > &v, const typename TDataType::WeakPointer candidate)
Definition: split_elements_process.hpp:316
SplitElementsProcess(ModelPart &rModelPart, int EchoLevel)
Default constructor.
Definition: split_elements_process.hpp:78
std::string Info() const override
Turn back information as a string.
Definition: split_elements_process.hpp:121
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: split_elements_process.hpp:127
KRATOS_CLASS_POINTER_DEFINITION(SplitElementsProcess)
Pointer definition of SplitElementsProcess.
void operator()()
Definition: split_elements_process.hpp:90
void ExecuteInitialize() override
This function is designed for being called at the beginning of the computations right after reading t...
Definition: split_elements_process.hpp:132
void ExecuteFinalize() override
This function is designed for being called at the end of the computations.
Definition: split_elements_process.hpp:413
ModelPart::NodeType::Pointer CreateAndAddNewNodeToSubModelPart(ModelPart::SubModelPartIterator i_mp, ElementsContainerType::iterator i_elem, PointsArrayType vertices, bool &addedNode)
Definition: split_elements_process.hpp:330
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: split_elements_process.hpp:99
virtual ~SplitElementsProcess()
Destructor.
Definition: split_elements_process.hpp:86
A four node tetrahedra geometry with linear shape functions.
Definition: tetrahedra_3d_4.h:59
A three node 2D triangle geometry with linear shape functions.
Definition: triangle_2d_3.h:74
Holds a list of variables and their position in VariablesListDataValueContainer.
Definition: variables_list.h:50
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
GlobalPointersVector< Element > ElementWeakPtrVectorType
Definition: build_model_part_boundary_process.hpp:60
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
ModelPart::NodesContainerType NodesContainerType
Definition: find_conditions_neighbours_process.h:44
GlobalPointersVector< Node > NodeWeakPtrVectorType
Definition: build_model_part_boundary_process.hpp:59
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
ModelPart::ElementsContainerType ElementsContainerType
Definition: clear_contact_conditions_mesher_process.hpp:43
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
GeometryType::PointsArrayType PointsArrayType
Definition: settle_model_structure_process.hpp:48
v
Definition: generate_convection_diffusion_explicit_element.py:114
alpha
Definition: generate_convection_diffusion_explicit_element.py:113
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
integer i
Definition: TensorModule.f:17