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.
set_active_flag_mesher_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: August 2017 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined(KRATOS_SET_ACTIVE_FLAG_MESHER_PROCESS_H_INCLUDED)
11 #define KRATOS_SET_ACTIVE_FLAG_MESHER_PROCESS_H_INCLUDED
12 
13 // System includes
14 
15 // External includes
16 
17 // Project includes
18 
20 
23 #include "includes/model_part.h"
24 #include "utilities/openmp_utils.h"
25 #include "utilities/math_utils.h"
26 
28 //Data:
29 //StepData:
30 //Flags: (checked)
31 // (set)
32 // (modified)
33 // (reset)
34 
35 namespace Kratos
36 {
37 
40 
47 
48  typedef GlobalPointersVector<Node> NodeWeakPtrVectorType;
49  typedef GlobalPointersVector<Element> ElementWeakPtrVectorType;
50 
54 
58 
62 
64 
67  : public SetActiveFlagProcess
68  {
69  public:
72 
75 
79 
82  bool unactivePeakElements,
83  bool unactiveSliverElements,
84  int EchoLevel)
85  : SetActiveFlagProcess(rModelPart, unactivePeakElements, unactiveSliverElements, EchoLevel)
86  {
87  }
88 
91  {
92  }
93 
94  void operator()()
95  {
96  Execute();
97  }
98 
102 
103  void Execute() override{
104 
105  KRATOS_TRY
106 #pragma omp parallel
107  {
108  double tolerance = 0.0000000001;
109  const ProcessInfo &rCurrentProcessInfo = mrModelPart.GetProcessInfo();
110  const double timeInterval = rCurrentProcessInfo[DELTA_TIME];
111  const unsigned int dimension = mrModelPart.ElementsBegin()->GetGeometry().WorkingSpaceDimension();
112  unsigned int sliversDetectedFromVolume = 0;
113  unsigned int sliversDetectedFromShape = 0;
114  // const unsigned int dimension = (itElem)->GetGeometry().WorkingSpaceDimension();
115  ModelPart::ElementIterator ElemBegin;
118  double ModelPartVolume = 0;
119  if (mUnactiveSliverElements == true)
120  {
121  MesherUtilities MesherUtils;
122  ModelPartVolume = MesherUtils.ComputeModelPartVolume(mrModelPart);
123  }
124  for (ModelPart::ElementIterator itElem = ElemBegin; itElem != ElemEnd; ++itElem)
125  {
126  bool sliverEliminationCriteria = false;
127  bool peakElementsEliminationCriteria = false;
128  bool wallElementsEliminationCriteria = false;
129  unsigned int numNodes = itElem->GetGeometry().size();
130 
131  // ELIMINATION CHECK FOR SLIVERS
132  if (mUnactiveSliverElements == true && numNodes == (dimension + 1))
133  {
134  double ElementalVolume = 0;
135  if (dimension == 2)
136  {
137  ElementalVolume = (itElem)->GetGeometry().Area();
138  }
139  else if (dimension == 3)
140  {
141  ElementalVolume = 0;
142  if (itElem->GetGeometry().WorkingSpaceDimension() == 3)
143  ElementalVolume = (itElem)->GetGeometry().Volume();
144  }
145  else
146  {
147  ElementalVolume = 0;
148  }
149  double CriticalVolume = 0.005 * ModelPartVolume / double(mrModelPart.Elements().size());
150  // if(ElementalVolume<CriticalVolume && ElementalVolume>0){
151  if (fabs(ElementalVolume) < CriticalVolume)
152  {
153  sliverEliminationCriteria = true;
154  sliversDetectedFromVolume++;
155  // std::cout << "RESET ACTIVE FOR THIS SLIVER! \t";
156  // std::cout << "its volume is " << ElementalVolume << " vs CriticalVolume " << CriticalVolume <<"number of elements= "<<mrModelPart.Elements().size()<<std::endl;
157  // for (unsigned int i = 0; i < numNodes; i++)
158  // {
159  // itElem->GetGeometry()[i].Set(ACTIVE,true);
160  // }
161  }
162 
163  if (sliverEliminationCriteria == false && dimension == 3)
164  {
165 
166  array_1d<double, 3> nodeA = itElem->GetGeometry()[0].Coordinates();
167  array_1d<double, 3> nodeB = itElem->GetGeometry()[1].Coordinates();
168  array_1d<double, 3> nodeC = itElem->GetGeometry()[2].Coordinates();
169  array_1d<double, 3> nodeD = itElem->GetGeometry()[3].Coordinates();
170 
171  double a1 = 0; //slope x for plane on the first triangular face of the tetrahedra (nodes A,B,C)
172  double b1 = 0; //slope y for plane on the first triangular face of the tetrahedra (nodes A,B,C)
173  double c1 = 0; //slope z for plane on the first triangular face of the tetrahedra (nodes A,B,C)
174  a1 = (nodeB[1] - nodeA[1]) * (nodeC[2] - nodeA[2]) - (nodeC[1] - nodeA[1]) * (nodeB[2] - nodeA[2]);
175  b1 = (nodeB[2] - nodeA[2]) * (nodeC[0] - nodeA[0]) - (nodeC[2] - nodeA[2]) * (nodeB[0] - nodeA[0]);
176  c1 = (nodeB[0] - nodeA[0]) * (nodeC[1] - nodeA[1]) - (nodeC[0] - nodeA[0]) * (nodeB[1] - nodeA[1]);
177  double a2 = 0; //slope x for plane on the second triangular face of the tetrahedra (nodes A,B,D)
178  double b2 = 0; //slope y for plane on the second triangular face of the tetrahedra (nodes A,B,D)
179  double c2 = 0; //slope z for plane on the second triangular face of the tetrahedra (nodes A,B,D)
180  a2 = (nodeB[1] - nodeA[1]) * (nodeD[2] - nodeA[2]) - (nodeD[1] - nodeA[1]) * (nodeB[2] - nodeA[2]);
181  b2 = (nodeB[2] - nodeA[2]) * (nodeD[0] - nodeA[0]) - (nodeD[2] - nodeA[2]) * (nodeB[0] - nodeA[0]);
182  c2 = (nodeB[0] - nodeA[0]) * (nodeD[1] - nodeA[1]) - (nodeD[0] - nodeA[0]) * (nodeB[1] - nodeA[1]);
183  double a3 = 0; //slope x for plane on the third triangular face of the tetrahedra (nodes B,C,D)
184  double b3 = 0; //slope y for plane on the third triangular face of the tetrahedra (nodes B,C,D)
185  double c3 = 0; //slope z for plane on the third triangular face of the tetrahedra (nodes B,C,D)
186  a3 = (nodeB[1] - nodeC[1]) * (nodeD[2] - nodeC[2]) - (nodeD[1] - nodeC[1]) * (nodeB[2] - nodeC[2]);
187  b3 = (nodeB[2] - nodeC[2]) * (nodeD[0] - nodeC[0]) - (nodeD[2] - nodeC[2]) * (nodeB[0] - nodeC[0]);
188  c3 = (nodeB[0] - nodeC[0]) * (nodeD[1] - nodeC[1]) - (nodeD[0] - nodeC[0]) * (nodeB[1] - nodeC[1]);
189  double a4 = 0; //slope x for plane on the fourth triangular face of the tetrahedra (nodes A,C,D)
190  double b4 = 0; //slope y for plane on the fourth triangular face of the tetrahedra (nodes A,C,D)
191  double c4 = 0; //slope z for plane on the fourth triangular face of the tetrahedra (nodes A,C,D)
192  a4 = (nodeA[1] - nodeC[1]) * (nodeD[2] - nodeC[2]) - (nodeD[1] - nodeC[1]) * (nodeA[2] - nodeC[2]);
193  b4 = (nodeA[2] - nodeC[2]) * (nodeD[0] - nodeC[0]) - (nodeD[2] - nodeC[2]) * (nodeA[0] - nodeC[0]);
194  c4 = (nodeA[0] - nodeC[0]) * (nodeD[1] - nodeC[1]) - (nodeD[0] - nodeC[0]) * (nodeA[1] - nodeC[1]);
195 
196  double cosAngle12 = (a1 * a2 + b1 * b2 + c1 * c2) / (sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2)) * sqrt(pow(a2, 2) + pow(b2, 2) + pow(c2, 2)));
197  double cosAngle13 = (a1 * a3 + b1 * b3 + c1 * c3) / (sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2)) * sqrt(pow(a3, 2) + pow(b3, 2) + pow(c3, 2)));
198  double cosAngle14 = (a1 * a4 + b1 * b4 + c1 * c4) / (sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2)) * sqrt(pow(a4, 2) + pow(b4, 2) + pow(c4, 2)));
199  double cosAngle23 = (a3 * a2 + b3 * b2 + c3 * c2) / (sqrt(pow(a3, 2) + pow(b3, 2) + pow(c3, 2)) * sqrt(pow(a2, 2) + pow(b2, 2) + pow(c2, 2)));
200  double cosAngle24 = (a4 * a2 + b4 * b2 + c4 * c2) / (sqrt(pow(a4, 2) + pow(b4, 2) + pow(c4, 2)) * sqrt(pow(a2, 2) + pow(b2, 2) + pow(c2, 2)));
201  double cosAngle34 = (a4 * a3 + b4 * b3 + c4 * c3) / (sqrt(pow(a4, 2) + pow(b4, 2) + pow(c4, 2)) * sqrt(pow(a3, 2) + pow(b3, 2) + pow(c3, 2)));
202 
203  // if two faces are coplanar, I will erase the element (which is probably a sliver)
204  double limit = 0.99999;
205  if (fabs(cosAngle12) > limit || fabs(cosAngle13) > limit || fabs(cosAngle14) > limit || fabs(cosAngle23) > limit || fabs(cosAngle24) > limit || fabs(cosAngle34) > limit)
206  {
207  unsigned int fsNodes = 0;
208  for (unsigned int i = 0; i < numNodes; i++)
209  {
210  if (itElem->GetGeometry()[i].Is(FREE_SURFACE))
211  {
212  fsNodes++;
213  }
214  NodeWeakPtrVectorType &rN = itElem->GetGeometry()[i].GetValue(NEIGHBOUR_NODES);
215  unsigned int neighborNodes = rN.size();
216  if (neighborNodes == numNodes)
217  {
218  fsNodes = 4;
219  // std::cout << "ATTENTION WITH THIS, ONE NODE COULD BE ALONE IN THE LINEAR SYSTEM" << std::endl;
220  }
221  }
222  if (fsNodes < 3)
223  {
224  sliverEliminationCriteria = true;
225  sliversDetectedFromShape++;
226  }
227  }
228  }
229  }
230 
231  // ELIMINATION CHECK FOR PEAK ELEMENTS (those annoying elements created by pfem remeshing and placed bewteen the free-surface and the walls)
232  if (mUnactivePeakElements == true && sliverEliminationCriteria == false)
233  {
234  double scalarProduct = 1.0;
235  bool doNotErase = false;
236  unsigned int elementRigidNodes = 0;
237  for (unsigned int i = 0; i < numNodes; i++)
238  {
239  if (itElem->GetGeometry()[i].Is(RIGID) && itElem->GetGeometry()[i].IsNot(SOLID))
240  {
241  elementRigidNodes++;
242  }
243  if (itElem->GetGeometry()[i].IsNot(RIGID) && itElem->GetGeometry()[i].IsNot(FREE_SURFACE))
244  {
245  peakElementsEliminationCriteria = false;
246  doNotErase = true;
247  // break;
248  }
249  else if (itElem->GetGeometry()[i].Is(RIGID) && itElem->GetGeometry()[i].IsNot(SOLID) && itElem->GetGeometry()[i].Is(FREE_SURFACE) && doNotErase == false)
250  {
251  peakElementsEliminationCriteria = true;
252  const array_1d<double, 3> &wallVelocity = itElem->GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
253  double normWallVelocity = norm_2(wallVelocity);
254  if (normWallVelocity == 0)
255  { // up to now this is for fixed walls only
256  for (unsigned int j = 0; j < numNodes; j++)
257  {
258 
259  if (itElem->GetGeometry()[j].IsNot(RIGID) && itElem->GetGeometry()[j].Is(FREE_SURFACE))
260  {
261  Point freeSurfaceToRigidNodeVector = Point{itElem->GetGeometry()[i].Coordinates() - itElem->GetGeometry()[j].Coordinates()};
262  const array_1d<double, 3> &freeSurfaceVelocity = itElem->GetGeometry()[j].FastGetSolutionStepValue(VELOCITY);
263 
264  double freeSurfaceToRigidNodeDistance = sqrt(freeSurfaceToRigidNodeVector[0] * freeSurfaceToRigidNodeVector[0] +
265  freeSurfaceToRigidNodeVector[1] * freeSurfaceToRigidNodeVector[1] +
266  freeSurfaceToRigidNodeVector[2] * freeSurfaceToRigidNodeVector[2]);
267  double displacementFreeSurface = timeInterval * (sqrt(freeSurfaceVelocity[0] * freeSurfaceVelocity[0] +
268  freeSurfaceVelocity[1] * freeSurfaceVelocity[1] +
269  freeSurfaceVelocity[2] * freeSurfaceVelocity[2]));
270  if (dimension == 2)
271  {
272  scalarProduct = freeSurfaceToRigidNodeVector[0] * freeSurfaceVelocity[0] + freeSurfaceToRigidNodeVector[1] * freeSurfaceVelocity[1];
273  }
274  else if (dimension == 3)
275  {
276  scalarProduct = freeSurfaceToRigidNodeVector[0] * freeSurfaceVelocity[0] + freeSurfaceToRigidNodeVector[1] * freeSurfaceVelocity[1] + freeSurfaceToRigidNodeVector[2] * freeSurfaceVelocity[2];
277  }
278  if (scalarProduct > tolerance && displacementFreeSurface > (0.01 * freeSurfaceToRigidNodeDistance))
279  {
280  // if(scalarProduct>tolerance){
281  peakElementsEliminationCriteria = false;
282  doNotErase = true;
283  break;
284  }
285  else
286  {
287  // I will not unactive the element if the free-surface node is sorrounded by rigd nodes only
288  NodeWeakPtrVectorType &rN = itElem->GetGeometry()[j].GetValue(NEIGHBOUR_NODES);
289  unsigned int rigidNodes = 0;
290  unsigned int freeSurfaceNodes = 0;
291  for (unsigned int i = 0; i < rN.size(); i++)
292  {
293  if (rN[i].Is(RIGID) && rN[i].IsNot(SOLID))
294  rigidNodes += 1;
295  if (rN[i].Is(FREE_SURFACE) && rN[i].IsNot(RIGID))
296  freeSurfaceNodes += 1;
297  }
298  if (dimension == 2)
299  {
300  if (rigidNodes == rN.size())
301  {
302  peakElementsEliminationCriteria = false;
303  doNotErase = true;
304  break;
305  }
306  }
307  else if (dimension == 3)
308  {
309  if (rigidNodes == rN.size() || freeSurfaceNodes == 1 || (scalarProduct > tolerance && freeSurfaceNodes < 4))
310  {
311  peakElementsEliminationCriteria = false;
312  doNotErase = true;
313  break;
314  }
315  }
316  }
317  }
318  }
319  }
320  }
321  }
322  if (elementRigidNodes == numNodes)
323  {
324  wallElementsEliminationCriteria = true;
325  Geometry<Node> wallElementNodes = itElem->GetGeometry();
326  this->SetPressureToIsolatedWallNodes(wallElementNodes);
327  }
328  }
329  // ELIMINATION CHECK FOR ELEMENTS FORMED BY WALL PARTICLES ONLY (this is included for computational efficiency purpose also in the previous peak element check)
330  else if (mUnactivePeakElements == false)
331  {
332  unsigned int elementRigidNodes = 0;
333  for (unsigned int i = 0; i < numNodes; i++)
334  {
335  if (itElem->GetGeometry()[i].Is(RIGID) && itElem->GetGeometry()[i].IsNot(SOLID))
336  {
337  elementRigidNodes++;
338  }
339  }
340 
341  if (elementRigidNodes == numNodes)
342  {
343  wallElementsEliminationCriteria = true;
344  Geometry<Node> wallElementNodes = itElem->GetGeometry();
345  this->SetPressureToIsolatedWallNodes(wallElementNodes);
346  }
347  }
348 
349  if (sliverEliminationCriteria == true || peakElementsEliminationCriteria == true || wallElementsEliminationCriteria == true)
350  {
351  (itElem)->Set(ACTIVE, false);
352  }
353  else
354  {
355  (itElem)->Set(ACTIVE, true);
356  }
357  }
358  // if (sliversDetectedFromShape > 0)
359  // {
360  // std::cout << "I have set ACTIVE=false to " << sliversDetectedFromShape << " slivers due to shape." << std::endl;
361  // }
362  // if (sliversDetectedFromVolume > 0)
363  // {
364  // std::cout << "I have set ACTIVE=false to " << sliversDetectedFromVolume << " slivers due to volume." << std::endl;
365  // }
366  }
367 
368  KRATOS_CATCH(" ")
369 }; // namespace Kratos
370 
374 
378 
382 
386 
388 std::string Info() const override
389 {
390  return "SetActiveFlagMesherProcess";
391 }
392 
394 void PrintInfo(std::ostream &rOStream) const override
395 {
396  rOStream << "SetActiveFlagMesherProcess";
397 }
398 
399 protected:
402 
406 
410 
414 
418 
420 
421 private:
424 
428 
432 
436 
440 
444 
448 
451 
453 //SetActiveFlagMesherProcess(SetActiveFlagMesherProcess const& rOther);
454 
456 }
457 ; // Class SetActiveFlagMesherProcess
458 
460 
463 
467 
469 inline std::istream &operator>>(std::istream &rIStream,
471 
473 inline std::ostream &operator<<(std::ostream &rOStream,
474  const SetActiveFlagMesherProcess &rThis)
475 {
476  rThis.PrintInfo(rOStream);
477  rOStream << std::endl;
478  rThis.PrintData(rOStream);
479 
480  return rOStream;
481 }
483 
484 } // namespace Kratos.
485 
486 #endif // KRATOS_SET_ACTIVE_FLAG_MESHER_PROCESS_H_INCLUDED defined
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
bool Is(Flags const &rOther) const
Definition: flags.h:274
Geometry base class.
Definition: geometry.h:71
PointerVector< TPointType > PointsArrayType
Definition: geometry.h:118
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
size_type size() const
Definition: global_pointers_vector.h:307
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: mesher_process.hpp:157
Short class definition.
Definition: mesher_utilities.hpp:49
double ComputeModelPartVolume(ModelPart &rModelPart)
Definition: mesher_utilities.cpp:228
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
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
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
MeshType::ElementIterator ElementIterator
Definition: model_part.h:174
static void PartitionedIterators(TVector &rVector, typename TVector::iterator &rBegin, typename TVector::iterator &rEnd)
Generate a partition for an std::vector-like array, providing iterators to the begin and end position...
Definition: openmp_utils.h:179
Point class.
Definition: point.h:59
CoordinatesArrayType const & Coordinates() const
Definition: point.h:215
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Short class definition.
Definition: set_active_flag_mesher_process.hpp:68
void operator()()
Definition: set_active_flag_mesher_process.hpp:94
KRATOS_CLASS_POINTER_DEFINITION(SetActiveFlagMesherProcess)
Pointer definition of SetActiveFlagMesherProcess.
std::string Info() const override
Turn back information as a string.
Definition: set_active_flag_mesher_process.hpp:388
SetActiveFlagMesherProcess(ModelPart &rModelPart, bool unactivePeakElements, bool unactiveSliverElements, int EchoLevel)
Default constructor.
Definition: set_active_flag_mesher_process.hpp:81
virtual ~SetActiveFlagMesherProcess()
Destructor.
Definition: set_active_flag_mesher_process.hpp:90
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: set_active_flag_mesher_process.hpp:394
void Execute() override
Execute method is used to execute the MesherProcess algorithms.
Definition: set_active_flag_mesher_process.hpp:103
Short class definition.
Definition: set_active_flag_process.hpp:69
void SetPressureToIsolatedWallNodes(Geometry< Node > &wallElementNodes)
Definition: set_active_flag_process.hpp:203
bool mUnactiveSliverElements
Definition: set_active_flag_process.hpp:198
bool mUnactivePeakElements
Definition: set_active_flag_process.hpp:197
ModelPart & mrModelPart
Definition: set_active_flag_process.hpp:194
#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
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
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
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
int j
Definition: quadrature.py:648
limit
Definition: run_t_junction_analysis.py:8
integer i
Definition: TensorModule.f:17