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.
edgebased_levelset_auxiliary_utils.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: Riccardo Rossi
11 // Joaquín Irazábal
12 //
13 //
14 
15 #ifndef _EDGEBASED_LEVELSET_AUXILIARY_UTILS_H
16 #define _EDGEBASED_LEVELSET_AUXILIARY_UTILS_H
17 /* System includes */
18 
19 
20 /* External includes */
21 
22 
23 /* Project includes */
24 //#include "utilities/math_utils.h"
25 #include "utilities/geometry_utilities.h"
26 #include "utilities/math_utils.h"
28 
29 
30 namespace Kratos
31 {
32 
63 template< unsigned int TDim>
65 {
66 public:
93  ModelPart& r_model_part,
94  Variable<double>& rDistanceVar,
95  const double max_distance
96  )
97  {
98  if constexpr (TDim == 2)
99  CalculateDistances2D(r_model_part, rDistanceVar, max_distance);
100  else if constexpr (TDim == 3)
101  CalculateDistances3D(r_model_part, rDistanceVar, max_distance);
102 
103  // r_model_part.GetCommunicator().SynchronizeCurrentDataToMin(rDistanceVar);
104  }
105 
106  //***********************************************************************
107  //***********************************************************************
109  ModelPart& r_model_part,
110  Variable<double>& rDistanceVar,
111  const double max_distance
112  )
113  {
114  KRATOS_TRY
115 
116  double large_distance = 1e6;
117  double tol = 1.0/large_distance;
118 
119  //copy rDistance var to GetValue database
120  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
121  {
122  it->GetValue(rDistanceVar) = it->FastGetSolutionStepValue(rDistanceVar);
123  it->FastGetSolutionStepValue(rDistanceVar) = large_distance;
124  it->GetValue(IS_VISITED) = 0;
125  }
126 
128  array_1d<double,TDim+1> N, distances;
129  array_1d<double,TDim> grad_d;
130  array_1d<double,3> coord_on_0(3,0.0);
132  BoundedMatrix<double, TDim, TDim> free_surface_points;
133 
134  //fill the list of the first elements to be solved for the "distance"
135  for(ElementsArrayType::iterator it = r_model_part.ElementsBegin(); it !=r_model_part.ElementsEnd(); it++)
136  {
137  Element::GeometryType& geom = it->GetGeometry();
138 
139  unsigned int n_positive = 0;
140  unsigned int n_negative = 0;
141  for(unsigned int kk = 0; kk<TDim+1 ; kk++)
142  {
143  const double dist = geom[kk].GetValue(rDistanceVar);
144  distances[kk] = dist;
145  if(dist < 0)
146  n_negative += 1;
147  else
148  n_positive += 1;
149  }
150 
151  if(n_negative > 0 && n_positive > 0) //ELEMENT IS CROSSED BY THE INTERFACE!
152  {
153  double Volume;
154  GeometryUtils::CalculateGeometryData(geom,DN_DX,N,Volume);
155 
156  //compute the gradient of the distance and normalize it
157  noalias(grad_d) = prod(trans(DN_DX),distances);
158  double norm = norm_2(grad_d);
159  grad_d /= norm;
160 
161  //find one division point on one edge
162  for(unsigned int i = 1; i<TDim+1; i++)
163  {
164  if(distances[0]*distances[i]<=0) //if the edge is divided
165  {
166  double delta_d = fabs(distances[i]) + fabs(distances[0]);
167 
168  if(delta_d>1e-15)
169  {
170  double Ni = fabs(distances[0]) / delta_d;
171  double N0 = fabs(distances[i]) / delta_d;
172 
173  noalias(coord_on_0) = N0 * geom[0].Coordinates();
174  noalias(coord_on_0) += Ni * geom[i].Coordinates();
175  }
176  else
177  noalias(coord_on_0) = geom[0].Coordinates();
178 
179  break;
180 
181  }
182  }
183 
184  //now calculate the distance of all the nodes from the elemental free surface
185  for(unsigned int i = 0; i<TDim+1; i++)
186  {
187  noalias(temp) = geom[i].Coordinates();
188  noalias(temp) -= coord_on_0 ;
189 
190  double real_distance = 0.0;
191  for(unsigned int k=0; k<TDim; k++)
192  real_distance += temp[k]*grad_d[k];
193  real_distance = fabs(real_distance);
194 
195  double& dist_i = geom[i].FastGetSolutionStepValue(rDistanceVar);
196  if(real_distance < dist_i)
197  dist_i = real_distance;
198 
199  //select the nodes for the computation of the distance
200  geom[i].GetValue(IS_VISITED) = 1;
201  }
202 
203  }
204 
205 
206 
207  }
208 
209  //loop on all nodes to treat correctly the case of the surface coinciding with a node
210  //copy rDistance var to GetValue database
211  array_1d<double,3> aux;
212  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
213  {
214  if(fabs(it->GetValue(rDistanceVar)) < tol)
215  {
216  it->FastGetSolutionStepValue(rDistanceVar) = 0.0;
217  it->GetValue(IS_VISITED) = 1;
218  }
219  }
220 
221  //compute the distance using the element based approach
223  util.CalculateDistances<TDim>(r_model_part.Elements(),rDistanceVar,max_distance);
224 
225  //finally change the sign to the distance as needed
226  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
227  {
228  if(it->GetValue(rDistanceVar) < 0)
229  it->FastGetSolutionStepValue(rDistanceVar) = -it->FastGetSolutionStepValue(rDistanceVar);
230  }
231 
232  //check if something is wrong
233  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
234  {
235  if(fabs(it->FastGetSolutionStepValue(rDistanceVar)) == large_distance)
236  {
237  KRATOS_WATCH("error in the calculation of the distance for node")
238  KRATOS_WATCH(it->Id());
239 
240  }
241  }
242 
243  KRATOS_CATCH("")
244  }
245 
247  ModelPart& r_model_part,
248  Variable<double>& rDistanceVar,
249  const double max_distance
250  )
251  {
252  KRATOS_TRY
253 
254  const double large_distance = 1e9;
255 
256  std::vector<array_1d<double,TDim + 1> > distances;
257  std::vector<Element::Pointer> interface_elements;
258 
259  //copy rDistance var to GetValue database
260  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
261  {
262  it->GetValue(rDistanceVar) = it->FastGetSolutionStepValue(rDistanceVar);
263  it->GetValue(IS_VISITED) = 0;
264  }
265 
266  // Make a list of all elements crossed by interface and get their nodal distances
267  for(ElementsArrayType::iterator i_element = r_model_part.ElementsBegin(); i_element !=r_model_part.ElementsEnd(); i_element++)
268  {
269  // Get a reference to the geometry
270  Element::GeometryType& element_geometry = i_element->GetGeometry();
271  array_1d<double,TDim + 1> element_distance;
272 
273  bool positive = false;
274  bool negative = false;
275 
276  // loop over nodes to see if they have positive or negative distance.
277  for(unsigned int i_node = 0; i_node < element_geometry.size() ; i_node++)
278  {
279  const double distance = element_geometry[i_node].GetSolutionStepValue(rDistanceVar);
280  element_distance[i_node] = distance;
281  negative |= (distance < 0);
282  positive |= (distance >= 0);
283  }
284 
285  if(negative && positive) //ELEMENT IS CROSSED BY THE INTERFACE!
286  {
287  interface_elements.push_back(*(i_element.base()));
288  distances.push_back(element_distance);
289  }
290  }
291 
292  // Reset the distance to a large value maintaining the sign
293  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
294  {
295  double& distance = it->FastGetSolutionStepValue(rDistanceVar);
296 
297  if(distance >= 0.00)
298  distance = large_distance;
299  else
300  distance = -large_distance;
301  }
302 
303  // Now calculating the new distance for interface elements
304  int size = static_cast<int>(interface_elements.size());
305  for(int i = 0 ; i < size ; i++)
306  {
307  // Get a reference to the geometry
308  Element::GeometryType& element_geometry = interface_elements[i]->GetGeometry();
309 
310  GeometryUtils::CalculateTetrahedraDistances(element_geometry, distances[i]);
311 
312  // loop over nodes and apply the new distances.
313  for(unsigned int i_node = 0; i_node < element_geometry.size() ; i_node++)
314  {
315  double& distance = element_geometry[i_node].GetSolutionStepValue(rDistanceVar);
316  double new_distance = distances[i][i_node];
317 
318  if(fabs(distance) > fabs(new_distance))
319  {
320  if(distance >= 0)
321  distance = new_distance;
322  else
323  distance = new_distance;
324  }
325  element_geometry[i_node].GetValue(IS_VISITED) = 1;
326  }
327  }
328  //compute the distance using the element based approach
330  util.CalculateDistances<TDim>(r_model_part.Elements(),rDistanceVar,max_distance);
331 
332  //finally change the sign to the distance as needed
333  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
334  {
335  if(it->GetValue(rDistanceVar) < 0)
336  it->FastGetSolutionStepValue(rDistanceVar) = -it->FastGetSolutionStepValue(rDistanceVar);
337  }
338 
339  //check if something is wrong
340  for(ModelPart::NodesContainerType::iterator it = r_model_part.NodesBegin(); it !=r_model_part.NodesEnd(); it++)
341  {
342  if(fabs(it->FastGetSolutionStepValue(rDistanceVar)) == large_distance)
343  {
344  KRATOS_WATCH("error in the calculation of the distance for node")
345  KRATOS_WATCH(it->Id());
346 
347  }
348  }
349 
350  KRATOS_CATCH("")
351  }
352 
353  //**********************************************************************************+
354  //**********************************************************************************+
355  double FindMaximumEdgeSize(ModelPart& r_model_part)
356  {
357  KRATOS_TRY
358 
359  ModelPart::NodesContainerType& rNodes = r_model_part.Nodes();
360 
361  double h_max = 0.0;
362 
363  for (ModelPart::NodesContainerType::iterator in = rNodes.begin(); in != rNodes.end(); in++)
364  {
365  double xc = in->X();
366  double yc = in->Y();
367  double zc = in->Z();
368 
369  double h = 0.0;
370  for (GlobalPointersVector< Node >::iterator i = in->GetValue(NEIGHBOUR_NODES).begin();
371  i != in->GetValue(NEIGHBOUR_NODES).end(); i++)
372  {
373  double x = i->X();
374  double y = i->Y();
375  double z = i->Z();
376  double l = (x - xc)*(x - xc);
377  l += (y - yc)*(y - yc);
378  l += (z - zc)*(z - zc);
379 
380  if (l > h) h = l;
381  }
382  h = sqrt(h);
383 
384  if(h > h_max) h_max = h;
385 
386  }
387 
388  return h_max;
389 
390  KRATOS_CATCH("");
391  }
392 
410 private:
444 }; /* Class ClassName */
445 
454 } /* namespace Kratos.*/
455 
456 
457 #endif /* _EDGEBASED_LEVELSET_AUXILIARY_UTILS_H */
458 
Definition: body_distance_calculation_utils.h:93
void CalculateDistances(ElementsArrayType &rElements, Variable< double > &rDistanceVar, const double max_distance)
Definition: body_distance_calculation_utils.h:134
Definition: edgebased_levelset_auxiliary_utils.h:65
ModelPart::ElementsContainerType ElementsArrayType
Definition: edgebased_levelset_auxiliary_utils.h:70
void CalculateDistances(ModelPart &r_model_part, Variable< double > &rDistanceVar, const double max_distance)
Definition: edgebased_levelset_auxiliary_utils.h:92
ModelPart::NodesContainerType NodesArrayType
Definition: edgebased_levelset_auxiliary_utils.h:69
void CalculateDistances2D(ModelPart &r_model_part, Variable< double > &rDistanceVar, const double max_distance)
Definition: edgebased_levelset_auxiliary_utils.h:108
void CalculateDistances3D(ModelPart &r_model_part, Variable< double > &rDistanceVar, const double max_distance)
Definition: edgebased_levelset_auxiliary_utils.h:246
double FindMaximumEdgeSize(ModelPart &r_model_part)
Definition: edgebased_levelset_auxiliary_utils.h:355
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
static void CalculateTetrahedraDistances(const GeometryType &rGeometry, array_1d< double, TSize > &rDistances)
Calculate the exact distances to the interface TRIANGLE defined by a set of initial distances.
Definition: geometry_utilities.h:372
static void CalculateGeometryData(const GeometryType &rGeometry, BoundedMatrix< double, 4, 3 > &rDN_DX, array_1d< double, 4 > &rN, double &rVolume)
This function is designed to compute the shape function derivatives, shape functions and volume in 3D...
Definition: geometry_utilities.h:176
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
Definition: amatrix_interface.h:41
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_WATCH(variable)
Definition: define.h:806
#define KRATOS_TRY
Definition: define.h:109
z
Definition: GenerateWind.py:163
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
float dist
Definition: edgebased_PureConvection.py:89
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
h
Definition: generate_droplet_dynamics.py:91
int tol
Definition: hinsberg_optimization.py:138
int k
Definition: quadrature.py:595
float temp
Definition: rotating_cone.py:85
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
integer i
Definition: TensorModule.f:17
integer l
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31