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.
calculate_signed_distance_to_3d_condition_skin_process.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: Pooyan Dadvand
11 // Daniel Baumgaertner
12 // Johannes Wolf
13 //
14 
15 
16 
17 #if !defined(KRATOS_CALCULATE_DISTANCE_CONDITION_PROCESS_H_INCLUDED )
18 #define KRATOS_CALCULATE_DISTANCE_CONDITION_PROCESS_H_INCLUDED
19 
20 
21 
22 // System includes
23 #include <string>
24 #include <iostream>
25 
26 
27 // External includes
28 
29 
30 // Project includes
31 #include "includes/define.h"
32 #include "processes/process.h"
33 #include "includes/model_part.h"
37 #include "utilities/timer.h"
38 #include "utilities/math_utils.h"
39 #include "utilities/geometry_utilities.h"
43 
44 
45 namespace Kratos
46 {
47 
49 {
50  public:
51 
53  {
54  double mDistance;
55  double mCoordinates[3];
56  std::size_t mId;
57  public:
58  double& Distance(){return mDistance;}
59  double& X() {return mCoordinates[0];}
60  double& Y() {return mCoordinates[1];}
61  double& Z() {return mCoordinates[2];}
62  double& operator[](int i) {return mCoordinates[i];}
63  std::size_t& Id(){return mId;}
64  };
65 
66 
67 
68 
71 
72  enum { Dimension = 3,
73  DIMENSION = 3,
74  MAX_LEVEL = 12,
75  MIN_LEVEL = 2 // this cannot be less than 2!!!
76  };
77 
78  typedef Point PointType;
79  typedef std::vector<double>::iterator DistanceIteratorType;
80  typedef PointerVectorSet<
81  GeometricalObject::Pointer,
83  std::less<typename IndexedObject::result_type>,
84  std::equal_to<typename IndexedObject::result_type>,
86  std::vector< Kratos::shared_ptr<typename GeometricalObject::Pointer> >
90  typedef PointerVectorSet<
91  GeometricalObject::Pointer,
93  std::less<typename IndexedObject::result_type>,
94  std::equal_to<typename IndexedObject::result_type>,
96  std::vector< Kratos::shared_ptr<typename GeometricalObject::Pointer> >
100 
101  typedef GeometricalObject::Pointer pointer_type;
103  typedef std::vector<CellNodeData*> data_type;
104 
105  typedef std::vector<PointerType>::iterator PointerTypeIterator;
106 
107 
108 
109 
112 
116 
119 
122 
123 
127 
128 
132 
134  return new data_type(27, (CellNodeData*)NULL);
135  }
136 
137  static void CopyData(data_type* source, data_type* destination) {
138  *destination = *source;
139  }
140 
141  static void DeleteData(data_type* data) {
142  delete data;
143  }
146 
147  static inline void CalculateBoundingBox(const PointerType& rObject, PointType& rLowPoint, PointType& rHighPoint)
148  {
149  rHighPoint = rObject->GetGeometry().GetPoint(0);
150  rLowPoint = rObject->GetGeometry().GetPoint(0);
151  for (unsigned int point = 0; point<rObject->GetGeometry().PointsNumber(); point++)
152  {
153  for(std::size_t i = 0; i<3; i++)
154  {
155  rLowPoint[i] = (rLowPoint[i] > rObject->GetGeometry().GetPoint(point)[i] ) ? rObject->GetGeometry().GetPoint(point)[i] : rLowPoint[i];
156  rHighPoint[i] = (rHighPoint[i] < rObject->GetGeometry().GetPoint(point)[i] ) ? rObject->GetGeometry().GetPoint(point)[i] : rHighPoint[i];
157  }
158  }
159  }
160 
163 
164  static inline void GetBoundingBox(const PointerType rObject, double* rLowPoint, double* rHighPoint)
165  {
166 
167  for(std::size_t i = 0; i<3; i++)
168  {
169  rLowPoint[i] = rObject->GetGeometry().GetPoint(0)[i];
170  rHighPoint[i] = rObject->GetGeometry().GetPoint(0)[i];
171  }
172 
173  for (unsigned int point = 0; point<rObject->GetGeometry().PointsNumber(); point++)
174  {
175  for(std::size_t i = 0; i<3; i++)
176  {
177  rLowPoint[i] = (rLowPoint[i] > rObject->GetGeometry().GetPoint(point)[i] ) ? rObject->GetGeometry().GetPoint(point)[i] : rLowPoint[i];
178  rHighPoint[i] = (rHighPoint[i] < rObject->GetGeometry().GetPoint(point)[i] ) ? rObject->GetGeometry().GetPoint(point)[i] : rHighPoint[i];
179  }
180  }
181  }
182 
185 
186  static inline bool Intersection(const PointerType& rObj_1, const PointerType& rObj_2)
187  {
188  Element::GeometryType& geom_1 = rObj_1->GetGeometry();
189  Element::GeometryType& geom_2 = rObj_2->GetGeometry();
190  return geom_1.HasIntersection(geom_2);
191 
192  }
193 
194 
197 
198  static inline bool IntersectionBox(const PointerType& rObject, const PointType& rLowPoint, const PointType& rHighPoint)
199  {
200  return rObject->GetGeometry().HasIntersection(rLowPoint, rHighPoint);
201  }
202 
205 
206 
207  static inline bool IsIntersected(const Element::Pointer rObject, double Tolerance, const double* rLowPoint, const double* rHighPoint)
208  {
209  Point low_point(rLowPoint[0] - Tolerance, rLowPoint[1] - Tolerance, rLowPoint[2] - Tolerance);
210  Point high_point(rHighPoint[0] + Tolerance, rHighPoint[1] + Tolerance, rHighPoint[2] + Tolerance);
211 
212  KRATOS_THROW_ERROR(std::logic_error, "Not Implemented method", "")
213  //return HasIntersection(rObject->GetGeometry(), low_point, high_point);
214  }
215 
216 
220 
221 
225 
226 
230 
232  virtual std::string Info() const
233  {
234  return " Spatial Containers Configure";
235  }
236 
238  virtual void PrintInfo(std::ostream& rOStream) const {}
239 
241  virtual void PrintData(std::ostream& rOStream) const {}
242 
243 
245 
246 protected:
247 
248 private:
249 
252 
255 
256 
257 }; // Class DistanceSpatialContainersConditionConfigure
258 
261 
265 
266 
270 
274 
278 
280 
283  : public Process
284  {
285  public:
288 
291 
296  typedef Point PointType;
297  typedef OctreeType::cell_type::object_container_type object_container_type;
298  typedef struct{
302  typedef struct{
303  std::vector<IntersectionNodeStruct> IntNodes;
304  }TetEdgeStruct;
305 
306 
310 
312  CalculateSignedDistanceTo3DConditionSkinProcess(ModelPart& rThisModelPartStruc, ModelPart& rThisModelPartFluid)
313  : mrSkinModelPart(rThisModelPartStruc), mrBodyModelPart(rThisModelPartStruc), mrFluidModelPart(rThisModelPartFluid)
314  {
315  }
316 
319  {
320  }
321 
322 
326 
327  void operator()()
328  {
329  Execute();
330  }
331 
332 
336 
339 
340  void Execute() override
341  {
342  KRATOS_TRY
343  /*
344  std::cout << "Clearing the list of correspondances between the FIXED MESH ELEMENTS and the EMBEDDED CONDITIONS THAT ARE CROSSING THEM..." << std::endl;
345 
346 
347  for( ModelPart::ElementIterator i_fluidElement = mrFluidModelPart.ElementsBegin();
348  i_fluidElement != mrFluidModelPart.ElementsEnd();
349  i_fluidElement++)
350  {
351  //i_fluidElement->GetValue(NEIGHBOUR_CONDITIONS).resize(0);
352  ( i_fluidElement->GetValue(NEIGHBOUR_EMBEDDED_FACES)).reserve(6);
353 
354  GlobalPointersVector<GeometricalObject >& rE = i_fluidElement->GetValue(NEIGHBOUR_EMBEDDED_FACES);
355  rE.erase(rE.begin(),rE.end() );
356  }
357  */
358 
359 
360  //std::cout << "Generating the Octree..." << std::endl;
361  GenerateOctree();
362  //std::cout << "Generating the Octree finished" << std::endl;
363 
365 
366  //GenerateNodes();
367  CalculateDistance2(); // I have to change this. Pooyan.
368 
369 
370 
371 
372 
373 
374 // CalculateDistance();
375 // CalculateDistance2();
376 
377 // double coord[3] = {0.4375, 0.57812, 0.5};
378 // double distance = DistancePositionInSpace(coord);
379 // KRATOS_WATCH(distance);
380 
381 
382 
383  //mrSkinModelPart.GetCommunicator().AssembleCurrentData(DISTANCE);
384 
385 // std::ofstream mesh_file1("octree1.post.msh");
386 // std::ofstream res_file("octree1.post.res");
387 
388 // Timer::Start("Writing Gid conform Mesh");
389 
390 // PrintGiDMesh(mesh_file1);
391 // PrintGiDResults(res_file);
392  //octree.PrintGiDMeshNew(mesh_file2);
393 
394 // Timer::Stop("Writing Gid conform Mesh");
395 
396 // KRATOS_WATCH(mrBodyModelPart);
397 
398  //delete octree. TODO: Carlos
399 
400  KRATOS_CATCH("");
401  }
402 
405 
407  {
408 
409  // Initialize nodal distances each node in the domain to 1.0
411 
412  // Initialize index table to define line Edges of fluid element
413  BoundedMatrix<unsigned int,6,2> TetEdgeIndexTable;
414  SetIndexTable(TetEdgeIndexTable);
415 
416  for( ModelPart::ElementIterator i_fluidElement = mrFluidModelPart.ElementsBegin();
417  i_fluidElement != mrFluidModelPart.ElementsEnd();
418  i_fluidElement++)
419  {
420  i_fluidElement->GetValue(EMBEDDED_VELOCITY)=ZeroVector(3);
421  }
422 
423  // loop over all fluid elements
424  for( ModelPart::ElementIterator i_fluidElement = mrFluidModelPart.ElementsBegin();
425  i_fluidElement != mrFluidModelPart.ElementsEnd();
426  i_fluidElement++)
427  {
428  CalcNodalDistancesOfTetNodes( i_fluidElement , TetEdgeIndexTable );
429  }
430  KRATOS_WATCH("ENDOF LOOP")
431  }
432 
435 
437  {
438  ModelPart::NodesContainerType::ContainerType& nodes = mrFluidModelPart.NodesArray();
439 
440  // reset the node distance to 1.0 which is the maximum distance in our normalized space.
441  int nodesSize = nodes.size();
442  for(int i = 0 ; i < nodesSize ; i++)
443  nodes[i]->GetSolutionStepValue(DISTANCE) = 1.0;
444 
445  ModelPart::ElementsContainerType::ContainerType& fluid_elements = mrFluidModelPart.ElementsArray();
446 
447  array_1d<double,4> ElementalDistances;
448  const double initial_distance = 1.0;
449  ElementalDistances[0] = initial_distance;
450  ElementalDistances[1] = initial_distance;
451  ElementalDistances[2] = initial_distance;
452  ElementalDistances[3] = initial_distance;
453 
454  // reset the elemental distance to 1.0 which is the maximum distance in our normalized space.
455  for(unsigned int i = 0 ; i < fluid_elements.size() ; i++)
456  {
457  fluid_elements[i]->SetValue(ELEMENTAL_DISTANCES,ElementalDistances);
458  fluid_elements[i]->GetValue(SPLIT_ELEMENT) = false;
459  }
460  }
461 
464 
466  {
467  // Initialize index table to define line Edges of fluid element
468  TetEdgeIndexTable(0,0) = 0;
469  TetEdgeIndexTable(0,1) = 1;
470  TetEdgeIndexTable(1,0) = 0;
471  TetEdgeIndexTable(1,1) = 2;
472  TetEdgeIndexTable(2,0) = 0;
473  TetEdgeIndexTable(2,1) = 3;
474  TetEdgeIndexTable(3,0) = 1;
475  TetEdgeIndexTable(3,1) = 2;
476  TetEdgeIndexTable(4,0) = 1;
477  TetEdgeIndexTable(4,1) = 3;
478  TetEdgeIndexTable(5,0) = 2;
479  TetEdgeIndexTable(5,1) = 3;
480  }
481 
484 
485  void CalcNodalDistancesOfTetNodes( ModelPart::ElementsContainerType::iterator& i_fluidElement,
486  BoundedMatrix<unsigned int,6,2> TetEdgeIndexTable)
487  {
488  std::vector<OctreeType::cell_type*> leaves;
489  std::vector<TetEdgeStruct> IntersectedTetEdges;
490  unsigned int NumberIntersectionsOnTetCorner = 0;
491 
492  // Get leaves of octree intersecting with fluid element
493  mOctree.GetIntersectedLeaves(*(i_fluidElement).base(),leaves);
494 
495  int intersection_counter=0;
496  //i_fluidElement->GetValue(EMBEDDED_VELOCITY)=ZeroVector(3);
497  // Loop over all 6 line Edges of the tetrahedra
498  for(unsigned int i_tetEdge = 0; i_tetEdge < 6; i_tetEdge++)
499  {
500  IdentifyIntersectionNodes( i_fluidElement , i_tetEdge , leaves , IntersectedTetEdges ,
501  NumberIntersectionsOnTetCorner , TetEdgeIndexTable, intersection_counter );
502  }
503  if (intersection_counter!=0)
504  i_fluidElement->GetValue(EMBEDDED_VELOCITY)/=3.0*intersection_counter;
505  //else
506  // i_fluidElement->GetValue(EMBEDDED_VELOCITY)=ZeroVector(3);
507  //KRATOS_WATCH("============================================================")
508  // KRATOS_WATCH(i_fluidElement->GetValue(EMBEDDED_VELOCITY))
509  //KRATOS_WATCH("???????????????????????????????????????????????????????????????")
510  //if (intersection_counter!=0)
511  // KRATOS_WATCH(intersection_counter)
512 
513 
514  if(IntersectedTetEdges.size() > 0)
515  CalcNodalDistanceTo3DSkin( IntersectedTetEdges , i_fluidElement , NumberIntersectionsOnTetCorner );
516  }
517 
520 
521  void IdentifyIntersectionNodes( ModelPart::ElementsContainerType::iterator& i_fluidElement,
522  unsigned int i_tetEdge,
523  std::vector<OctreeType::cell_type*>& leaves,
524  std::vector<TetEdgeStruct>& IntersectedTetEdges,
525  unsigned int& NumberIntersectionsOnTetCorner,
526  BoundedMatrix<unsigned int,6,2> TetEdgeIndexTable,
527  int& intersection_counter)
528  {
529 
530 
531  std::vector<unsigned int> IntersectingStructCondID;
532  TetEdgeStruct NewTetEdge;
533 
534  // Get nodes of line Edge
535  unsigned int EdgeStartIndex = TetEdgeIndexTable(i_tetEdge,0);
536  unsigned int EdgeEndIndex = TetEdgeIndexTable(i_tetEdge,1);
537 
538  PointType& P1 = i_fluidElement->GetGeometry()[EdgeStartIndex];
539  PointType& P2 = i_fluidElement->GetGeometry()[EdgeEndIndex];
540 
541  double EdgeNode1[3] = {P1.X() , P1.Y() , P1.Z()};
542  double EdgeNode2[3] = {P2.X() , P2.Y() , P2.Z()};
543 
544  //int count=0;
545  // loop over all octree cells which are intersected by the fluid element
546  for(unsigned int i_cell = 0 ; i_cell < leaves.size() ; i_cell++)
547  {
548  // Structural element contained in one cell of the octree
549  object_container_type* struct_cond = (leaves[i_cell]->pGetObjects());
550 
551  // loop over all structural elements within each octree cell
552 
553  for(object_container_type::iterator i_StructCondition = struct_cond->begin(); i_StructCondition != struct_cond->end(); i_StructCondition++)
554  {
555  //KRATOS_WATCH(struct_cond->size())
556 
557  if( StructuralElementNotYetConsidered( (*i_StructCondition)->Id() , IntersectingStructCondID ) )
558  {
559 
560  // Calculate and associate intersection point to the current fluid element
561  double IntersectionPoint[3] = {0.0 , 0.0 , 0.0};
562  int TetEdgeHasIntersections = IntersectionTriangleSegment( (*i_StructCondition)->GetGeometry() , EdgeNode1 , EdgeNode2 , IntersectionPoint );
563 
564  if( TetEdgeHasIntersections == 1 )
565  {
566  IntersectionNodeStruct NewIntersectionNode;
567 
568  // Assign information to the intersection node
569  NewIntersectionNode.Coordinates[0] = IntersectionPoint[0];
570  NewIntersectionNode.Coordinates[1] = IntersectionPoint[1];
571  NewIntersectionNode.Coordinates[2] = IntersectionPoint[2];
572 
573  if ( IsNewIntersectionNode( NewIntersectionNode , IntersectedTetEdges ) )
574  {
575 
576  if( IsIntersectionNodeOnTetEdge( IntersectionPoint , EdgeNode1 , EdgeNode2 ) )
577  {
578 
579  // Calculate normal of the structural element at the position of the intersection point
580  CalculateNormal3D((*i_StructCondition)->GetGeometry(),NewIntersectionNode.StructElemNormal);
581 
582  // add the new intersection point to the list of intersection points of the fluid element
583  NewTetEdge.IntNodes.push_back(NewIntersectionNode);
584 
585  //(i_fluidElement->GetValue(NEIGHBOUR_EMBEDDED_FACES)).push_back( GeometricalObject::WeakPointer( *(i_StructCondition.base()) ) );
586  /*
587  array_1d<double,3> emb_vel=(*i_StructCondition)->GetGeometry()[0].FastGetSolutionStepValue(VELOCITY);
588  emb_vel+=(*i_StructCondition)->GetGeometry()[1].FastGetSolutionStepValue(VELOCITY);
589  emb_vel+=(*i_StructCondition)->GetGeometry()[2].FastGetSolutionStepValue(VELOCITY);
590 
591  //KRATOS_WATCH(emb_vel)
592  i_fluidElement->GetValue(EMBEDDED_VELOCITY)+=emb_vel;
593  intersection_counter++;
594  */
595 
596  // check, how many intersection nodes are located on corner points of the tetrahedra
597  if ( IsIntersectionOnCorner( NewIntersectionNode , EdgeNode1 , EdgeNode2) )
598  NumberIntersectionsOnTetCorner++;
599  //BY NOW I WANT TO CONSIDER ONLY THE EDGES THAT ARE CUT "NOT AT THE VERTEX"
600  else
601  {
602  // double dummy=0.0;
603  //(i_fluidElement->GetValue(NEIGHBOUR_EMBEDDED_FACES)).push_back( GeometricalObject::WeakPointer( *(i_StructCondition.base()) ) );
604 
605  array_1d<double,3> emb_vel=(*i_StructCondition)->GetGeometry()[0].FastGetSolutionStepValue(VELOCITY);
606  emb_vel+=(*i_StructCondition)->GetGeometry()[1].FastGetSolutionStepValue(VELOCITY);
607  emb_vel+=(*i_StructCondition)->GetGeometry()[2].FastGetSolutionStepValue(VELOCITY);
608 
609  //KRATOS_WATCH(emb_vel)
610 
611  i_fluidElement->GetValue(EMBEDDED_VELOCITY)+=emb_vel;
612  intersection_counter++;
613 
614  }
615  //(pGeom[i].GetValue(NEIGHBOUR_ELEMENTS)).push_back( Element::WeakPointer( *(ie.base()) ) );
616  }
617 
618  }
619 
620 
621  }
622 
623  }
624  }
625 
626  }
627 
628  // check, if intersection nodes have been found on the tet edge --> if yes, then add these information to the TetEdgeVector
629  if( NewTetEdge.IntNodes.size() > 0 )
630  IntersectedTetEdges.push_back(NewTetEdge);
631  }
632 
635 
636  bool StructuralElementNotYetConsidered( unsigned int IDCurrentStructCond,
637  std::vector<unsigned int>& IntersectingStructCondID )
638  {
639  // check if the structural element was already considered as intersecting element
640  for(unsigned int k = 0 ; k < IntersectingStructCondID.size() ; k++)
641  {
642  if( IDCurrentStructCond == IntersectingStructCondID[k] )
643  return false;
644  }
645 
646  // if structural element has not been considered in another octree, which also intersects the fluid element
647  // add the new object ID to the vector
648  IntersectingStructCondID.push_back( IDCurrentStructCond );
649  return true;
650  }
651 
654 
655  bool IsIntersectionNodeOnTetEdge( double* IntersectionPoint , double* EdgeNode1 , double* EdgeNode2 )
656  {
657  // check, if intersection point is located on any edge of the fluid element
658  array_1d<double,3> ConnectVectTetNodeIntNode1;
659  array_1d<double,3> ConnectVectTetNodeIntNode2;
660  array_1d<double,3> EdgeVector;
661 
662  ConnectVectTetNodeIntNode1[0] = IntersectionPoint[0] - EdgeNode1[0];
663  ConnectVectTetNodeIntNode1[1] = IntersectionPoint[1] - EdgeNode1[1];
664  ConnectVectTetNodeIntNode1[2] = IntersectionPoint[2] - EdgeNode1[2];
665 
666  ConnectVectTetNodeIntNode2[0] = IntersectionPoint[0] - EdgeNode2[0];
667  ConnectVectTetNodeIntNode2[1] = IntersectionPoint[1] - EdgeNode2[1];
668  ConnectVectTetNodeIntNode2[2] = IntersectionPoint[2] - EdgeNode2[2];
669 
670  double LengthConnectVect1 = norm_2( ConnectVectTetNodeIntNode1 );
671  double LengthConnectVect2 = norm_2( ConnectVectTetNodeIntNode2 );
672 
673  EdgeVector[0] = EdgeNode2[0] - EdgeNode1[0];
674  EdgeVector[1] = EdgeNode2[1] - EdgeNode1[1];
675  EdgeVector[2] = EdgeNode2[2] - EdgeNode1[2];
676 
677  double MaxEdgeLength = norm_2( EdgeVector );
678 
679  // if both connection vectors (corner point --> intersection point)
680  // are smaller or equal to the edge length of tetrahedra,
681  // then intersection point is located on the edge
682  if( (LengthConnectVect1 <= (MaxEdgeLength)) && (LengthConnectVect2 <= (MaxEdgeLength)) )
683  return true;
684  else
685  return false;
686  }
687 
690 
692  std::vector<TetEdgeStruct> IntersectedTetEdges )
693  {
694  array_1d<double,3> DiffVector;
695  double NormDiffVector;
696  unsigned int NumberIntNodes;
697 
698  for( unsigned int i_TetEdge = 0 ; i_TetEdge < IntersectedTetEdges.size() ; i_TetEdge++ )
699  {
700  NumberIntNodes = IntersectedTetEdges[i_TetEdge].IntNodes.size();
701  for( unsigned int i_IntNode = 0 ; i_IntNode < NumberIntNodes ; i_IntNode++ )
702  {
703  DiffVector[0] = NewIntersectionNode.Coordinates[0] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[0];
704  DiffVector[1] = NewIntersectionNode.Coordinates[1] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[1];
705  DiffVector[2] = NewIntersectionNode.Coordinates[2] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[2];
706  NormDiffVector = norm_2(DiffVector);
707 
708  if( NormDiffVector < epsilon )
709  return false;
710  }
711  }
712 
713  // if the new intersection node is not existing (as intersection with a corner point), then return false
714  return true;
715  }
716 
719 
721  double* EdgeNode1,
722  double* EdgeNode2 )
723  {
724  array_1d<double,3> DiffVector;
725  double NormDiffVector;
726 
727  DiffVector[0] = EdgeNode1[0] - NewIntersectionNode.Coordinates[0];
728  DiffVector[1] = EdgeNode1[1] - NewIntersectionNode.Coordinates[1];
729  DiffVector[2] = EdgeNode1[2] - NewIntersectionNode.Coordinates[2];
730  NormDiffVector = norm_2(DiffVector);
731 
732  if( NormDiffVector < epsilon )
733  return true;
734 
735  DiffVector[0] = EdgeNode2[0] - NewIntersectionNode.Coordinates[0];
736  DiffVector[1] = EdgeNode2[1] - NewIntersectionNode.Coordinates[1];
737  DiffVector[2] = EdgeNode2[2] - NewIntersectionNode.Coordinates[2];
738  NormDiffVector = norm_2(DiffVector);
739 
740  if( NormDiffVector < epsilon )
741  return true;
742  else
743  return false;
744  }
745 
748 
750  array_1d<double,3>& rResultNormal)
751  {
753  array_1d<double,3> v2 ;
754 
755  v1[0] = rGeometry[1].X() - rGeometry[0].X();
756  v1[1] = rGeometry[1].Y() - rGeometry[0].Y();
757  v1[2] = rGeometry[1].Z() - rGeometry[0].Z();
758 
759  v2[0] = rGeometry[2].X() - rGeometry[0].X();
760  v2[1] = rGeometry[2].Y() - rGeometry[0].Y();
761  v2[2] = rGeometry[2].Z() - rGeometry[0].Z();
762 
763  MathUtils<double>::CrossProduct(rResultNormal,v1,v2);
764  rResultNormal *= 0.5;
765  }
766 
769 
770  void CalcNodalDistanceTo3DSkin(std::vector<TetEdgeStruct>& IntersectedTetEdges,
771  ModelPart::ElementsContainerType::iterator& i_fluid_element,
772  unsigned int NumberIntersectionsOnTetCorner)
773  {
774  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure;
775  array_1d<double,4> ElementalDistances;
776 
777  // Reduce all found intersection nodes located on each tetdrahedra edge to just one intersection node by averaging
778  ComputeApproximationNodes(IntersectedTetEdges,NodesOfApproximatedStructure);
779 
780  // Intersection with one corner point
781  if( NodesOfApproximatedStructure.size() == 1 && NumberIntersectionsOnTetCorner == 1 )
782  {
783  CalcSignedDistancesToOneIntNode(i_fluid_element,NodesOfApproximatedStructure,ElementalDistances);
784  i_fluid_element->GetValue(SPLIT_ELEMENT) = true;
785  }
786 
787  // Intersection with two corner points / one tetrahedra edge
788  if( NodesOfApproximatedStructure.size() == 2 && NumberIntersectionsOnTetCorner == 2 )
789  {
790  CalcSignedDistancesToTwoIntNodes(i_fluid_element,NodesOfApproximatedStructure,ElementalDistances);
791  i_fluid_element->GetValue(SPLIT_ELEMENT) = true;
792  }
793 
794  // Intersection with three tetrahedra edges
795  if( NodesOfApproximatedStructure.size() == 3 )
796  {
797  CalcSignedDistancesToThreeIntNodes(i_fluid_element,NodesOfApproximatedStructure,IntersectedTetEdges,ElementalDistances);
798  i_fluid_element->GetValue(SPLIT_ELEMENT) = true;
799  }
800 
801  // Intersection with four tetrahedra edges
802  if( NodesOfApproximatedStructure.size() == 4 )
803  {
804  CalcSignedDistancesToFourIntNodes(i_fluid_element,NodesOfApproximatedStructure,IntersectedTetEdges,ElementalDistances);
805  i_fluid_element->GetValue(SPLIT_ELEMENT) = true;
806  }
807 
808  // In case there is NO intersection with fluid element
809  if( i_fluid_element->GetValue(SPLIT_ELEMENT) == true )
810  AssignDistancesToElements(i_fluid_element,ElementalDistances);
811  }
812 
815 
816  void ComputeApproximationNodes(std::vector<TetEdgeStruct> IntersectedTetEdges,
817  std::vector<IntersectionNodeStruct>& NodesOfApproximatedStructure)
818  {
819  unsigned int NumberIntNodes;
820  double sum_X;
821  double sum_Y;
822  double sum_Z;
823 
824  // calculate average of all intersection nodes of each tetrahedra edge
825  for(unsigned int i_TetEdge = 0 ; i_TetEdge < IntersectedTetEdges.size() ; i_TetEdge++)
826  {
827  NumberIntNodes = IntersectedTetEdges[i_TetEdge].IntNodes.size();
828  sum_X = 0;
829  sum_Y = 0;
830  sum_Z = 0;
831 
832  for( unsigned int i_IntNode = 0 ; i_IntNode < NumberIntNodes ; i_IntNode++ )
833  {
834  sum_X += IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[0];
835  sum_Y += IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[1];
836  sum_Z += IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[2];
837  }
838 
839  IntersectionNodeStruct NewApproximationNode;
840  NewApproximationNode.Coordinates[0] = sum_X / NumberIntNodes;
841  NewApproximationNode.Coordinates[1] = sum_Y / NumberIntNodes;
842  NewApproximationNode.Coordinates[2] = sum_Z / NumberIntNodes;
843 
844  if(IntersectedTetEdges.size() <= 2)
845  NewApproximationNode.StructElemNormal = IntersectedTetEdges[i_TetEdge].IntNodes[0].StructElemNormal;
846 
847  NodesOfApproximatedStructure.push_back(NewApproximationNode);
848  }
849  }
850 
853 
854  void CalcSignedDistancesToOneIntNode( ModelPart::ElementsContainerType::iterator& i_fluid_element,
855  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
856  array_1d<double,4>& ElementalDistances)
857  {
858  const array_1d<double,3>& IntersectionNodeCoord = NodesOfApproximatedStructure[0].Coordinates;
859  array_1d<double,3> DistVecTetNode;
860  array_1d<double,3> TetNode;
861  array_1d<double,3> NormalAtIntersectionNode;
862  double NormDistTetNode;
863  double InnerProduct;
864 
865  Geometry< Node >& rFluidGeom = i_fluid_element->GetGeometry();
866 
867  for(unsigned int i_TetNode = 0 ; i_TetNode < 4 ; i_TetNode++)
868  {
869  // Get coordinates of the fluid elmenent nodes
870  TetNode = rFluidGeom[i_TetNode].Coordinates();
871 
872  // Compute unsigned distance
873  DistVecTetNode[0] = TetNode[0] - IntersectionNodeCoord[0];
874  DistVecTetNode[1] = TetNode[1] - IntersectionNodeCoord[1];
875  DistVecTetNode[2] = TetNode[2] - IntersectionNodeCoord[2];
876  NormDistTetNode = norm_2( DistVecTetNode );
877 
878  // Get normal at intersection
879  NormalAtIntersectionNode = NodesOfApproximatedStructure[0].StructElemNormal;
880  InnerProduct = inner_prod(DistVecTetNode,NormalAtIntersectionNode);
881 
882  // Assign distances as nodal solution values
883  if(InnerProduct>epsilon)
884  ElementalDistances[i_TetNode] = NormDistTetNode;
885  else if(InnerProduct>-epsilon)
886  ElementalDistances[i_TetNode] = 0;
887  else
888  ElementalDistances[i_TetNode] = -NormDistTetNode;
889  }
890  }
891 
894 
895  void CalcSignedDistancesToTwoIntNodes( ModelPart::ElementsContainerType::iterator& i_fluid_element,
896  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
897  array_1d<double,4>& ElementalDistances)
898  {
899  const array_1d<double,3>& IntersectionNode1Coord = NodesOfApproximatedStructure[0].Coordinates;
900  const array_1d<double,3>& IntersectionNode2Coord = NodesOfApproximatedStructure[1].Coordinates;
901  array_1d<double,3> TetNode;
902  array_1d<double,3> DistVecTetNode;
903  array_1d<double,3> NormalAtIntersectionNode1;
904  array_1d<double,3> NormalAtIntersectionNode2;
905  array_1d<double,3> ResNormal;
906  double InnerProduct;
907  double NormDistTetNode;
908 
909  const Point LinePoint1 = Point(IntersectionNode1Coord[0] , IntersectionNode1Coord[1] , IntersectionNode1Coord[2]);
910  const Point LinePoint2 = Point(IntersectionNode2Coord[0] , IntersectionNode2Coord[1] , IntersectionNode2Coord[2]);
911 
912  Geometry< Node >& rFluidGeom = i_fluid_element->GetGeometry();
913 
914  for(unsigned int i_TetNode = 0 ; i_TetNode < 4 ; i_TetNode++)
915  {
916  // Get coordinates of the fluid element nodes
917  TetNode = rFluidGeom(i_TetNode)->Coordinates();
918 
919  // Compute distance to point
920  NormDistTetNode = GeometryUtils::PointDistanceToLineSegment3D(LinePoint1, LinePoint2 , Point(TetNode[0],TetNode[1],TetNode[2]));
921 
922  // Compute unsigned distance vector by assuming the mean position vector of the two intersection points
923  DistVecTetNode[0] = TetNode[0] - IntersectionNode1Coord[0];
924  DistVecTetNode[1] = TetNode[1] - IntersectionNode1Coord[1];
925  DistVecTetNode[2] = TetNode[2] - IntersectionNode1Coord[2];
926 
927  // Get normal at intersections, average them and check direction of distances
928  NormalAtIntersectionNode1 = NodesOfApproximatedStructure[0].StructElemNormal;
929  NormalAtIntersectionNode2 = NodesOfApproximatedStructure[1].StructElemNormal;
930 
931  // Compute unsigned distance
932  ResNormal[0] = 0.5*(NormalAtIntersectionNode1[0] + NormalAtIntersectionNode2[0]);
933  ResNormal[1] = 0.5*(NormalAtIntersectionNode1[1] + NormalAtIntersectionNode2[1]);
934  ResNormal[2] = 0.5*(NormalAtIntersectionNode1[2] + NormalAtIntersectionNode2[2]);
935  InnerProduct = inner_prod(DistVecTetNode,ResNormal);
936 
937  // Assign distances as nodal solution values
938  if(InnerProduct>epsilon)
939  ElementalDistances[i_TetNode] = NormDistTetNode;
940  else if(InnerProduct>-epsilon)
941  ElementalDistances[i_TetNode] = 0;
942  else
943  ElementalDistances[i_TetNode] = -NormDistTetNode;
944  }
945  }
946 
949 
950  void CalcSignedDistancesToThreeIntNodes( ModelPart::ElementsContainerType::iterator& i_fluid_element,
951  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
952  std::vector<TetEdgeStruct> IntersectedTetEdges,
953  array_1d<double,4>& ElementalDistances)
954  {
955  array_1d<unsigned int,3> IndexNodes;
956 
957  IndexNodes[0] = 0;
958  IndexNodes[1] = 1;
959  IndexNodes[2] = 2;
960 
961  // Compute distance for each tetrahedra node to the triangle to approximate the structure
962  CalcSignedDistancesToApproxTriangle( i_fluid_element , NodesOfApproximatedStructure , IntersectedTetEdges , ElementalDistances , IndexNodes );
963  }
964 
967 
968  void CalcSignedDistancesToFourIntNodes( ModelPart::ElementsContainerType::iterator& i_fluid_element,
969  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
970  std::vector<TetEdgeStruct> IntersectedTetEdges,
971  array_1d<double,4>& ElementalDistances)
972  {
973  array_1d<unsigned int,3> IndexNodes_T1; // nodes of first triangle
974  array_1d<unsigned int,3> IndexNodes_T2; // nodes of second triangle
975 
976  array_1d<double,4> ElementalDistances_T1;
977  array_1d<double,4> ElementalDistances_T2;
978 
979  double dist_T1;
980  double dist_T2;
981 
982  // Generate 2 triangles out of the 4 int nodes which form a parallelogram together
983  // Therefor first define arbitrarily a set of 3 nodes which form a triangle and search for the 2 nodes
984  // of the triangle which form the other triangle together with the fourth node
985  IndexNodes_T1[0] = 0;
986  IndexNodes_T1[1] = 1;
987  IndexNodes_T1[2] = 2;
988 
989  FindIndexNodesOfTriangle2(NodesOfApproximatedStructure,IndexNodes_T2);
990 
991  // Compute distance for first triangle
992  CalcSignedDistancesToApproxTriangle( i_fluid_element , NodesOfApproximatedStructure , IntersectedTetEdges,
993  ElementalDistances_T1 , IndexNodes_T1 );
994  // Compute distance for second triangle
995  CalcSignedDistancesToApproxTriangle( i_fluid_element , NodesOfApproximatedStructure , IntersectedTetEdges,
996  ElementalDistances_T2 , IndexNodes_T2 );
997 
998  // Determine about the minimal distance by considering the distances to both triangles
999  for(unsigned int i_TetNode = 0 ; i_TetNode < 4 ; i_TetNode++)
1000  {
1001  dist_T1 = ElementalDistances_T1[i_TetNode];
1002  dist_T2 = ElementalDistances_T2[i_TetNode];
1003  if(fabs(dist_T1) < fabs(dist_T2))
1004  ElementalDistances[i_TetNode] = dist_T1;
1005  else
1006  ElementalDistances[i_TetNode] = dist_T2;
1007  }
1008  }
1009 
1012 
1013  void FindIndexNodesOfTriangle2(std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
1014  array_1d<unsigned int,3>& IndexNodes_T2)
1015  {
1016  double maxDist = 0;
1017  unsigned int indexExcludedNode = 1000000; // index of the node which is not part of the second triangle
1018  array_1d<double,3> TrianglePoint;
1019  array_1d<double,3> RemainingPoint;
1020  array_1d<double,3> DistVecNode;
1021 
1022  RemainingPoint = NodesOfApproximatedStructure[3].Coordinates;
1023 
1024  // strategy: these two nodes of the first triangle form a triangle with the 4th node, which are closest to that node
1025  // --> look for these nodes with the shortest distance to the remaining node
1026  for(unsigned int i_TriangleNode = 0 ; i_TriangleNode < 3 ; i_TriangleNode++)
1027  {
1028  TrianglePoint = NodesOfApproximatedStructure[i_TriangleNode].Coordinates;
1029  DistVecNode[0] = RemainingPoint[0] - TrianglePoint[0];
1030  DistVecNode[1] = RemainingPoint[1] - TrianglePoint[1];
1031  DistVecNode[2] = RemainingPoint[2] - TrianglePoint[2];
1032  if(norm_2(DistVecNode) > maxDist)
1033  {
1034  maxDist = norm_2(DistVecNode);
1035  indexExcludedNode = i_TriangleNode;
1036  }
1037  }
1038 
1039  // assign the "not excluded" nodes to the index vector of the second triangle
1040  unsigned int indexCursor = 0;
1041  for(unsigned int k = 0 ; k < 3 ; k++)
1042  {
1043  if(indexExcludedNode != k)
1044  {
1045  IndexNodes_T2[indexCursor] = k;
1046  indexCursor += 1;
1047  }
1048  }
1049 
1050  IndexNodes_T2[2] = 3;
1051  }
1052 
1055 
1056  void CalcSignedDistancesToApproxTriangle( ModelPart::ElementsContainerType::iterator& i_fluid_element,
1057  std::vector<IntersectionNodeStruct> NodesOfApproximatedStructure,
1058  std::vector<TetEdgeStruct> IntersectedTetEdges,
1059  array_1d<double,4>& ElementalDistances,
1060  array_1d<unsigned int,3> IndexNodes)
1061  {
1062  Geometry< Node >& rFluidGeom = i_fluid_element->GetGeometry();
1063 
1064  for(unsigned int i_TetNode = 0 ; i_TetNode < 4 ; i_TetNode++)
1065  {
1066  array_1d<double,3> TetNode;
1067  array_1d<double,3> IntersectionNode1Coord;
1068  array_1d<double,3> IntersectionNode2Coord;
1069  array_1d<double,3> IntersectionNode3Coord;
1070  Point ApproxTrianglePoint1;
1071  Point ApproxTrianglePoint2;
1072  Point ApproxTrianglePoint3;
1073  double UnsignedDistance;
1074  double InnerProduct;
1075  unsigned int IndexNode1;
1076  unsigned int IndexNode2;
1077  unsigned int IndexNode3;
1078 
1079  // Get coordinates of the fluid element nodes
1080  TetNode = rFluidGeom(i_TetNode)->Coordinates();
1081 
1082  IndexNode1 = IndexNodes[0];
1083  IndexNode2 = IndexNodes[1];
1084  IndexNode3 = IndexNodes[2];
1085 
1086  IntersectionNode1Coord = NodesOfApproximatedStructure[IndexNode1].Coordinates;
1087  IntersectionNode2Coord = NodesOfApproximatedStructure[IndexNode2].Coordinates;
1088  IntersectionNode3Coord = NodesOfApproximatedStructure[IndexNode3].Coordinates;
1089 
1090  ApproxTrianglePoint1 = Point(IntersectionNode1Coord[0] , IntersectionNode1Coord[1] , IntersectionNode1Coord[2]);
1091  ApproxTrianglePoint2 = Point(IntersectionNode2Coord[0] , IntersectionNode2Coord[1] , IntersectionNode2Coord[2]);
1092  ApproxTrianglePoint3 = Point(IntersectionNode3Coord[0] , IntersectionNode3Coord[1] , IntersectionNode3Coord[2]);
1093 
1094  // Compute distance from tet node to current triangle
1095  UnsignedDistance = GeometryUtils::PointDistanceToTriangle3D(ApproxTrianglePoint1, ApproxTrianglePoint2 , ApproxTrianglePoint3 , Point(TetNode[0],TetNode[1],TetNode[2]));
1096 
1097  bool TetNodeIsInsideStructure = true;
1098  bool TetNodeIsOnStructure = true;
1099  array_1d <double,3> DistVec;
1100  array_1d <double,3> NormalAtIntersectionNode;
1101 
1102  for( unsigned int i_TetEdge = 0 ; i_TetEdge < IntersectedTetEdges.size() ; i_TetEdge++ )
1103  {
1104  for( unsigned int i_IntNode = 0 ; i_IntNode < IntersectedTetEdges[i_TetEdge].IntNodes.size() ; i_IntNode++ )
1105  {
1106  DistVec[0] = TetNode[0] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[0];
1107  DistVec[1] = TetNode[1] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[1];
1108  DistVec[2] = TetNode[2] - IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].Coordinates[2];
1109 
1110  NormalAtIntersectionNode = IntersectedTetEdges[i_TetEdge].IntNodes[i_IntNode].StructElemNormal;
1111 
1112  InnerProduct = inner_prod(DistVec,NormalAtIntersectionNode);
1113 
1114  if(InnerProduct > epsilon)
1115  {
1116  TetNodeIsInsideStructure = false;
1117  TetNodeIsOnStructure = false;
1118  }
1119  else if (InnerProduct < -epsilon)
1120  TetNodeIsOnStructure = false;
1121  }
1122  }
1123 
1124  // Assign distances as nodal solution values ( + = outside of structure, - = inside structure)
1125  if( TetNodeIsInsideStructure == true )
1126  ElementalDistances[i_TetNode] = -UnsignedDistance;
1127  else if( TetNodeIsOnStructure == true )
1128  ElementalDistances[i_TetNode] = 0;
1129  else
1130  ElementalDistances[i_TetNode] = +UnsignedDistance;
1131  }
1132  }
1133 
1136 
1137  void AssignDistancesToElements(ModelPart::ElementsContainerType::iterator& i_fluid_element,
1138  array_1d<double,4> ElementalDistances)
1139  {
1140  Geometry< Node >& rFluidGeom = i_fluid_element->GetGeometry();
1141 
1142  array_1d<double,4> MinElementalDistances;
1143 
1144  for(unsigned int i_TetNode = 0 ; i_TetNode < 4 ; i_TetNode++)
1145  {
1146  //Assign distances to the element, if a smaller value could be found
1147  if( fabs(ElementalDistances[i_TetNode]) < fabs(i_fluid_element->GetValue(ELEMENTAL_DISTANCES)[i_TetNode]) )
1148  MinElementalDistances[i_TetNode] = ElementalDistances[i_TetNode];
1149  else
1150  MinElementalDistances[i_TetNode] = i_fluid_element->GetValue(ELEMENTAL_DISTANCES)[i_TetNode];
1151 
1152  //Assign distances to the single nodes (for visualization), if a smaller value could be found
1153  if( fabs(ElementalDistances[i_TetNode]) < fabs(rFluidGeom[i_TetNode].GetSolutionStepValue(DISTANCE)) )
1154  rFluidGeom[i_TetNode].GetSolutionStepValue(DISTANCE) = ElementalDistances[i_TetNode];
1155  }
1156 
1157  i_fluid_element->SetValue(ELEMENTAL_DISTANCES,MinElementalDistances);
1158  }
1159 
1162 
1163 
1164 
1165  /*
1166  void GenerateOctree()
1167  {
1168  Timer::Start("Generating Octree");
1169 
1170  // Setting the boundingbox for non-normalized coordinates
1171  const int dimension = 3;
1172  double boundingBox_low[3],boundingBox_high[3];
1173 
1174  for(int i = 0; i < dimension; i++)
1175  {
1176  boundingBox_low[i] = mrSkinModelPart.NodesBegin()->Coordinates()[i];
1177  boundingBox_high[i] = mrSkinModelPart.NodesBegin()->Coordinates()[i];
1178  }
1179 
1180  for(ModelPart::NodeIterator i_node = mrSkinModelPart.NodesBegin();
1181  i_node != mrSkinModelPart.NodesEnd();
1182  i_node++)
1183  {
1184  for(int i = 0; i < dimension; i++)
1185  {
1186  if(i_node->Coordinates()[i] < boundingBox_low[i]) boundingBox_low[i] = i_node->Coordinates()[i];
1187  if(i_node->Coordinates()[i] > boundingBox_high[i]) boundingBox_high[i] = i_node->Coordinates()[i];
1188  }
1189  }
1190 
1191  mOctree.SetBoundingBox(boundingBox_low,boundingBox_high);
1192 
1193 
1194  //mOctree.RefineWithUniformSize(0.0625);
1195  for(ModelPart::NodeIterator i_node = mrSkinModelPart.NodesBegin() ; i_node != mrSkinModelPart.NodesEnd() ; i_node++)
1196  {
1197  double temp_point[3];
1198  const array_1d<double,3>& r_coordinates = i_node->Coordinates();
1199  temp_point[0] = r_coordinates[0];
1200  temp_point[1] = r_coordinates[1];
1201  temp_point[2] = r_coordinates[2];
1202  mOctree.Insert(temp_point);
1203  }
1204 
1205 
1206  //mOctree.Constrain2To1(); // To be removed. Pooyan.
1207 
1208  for(ModelPart::ElementIterator i_element = mrSkinModelPart.ElementsBegin() ; i_element != mrSkinModelPart.ElementsEnd() ; i_element++)
1209  {
1210  mOctree.Insert(*(i_element).base());
1211  }
1212 
1213  Timer::Stop("Generating Octree");
1214 // octree.Insert(*(mrSkinModelPart.ElementsBegin().base()));
1215  KRATOS_WATCH(mOctree);
1216 
1217 // std::cout << "######## WRITING OCTREE MESH #########" << std::endl;
1218 // std::ofstream myfile;
1219 // myfile.open ("unserbaum.post.msh");
1220 // mOctree.PrintGiDMesh(myfile);
1221 // myfile.close();
1222  }
1223 */
1224 
1226  {
1227  Timer::Start("Generating Octree");
1228  //std::cout << "Generating the Octree..." << std::endl;
1229 
1230  double low[3];
1231  double high[3];
1232 
1233  for (int i = 0 ; i < 3; i++)
1234  {
1235  low[i] = high[i] = mrFluidModelPart.NodesBegin()->Coordinates()[i];
1236  }
1237 
1238  // loop over all structure nodes
1239  for(ModelPart::NodeIterator i_node = mrFluidModelPart.NodesBegin();
1240  i_node != mrFluidModelPart.NodesEnd();
1241  i_node++)
1242  {
1243  const array_1d<double,3>& r_coordinates = i_node->Coordinates();
1244  for (int i = 0 ; i < 3; i++)
1245  {
1246  low[i] = r_coordinates[i] < low[i] ? r_coordinates[i] : low[i];
1247  high[i] = r_coordinates[i] > high[i] ? r_coordinates[i] : high[i];
1248  }
1249  }
1250 // KRATOS_WATCH( low[0] )
1251 // KRATOS_WATCH( low[1] )
1252 // KRATOS_WATCH( low[2] )
1253 // KRATOS_WATCH( "" )
1254 // KRATOS_WATCH( high[0] )
1255 // KRATOS_WATCH( high[1] )
1256 // KRATOS_WATCH( high[2] )
1257  mOctree.SetBoundingBox(low,high);
1258 
1259  //mOctree.RefineWithUniformSize(0.0625);
1260 
1261  // loop over all structure nodes
1262  for(ModelPart::NodeIterator i_node = mrSkinModelPart.NodesBegin();
1263  i_node != mrSkinModelPart.NodesEnd();
1264  i_node++)
1265  {
1266  double temp_point[3];
1267  temp_point[0] = i_node->X();
1268  temp_point[1] = i_node->Y();
1269  temp_point[2] = i_node->Z();
1270  mOctree.Insert(temp_point);
1271  }
1272 
1273  //mOctree.Constrain2To1(); // To be removed. Pooyan.
1274 
1275  // loop over all structure elements
1276  //for(ModelPart::ElementIterator i_element = mrSkinModelPart.ElementsBegin();
1277  // i_element != mrSkinModelPart.ElementsEnd();
1278  // i_element++)
1279  for(ModelPart::ConditionIterator i_cond = mrSkinModelPart.ConditionsBegin();
1280  i_cond != mrSkinModelPart.ConditionsEnd();
1281  i_cond++)
1282  {
1283  mOctree.Insert(*(i_cond).base());
1284  }
1285 
1286  Timer::Stop("Generating Octree");
1287 
1288 // KRATOS_WATCH(mOctree);
1289 
1290 // std::cout << "######## WRITING OCTREE MESH #########" << std::endl;
1291 // std::ofstream myfile;
1292 // myfile.open ("octree.post.msh");
1293 // mOctree.PrintGiDMesh(myfile);
1294 // myfile.close();
1295 
1296  //std::cout << "Generating the Octree finished" << std::endl;
1297  }
1298 
1299 
1302 
1305 
1306 
1308  {
1309  Timer::Start("Generating Nodes");
1310  std::vector<OctreeType::cell_type*> all_leaves;
1311  mOctree.GetAllLeavesVector(all_leaves);
1312 
1313  IndexPartition<std::size_t>(all_leaves.size()).for_each([&](std::size_t Index){
1314  *(all_leaves[Index]->pGetDataPointer()) = ConfigurationType::AllocateData();
1315  });
1316 
1317  std::size_t last_id = mrBodyModelPart.NumberOfNodes() + 1;
1318  //KRATOS_WATCH(all_leaves.size());
1319  for (std::size_t i = 0; i < all_leaves.size(); i++)
1320  {
1321  //KRATOS_WATCH(i)
1322  CellType* cell = all_leaves[i];
1323  GenerateCellNode(cell, last_id);
1324  }
1325 
1326  Timer::Stop("Generating Nodes");
1327 
1328  }
1329 
1330  void GenerateCellNode(CellType* pCell, std::size_t& LastId)
1331  {
1332  for (int i_pos=0; i_pos < 8; i_pos++) // position 8 is for center
1333  {
1334  ConfigurationType::cell_node_data_type* p_node = (*(pCell->pGetData()))[i_pos];
1335  if(p_node == 0)
1336  {
1337  (*(pCell->pGetData()))[i_pos] = new ConfigurationType::cell_node_data_type;
1338 
1339  (*(pCell->pGetData()))[i_pos]->Id() = LastId++;
1340  //KRATOS_WATCH(LastId)
1341 
1342  mOctreeNodes.push_back((*(pCell->pGetData()))[i_pos]);
1343 
1344  SetNodeInNeighbours(pCell,i_pos,(*(pCell->pGetData()))[i_pos]);
1345  }
1346 
1347  }
1348  }
1349 
1350  void SetNodeInNeighbours(CellType* pCell, int Position, CellNodeDataType* pNode)
1351 {
1352  CellType::key_type point_key[3];
1353  pCell->GetKey(Position, point_key);
1354 
1355  for (std::size_t i_direction = 0; i_direction < 8; i_direction++) {
1356  CellType::key_type neighbour_key[3];
1357  if (pCell->GetNeighbourKey(Position, i_direction, neighbour_key)) {
1358  CellType* neighbour_cell = mOctree.pGetCell(neighbour_key);
1359  if (!neighbour_cell || (neighbour_cell == pCell))
1360  continue;
1361 
1362  std::size_t position = neighbour_cell->GetLocalPosition(point_key);
1363  if((*neighbour_cell->pGetData())[position])
1364  {
1365  std::cout << "ERROR!! Bad Position calculated!!!!!!!!!!! position :" << position << std::endl;
1366  continue;
1367  }
1368 
1369  (*neighbour_cell->pGetData())[position] = pNode;
1370  }
1371  }
1372  }
1373 
1374 
1376  {
1377  Timer::Start("Calculate Distances2");
1378  ModelPart::NodesContainerType::ContainerType& nodes = mrFluidModelPart.NodesArray();
1379  int nodes_size = nodes.size();
1380 // // first of all we reset the node distance to 1.00 which is the maximum distnace in our normalized space.
1381 //#pragma omp parallel for firstprivate(nodes_size)
1382 // for(int i = 0 ; i < nodes_size ; i++)
1383 // nodes[i]->GetSolutionStepValue(DISTANCE) = 1.00;
1384 
1385  std::vector<CellType*> leaves;
1386 
1387  mOctree.GetAllLeavesVector(leaves);
1388  //int leaves_size = leaves.size();
1389 
1390 // for(int i = 0 ; i < leaves_size ; i++)
1391 // CalculateNotEmptyLeavesDistance(leaves[i]);
1392 
1393  IndexPartition<std::size_t>(nodes_size).for_each([&](std::size_t Index){
1394  CalculateNodeDistance(*(nodes[Index]));
1395  });
1396 
1397  Timer::Stop("Calculate Distances2");
1398 
1399  }
1400 // void CalculateDistance3()
1401 // {
1402 // Timer::Start("Calculate Distances2");
1403 // ModelPart::NodesContainerType::ContainerType& nodes = mrFluidModelPart.NodesArray();
1404 // int nodes_size = nodes.size();
1406 //#pragma omp parallel for firstprivate(nodes_size)
1407 // for(int i = 0 ; i < nodes_size ; i++)
1408 // nodes[i]->GetSolutionStepValue(DISTANCE) = 1.00;
1409 
1410 // std::vector<CellType*> leaves;
1411 
1412 // mOctree.GetAllLeavesVector(leaves);
1413 // int leaves_size = leaves.size();
1414 
1415 // for(int i = 0 ; i < leaves_size ; i++)
1416 // CalculateNotEmptyLeavesDistance(leaves[i]);
1417 
1418 //#pragma omp parallel for firstprivate(nodes_size)
1419 // for(int i = 0 ; i < nodes_size ; i++)
1420 // {
1421 // CalculateNodeDistance(*(nodes[i]));
1422 // }
1423 // Timer::Stop("Calculate Distances2");
1424 
1425 // }
1426 // void CalculateDistance4()
1427 // {
1428 // Timer::Start("Calculate Distances3");
1429 // ModelPart::NodesContainerType::ContainerType& nodes = mrFluidModelPart.NodesArray();
1430 // int nodes_size = nodes.size();
1431 // std::vector<CellType*> leaves;
1432 
1433 // mOctree.GetAllLeavesVector(leaves);
1434 // int leaves_size = leaves.size();
1435 
1436 //#pragma omp parallel for firstprivate(nodes_size)
1437 // for(int i = 0 ; i < nodes_size ; i++)
1438 // {
1439 // CalculateNodeDistanceFromCell(*(nodes[i]));
1440 // }
1441 // Timer::Stop("Calculate Distances3");
1442 
1443 // }
1444 
1445 
1447  {
1448  Timer::Start("Calculate Distances");
1449  ConfigurationType::data_type& nodes = mOctreeNodes;
1450  int nodes_size = nodes.size();
1451  // first of all we reste the node distance to 1.00 which is the maximum distnace in our normalized space.
1452 
1453  IndexPartition<std::size_t>(nodes_size).for_each([&](std::size_t Index){
1454  nodes[Index]->Distance() = 1.00;
1455  });
1456 
1457  std::vector<CellType*> leaves;
1458 
1459  mOctree.GetAllLeavesVector(leaves);
1460  int leaves_size = leaves.size();
1461 
1462  for(int i = 0 ; i < leaves_size ; i++)
1464 
1465  for(int i_direction = 0 ; i_direction < 1 ; i_direction++)
1466  {
1467 
1468 //#pragma omp parallel for firstprivate(nodes_size)
1469  for(int i = 0 ; i < nodes_size ; i++)
1470  {
1471  if(nodes[i]->X() < 1.00 && nodes[i]->Y() < 1.00 && nodes[i]->Z() < 1.00)
1472  // if((*nodes[i])[i_direction] == 0.00)
1473  CalculateDistance(*(nodes[i]), i_direction);
1474  }
1475  }
1476  Timer::Stop("Calculate Distances");
1477 
1478  }
1479 
1480  void CalculateDistance(CellNodeDataType& rNode, int i_direction)
1481  {
1482  double coords[3] = {rNode.X(), rNode.Y(), rNode.Z()};
1483  // KRATOS_WATCH_3(coords);
1484 
1485  //This function must color the positions in space defined by 'coords'.
1486  //coords is of dimension (3) normalized in (0,1)^3 space
1487 
1488  typedef Element::GeometryType triangle_type;
1489  typedef std::vector<std::pair<double, triangle_type*> > intersections_container_type;
1490 
1491  intersections_container_type intersections;
1492  ConfigurationType::data_type nodes_array;
1493 
1494 
1495  const double epsilon = 1e-12;
1496 
1497  double distance = 1.0;
1498 
1499  // Creating the ray
1500  double ray[3] = {coords[0], coords[1], coords[2]};
1501  ray[i_direction] = 0; // starting from the lower extreme
1502 
1503 // KRATOS_WATCH_3(ray)
1504  GetIntersectionsAndNodes(ray, i_direction, intersections, nodes_array);
1505 // KRATOS_WATCH(nodes_array.size())
1506  for (std::size_t i_node = 0; i_node < nodes_array.size() ; i_node++)
1507  {
1508  double coord = (*nodes_array[i_node])[i_direction];
1509  // KRATOS_WATCH(intersections.size());
1510 
1511  int ray_color= 1;
1512  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_intersection = intersections.begin();
1513  while (i_intersection != intersections.end()) {
1514  double d = coord - i_intersection->first;
1515  if (d > epsilon) {
1516 
1517  ray_color = -ray_color;
1518  distance = d;
1519  } else if (d > -epsilon) {//interface
1520  distance = 0.00;
1521  break;
1522  } else {
1523  if(distance > -d)
1524  distance = -d;
1525  break;
1526  }
1527 
1528  i_intersection++;
1529  }
1530 
1531  distance *= ray_color;
1532 
1533  double& node_distance = nodes_array[i_node]->Distance();
1534  if(fabs(distance) < fabs(node_distance))
1535  node_distance = distance;
1536  else if (distance*node_distance < 0.00) // assigning the correct sign
1537  node_distance = -node_distance;
1538 
1539 
1540  }
1541  }
1542 
1544  {
1545  //typedef Element::GeometryType triangle_type;
1546  typedef OctreeType::cell_type::object_container_type object_container_type;
1547 
1548  object_container_type* objects = (pCell->pGetObjects());
1549 
1550  // There are no intersection in empty cells
1551  if (objects->empty())
1552  return;
1553 
1554 
1555  for (int i_pos=0; i_pos < 8; i_pos++) // position 8 is for center
1556  {
1557  double distance = 1.00; // maximum distance is 1.00
1558 
1559  for(object_container_type::iterator i_object = objects->begin(); i_object != objects->end(); i_object++)
1560  {
1562  pCell->GetKey(i_pos,keys);
1563 
1564  double cell_point[3];
1565  mOctree.CalculateCoordinates(keys,cell_point);
1566 
1567  double d = GeometryUtils::PointDistanceToTriangle3D((*i_object)->GetGeometry()[0], (*i_object)->GetGeometry()[1], (*i_object)->GetGeometry()[2], Point(cell_point[0], cell_point[1], cell_point[2]));
1568 
1569  if(d < distance)
1570  distance = d;
1571  }
1572 
1573  double& node_distance = (*(pCell->pGetData()))[i_pos]->Distance();
1574  if(distance < node_distance)
1575  node_distance = distance;
1576 
1577  }
1578 
1579  }
1580 
1581 
1583  {
1584  double coord[3] = {rNode.X(), rNode.Y(), rNode.Z()};
1585  double distance = DistancePositionInSpace(coord);
1586  double& node_distance = rNode.GetSolutionStepValue(DISTANCE);
1587 
1588  //const double epsilon = 1.00e-12;
1589  if(fabs(node_distance) > fabs(distance))
1590  node_distance = distance;
1591  else if (distance*node_distance < 0.00) // assigning the correct sign
1592  node_distance = -node_distance;
1593  }
1594 
1595 // void CalculateNodeDistanceFromCell(Node& rNode)
1596 // {
1597 // OctreeType::key_type node_key[3] = {octree->CalcKeyNormalized(rNode.X()), octree->CalcKeyNormalized(rNode.Y()), octree->CalcKeyNormalized(rNode.Z())};
1598 // OctreeType::cell_type* pcell = octree->pGetCell(node_key);
1599 
1600 // object_container_type* objects = (pCell->pGetObjects());
1601 
1602 // // We interpolate the cell distances for the node in empty cells
1603 // if (objects->empty())
1604 // {
1605 
1606 // }
1607 
1608 // double distance = DistancePositionInSpace(coord);
1609 // double& node_distance = rNode.GetSolutionStepValue(DISTANCE);
1610 
1611 // //const double epsilon = 1.00e-12;
1612 // if(fabs(node_distance) > fabs(distance))
1613 // node_distance = distance;
1614 // else if (distance*node_distance < 0.00) // assigning the correct sign
1615 // node_distance = -node_distance;
1616 // }
1617 
1618  double DistancePositionInSpace(double* coords)
1619  {
1620  //This function must color the positions in space defined by 'coords'.
1621  //coords is of dimension (3) normalized in (0,1)^3 space
1622 
1623  typedef Element::GeometryType triangle_type;
1624  typedef std::vector<std::pair<double, triangle_type*> > intersections_container_type;
1625 
1626  intersections_container_type intersections;
1627 
1628  const int dimension = 3;
1629  const double epsilon = 1e-12;
1630 
1631  double distances[3] = {1.0, 1.0, 1.0};
1632 
1633  for (int i_direction = 0; i_direction < dimension; i_direction++)
1634  {
1635  // Creating the ray
1636  double ray[3] = {coords[0], coords[1], coords[2]};
1637  mOctree.NormalizeCoordinates(ray);
1638  ray[i_direction] = 0; // starting from the lower extreme
1639 
1640  GetIntersections(ray, i_direction, intersections);
1641 
1642 // if(intersections.size() == 1)
1643 // KRATOS_WATCH_3(ray)
1644 
1645  // KRATOS_WATCH(intersections.size());
1646 
1647  int ray_color= 1;
1648  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_intersection = intersections.begin();
1649  while (i_intersection != intersections.end()) {
1650  double d = coords[i_direction] - i_intersection->first;
1651  if (d > epsilon) {
1652 
1653  ray_color = -ray_color;
1654  distances[i_direction] = d;
1655 // if(distances[i_direction] > d) // I think this is redundunt. Pooyan.
1656 // {
1657 // if(ray_color > 0.00)
1658 // distances[i_direction] = d;
1659 // else
1660 // distances[i_direction] = -d;
1661 // }
1662  } else if (d > -epsilon) {//interface
1663  distances[i_direction] = 0.00;
1664  break;
1665  } else {
1666  if(distances[i_direction] > -d)
1667  distances[i_direction] = -d;
1668  break;
1669  }
1670 
1671  i_intersection++;
1672  }
1673 
1674  distances[i_direction] *= ray_color;
1675  }
1676 
1677 // if(distances[0]*distances[1] < 0.00 || distances[2]*distances[1] < 0.00)
1678 // KRATOS_WATCH_3(distances);
1679 
1680  double distance = (fabs(distances[0]) > fabs(distances[1])) ? distances[1] : distances[0];
1681  distance = (fabs(distance) > fabs(distances[2])) ? distances[2] : distance;
1682 
1683  return distance;
1684 
1685  }
1686 
1687 
1688  void GetIntersectionsAndNodes(double* ray, int direction, std::vector<std::pair<double,Element::GeometryType*> >& intersections, ConfigurationType::data_type& rNodesArray)
1689  {
1690  //This function passes the ray through the model and gives the hit point to all objects in its way
1691  //ray is of dimension (3) normalized in (0,1)^3 space
1692  // direction can be 0,1,2 which are x,y and z respectively
1693 
1694  const double epsilon = 1.00e-12;
1695 
1696  // first clearing the intersections points vector
1697  intersections.clear();
1698 
1699  OctreeType* octree = &mOctree;
1700 
1701  OctreeType::key_type ray_key[3] = {octree->CalcKeyNormalized(ray[0]), octree->CalcKeyNormalized(ray[1]), octree->CalcKeyNormalized(ray[2])};
1702  OctreeType::key_type cell_key[3];
1703 
1704  // getting the entrance cell from lower extreme
1705  ray_key[direction] = 0;
1706  OctreeType::cell_type* cell = octree->pGetCell(ray_key);
1707 
1708  while (cell) {
1709  std::size_t position = cell->GetLocalPosition(ray_key); // Is this the local position!?!?!?!
1710  OctreeType::key_type node_key[3];
1711  cell->GetKey(position, node_key);
1712  if((node_key[0] == ray_key[0]) && (node_key[1] == ray_key[1]) && (node_key[2] == ray_key[2]))
1713  {
1714  if(cell->pGetData())
1715  {
1716  if(cell->pGetData()->size() > position)
1717  {
1718  CellNodeDataType* p_node = (*cell->pGetData())[position];
1719  if(p_node)
1720  {
1721  //KRATOS_WATCH(p_node->Id())
1722  rNodesArray.push_back(p_node);
1723  }
1724  }
1725  else
1726  KRATOS_WATCH(cell->pGetData()->size())
1727  }
1728  }
1729 
1730 
1731 // std::cout << ".";
1732  GetCellIntersections(cell, ray, ray_key, direction, intersections);
1733 
1734  // Add the cell's middle node if existed
1735 // cell->GetKey(8, cell_key); // 8 is the central position
1736 // ray_key[direction]=cell_key[direction]; // positioning the ray in the middle of cell in its direction
1737 
1738 // position = cell->GetLocalPosition(ray_key);
1739 // if(position < 27) // principal nodes
1740 // {
1741 // if(cell->pGetData())
1742 // {
1743 // if(cell->pGetData()->size() > position)
1744 // {
1745 // Node* p_node = (*cell->pGetData())[position];
1746 // if(p_node)
1747 // {
1748 // //KRATOS_WATCH(p_node->Id())
1749 // rNodesArray.push_back(p_node);
1750 // }
1751 // }
1752 // else
1753 // KRATOS_WATCH(cell->pGetData()->size())
1754 // }
1755 // }
1756 // else
1757 // {
1758 // KRATOS_WATCH(position);
1759 // KRATOS_WATCH(*cell);
1760 // }
1761 
1762 
1763  // go to the next cell
1764  if (cell->GetNeighbourKey(1 + direction * 2, cell_key)) {
1765  ray_key[direction] = cell_key[direction];
1766  cell = octree->pGetCell(ray_key);
1767  ray_key[direction] -= 1 ;//the key returned by GetNeighbourKey is inside the cell (minkey +1), to ensure that the corresponding
1768  //cell get in pGetCell is the right one.
1769  } else
1770  cell = NULL;
1771  }
1772 
1773 
1774 
1775  // KRATOS_WATCH(rNodesArray.size());
1776  // now eliminating the repeated objects
1777  if (!intersections.empty()) {
1778  //sort
1779  std::sort(intersections.begin(), intersections.end());
1780  // unique
1781  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_begin = intersections.begin();
1782  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_intersection = intersections.begin();
1783  while (++i_begin != intersections.end()) {
1784  // considering the very near points as the same points
1785  if (fabs(i_begin->first - i_intersection->first) > epsilon) // if the hit points are far enough they are not the same
1786  *(++i_intersection) = *i_begin;
1787  }
1788  intersections.resize((++i_intersection) - intersections.begin());
1789 
1790  }
1791  }
1792 
1793  void GetIntersections(double* ray, int direction, std::vector<std::pair<double,Element::GeometryType*> >& intersections)
1794  {
1795  //This function passes the ray through the model and gives the hit point to all objects in its way
1796  //ray is of dimension (3) normalized in (0,1)^3 space
1797  // direction can be 0,1,2 which are x,y and z respectively
1798 
1799  const double epsilon = 1.00e-12;
1800 
1801  // first clearing the intersections points vector
1802  intersections.clear();
1803 
1804  OctreeType* octree = &mOctree;
1805 
1806  OctreeType::key_type ray_key[3] = {octree->CalcKeyNormalized(ray[0]), octree->CalcKeyNormalized(ray[1]), octree->CalcKeyNormalized(ray[2])};
1807  OctreeType::key_type cell_key[3];
1808 
1809  // getting the entrance cell from lower extreme
1810  OctreeType::cell_type* cell = octree->pGetCell(ray_key);
1811 
1812  while (cell) {
1813 // std::cout << ".";
1814  GetCellIntersections(cell, ray, ray_key, direction, intersections);
1815  // go to the next cell
1816  if (cell->GetNeighbourKey(1 + direction * 2, cell_key)) {
1817  ray_key[direction] = cell_key[direction];
1818  cell = octree->pGetCell(ray_key);
1819  ray_key[direction] -= 1 ;//the key returned by GetNeighbourKey is inside the cell (minkey +1), to ensure that the corresponding
1820  //cell get in pGetCell is the right one.
1821  } else
1822  cell = NULL;
1823  }
1824 
1825 
1826  // now eliminating the repeated objects
1827  if (!intersections.empty()) {
1828  //sort
1829  std::sort(intersections.begin(), intersections.end());
1830  // unique
1831  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_begin = intersections.begin();
1832  std::vector<std::pair<double, Element::GeometryType*> >::iterator i_intersection = intersections.begin();
1833  while (++i_begin != intersections.end()) {
1834  // considering the very near points as the same points
1835  if (fabs(i_begin->first - i_intersection->first) > epsilon) // if the hit points are far enough they are not the same
1836  *(++i_intersection) = *i_begin;
1837  }
1838  intersections.resize((++i_intersection) - intersections.begin());
1839 
1840  }
1841  }
1842 
1844  OctreeType::key_type* ray_key, int direction,
1845  std::vector<std::pair<double, Element::GeometryType*> >& intersections) {
1846  //This function passes the ray through the cell and gives the hit point to all objects in its way
1847  //ray is of dimension (3) normalized in (0,1)^3 space
1848  // direction can be 0,1,2 which are x,y and z respectively
1849 
1850  //typedef Element::GeometryType triangle_type;
1851  typedef OctreeType::cell_type::object_container_type object_container_type;
1852 
1853  object_container_type* objects = (cell->pGetObjects());
1854 
1855  // There are no intersection in empty cells
1856  if (objects->empty())
1857  return 0;
1858 
1859 // std::cout << "X";
1860  // calculating the two extreme of the ray segment inside the cell
1861  double ray_point1[3] = {ray[0], ray[1], ray[2]};
1862  double ray_point2[3] = {ray[0], ray[1], ray[2]};
1863  double normalized_coordinate;
1864  mOctree.CalculateCoordinateNormalized(ray_key[direction], normalized_coordinate);
1865  ray_point1[direction] = normalized_coordinate;
1866  ray_point2[direction] = ray_point1[direction] + mOctree.CalcSizeNormalized(cell);
1867 
1868  mOctree.ScaleBackToOriginalCoordinate(ray_point1);
1869  mOctree.ScaleBackToOriginalCoordinate(ray_point2);
1870 
1871  for (object_container_type::iterator i_object = objects->begin(); i_object != objects->end(); i_object++) {
1872  double intersection[3]={0.00,0.00,0.00};
1873 
1874  int is_intersected = IntersectionTriangleSegment((*i_object)->GetGeometry(), ray_point1, ray_point2, intersection); // This intersection has to be optimized for axis aligned rays
1875 
1876  if (is_intersected == 1) // There is an intersection but not coplanar
1877  intersections.push_back(std::pair<double, Element::GeometryType*>(intersection[direction], &((*i_object)->GetGeometry())));
1878  //else if(is_intersected == 2) // coplanar case
1879  }
1880 
1881  return 0;
1882  }
1883 
1884  int IntersectionTriangleSegment(Element::GeometryType& rGeometry, double* RayPoint1, double* RayPoint2, double* IntersectionPoint)
1885  {
1886  // This is the adaption of the implemnetation provided in:
1887  // http://www.softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm#intersect_RayTriangle()
1888 
1889  const double epsilon = 1.00e-12;
1890 
1891  array_1d<double,3> u, v, n; // triangle vectors
1892  array_1d<double,3> dir, w0, w; // ray vectors
1893  double r, a, b; // params to calc ray-plane intersect
1894 
1895 
1896  // get triangle edge vectors and plane normal
1897  u = rGeometry[1] - rGeometry[0];
1898  v = rGeometry[2] - rGeometry[0];
1899 
1900  MathUtils<double>::CrossProduct(n, u, v); // cross product
1901 
1902  if (norm_2(n) == 0) // triangle is degenerate
1903  return -1; // do not deal with this case
1904 
1905  for(int i = 0 ; i < 3 ; i++)
1906  {
1907  dir[i] = RayPoint2[i] - RayPoint1[i]; // ray direction vector
1908  w0[i] = RayPoint1[i] - rGeometry[0][i];
1909  }
1910 
1911  a = -inner_prod(n,w0);
1912  b = inner_prod(n,dir);
1913 
1914  if (fabs(b) < epsilon) { // ray is parallel to triangle plane
1915  if (a == 0) // ray lies in triangle plane
1916  return 2;
1917  else return 0; // ray disjoint from plane
1918  }
1919 
1920  // get intersect point of ray with triangle plane
1921  r = a / b;
1922  if (r < 0.0) // ray goes away from triangle
1923  return 0; // => no intersect
1924  // for a segment, also test if (r > 1.0) => no intersect
1925 
1926  for(int i = 0 ; i < 3 ; i++)
1927  IntersectionPoint[i] = RayPoint1[i] + r * dir[i]; // intersect point of ray and plane
1928 
1929  // is I inside T?
1930  double uu, uv, vv, wu, wv, D;
1931  uu = inner_prod(u,u);
1932  uv = inner_prod(u,v);
1933  vv = inner_prod(v,v);
1934 
1935 
1936  for(int i = 0 ; i < 3 ; i++)
1937  w[i] = IntersectionPoint[i] - rGeometry[0][i];
1938 
1939 
1940  wu = inner_prod(w,u);
1941  wv = inner_prod(w,v);
1942  D = uv * uv - uu * vv;
1943 
1944  // get and test parametric coords
1945  double s, t;
1946  s = (uv * wv - vv * wu) / D;
1947  if (s < 0.0 - epsilon || s > 1.0 + epsilon) // I is outside T
1948  return 0;
1949  t = (uv * wu - uu * wv) / D;
1950  if (t < 0.0 - epsilon || (s + t) > 1.0 + epsilon) // I is outside T
1951  return 0;
1952 
1953  return 1; // I is in T
1954 
1955  }
1956 
1957 
1958 
1962 
1963 
1967 
1968 
1972 
1974  std::string Info() const override
1975  {
1976  return "CalculateSignedDistanceTo3DConditionSkinProcess";
1977  }
1978 
1980  void PrintInfo(std::ostream& rOStream) const override
1981  {
1982  rOStream << "CalculateSignedDistanceTo3DConditionSkinProcess";
1983  }
1984 
1986  void PrintData(std::ostream& rOStream) const override
1987  {
1988  }
1989 
1990  void PrintGiDMesh(std::ostream & rOStream) const {
1991  std::vector<CellType*> leaves;
1992 
1993  mOctree.GetAllLeavesVector(leaves);
1994 
1995  std::cout << "writing " << leaves.size() << " leaves" << std::endl;
1996  rOStream << "MESH \"leaves\" dimension 3 ElemType Hexahedra Nnode 8" << std::endl;
1997  rOStream << "# color 96 96 96" << std::endl;
1998  rOStream << "Coordinates" << std::endl;
1999  rOStream << "# node number coordinate_x coordinate_y coordinate_z " << std::endl;
2000 
2001  for(ConfigurationType::data_type::const_iterator i_node = mOctreeNodes.begin() ; i_node != mOctreeNodes.end() ; i_node++)
2002  {
2003  rOStream << (*i_node)->Id() << " " << (*i_node)->X() << " " << (*i_node)->Y() << " " << (*i_node)->Z() << std::endl;
2004  //mOctree.Insert(temp_point);
2005  }
2006  std::cout << "Nodes written..." << std::endl;
2007  rOStream << "end coordinates" << std::endl;
2008  rOStream << "Elements" << std::endl;
2009  rOStream << "# element node_1 node_2 node_3 material_number" << std::endl;
2010 
2011  for (std::size_t i = 0; i < leaves.size(); i++) {
2012  if ((leaves[i]->pGetData()))
2013  {
2014  ConfigurationType::data_type& nodes = (*(leaves[i]->pGetData()));
2015 
2016  rOStream << i + 1;
2017  for(int j = 0 ; j < 8 ; j++)
2018  rOStream << " " << nodes[j]->Id();
2019  rOStream << std::endl;
2020  }
2021  }
2022  rOStream << "end elements" << std::endl;
2023 
2024  }
2025 
2026  void PrintGiDResults(std::ostream & rOStream) const {
2027  std::vector<CellType*> leaves;
2028 
2029  mOctree.GetAllLeavesVector(leaves);
2030 
2031  rOStream << "GiD Post Results File 1.0" << std::endl << std::endl;
2032 
2033  rOStream << "Result \"Distance\" \"Kratos\" 1 Scalar OnNodes" << std::endl;
2034 
2035  rOStream << "Values" << std::endl;
2036 
2037  for(ConfigurationType::data_type::const_iterator i_node = mOctreeNodes.begin() ; i_node != mOctreeNodes.end() ; i_node++)
2038  {
2039  rOStream << (*i_node)->Id() << " " << (*i_node)->Distance() << std::endl;
2040  }
2041  rOStream << "End Values" << std::endl;
2042 
2043  }
2044 
2048 
2049 
2051 
2052  protected:
2055 
2056 
2060 
2061 
2065 
2066 
2070 
2071 
2075 
2076 
2080 
2081 
2085 
2086 
2088 
2089  private:
2092 
2093 
2097  ModelPart& mrSkinModelPart;
2098  ModelPart& mrBodyModelPart;
2099  ModelPart& mrFluidModelPart;
2100 
2101  ConfigurationType::data_type mOctreeNodes;
2102 
2103  OctreeType mOctree;
2104 
2105  static const double epsilon;
2106 
2110 
2111 
2115 
2116 
2120 
2121 
2125 
2126 
2130 
2133 
2135  //CalculateSignedDistanceTo3DConditionSkinProcess(CalculateSignedDistanceTo3DConditionSkinProcess const& rOther);
2136 
2137 
2139 
2140  }; // Class CalculateSignedDistanceTo3DConditionSkinProcess
2141 
2143 
2146 
2147 
2151 
2152 
2154  inline std::istream& operator >> (std::istream& rIStream,
2156 
2158  inline std::ostream& operator << (std::ostream& rOStream,
2160  {
2161  rThis.PrintInfo(rOStream);
2162  rOStream << std::endl;
2163  rThis.PrintData(rOStream);
2164 
2165  return rOStream;
2166  }
2168 
2169  const double CalculateSignedDistanceTo3DConditionSkinProcess::epsilon = 1e-12;
2170 
2171 
2172 } // namespace Kratos.
2173 
2174 #endif // KRATOS_CALCULATE_DISTANCE_CONDITION_PROCESS_H_INCLUDED defined
2175 
2176 
Short class definition.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:284
int IntersectionTriangleSegment(Element::GeometryType &rGeometry, double *RayPoint1, double *RayPoint2, double *IntersectionPoint)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1884
double DistancePositionInSpace(double *coords)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1618
void DistanceFluidStructure()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:406
void CalculateDistance2()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1375
ConfigurationType::cell_node_data_type CellNodeDataType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:295
void CalculateNormal3D(Element::GeometryType &rGeometry, array_1d< double, 3 > &rResultNormal)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:749
void CalcNodalDistanceTo3DSkin(std::vector< TetEdgeStruct > &IntersectedTetEdges, ModelPart::ElementsContainerType::iterator &i_fluid_element, unsigned int NumberIntersectionsOnTetCorner)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:770
bool IsIntersectionNodeOnTetEdge(double *IntersectionPoint, double *EdgeNode1, double *EdgeNode2)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:655
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1980
OctreeBinary< CellType > OctreeType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:294
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:340
void SetNodeInNeighbours(CellType *pCell, int Position, CellNodeDataType *pNode)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1350
DistanceSpatialContainersConditionConfigure ConfigurationType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:292
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1986
void GetIntersections(double *ray, int direction, std::vector< std::pair< double, Element::GeometryType * > > &intersections)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1793
void CalculateNotEmptyLeavesDistance(CellType *pCell)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1543
void GenerateCellNode(CellType *pCell, std::size_t &LastId)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1330
void operator()()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:327
CalculateSignedDistanceTo3DConditionSkinProcess(ModelPart &rThisModelPartStruc, ModelPart &rThisModelPartFluid)
Constructor.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:312
void AssignDistancesToElements(ModelPart::ElementsContainerType::iterator &i_fluid_element, array_1d< double, 4 > ElementalDistances)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1137
void CalcNodalDistancesOfTetNodes(ModelPart::ElementsContainerType::iterator &i_fluidElement, BoundedMatrix< unsigned int, 6, 2 > TetEdgeIndexTable)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:485
std::string Info() const override
Turn back information as a string.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1974
OctreeType::cell_type::object_container_type object_container_type
always the point 3D
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:297
void InitializeDistances()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:436
void CalcSignedDistancesToThreeIntNodes(ModelPart::ElementsContainerType::iterator &i_fluid_element, std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, std::vector< TetEdgeStruct > IntersectedTetEdges, array_1d< double, 4 > &ElementalDistances)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:950
OctreeBinaryCell< ConfigurationType > CellType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:293
void ComputeApproximationNodes(std::vector< TetEdgeStruct > IntersectedTetEdges, std::vector< IntersectionNodeStruct > &NodesOfApproximatedStructure)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:816
void GenerateOctree()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1225
void PrintGiDMesh(std::ostream &rOStream) const
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1990
Point PointType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:296
void GenerateNodes()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1307
void CalcSignedDistancesToApproxTriangle(ModelPart::ElementsContainerType::iterator &i_fluid_element, std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, std::vector< TetEdgeStruct > IntersectedTetEdges, array_1d< double, 4 > &ElementalDistances, array_1d< unsigned int, 3 > IndexNodes)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1056
void SetIndexTable(BoundedMatrix< unsigned int, 6, 2 > &TetEdgeIndexTable)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:465
void CalculateDistance(CellNodeDataType &rNode, int i_direction)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1480
void CalcSignedDistancesToFourIntNodes(ModelPart::ElementsContainerType::iterator &i_fluid_element, std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, std::vector< TetEdgeStruct > IntersectedTetEdges, array_1d< double, 4 > &ElementalDistances)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:968
void CalculateNodeDistance(Node &rNode)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1582
void CalcSignedDistancesToTwoIntNodes(ModelPart::ElementsContainerType::iterator &i_fluid_element, std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, array_1d< double, 4 > &ElementalDistances)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:895
bool IsNewIntersectionNode(IntersectionNodeStruct &NewIntersectionNode, std::vector< TetEdgeStruct > IntersectedTetEdges)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:691
KRATOS_CLASS_POINTER_DEFINITION(CalculateSignedDistanceTo3DConditionSkinProcess)
Pointer definition of CalculateSignedDistanceTo3DConditionSkinProcess.
void CalculateDistance()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1446
void GetIntersectionsAndNodes(double *ray, int direction, std::vector< std::pair< double, Element::GeometryType * > > &intersections, ConfigurationType::data_type &rNodesArray)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1688
void PrintGiDResults(std::ostream &rOStream) const
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:2026
bool IsIntersectionOnCorner(IntersectionNodeStruct &NewIntersectionNode, double *EdgeNode1, double *EdgeNode2)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:720
void CalcSignedDistancesToOneIntNode(ModelPart::ElementsContainerType::iterator &i_fluid_element, std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, array_1d< double, 4 > &ElementalDistances)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:854
int GetCellIntersections(OctreeType::cell_type *cell, double *ray, OctreeType::key_type *ray_key, int direction, std::vector< std::pair< double, Element::GeometryType * > > &intersections)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1843
~CalculateSignedDistanceTo3DConditionSkinProcess() override
Destructor.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:318
void IdentifyIntersectionNodes(ModelPart::ElementsContainerType::iterator &i_fluidElement, unsigned int i_tetEdge, std::vector< OctreeType::cell_type * > &leaves, std::vector< TetEdgeStruct > &IntersectedTetEdges, unsigned int &NumberIntersectionsOnTetCorner, BoundedMatrix< unsigned int, 6, 2 > TetEdgeIndexTable, int &intersection_counter)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:521
bool StructuralElementNotYetConsidered(unsigned int IDCurrentStructCond, std::vector< unsigned int > &IntersectingStructCondID)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:636
void FindIndexNodesOfTriangle2(std::vector< IntersectionNodeStruct > NodesOfApproximatedStructure, array_1d< unsigned int, 3 > &IndexNodes_T2)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:1013
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:53
double & Y()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:60
double & Distance()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:58
double & Z()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:61
double & operator[](int i)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:62
std::size_t & Id()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:63
double & X()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:59
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:49
static void DeleteData(data_type *data)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:141
GeometricalObject::Pointer pointer_type
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:101
CellNodeData cell_node_data_type
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:102
virtual std::string Info() const
Turn back information as a string.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:232
ContainerType::value_type PointerType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:88
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:238
PointerVectorSet< GeometricalObject::Pointer, IndexedObject, std::less< typename IndexedObject::result_type >, std::equal_to< typename IndexedObject::result_type >, Kratos::shared_ptr< typename GeometricalObject::Pointer >, std::vector< Kratos::shared_ptr< typename GeometricalObject::Pointer > > > ContainerType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:87
std::vector< double >::iterator DistanceIteratorType
always the point 3D
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:79
static bool IntersectionBox(const PointerType &rObject, const PointType &rLowPoint, const PointType &rHighPoint)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:198
static void CopyData(data_type *source, data_type *destination)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:137
static void GetBoundingBox(const PointerType rObject, double *rLowPoint, double *rHighPoint)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:164
static data_type * AllocateData()
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:133
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:241
static void CalculateBoundingBox(const PointerType &rObject, PointType &rLowPoint, PointType &rHighPoint)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:147
ContainerType::iterator IteratorType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:89
std::vector< CellNodeData * > data_type
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:103
Point PointType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:78
ResultContainerType::value_type ResultPointerType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:98
static bool Intersection(const PointerType &rObj_1, const PointerType &rObj_2)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:186
PointerVectorSet< GeometricalObject::Pointer, IndexedObject, std::less< typename IndexedObject::result_type >, std::equal_to< typename IndexedObject::result_type >, Kratos::shared_ptr< typename GeometricalObject::Pointer >, std::vector< Kratos::shared_ptr< typename GeometricalObject::Pointer > > > ResultContainerType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:97
DistanceSpatialContainersConditionConfigure()
Default constructor.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:118
std::vector< PointerType >::iterator PointerTypeIterator
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:105
ResultContainerType::iterator ResultIteratorType
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:99
static bool IsIntersected(const Element::Pointer rObject, double Tolerance, const double *rLowPoint, const double *rHighPoint)
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:207
KRATOS_CLASS_POINTER_DEFINITION(DistanceSpatialContainersConditionConfigure)
Pointer definition of DistanceSpatialContainersConditionConfigure.
@ DIMENSION
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:73
@ MIN_LEVEL
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:75
@ Dimension
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:72
@ MAX_LEVEL
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:74
virtual ~DistanceSpatialContainersConditionConfigure()
Destructor.
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:121
Geometry base class.
Definition: geometry.h:71
virtual bool HasIntersection(const GeometryType &ThisGeometry) const
Definition: geometry.h:1453
static double PointDistanceToLineSegment3D(const Point &rLinePoint1, const Point &rLinePoint2, const Point &rToPoint)
This function calculates the distance of a 3D point to a 3D line segment.
Definition: geometry_utilities.cpp:129
static double PointDistanceToTriangle3D(const Point &rTrianglePoint1, const Point &rTrianglePoint2, const Point &rTrianglePoint3, const Point &rPoint)
This function calculates the distance of a 3D point to a 3D triangle.
Definition: geometry_utilities.cpp:172
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
This object defines an indexed object.
Definition: indexed_object.h:54
Definition: amatrix_interface.h:41
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
NodesContainerType::ContainerType & NodesArray(IndexType ThisIndex=0)
Definition: model_part.h:527
MeshType::NodeIterator NodeIterator
Definition: model_part.h:134
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
MeshType::ElementIterator ElementIterator
Definition: model_part.h:174
SizeType NumberOfNodes(IndexType ThisIndex=0) const
Definition: model_part.h:341
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
MeshType::ConditionIterator ConditionIterator
Definition: model_part.h:189
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
ElementsContainerType::ContainerType & ElementsArray(IndexType ThisIndex=0)
Definition: model_part.h:1209
This class defines the node.
Definition: node.h:65
TVariableType::Type & GetSolutionStepValue(const TVariableType &rThisVariable)
Definition: node.h:406
This class represents a cell in an octree to be used with Octree class.
Definition: octree_binary_cell.h:70
std::size_t GetLocalPosition(key_type *keys)
Definition: octree_binary_cell.h:327
const std::vector< pointer_type > * pGetObjects() const
Definition: octree_binary_cell.h:451
std::size_t key_type
Definition: octree_binary_cell.h:86
data_type * pGetData() const
Definition: octree_binary_cell.h:441
int GetKey(std::size_t position, key_type *keys) const
Definition: octree_binary_cell.h:241
int GetNeighbourKey(std::size_t direction, key_type *keys) const
Definition: octree_binary_cell.h:265
CellType cell_type
Definition: octree_binary.h:68
void SetBoundingBox(const coordinate_type *Low, const coordinate_type *High)
Definition: octree_binary.h:122
cell_type::key_type key_type
Definition: octree_binary.h:70
void ScaleBackToOriginalCoordinate(coordinate_type *ThisCoordinates) const
Definition: octree_binary.h:175
void NormalizeCoordinates(coordinate_type *Coordinates) const
Definition: octree_binary.h:141
int GetAllLeavesVector(std::vector< cell_type * > &all_leaves) const
Definition: octree_binary.h:404
key_type CalcKeyNormalized(coordinate_type coordinate) const
Definition: octree_binary.h:199
void CalculateCoordinateNormalized(const key_type key, coordinate_type &NormalizedCoordinate) const
Definition: octree_binary.h:158
void CalculateCoordinates(key_type *keys, coordinate_type *ResultCoordinates) const
Definition: octree_binary.h:169
void GetIntersectedLeaves(typename cell_type::pointer_type pObject, std::vector< cell_type * > &rLeaves, const double ToleranceCoefficient=0.001)
This method fills the intersected leaves.
Definition: octree_binary.h:808
void Insert(coordinate_type *point)
Definition: octree_binary.h:220
double CalcSizeNormalized(const cell_type *cell) const
Definition: octree_binary.h:130
cell_type * pGetCell(key_type *keys) const
Definition: octree_binary.h:429
Point class.
Definition: point.h:59
double Y() const
Definition: point.h:187
double Z() const
Definition: point.h:193
double X() const
Definition: point.h:181
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
TDataType value_type
Definition: pointer_vector_set.h:85
The base class for all processes in Kratos.
Definition: process.h:49
static void Start(std::string const &rIntervalName)
This method starts the timer meassures.
Definition: timer.cpp:109
static void Stop(std::string const &rIntervalName)
This method stops the timer meassures.
Definition: timer.cpp:125
BOOST_UBLAS_INLINE size_type size() const
Definition: array_1d.h:370
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_WATCH(variable)
Definition: define.h:806
#define KRATOS_TRY
Definition: define.h:109
pybind11::list keys(Parameters const &self)
Definition: add_kratos_parameters_to_python.cpp:32
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
std::shared_ptr< T > shared_ptr
Definition: smart_pointers.h:27
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
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
def GetSolutionStepValue(entity, variable, solution_step_index)
Definition: coupling_interface_data.py:253
v
Definition: generate_convection_diffusion_explicit_element.py:114
w
Definition: generate_convection_diffusion_explicit_element.py:108
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
u
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:30
def Index()
Definition: hdf5_io_tools.py:38
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
data
Definition: mesh_to_mdpa_converter.py:59
int t
Definition: ode_solve.py:392
int d
Definition: ode_solve.py:397
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
dir
Definition: radii_error_plotter.py:10
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:298
array_1d< double, 3 > StructElemNormal
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:300
array_1d< double, 3 > Coordinates
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:299
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:302
std::vector< IntersectionNodeStruct > IntNodes
Definition: calculate_signed_distance_to_3d_condition_skin_process.h:303
Configure::ContainerType ContainerType
Definition: transfer_utility.h:247