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.
binbased_nodes_in_element_locator.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: Pablo Becker
11 // Riccardo Rossi
12 //
13 //
14 
15 #if !defined(KRATOS_BINBASED_NODES_IN_ELEMENT_LOCATOR_INCLUDED )
16 #define KRATOS_BINBASED_NODES_IN_ELEMENT_LOCATOR_INCLUDED
17 
18 // System includes
19 #include <string>
20 #include <iostream>
21 #include <algorithm>
22 
23 // External includes
24 
25 // Project includes
26 #include "includes/define.h"
27 #include "includes/node.h"
28 
30 
31 namespace Kratos
32 {
40 
42 template< unsigned int TDim>
44 {
45 public:
46 
47  typedef Node PointType;
48  typedef Node::Pointer PointTypePointer;
49  typedef std::vector<PointType::Pointer > PointVector;
50  typedef typename std::vector<PointType::Pointer >::iterator PointIterator;
51  typedef std::vector<double> DistanceVector;
52  typedef typename std::vector<double>::iterator DistanceIterator;
53 
54  // Bucket types
56 // typedef Tree< StaticBins > tree; //Binstree;
57 
59 
61  : mr_model_part(model_part)
62  {
63  }
64 
66  {
67  }
68 
71  {
73 
74  mlist_of_new_nodes.clear();
75  for (ModelPart::NodesContainerType::iterator node_it = mr_model_part.NodesBegin();
76  node_it != mr_model_part.NodesEnd(); ++node_it)
77  {
78  //PointType::Pointer pnode(new PointType(*node_it));
79  Node::Pointer pnode = *(node_it.base());
80 
81  //putting the nodes of the destination_model part in an auxiliary list
82  mlist_of_new_nodes.push_back( pnode );
83  }
84 
85  //create a spatial database with the list of new nodes
86  typename StaticBins::SizeType bucket_size = 20;
87 
88  typename StaticBins::Pointer paux = typename StaticBins::Pointer(new StaticBins(mlist_of_new_nodes.begin(),mlist_of_new_nodes.end(),bucket_size) );
89  paux.swap(mp_search_structure); //the class mp_search_structure remains in the memory, while the paux just constucted is destryed.
90 
91  KRATOS_CATCH("")
92  }
93 
97 
100  void UpdateSearchDatabaseAssignedSize(double CellSize)
101  {
102  KRATOS_TRY
103 
104  mlist_of_new_nodes.clear();
105  for (ModelPart::NodesContainerType::iterator node_it = mr_model_part.NodesBegin();
106  node_it != mr_model_part.NodesEnd(); ++node_it)
107  {
108  //PointType::Pointer pnode(new PointType(*node_it));
109  Node::Pointer pnode = *(node_it.base());
110 
111  //putting the nodes of the destination_model part in an auxiliary list
112  mlist_of_new_nodes.push_back( pnode );
113  }
114 
115  typename StaticBins::Pointer paux = typename StaticBins::Pointer(new StaticBins(mlist_of_new_nodes.begin(),mlist_of_new_nodes.end(),CellSize) );
116  paux.swap(mp_search_structure); //the class mp_search_structure remains in the memory, while the paux just constucted is destryed.
117 
118  KRATOS_CATCH("")
119  }
120 
122 
133  unsigned int FindNodesInElement(Element::Pointer& pelement,
134  DenseVector<int>& positions,
135  Matrix& Nmat,
136  const unsigned int max_results,
137  PointIterator work_results,
138  DistanceIterator work_distances,
139  Node& work_point // is it needed from outside???????????????
140  )
141  {
142  Geometry<Node >&geom = pelement->GetGeometry();
144 
145  double xc, yc, zc, radius;
146  CalculateCenterAndSearchRadius( geom, xc,yc,zc, radius,N);
147  work_point.X() = xc;
148  work_point.Y() = yc;
149  work_point.Z() = zc;
150 
151  //find all of the new nodes within the radius
152  int number_of_points_in_radius;
153 
154  //look between the new nodes which of them is inside the radius of the circumscribed cyrcle
155  number_of_points_in_radius = mp_search_structure->SearchInRadius(work_point, radius, work_results, work_distances, max_results);
156 
157  //check if inside
158  unsigned int counter = 0;
159 
160  for( PointIterator it_found = work_results; it_found != work_results + number_of_points_in_radius; it_found++)
161  {
162  bool is_inside = false;
163  is_inside = CalculatePosition(geom, (*it_found)->X(),(*it_found)->Y(),(*it_found)->Z(),N);
164 
165  //if the node falls inside the element interpolate
166  if(is_inside == true)
167  {
168  positions[counter] = it_found - work_results;
169  for(unsigned int k=0; k<TDim+1; k++)
170  Nmat(counter,k) = N[k];
171  counter++;
172  }
173  }
174  return counter;
175  }
176 
177 protected:
178 
179 
180 private:
181 
190  inline void CalculateCenterAndSearchRadius(
191  Geometry<Node >&geom,
192  double& xc,
193  double& yc,
194  double& zc,
195  double& R,
197  )
198  {
199  const double x0 = geom[0].X();
200  const double y0 = geom[0].Y();
201  const double x1 = geom[1].X();
202  const double y1 = geom[1].Y();
203  const double x2 = geom[2].X();
204  const double y2 = geom[2].Y();
205 
206  xc = 0.3333333333333333333*(x0+x1+x2);
207  yc = 0.3333333333333333333*(y0+y1+y2);
208  zc = 0.0;
209 
210  const double R1 = (xc-x0)*(xc-x0) + (yc-y0)*(yc-y0);
211  const double R2 = (xc-x1)*(xc-x1) + (yc-y1)*(yc-y1);
212  const double R3 = (xc-x2)*(xc-x2) + (yc-y2)*(yc-y2);
213 
214  R = R1;
215  if(R2 > R) R = R2;
216  if(R3 > R) R = R3;
217 
218  R = 1.01 * std::sqrt(R);
219  }
220 
229  inline void CalculateCenterAndSearchRadius(
230  Geometry<Node >&geom,
231  double& xc,
232  double& yc,
233  double& zc,
234  double& R,
235  array_1d<double,4>& N
236  )
237  {
238  const double x0 = geom[0].X();
239  const double y0 = geom[0].Y();
240  const double z0 = geom[0].Z();
241  const double x1 = geom[1].X();
242  const double y1 = geom[1].Y();
243  const double z1 = geom[1].Z();
244  const double x2 = geom[2].X();
245  const double y2 = geom[2].Y();
246  const double z2 = geom[2].Z();
247  const double x3 = geom[3].X();
248  const double y3 = geom[3].Y();
249  const double z3 = geom[3].Z();
250 
251  xc = 0.25*(x0+x1+x2+x3);
252  yc = 0.25*(y0+y1+y2+y3);
253  zc = 0.25*(z0+z1+z2+z3);
254 
255  const double R1 = (xc-x0)*(xc-x0) + (yc-y0)*(yc-y0) + (zc-z0)*(zc-z0);
256  const double R2 = (xc-x1)*(xc-x1) + (yc-y1)*(yc-y1) + (zc-z1)*(zc-z1);
257  const double R3 = (xc-x2)*(xc-x2) + (yc-y2)*(yc-y2) + (zc-z2)*(zc-z2);
258  const double R4 = (xc-x3)*(xc-x3) + (yc-y3)*(yc-y3) + (zc-z3)*(zc-z3);
259 
260  R = R1;
261  if(R2 > R) R = R2;
262  if(R3 > R) R = R3;
263  if(R4 > R) R = R4;
264 
265  R = std::sqrt(R);
266  }
267 
277  inline bool CalculatePosition(
278  Geometry<Node >&geom,
279  const double xc,
280  const double yc,
281  const double zc,
282  array_1d<double, 3 > & N
283  )
284  {
285  const double x0 = geom[0].X();
286  const double y0 = geom[0].Y();
287  const double x1 = geom[1].X();
288  const double y1 = geom[1].Y();
289  const double x2 = geom[2].X();
290  const double y2 = geom[2].Y();
291 
292  const double area = CalculateVol(x0, y0, x1, y1, x2, y2);
293  double inv_area = 0.0;
294  if (area == 0.0)
295  {
296  //The interpolated node will not be inside an elemente with zero area
297  return false;
298  }
299  else
300  {
301  inv_area = 1.0 / area;
302  }
303 
304  N[0] = CalculateVol(x1, y1, x2, y2, xc, yc) * inv_area;
305  N[1] = CalculateVol(x2, y2, x0, y0, xc, yc) * inv_area;
306  N[2] = CalculateVol(x0, y0, x1, y1, xc, yc) * inv_area;
307 
308  if (N[0] >= 0.0 && N[1] >= 0.0 && N[2] >= 0.0 && N[0] <= 1.0 && N[1] <= 1.0 && N[2] <= 1.0) //if the xc yc is inside the triangle return true
309  return true;
310 
311  return false;
312  }
313 
323  inline bool CalculatePosition(
324  Geometry<Node >&geom,
325  const double xc,
326  const double yc,
327  const double zc,
328  array_1d<double, 4 > & N
329  )
330  {
331 
332  const double x0 = geom[0].X();
333  const double y0 = geom[0].Y();
334  const double z0 = geom[0].Z();
335  const double x1 = geom[1].X();
336  const double y1 = geom[1].Y();
337  const double z1 = geom[1].Z();
338  const double x2 = geom[2].X();
339  const double y2 = geom[2].Y();
340  const double z2 = geom[2].Z();
341  const double x3 = geom[3].X();
342  const double y3 = geom[3].Y();
343  const double z3 = geom[3].Z();
344 
345  const double vol = CalculateVol(x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3);
346 
347  double inv_vol = 0.0;
348  if (vol < 0.0000000000001)
349  {
350  //The interpolated node will not be inside an elemente with zero area
351  return false;
352  }
353  else
354  {
355  inv_vol = 1.0 / vol;
356  }
357 
358  N[0] = CalculateVol(x1, y1, z1, x3, y3, z3, x2, y2, z2, xc, yc, zc) * inv_vol;
359  N[1] = CalculateVol(x0, y0, z0, x1, y1, z1, x2, y2, z2, xc, yc, zc) * inv_vol;
360  N[2] = CalculateVol(x3, y3, z3, x1, y1, z1, x0, y0, z0, xc, yc, zc) * inv_vol;
361  N[3] = CalculateVol(x3, y3, z3, x0, y0, z0, x2, y2, z2, xc, yc, zc) * inv_vol;
362 
363 
364  if (N[0] >= 0.0 && N[1] >= 0.0 && N[2] >= 0.0 && N[3] >= 0.0 &&
365  N[0] <= 1.0 && N[1] <= 1.0 && N[2] <= 1.0 && N[3] <= 1.0)
366  //if the xc yc zc is inside the tetrahedron return true
367  return true;
368 
369  return false;
370  }
371 
375  inline double CalculateVol(const double x0, const double y0,
376  const double x1, const double y1,
377  const double x2, const double y2
378  )
379  {
380  return 0.5 * ((x1 - x0)*(y2 - y0)- (y1 - y0)*(x2 - x0));
381  }
382 
383 
387  inline double CalculateVol(const double x0, const double y0, const double z0,
388  const double x1, const double y1, const double z1,
389  const double x2, const double y2, const double z2,
390  const double x3, const double y3, const double z3
391  )
392  {
393  const double x10 = x1 - x0;
394  const double y10 = y1 - y0;
395  const double z10 = z1 - z0;
396 
397  const double x20 = x2 - x0;
398  const double y20 = y2 - y0;
399  const double z20 = z2 - z0;
400 
401  const double x30 = x3 - x0;
402  const double y30 = y3 - y0;
403  const double z30 = z3 - z0;
404 
405  const double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
406  return detJ * 0.1666666666666666666667;
407  }
408 
409 
410  PointVector mlist_of_new_nodes;
411 
412  ModelPart& mr_model_part;
413 
414  typename StaticBins::Pointer mp_search_structure;
415 
416 
417 };
418 
419 } // namespace Kratos.
420 
421 #endif // KRATOS_BINBASED_NODES_IN_ELEMENT_LOCATOR_INCLUDED defined
422 
423 
REMARK: the location function is threadsafe, and can be used in OpenMP loops.
Definition: binbased_nodes_in_element_locator.h:44
std::vector< PointType::Pointer > PointVector
Definition: binbased_nodes_in_element_locator.h:49
unsigned int FindNodesInElement(Element::Pointer &pelement, DenseVector< int > &positions, Matrix &Nmat, const unsigned int max_results, PointIterator work_results, DistanceIterator work_distances, Node &work_point)
function to find all teh nodes of a fixed mesh contained in the elements of a moving mesh
Definition: binbased_nodes_in_element_locator.h:133
std::vector< PointType::Pointer >::iterator PointIterator
Definition: binbased_nodes_in_element_locator.h:50
void UpdateSearchDatabaseAssignedSize(double CellSize)
Definition: binbased_nodes_in_element_locator.h:100
BinBasedNodesInElementLocator(ModelPart &model_part)
Definition: binbased_nodes_in_element_locator.h:60
Node PointType
Definition: binbased_nodes_in_element_locator.h:47
std::vector< double >::iterator DistanceIterator
Definition: binbased_nodes_in_element_locator.h:52
Node::Pointer PointTypePointer
Definition: binbased_nodes_in_element_locator.h:48
void UpdateSearchDatabase()
Function to construct or update the search database.
Definition: binbased_nodes_in_element_locator.h:70
KRATOS_CLASS_POINTER_DEFINITION(BinBasedNodesInElementLocator)
Bins< TDim, PointType, PointVector, PointTypePointer, PointIterator, DistanceIterator > StaticBins
Definition: binbased_nodes_in_element_locator.h:55
~BinBasedNodesInElementLocator()
Definition: binbased_nodes_in_element_locator.h:65
std::vector< double > DistanceVector
Definition: binbased_nodes_in_element_locator.h:51
Definition: bins_static.h:35
TreeNodeType::SizeType SizeType
Definition: bins_static.h:51
Geometry base class.
Definition: geometry.h:71
Definition: amatrix_interface.h:41
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
This class defines the node.
Definition: node.h:65
double Y() const
Definition: point.h:187
double Z() const
Definition: point.h:193
double X() const
Definition: point.h:181
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
Kratos::ModelPart ModelPart
Definition: kratos_wrapper.h:31
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
model_part
Definition: face_heat.py:14
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
R
Definition: isotropic_damage_automatic_differentiation.py:172
float radius
Definition: mesh_to_mdpa_converter.py:18
int k
Definition: quadrature.py:595
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
int counter
Definition: script_THERMAL_CORRECT.py:218
N
Definition: sensitivityMatrix.py:29