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.
remove_fluid_nodes_mesher_process.hpp
Go to the documentation of this file.
1 //
2 // Project Name: KratosPfemFluidApplication $
3 // Created by: $Author: JMCarbonell $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: July 2018 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 #if !defined(KRATOS_REMOVE_FLUID_NODES_MESHER_PROCESS_H_INCLUDED )
11 #define KRATOS_REMOVE_FLUID_NODES_MESHER_PROCESS_H_INCLUDED
12 
13 
14 // External includes
15 
16 // System includes
17 
18 // Project includes
20 
22 //Data: NORMAL, MASTER_NODES, NEIGHBOUR_NODES, NEIGBOUR_ELEMENTS
23 //StepData: MEAN_ERROR
24 //Flags: (checked) TO_ERASE, BOUNDARY, STRUCTURE, NEW_ENTITY, BLOCKED
25 // (set) TO_ERASE(conditions,nodes)(set), NEW_ENTITY(conditions,nodes)(set), BLOCKED(nodes)->locally, VISITED(nodes)(set)
26 // (modified)
27 // (reset) BLOCKED->locally
28 //(set):=(set in this process)
29 
30 namespace Kratos
31 {
32 
35 
37 
40 {
41  public:
44 
47 
51  typedef Bucket<3, Node, std::vector<Node::Pointer>, Node::Pointer, std::vector<Node::Pointer>::iterator, std::vector<double>::iterator > BucketType;
54 
61 
64  MesherUtilities::MeshingParameters& rRemeshingParameters,
65  int EchoLevel)
66  : RemoveNodesMesherProcess(rModelPart,rRemeshingParameters,EchoLevel)
67  {
68  }
69 
70 
73 
74 
78 
80  void operator()()
81  {
82  Execute();
83  }
84 
85 
98 
100  std::string Info() const override
101  {
102  return "RemoveFluidNodesMesherProcess";
103  }
104 
106  void PrintInfo(std::ostream& rOStream) const override
107  {
108  rOStream << "RemoveFluidNodesMesherProcess";
109  }
110 
112  void PrintData(std::ostream& rOStream) const override
113  {
114  }
115 
116 
120 
122 
123  protected:
124 
136 
137  bool RemoveNodesOnDistance(ModelPart& rModelPart, unsigned int& inside_nodes_removed, unsigned int& boundary_nodes_removed, bool& any_condition_removed) override
138  {
139  KRATOS_TRY
140 
141  const unsigned int dimension = rModelPart.ElementsBegin()->GetGeometry().WorkingSpaceDimension();
142 
143  //***SIZES :::: parameters do define the tolerance in mesh size:
144  double size_for_distance_inside = 2.0 * mrRemesh.Refine->CriticalRadius; //compared with element radius
145  double size_for_distance_boundary = 1.5 * size_for_distance_inside; //compared with element radius
146 
147  bool any_node_removed = false;
148 
149  //bucket size definition:
150  unsigned int bucket_size = 20;
151 
152  //create the list of the nodes to be check during the search
153  std::vector<Node::Pointer> list_of_nodes;
154  list_of_nodes.reserve(rModelPart.NumberOfNodes());
155  for(ModelPart::NodesContainerType::iterator i_node = rModelPart.NodesBegin() ; i_node != rModelPart.NodesEnd() ; ++i_node)
156  {
157  (list_of_nodes).push_back(*i_node.base());
158  }
159 
160  KdtreeType nodes_tree(list_of_nodes.begin(),list_of_nodes.end(), bucket_size);
161 
163 
164  //all of the nodes in this list will be preserved
165  unsigned int num_neighbours = 20;
166 
167  std::vector<Node::Pointer> neighbours (num_neighbours);
168  std::vector<double> neighbour_distances(num_neighbours);
169 
170 
171  //radius means the distance, if the distance between two nodes is closer to radius -> mark for removing
172  double radius=0;
173  Node work_point(0,0.0,0.0,0.0);
174  unsigned int n_points_in_radius;
175 
176 
177  for(ModelPart::NodesContainerType::const_iterator in = rModelPart.NodesBegin(); in != rModelPart.NodesEnd(); ++in)
178  {
179  if(in->Is(TO_ERASE)){
180  any_node_removed = true;
181  std::cout<<" TO_ERASE "<<in->Id()<<" "<<in->Coordinates()<<std::endl;
182  }
183 
184  if( in->IsNot(NEW_ENTITY) && in->IsNot(BLOCKED) && in->IsNot(SOLID) && in->IsNot(TO_ERASE) )
185  {
186  radius = size_for_distance_inside;
187 
188  work_point.Coordinates()=in->Coordinates();
189 
190  unsigned int FreeSurfaceNeighbours=0;
191  unsigned int RigidNeighbours=0;
192  NodeWeakPtrVectorType& nNodes = in->GetValue(NEIGHBOUR_NODES);
193  for(auto& i_nnode : nNodes)
194  {
195  if(i_nnode.Is(BLOCKED) || i_nnode.Is(SOLID)){
196  ++RigidNeighbours;
197  }
198  if(i_nnode.Is(FREE_SURFACE)){
199  ++FreeSurfaceNeighbours;
200  }
201  }
202 
203  if(in->Is(FREE_SURFACE)){ // it must be more difficult to erase a free_surface node, otherwise, lot of volume is lost
204 
205  if( RigidNeighbours == nNodes.size() ){
206  radius*=0.25;
207  }
208  else{
209  radius*=0.85;
210  }
211 
212  }
213 
214  n_points_in_radius = nodes_tree.SearchInRadius(work_point, radius, neighbours.begin(),neighbour_distances.begin(), num_neighbours);
215 
216  if (n_points_in_radius>1)
217  {
218  //std::cout<<" Points in Radius "<< n_points_in_radius<<" radius "<<radius<<std::endl;
219  if ( in->IsNot(BOUNDARY) )
220  {
221  if( this->mrRemesh.Refine->RemovingOptions.Is(MesherUtilities::REMOVE_NODES_ON_DISTANCE) ){
222 
223  // if the node is close to the surface, do not erase it, move to a mean (laplacian) position
224  if(in->IsNot(FREE_SURFACE) && FreeSurfaceNeighbours>=dimension){
225  this->MoveInsideNode((*in));
226  }
227  else{
228  if( !this->CheckEngagedNode((*in),neighbours,neighbour_distances,n_points_in_radius) ){ //we release the node if no other nodes neighbours are being erased
229  in->Set(TO_ERASE);
230  any_node_removed = true;
231  ++inside_nodes_removed;
232  //std::cout<<" Distance Criterion Node ["<<in->Id()<<"] TO_ERASE "<<in->Coordinates()<<std::endl;
233  }
234  }
235  }
236 
237  }
238  else{
239 
240  // std::cout<<" Remove close boundary nodes: Candidate ["<<in->Id()<<"]"<<std::endl;
241  bool engaged_node = false;
242  unsigned int counter = 0;
243  for(std::vector<Node::Pointer>::iterator nn=neighbours.begin(); nn!=neighbours.begin() + n_points_in_radius ; ++nn)
244  {
245 
246  if ( (*nn)->Is(BOUNDARY) && (neighbour_distances[counter] < 2.0 * size_for_distance_boundary) && (neighbour_distances[counter] > 0.0) )
247  {
248  if((*nn)->Is(TO_ERASE) || (*nn)->Is(BLOCKED)){
249  engaged_node = true;
250  break;
251  }
252  }
253 
254  ++counter;
255  }
256 
257  if(!engaged_node && in->IsNot(BLOCKED)){ //Can be inserted in the boundary refine
258  in->Set(TO_ERASE);
259  ++boundary_nodes_removed;
260  //std::cout<<" Removed Boundary Node ["<<in->Id()<<"] on Distance "<<std::endl;
261  }
262 
263  }
264 
265 
266  }
267  }
268  }
269 
270  if( boundary_nodes_removed > 0 )
271  this->MoveBoundaries(rModelPart,boundary_nodes_removed);
272 
273  if( boundary_nodes_removed > 0 )
274  any_node_removed = true;
275 
276 
277  bool critical_nodes_removed = false;
278  critical_nodes_removed = this->EraseCriticalNodes(rModelPart,inside_nodes_removed);
279 
280  if( any_node_removed || critical_nodes_removed )
281  any_node_removed = true;
282 
283 
284  //Build boundary after removing boundary nodes due distance criterion
285  if( this->mEchoLevel > 0 ){
286  std::cout<<"boundary_nodes_removed "<<boundary_nodes_removed<<std::endl;
287  std::cout<<"inside_nodes_removed "<<inside_nodes_removed<<std::endl;
288  std::cout<<"critical_nodes_removed "<<critical_nodes_removed<<std::endl;
289  }
290 
291  //Build boundary after removing boundary nodes due distance criterion
292  // if(boundary_nodes_removed){
293  // std::cout<<" Rebuild boundary needed after release on Distance "<<std::endl;
294  // //any_condition_removed = this->RebuildBoundary(rModelPart);
295  // }
296 
297  return any_node_removed;
298 
299  KRATOS_CATCH(" ")
300 
301  }
302 
303 
314 
315  private:
316 
328 
329  //**************************************************************************
330  //**************************************************************************
331 
332  void MoveBoundaries(ModelPart& rModelPart, unsigned int& boundary_nodes_removed)
333  {
334 
335  KRATOS_TRY
336 
337  for(ModelPart::ConditionsContainerType::const_iterator i_cond = rModelPart.ConditionsBegin(); i_cond != rModelPart.ConditionsEnd(); ++i_cond)
338  {
339  Condition::GeometryType& rGeometry = i_cond->GetGeometry();
340  unsigned int NumberOfVertices = rGeometry.size();
341 
342  unsigned int counter = 0;
343  int id = -1;
344  for(unsigned int i=0; i<NumberOfVertices; ++i)
345  {
346  if(rGeometry[i].Is(TO_ERASE)){
347  id = i;
348  ++counter;
349  }
350 
351  }
352 
353  if(counter==1 && id>=0){
354 
355  if( this->MoveBoundaryNode(rGeometry[id]) ){
356  rGeometry[id].Set(TO_ERASE,false);
357  --boundary_nodes_removed;
358  }
359 
360  }
361  }
362 
363  KRATOS_CATCH( "" )
364  }
365 
366  //**************************************************************************
367  //**************************************************************************
368 
369  bool CheckApproachingPoint(Node& rNode, Node& rEdgeNode)
370  {
371  KRATOS_TRY
372 
373  bool approaching_point = false;
374 
375  array_1d<double,3> EdgeVelocity = rEdgeNode.FastGetSolutionStepValue(VELOCITY);
376 
377  array_1d<double,3> Direction = rEdgeNode.FastGetSolutionStepValue(NORMAL);
378  if( norm_2(Direction) )
379  Direction /= norm_2(Direction);
380 
381  array_1d<double,3> Distance = (rEdgeNode.Coordinates()-rNode.Coordinates());
382  double distance = inner_prod(Distance, Direction);
383  Distance = distance * Direction;
384 
385  array_1d<double,3> VelocityDirection = rNode.FastGetSolutionStepValue(VELOCITY);
386 
387  double velocity = norm_2(VelocityDirection);
388  if(velocity!=0)
389  VelocityDirection/=velocity;
390 
391  //different velocity directions
392  if( inner_prod( EdgeVelocity, VelocityDirection ) < 0 ){
393  //node velocity direction towards edge
394  if( inner_prod( Distance, VelocityDirection ) > 0 )
395  approaching_point = true;
396  else
397  approaching_point = false;
398  } //same velocity directions
399  else if( velocity > 0.1 * norm_2(EdgeVelocity) ){
400  //node velocity direction towards edge
401  if( inner_prod( Distance, VelocityDirection ) > 0 )
402  approaching_point = true;
403  else
404  approaching_point = false;
405  }
406 
407  return approaching_point;
408 
409  KRATOS_CATCH( "" )
410  }
411 
412  //**************************************************************************
413  //**************************************************************************
414 
415  bool CheckApproachingEdge(Node& rNode, Node& rEdgeNodeA, Node& rEdgeNodeB)
416  {
417  KRATOS_TRY
418 
419  bool approaching_edge = false;
420 
421  array_1d<double,3> EdgeVelocity = 0.5 * (rEdgeNodeA.FastGetSolutionStepValue(VELOCITY)+rEdgeNodeB.FastGetSolutionStepValue(VELOCITY));
422  array_1d<double,3> MidPoint = 0.5 * (rEdgeNodeA.Coordinates() + rEdgeNodeB.Coordinates());
423 
424  array_1d<double,3> Direction;
425  this->GetDirectionToEdge(Direction,rEdgeNodeA,rEdgeNodeB);
426 
427  array_1d<double,3> Distance = (MidPoint-rNode.Coordinates());
428  double distance = inner_prod(Distance, Direction);
429  Distance = distance * Direction;
430 
431  array_1d<double,3> VelocityDirection = rNode.FastGetSolutionStepValue(VELOCITY);
432 
433  double velocity = norm_2(VelocityDirection);
434  if(velocity!=0)
435  VelocityDirection/=velocity;
436 
437  //different velocity directions
438  if( inner_prod( EdgeVelocity, VelocityDirection ) < 0 ){
439  //node velocity direction towards edge
440  if( inner_prod( Distance, VelocityDirection ) > 0 )
441  approaching_edge = true;
442  else
443  approaching_edge = false;
444  } //same velocity directions
445  else if( velocity > 0.1 * norm_2(EdgeVelocity) ){
446  //node velocity direction towards edge
447  if( inner_prod( Distance, VelocityDirection ) > 0 )
448  approaching_edge = true;
449  else
450  approaching_edge = false;
451  }
452 
453  return approaching_edge;
454 
455  KRATOS_CATCH( "" )
456  }
457 
458 
459  //**************************************************************************
460  //**************************************************************************
461 
462  bool CheckApproachingFace(Node& rNode, Node& rEdgeNodeA, Node& rEdgeNodeB, Node& rEdgeNodeC)
463  {
464  KRATOS_TRY
465 
466  bool approaching_face = false;
467 
468  array_1d<double,3> EdgeVelocity = (1.0/3.0) * (rEdgeNodeA.FastGetSolutionStepValue(VELOCITY)+rEdgeNodeB.FastGetSolutionStepValue(VELOCITY)+rEdgeNodeC.FastGetSolutionStepValue(VELOCITY));
469  array_1d<double,3> MidPoint = (1.0/3.0) * (rEdgeNodeA.Coordinates() + rEdgeNodeB.Coordinates() + rEdgeNodeC.Coordinates());
470 
471  array_1d<double,3> Direction;
472  this->GetDirectionToFace(Direction,rEdgeNodeA,rEdgeNodeB,rEdgeNodeC);
473 
474  array_1d<double,3> Distance = (MidPoint-rNode.Coordinates());
475  double distance = inner_prod(Distance, Direction);
476  Distance = distance * Direction;
477 
478  array_1d<double,3> VelocityDirection = rNode.FastGetSolutionStepValue(VELOCITY);
479 
480  double velocity = norm_2(VelocityDirection);
481  if(velocity!=0)
482  VelocityDirection/=velocity;
483 
484  //different velocity directions
485  if( inner_prod( EdgeVelocity, VelocityDirection ) < 0 ){
486  //node velocity direction towards edge
487  if( inner_prod( Distance, VelocityDirection ) > 0 )
488  approaching_face = true;
489  else
490  approaching_face = false;
491  } //same velocity directions
492  else if( velocity > 0.1 * norm_2(EdgeVelocity) ){
493  //node velocity direction towards edge
494  if( inner_prod( Distance, VelocityDirection ) > 0 )
495  approaching_face = true;
496  else
497  approaching_face = false;
498  }
499 
500  return approaching_face;
501 
502  KRATOS_CATCH( "" )
503  }
504 
505  //**************************************************************************
506  //**************************************************************************
507 
508  double GetDistanceToNode(Node& rNode, Node& rEdgeNode, array_1d<double,3>& rDirection)
509  {
510  KRATOS_TRY
511 
512  array_1d<double,3> Direction = rEdgeNode.FastGetSolutionStepValue(NORMAL);
513  if( norm_2(Direction) )
514  Direction /= norm_2(Direction);
515 
516  array_1d<double,3> Distance = (rEdgeNode.Coordinates()-rNode.Coordinates());
517  double distance = fabs(inner_prod(Distance, Direction));
518 
519  return distance;
520 
521  KRATOS_CATCH( "" )
522  }
523 
524  //**************************************************************************
525  //**************************************************************************
526 
527  double GetDistanceToEdge(Node& rNode, Node& rEdgeNodeA, Node& rEdgeNodeB, array_1d<double,3>& rDirection)
528  {
529  KRATOS_TRY
530 
531  array_1d<double,3> MidPoint = 0.5 * (rEdgeNodeA.Coordinates() + rEdgeNodeB.Coordinates()) ;
532 
533  this->GetDirectionToEdge(rDirection,rEdgeNodeA,rEdgeNodeB);
534 
535  double distance = fabs(inner_prod((MidPoint-rNode.Coordinates()), rDirection));
536 
537  return distance;
538 
539  KRATOS_CATCH( "" )
540  }
541 
542  //**************************************************************************
543  //**************************************************************************
544 
545  double GetDistanceToFace(Node& rNode, Node& rEdgeNodeA, Node& rEdgeNodeB, Node& rEdgeNodeC, array_1d<double,3>& rDirection)
546  {
547  KRATOS_TRY
548 
549  array_1d<double,3> MidPoint = (1.0/3.0) * (rEdgeNodeA.Coordinates() + rEdgeNodeB.Coordinates() + rEdgeNodeC.Coordinates() ) ;
550 
551  this->GetDirectionToFace(rDirection,rEdgeNodeA,rEdgeNodeB,rEdgeNodeC);
552 
553  double distance = fabs(inner_prod((MidPoint-rNode.Coordinates()), rDirection));
554 
555  return distance;
556 
557  KRATOS_CATCH( "" )
558  }
559 
560 
561  //**************************************************************************
562  //**************************************************************************
563 
564  void GetDirectionToEdge(array_1d<double,3>& rDirection, Node& rEdgeNodeA, Node& rEdgeNodeB)
565  {
566  //get wall direction from normals:
567  if( rEdgeNodeA.FastGetSolutionStepValue(SHRINK_FACTOR) == 1 && rEdgeNodeB.FastGetSolutionStepValue(SHRINK_FACTOR) == 1 ){
568  rDirection = 0.5 * (rEdgeNodeA.FastGetSolutionStepValue(NORMAL) + rEdgeNodeB.FastGetSolutionStepValue(NORMAL) ) ;
569  }
570  else{
571  if( rEdgeNodeA.FastGetSolutionStepValue(SHRINK_FACTOR) == 1 ){
572  rDirection = rEdgeNodeA.FastGetSolutionStepValue(NORMAL);
573  }
574  else if( rEdgeNodeB.FastGetSolutionStepValue(SHRINK_FACTOR) == 1 ){
575  rDirection = rEdgeNodeB.FastGetSolutionStepValue(NORMAL);
576  }
577  else{
578  rDirection = 0.5 * (rEdgeNodeA.FastGetSolutionStepValue(NORMAL) + rEdgeNodeB.FastGetSolutionStepValue(NORMAL) ) ;
579  }
580  }
581 
582  if( norm_2(rDirection) )
583  rDirection /= norm_2(rDirection);
584 
585  }
586 
587  //**************************************************************************
588  //**************************************************************************
589 
590  void GetDirectionToFace(array_1d<double,3>& rDirection, Node& rEdgeNodeA, Node& rEdgeNodeB, Node& rEdgeNodeC)
591  {
592 
593  array_1d<double,3> VectorB = rEdgeNodeB.Coordinates() - rEdgeNodeA.Coordinates();
594  array_1d<double,3> VectorC = rEdgeNodeC.Coordinates() - rEdgeNodeA.Coordinates();
595 
596  MathUtils<double>::CrossProduct(rDirection,VectorB,VectorC);
597 
598  if( norm_2(rDirection) )
599  rDirection /= norm_2(rDirection);
600 
601  }
602 
603  //**************************************************************************
604  //**************************************************************************
605 
606  bool EraseCriticalNodes(ModelPart& rModelPart, unsigned int& inside_nodes_removed)
607  {
608 
609  KRATOS_TRY
610 
611  bool any_node_removed = false;
612  unsigned int erased_nodes=0;
613 
615 
616  MesherUtilities MesherUtils;
617  double MaxRelativeVelocity = 1.5; //arbitrary value, will depend on time step (AF)
618 
619  for(ModelPart::ElementsContainerType::const_iterator ie = rModelPart.ElementsBegin(); ie != rModelPart.ElementsEnd(); ++ie)
620  {
621  Element::GeometryType& rGeometry = ie->GetGeometry();
622  const unsigned int NumberOfNodes = rGeometry.size();
623 
624  bool wall_boundary = false;
625  for(unsigned int i=0; i<NumberOfNodes; ++i)
626  {
627  if(rGeometry[i].Is(BLOCKED) || rGeometry[i].Is(SOLID)){
628  wall_boundary = true;
629  break;
630  }
631  }
632 
633  if( wall_boundary ){
634 
635  bool speedy_approach = MesherUtils.CheckRelativeVelocities(rGeometry, MaxRelativeVelocity);
636 
637  if( speedy_approach ){
638 
639  for(unsigned int i=0; i<NumberOfNodes; ++i)
640  {
641  if((rGeometry[i].IsNot(BLOCKED) && rGeometry[i].IsNot(SOLID))){
642  LayerNodes.push_back(rGeometry(i));
643  }
644  }
645 
646  }
647  }
648  }
649 
650  const int nnodes = LayerNodes.size();
651  // const unsigned int& dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
652 
653  if (nnodes != 0)
654  {
655  ModelPart::NodesContainerType::iterator it_begin = LayerNodes.begin();
656 
657  unsigned int inside_nodes_removed_accum = 0;
658  #pragma omp parallel for reduction(+:inside_nodes_removed_accum,erased_nodes)
659  for (int i = 0; i < nnodes; ++i)
660  {
661  ModelPart::NodesContainerType::iterator it = it_begin + i;
662 
663  double MinimumDistance = std::numeric_limits<double>::max();
664  array_1d<double,3> Direction;
665  // PointsArrayType Vertices(dimension);
666  double distance = 0;
667  unsigned int face = 0;
668 
669  ElementWeakPtrVectorType& nElements = it->GetValue(NEIGHBOUR_ELEMENTS);
670 
671  for(auto& i_nelem : nElements)
672  {
673  ElementWeakPtrVectorType& inElements = i_nelem.GetValue(NEIGHBOUR_ELEMENTS);
674 
675  DenseMatrix<unsigned int> lpofa; //connectivities of points defining faces
676 
677  distance = 0;
678  face = 0;
679  for(auto& j_nelem : inElements)
680  {
681  if (i_nelem.Id() == j_nelem.Id()){
682 
683  GeometryType& rGeometry = i_nelem.GetGeometry();
684 
685  rGeometry.NodesInFaces(lpofa);
686 
687  const unsigned int NumberOfNodes = rGeometry.size();
688 
689  unsigned int wall_boundary = 0;
690  std::vector<unsigned int> wall_nodes;
691  for(unsigned int j=1; j<NumberOfNodes; ++j)
692  {
693  if( rGeometry[lpofa(j,face)].Is(BLOCKED) || rGeometry[lpofa(j,face)].Is(SOLID) ){
694  ++wall_boundary;
695  wall_nodes.push_back(j);
696  }
697  }
698 
699  if( wall_boundary == NumberOfNodes-1 ){ //node to face criterion
700 
701  if( NumberOfNodes == 3 ){
702 
703  if( this->CheckApproachingEdge(*it,rGeometry[lpofa(1,face)], rGeometry[lpofa(2,face)]) ){
704  distance = this->GetDistanceToEdge(*it, rGeometry[lpofa(1,face)], rGeometry[lpofa(2,face)], Direction);
705  if( distance < MinimumDistance ){
706  MinimumDistance = distance;
707  // Vertices[0] = rGeometry[lpofa(1,face)];
708  // Vertices[1] = rGeometry[lpofa(2,face)];
709  }
710  }
711 
712  }
713  else if( NumberOfNodes == 4 ){
714 
715  if( this->CheckApproachingFace(*it,rGeometry[lpofa(1,face)], rGeometry[lpofa(2,face)], rGeometry[lpofa(3,face)]) ){
716  distance = this->GetDistanceToFace(*it, rGeometry[lpofa(1,face)], rGeometry[lpofa(2,face)], rGeometry[lpofa(3,face)], Direction);
717  if( distance < MinimumDistance ){
718  MinimumDistance = distance;
719  // Vertices[0] = rGeometry[lpofa(1,face)];
720  // Vertices[1] = rGeometry[lpofa(2,face)];
721  // Vertices[2] = rGeometry[lpofa(3,face)];
722  }
723  }
724  }
725  }
726  else if( wall_boundary == NumberOfNodes-2 ){ //node to edge criterion
727 
728  if( NumberOfNodes == 3 ){
729 
730  if( this->CheckApproachingPoint(*it,rGeometry[lpofa(wall_nodes.front(),face)]) ){
731  distance = this->GetDistanceToNode(*it, rGeometry[lpofa(wall_nodes.front(),face)], Direction);
732  if( distance < MinimumDistance ){
733  MinimumDistance = distance;
734  }
735  }
736 
737  }
738  else if( NumberOfNodes == 4 ){
739 
740  if( this->CheckApproachingEdge(*it,rGeometry[lpofa(wall_nodes.front(),face)],rGeometry[lpofa(wall_nodes.back(),face)]) ){
741  distance = this->GetDistanceToEdge(*it, rGeometry[lpofa(wall_nodes.front(),face)], rGeometry[lpofa(wall_nodes.back(),face)], Direction);
742  if( distance < MinimumDistance ){
743  MinimumDistance = distance;
744  }
745  }
746  }
747 
748  }
749  }
750  ++face;
751  }
752  }
753 
754  if( MinimumDistance < 0.25 * mrRemesh.Refine->CriticalRadius ){
755  it->Set(TO_ERASE);
756  ++erased_nodes;
757  ++inside_nodes_removed_accum;
758  }
759  else if( MinimumDistance < 1.5 * mrRemesh.Refine->CriticalRadius ){
760  distance = (1.5 * mrRemesh.Refine->CriticalRadius - MinimumDistance);
761  this->MoveLayerNode(*it, Direction, distance);
762  }
763 
764  }
765 
766  inside_nodes_removed += inside_nodes_removed_accum;
767 
768  }
769  if(erased_nodes>0){
770  //std::cout<<" Layer Nodes removed "<<erased_nodes<<std::endl;
771  any_node_removed = true;
772  }
773 
774  return any_node_removed;
775 
776  KRATOS_CATCH( "" )
777  }
778 
779 
780  //**************************************************************************
781  //**************************************************************************
782 
783  bool MoveBoundaryNode(Node& rNode)
784  {
785 
786  KRATOS_TRY
787 
788  bool moved_node = false;
789  //std::cout<<" Boundary to Move Pre ["<<rNode.Id()<<"] "<<rNode.Coordinates()<<std::endl;
790  unsigned int FreeSurfaceNodes = 0;
791  NodeWeakPtrVectorType& nNodes = rNode.GetValue(NEIGHBOUR_NODES);
792  NodeWeakPtrVectorType FreeNeighbours;
793  for(auto i_nnodes(nNodes.begin()); i_nnodes != nNodes.end(); ++i_nnodes)
794  {
795  if(i_nnodes->Is(FREE_SURFACE) ){
796  FreeNeighbours.push_back(*i_nnodes.base());
797  ++FreeSurfaceNodes;
798  }
799  }
800 
801  if( FreeSurfaceNodes == 2 )
802  {
803  array_1d<double,3> MidPoint = 0.5 * (FreeNeighbours.front().Coordinates()+FreeNeighbours.back().Coordinates());
804  array_1d<double,3> Direction = (FreeNeighbours.front().Coordinates()-FreeNeighbours.back().Coordinates());
805 
806  if(norm_2(Direction))
807  Direction/=norm_2(Direction);
808 
809  array_1d<double,3> Displacement = inner_prod( (MidPoint-rNode.Coordinates()), Direction ) * Direction;
810  noalias(rNode.Coordinates()) += Displacement;
811  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT)) += Displacement;
812  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT,1)) += Displacement;
813 
814  for(auto& i_fnnodes : FreeNeighbours)
815  {
816  noalias(rNode.FastGetSolutionStepValue(VELOCITY)) += i_fnnodes.FastGetSolutionStepValue(VELOCITY);
817  noalias(rNode.FastGetSolutionStepValue(VELOCITY,1)) += i_fnnodes.FastGetSolutionStepValue(VELOCITY,1);
818  noalias(rNode.FastGetSolutionStepValue(ACCELERATION)) += i_fnnodes.FastGetSolutionStepValue(ACCELERATION);
819  noalias(rNode.FastGetSolutionStepValue(ACCELERATION,1)) += i_fnnodes.FastGetSolutionStepValue(ACCELERATION,1);
820  rNode.FastGetSolutionStepValue(PRESSURE) += i_fnnodes.FastGetSolutionStepValue(PRESSURE);
821  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) += i_fnnodes.FastGetSolutionStepValue(PRESSURE_VELOCITY);
822  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) += i_fnnodes.FastGetSolutionStepValue(PRESSURE_VELOCITY,1);
823  }
824 
825 
826  double quotient = 1.0/double(FreeSurfaceNodes+1);
827  rNode.FastGetSolutionStepValue(VELOCITY) *= quotient;
828  rNode.FastGetSolutionStepValue(VELOCITY,1) *= quotient;
829  rNode.FastGetSolutionStepValue(ACCELERATION) *= quotient;
830  rNode.FastGetSolutionStepValue(ACCELERATION,1) *= quotient;
831  rNode.FastGetSolutionStepValue(PRESSURE) *= quotient;
832  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) *= quotient;
833  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) *= quotient;
834 
835  moved_node = true;
836 
837  }
838  else if(FreeSurfaceNodes > 2) {
839 
840  array_1d<double,3> MidPoint;
841  noalias(MidPoint) = ZeroVector(3);
842  double quotient = 1.0/double(FreeSurfaceNodes);
843  for(auto& i_fnnodes : FreeNeighbours)
844  {
845  MidPoint += i_fnnodes.Coordinates();
846 
847  noalias(rNode.FastGetSolutionStepValue(VELOCITY)) += i_fnnodes.FastGetSolutionStepValue(VELOCITY);
848  noalias(rNode.FastGetSolutionStepValue(VELOCITY,1)) += i_fnnodes.FastGetSolutionStepValue(VELOCITY,1);
849  noalias(rNode.FastGetSolutionStepValue(ACCELERATION)) += i_fnnodes.FastGetSolutionStepValue(ACCELERATION);
850  noalias(rNode.FastGetSolutionStepValue(ACCELERATION,1)) += i_fnnodes.FastGetSolutionStepValue(ACCELERATION,1);
851  rNode.FastGetSolutionStepValue(PRESSURE) += i_fnnodes.FastGetSolutionStepValue(PRESSURE);
852  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) += i_fnnodes.FastGetSolutionStepValue(PRESSURE_VELOCITY);
853  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) += i_fnnodes.FastGetSolutionStepValue(PRESSURE_VELOCITY,1);
854  }
855  MidPoint *= quotient;
856  array_1d<double,3> Normal = rNode.FastGetSolutionStepValue(NORMAL);
857 
858  if(norm_2(Normal))
859  Normal/=norm_2(Normal);
860 
861  array_1d<double,3> Displacement = (MidPoint-rNode.Coordinates()) - inner_prod( (MidPoint-rNode.Coordinates()), Normal ) * Normal;
862  noalias(rNode.Coordinates()) += Displacement;
863  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT)) += Displacement;
864  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT,1)) += Displacement;
865 
866  quotient = 1.0/double(FreeSurfaceNodes+1);
867  rNode.FastGetSolutionStepValue(VELOCITY) *= quotient;
868  rNode.FastGetSolutionStepValue(VELOCITY,1) *= quotient;
869  rNode.FastGetSolutionStepValue(ACCELERATION) *= quotient;
870  rNode.FastGetSolutionStepValue(ACCELERATION,1) *= quotient;
871  rNode.FastGetSolutionStepValue(PRESSURE) *= quotient;
872  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) *= quotient;
873  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) *= quotient;
874 
875  moved_node = true;
876  }
877  else{
878  std::cout<<" Boundary node with only one FREE_SURFACE neighbour "<<std::endl;
879  }
880 
881  //std::cout<<" Boundary to Move Post ["<<rNode.Id()<<"] "<<rNode.Coordinates()<<std::endl;
882 
883  return moved_node;
884 
885  KRATOS_CATCH( "" )
886  }
887 
888  //**************************************************************************
889  //**************************************************************************
890 
891  void MoveInsideNode(Node& rNode)
892  {
893 
894  KRATOS_TRY
895 
896  NodeWeakPtrVectorType& nNodes = rNode.GetValue(NEIGHBOUR_NODES);
897  unsigned int NumberOfNeighbourNodes = nNodes.size();
898 
899  //std::cout<<" Moved Node Pre ["<<rNode.Id()<<"] Displacement"<<rNode.FastGetSolutionStepValue(DISPLACEMENT)<<" Position "<<rNode.Coordinates()<<" Initial Position "<<rNode.GetInitialPosition()<<std::endl;
900 
901  //array_1d<double,3> CurrentPosition = rNode.Coordinates();
902 
903  for(auto& i_nnode : nNodes)
904  {
905  noalias(rNode.Coordinates()) += i_nnode.Coordinates();
906  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT)) += i_nnode.FastGetSolutionStepValue(DISPLACEMENT);
907  noalias(rNode.FastGetSolutionStepValue(DISPLACEMENT,1)) += i_nnode.FastGetSolutionStepValue(DISPLACEMENT,1);
908  noalias(rNode.FastGetSolutionStepValue(VELOCITY)) += i_nnode.FastGetSolutionStepValue(VELOCITY);
909  noalias(rNode.FastGetSolutionStepValue(VELOCITY,1)) += i_nnode.FastGetSolutionStepValue(VELOCITY,1);
910  noalias(rNode.FastGetSolutionStepValue(ACCELERATION)) += i_nnode.FastGetSolutionStepValue(ACCELERATION);
911  noalias(rNode.FastGetSolutionStepValue(ACCELERATION,1)) += i_nnode.FastGetSolutionStepValue(ACCELERATION,1);
912  rNode.FastGetSolutionStepValue(PRESSURE) += i_nnode.FastGetSolutionStepValue(PRESSURE);
913  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) += i_nnode.FastGetSolutionStepValue(PRESSURE_VELOCITY);
914  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) += i_nnode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1);
915  }
916 
917  double quotient = 1.0/double(NumberOfNeighbourNodes+1);
918 
919  rNode.Coordinates() *= quotient;
920  rNode.FastGetSolutionStepValue(DISPLACEMENT) *= quotient;
921  rNode.FastGetSolutionStepValue(DISPLACEMENT,1) *= quotient;
922  //rNode.FastGetSolutionStepValue(DISPLACEMENT) += rNode.Coordinates()-CurrentPosition;
923  //rNode.FastGetSolutionStepValue(DISPLACEMENT,1) += rNode.Coordinates()-CurrentPosition;
924  rNode.GetInitialPosition() = Point(rNode.Coordinates() - rNode.FastGetSolutionStepValue(DISPLACEMENT));
925  rNode.FastGetSolutionStepValue(VELOCITY) *= quotient;
926  rNode.FastGetSolutionStepValue(VELOCITY,1) *= quotient;
927  rNode.FastGetSolutionStepValue(ACCELERATION) *= quotient;
928  rNode.FastGetSolutionStepValue(ACCELERATION,1) *= quotient;
929  rNode.FastGetSolutionStepValue(PRESSURE) *= quotient;
930  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY) *= quotient;
931  rNode.FastGetSolutionStepValue(PRESSURE_VELOCITY,1) *= quotient;
932 
933  //std::cout<<" Moved Node Post ["<<rNode.Id()<<"] Displacement"<<rNode.FastGetSolutionStepValue(DISPLACEMENT)<<" Position "<<rNode.Coordinates()<<" Initial Position "<<rNode.GetInitialPosition()<<std::endl;
934 
935  KRATOS_CATCH( "" )
936  }
937 
938  //**************************************************************************
939  //**************************************************************************
940 
941  void MoveLayerNode(Node& rNode, const array_1d<double,3>& rDirection, const double& rDistance)
942  {
943 
944  KRATOS_TRY
945 
946  //std::cout<<" Moved Node Pre ["<<rNode.Id()<<"] Displacement"<<rNode.FastGetSolutionStepValue(DISPLACEMENT)<<" Position "<<rNode.Coordinates()<<std::endl;
947 
948  const array_1d<double,3>& VelocityDirection = rNode.FastGetSolutionStepValue(VELOCITY);
949 
950  double sign = 1;
951  if( inner_prod(VelocityDirection,rDirection) > 0 )
952  sign*=(-1);
953 
954  noalias(rNode.Coordinates()) += sign * rDistance * rDirection;
955  rNode.FastGetSolutionStepValue(DISPLACEMENT) += sign * rDistance * rDirection;
956  rNode.FastGetSolutionStepValue(DISPLACEMENT,1) += sign * rDistance * rDirection;
957 
958  //std::cout<<" Moved Node Post ["<<rNode.Id()<<"] Displacement"<<rNode.FastGetSolutionStepValue(DISPLACEMENT)<<" Position "<<rNode.Coordinates()<<std::endl;
959 
960  KRATOS_CATCH( "" )
961  }
962 
963 
973 
976 
978 
980  //Process(Process const& rOther);
981 
982 
984 
985 }; // Class Process
986 
987 
989 
992 
993 
997 
998 
1000 inline std::istream& operator >> (std::istream& rIStream,
1002 
1004 inline std::ostream& operator << (std::ostream& rOStream,
1005  const RemoveFluidNodesMesherProcess& rThis)
1006 {
1007  rThis.PrintInfo(rOStream);
1008  rOStream << std::endl;
1009  rThis.PrintData(rOStream);
1010 
1011  return rOStream;
1012 }
1014 
1015 
1016 } // namespace Kratos.
1017 
1018 #endif // KRATOS_REMOVE_FLUID_NODES_MESHER_PROCESS_H_INCLUDED defined
Short class definition.
Definition: bucket.h:57
Base class for all Conditions.
Definition: condition.h:59
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: element.h:83
bool Is(Flags const &rOther) const
Definition: flags.h:274
bool IsNot(Flags const &rOther) const
Definition: flags.h:291
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
virtual void NodesInFaces(DenseMatrix< unsigned int > &rNodesInFaces) const
Definition: geometry.h:2195
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
static T CrossProduct(const T &a, const T &b)
Performs the vector product of the two input vectors a,b.
Definition: math_utils.h:762
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
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
SizeType NumberOfNodes(IndexType ThisIndex=0) const
Definition: model_part.h:341
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
This class defines the node.
Definition: node.h:65
CoordinatesArrayType const & Coordinates() const
Definition: point.h:215
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
Remove Fluid Nodes Process for 2D and 3D cases.
Definition: remove_fluid_nodes_mesher_process.hpp:40
GlobalPointersVector< Element > ElementWeakPtrVectorType
Definition: remove_fluid_nodes_mesher_process.hpp:56
ConditionType::GeometryType GeometryType
Definition: remove_fluid_nodes_mesher_process.hpp:50
KRATOS_CLASS_POINTER_DEFINITION(RemoveFluidNodesMesherProcess)
Pointer definition of Process.
GlobalPointersVector< Node > NodeWeakPtrVectorType
Definition: remove_fluid_nodes_mesher_process.hpp:55
ModelPart::MeshType::GeometryType::PointsArrayType PointsArrayType
Definition: remove_fluid_nodes_mesher_process.hpp:53
ModelPart::PropertiesType PropertiesType
Definition: remove_fluid_nodes_mesher_process.hpp:49
virtual ~RemoveFluidNodesMesherProcess()
Destructor.
Definition: remove_fluid_nodes_mesher_process.hpp:72
RemoveFluidNodesMesherProcess(ModelPart &rModelPart, MesherUtilities::MeshingParameters &rRemeshingParameters, int EchoLevel)
Default constructor.
Definition: remove_fluid_nodes_mesher_process.hpp:63
ModelPart::ConditionType ConditionType
Definition: remove_fluid_nodes_mesher_process.hpp:48
Bucket< 3, Node, std::vector< Node::Pointer >, Node::Pointer, std::vector< Node::Pointer >::iterator, std::vector< double >::iterator > BucketType
Definition: remove_fluid_nodes_mesher_process.hpp:51
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: remove_fluid_nodes_mesher_process.hpp:112
void operator()()
This operator is provided to call the process as a function and simply calls the Execute method.
Definition: remove_fluid_nodes_mesher_process.hpp:80
std::string Info() const override
Turn back information as a string.
Definition: remove_fluid_nodes_mesher_process.hpp:100
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: remove_fluid_nodes_mesher_process.hpp:106
bool RemoveNodesOnDistance(ModelPart &rModelPart, unsigned int &inside_nodes_removed, unsigned int &boundary_nodes_removed, bool &any_condition_removed) override
Definition: remove_fluid_nodes_mesher_process.hpp:137
Tree< KDTreePartition< BucketType > > KdtreeType
Definition: remove_fluid_nodes_mesher_process.hpp:52
GlobalPointersVector< Condition > ConditionWeakPtrVectorType
Definition: remove_fluid_nodes_mesher_process.hpp:57
Remove Mesh Nodes Process for 2D and 3D cases.
Definition: remove_nodes_mesher_process.hpp:63
MesherUtilities::MeshingParameters & mrRemesh
Definition: remove_nodes_mesher_process.hpp:301
int mEchoLevel
Definition: remove_nodes_mesher_process.hpp:305
virtual bool CheckEngagedNode(Node &rNode, std::vector< Node::Pointer > &rNeighbours, std::vector< double > &rNeighbourDistances, unsigned int &rn_points_in_radius)
Definition: remove_nodes_mesher_process.hpp:506
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: remove_nodes_mesher_process.hpp:117
A generic tree data structure for spatial partitioning.
Definition: tree.h:190
SizeType SearchInRadius(PointType const &ThisPoint, CoordinateType Radius, IteratorType Results, DistanceIteratorType ResultsDistances, SizeType MaxNumberOfResults)
Search for points within a given radius of a point.
Definition: tree.h:434
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static int sign(const double a)
Definition: GeometryFunctions.h:61
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
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
float velocity
Definition: PecletTest.py:54
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
float radius
Definition: mesh_to_mdpa_converter.py:18
int j
Definition: quadrature.py:648
int counter
Definition: script_THERMAL_CORRECT.py:218
int nnodes
Definition: sensitivityMatrix.py:24
integer i
Definition: TensorModule.f:17
Definition: mesher_utilities.hpp:631
RefiningParameters::Pointer Refine
Definition: mesher_utilities.hpp:684