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.
transfer_utility.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3 KratosIncompressibleFluidApplication
4 A library based on:
5 Kratos
6 A General Purpose Software for Multi-Physics Finite Element Analysis
7 Version 1.0 (Released on march 05, 2007).
8 
9 Copyright 2007
10 Pooyan Dadvand, Riccardo Rossi
11 pooyan@cimne.upc.edu
12 rrossi@cimne.upc.edu
13 - CIMNE (International Center for Numerical Methods in Engineering),
14 Gran Capita' s/n, 08034 Barcelona, Spain
15 
16 
17 Permission is hereby granted, free of charge, to any person obtaining
18 a copy of this software and associated documentation files (the
19 "Software"), to deal in the Software without restriction, including
20 without limitation the rights to use, copy, modify, merge, publish,
21 distribute, sublicense and/or sell copies of the Software, and to
22 permit persons to whom the Software is furnished to do so, subject to
23 the following condition:
24 
25 Distribution of this code for any commercial purpose is permissible
26 ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNERS.
27 
28 The above copyright notice and this permission notice shall be
29 included in all copies or substantial portions of the Software.
30 
31 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
34 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
35 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
36 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
37 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 
39 ==============================================================================
40 */
41 
42 //
43 // Project Name: Kratos
44 // Last Modified by: $Author: pbecker $
45 // Date: $Date: 2011-09-21 12:30:32 $
46 // Revision: $Revision: 1.0 $
47 //
48 //
49 
50 
51 #if !defined(KRATOS_MOVE_PART_UTILITY_FLUID_ONLY_DIFF2_INCLUDED )
52 #define KRATOS_MOVE_PART_UTILITY_FLUID_ONLY_DIFF2_INCLUDED
53 
54 
55 
56 // System includes
57 #include <string>
58 #include <iostream>
59 #include <algorithm>
60 
61 // External includes
62 
63 
64 // Project includes
65 #include "includes/define.h"
66 #include "includes/node.h"
67 
69 #include "includes/dof.h"
70 #include "includes/variables.h"
71 #include "containers/array_1d.h"
73 #include "includes/mesh.h"
74 #include "utilities/math_utils.h"
76 
77 #include "utilities/geometry_utilities.h"
78 
79 #include "includes/model_part.h"
80 
81 
85 
87 
88 #include "geometries/line_2d_2.h"
91 #include "geometries/point.h"
92 
94 #include "utilities/openmp_utils.h"
95 
96 #include "time.h"
97 
98 //#include "processes/process.h"
99 
100 namespace Kratos
101 {
102  //this class is to be modified by the user to customize the interpolation process
103  template< unsigned int TDim>
105  {
106  public:
107 
109  typedef typename Configure::PointType PointType;
110  //typedef PointType::CoordinatesArrayType CoordinatesArrayType;
112  //typedef Configure::PointerType PointerType;
115  //typedef Configure::ResultPointerType ResultPointerType;
117  //typedef Configure::ContactPairType ContactPairType;
118  //typedef Configure::ContainerContactType ContainerContactType;
119  //typedef Configure::IteratorContactType IteratorContactType;
120  //typedef Configure::PointerContactType PointerContactType;
121  //typedef Configure::PointerTypeIterator PointerTypeIterator;
122 
124 
125  //template<unsigned int TDim>
126  TransferUtility(ModelPart& calculation_model_part, ModelPart& topographic_model_part)
127  : mcalculation_model_part(calculation_model_part) , mtopographic_model_part(topographic_model_part)
128  {
129  KRATOS_WATCH("initializing transfer utility")
130 
131  ProcessInfo& CurrentProcessInfo = mcalculation_model_part.GetProcessInfo();
132 
133 
134 
135  //loop in elements to change their ID to their position in the array. Easier to get information later.
136  //DO NOT PARALELIZE THIS! IT MUST BE SERIAL!!!!!!!!!!!!!!!!!!!!!!
137  /*
138  ModelPart::ElementsContainerType::iterator ielembegin = mcalculation_model_part.ElementsBegin();
139  for(unsigned int ii=0; ii<mr_model_part.Elements().size(); ii++)
140  {
141  ModelPart::ElementsContainerType::iterator ielem = ielembegin+ii;
142  ielem->SetId(ii+1);
143  }
144  mlast_elem_id= (mr_model_part.ElementsEnd()-1)->Id();
145  */
146 
147 
148  //CONSTRUCTING BIN STRUCTURE
150  IteratorType it_begin = rElements.begin();
151  IteratorType it_end = rElements.end();
152  //const int number_of_elem = rElements.size();
153 
155  paux.swap(mpBinsObjectDynamic);
156 
157  }
158 
159 
161  {}
162 
163 
165  {
166  KRATOS_TRY
167  KRATOS_WATCH("Gathering Information From Topographic Domain ")
168  ProcessInfo& CurrentProcessInfo = mcalculation_model_part.GetProcessInfo();
169  double delta_t = CurrentProcessInfo[DELTA_TIME];
170  array_1d<double,3> & gravity= CurrentProcessInfo[GRAVITY];
171 
172  const unsigned int max_results = 1000;
173 
174  //array_1d<double,TDim+1> N;
175  //const int max_results = 1000;
176 
177  ModelPart::NodesContainerType::iterator inodebegin = mcalculation_model_part.NodesBegin();
178 
179 
180  vector<unsigned int> node_partition;
181  #ifdef _OPENMP
182  int number_of_threads = omp_get_max_threads();
183  #else
184  int number_of_threads = 1;
185  #endif
186  OpenMPUtils::CreatePartition(number_of_threads, mcalculation_model_part.Nodes().size(), node_partition);
187 
188  //before doing anything we must reset the vector of nodes contained by each element (particles that are inside each element.
189  #pragma omp parallel for
190  for(int kkk=0; kkk<number_of_threads; kkk++)
191  {
193  ResultContainerType results(max_results);
194  ResultIteratorType result_begin = results.begin();
195 
196  for(unsigned int ii=node_partition[kkk]; ii<node_partition[kkk+1]; ii++)
197  {
198  if ( (results.size()) !=max_results)
199  results.resize(max_results);
200 
201  //const int & elem_id = ielem->Id();
202  ModelPart::NodesContainerType::iterator inode = inodebegin+ii;
203  Element::Pointer pelement(*ielem.base());
204  Geometry<Node >& geom = ielem->GetGeometry();
205 
206  ParticlePointerVector& element_particle_pointers = (ielem->GetValue(FLUID_PARTICLE_POINTERS));
207  int & number_of_particles_in_elem=ielem->GetValue(NUMBER_OF_PARTICLES);
208  //std::cout << "elem " << ii << " with " << (unsigned int)number_of_particles_in_elem << " particles" << std::endl;
209 
210 
211  is_found = FindNodeOnMesh(position, N ,pelement,result_begin,MaxNumberOfResults); //good, now we know where this point is:
212 
213 
214  }
215 
216 
217 
218 
219  }
220  }
221  KRATOS_CATCH("")
222  }
223 
224 
225 
226 
227  protected:
228 
229 
230  private:
231 
232 
233 
234 
235 
236 
241  bool FindNodeOnMesh( //int last_element,
242  array_1d<double,3>& position,
243  array_1d<double,TDim+1>& N,
244  //Element::Pointer pelement,
245  Element::Pointer & pelement,
246  ResultIteratorType result_begin,
247  const unsigned int MaxNumberOfResults)
248  {
249  typedef std::size_t SizeType;
250 
251  const array_1d<double,3>& coords = position;
252  array_1d<double,TDim+1> aux_N;
253  //before using the bin to search for possible elements we check first the last element in which the particle was.
254 
255  //ModelPart::ElementsContainerType::iterator i = mr_model_part.ElementsBegin()+last_element;
256  Geometry<Node >& geom_default = pelement->GetGeometry(); //(*(i))->GetGeometry();
257  bool is_found_1 = CalculatePosition(geom_default,coords[0],coords[1],coords[2],N);
258  if(is_found_1 == true)
259  {
260  //pelement = (*(i));
261  return true;
262  }
263 
264  //KRATOS_WATCH("will look in another element")
265  //KRATOS_WATCH(TDim)
266 
267  //to begin with we check the neighbour elements:
268  GlobalPointersVector< Element >& neighb_elems = pelement->GetValue(NEIGHBOUR_ELEMENTS);
269  //the first we check is the one that has negative shape function, because it means it went outside in this direction:
270  /*
271  unsigned int checked_element=0;
272  for (unsigned int i=0;i!=(TDim+1);i++)
273  {
274  if (N[i]<0.0)
275  {
276  checked_element=i;
277  Geometry<Node >& geom = neighb_elems[i].GetGeometry();
278  bool is_found_2 = CalculatePosition(geom,coords[0],coords[1],coords[2],aux_N);
279  if (is_found_2)
280  {
281  pelement=Element::Pointer(((neighb_elems(i))));
282  N=aux_N;
283  return true;
284  }
285  break;
286  }
287  }
288  */
289 
290  for (unsigned int i=0;i!=(neighb_elems.size());i++)
291  {
292  if(neighb_elems(i).get()!=nullptr)
293  {
294  Geometry<Node >& geom = neighb_elems[i].GetGeometry();
295  bool is_found_2 = CalculatePosition(geom,coords[0],coords[1],coords[2],N);
296  if (is_found_2)
297  {
298  pelement=Element::Pointer(((neighb_elems(i))));
299  return true;
300  }
301  }
302  }
303 
304 
305  //ask to the container for the list of candidate elements
306  SizeType results_found = mpBinsObjectDynamic->SearchObjectsInCell(coords, result_begin, MaxNumberOfResults );
307  //KRATOS_WATCH(results_found)
308 
309  if(results_found>0){
310  //loop over the candidate elements and check if the particle falls within
311  for(SizeType i = 0; i< results_found; i++)
312  {
313  //std::cout<< "KIIIIIIIIIIIIII" << std::endl;
314  //KRATOS_WATCH((*(result_begin+i))->Id());
315  Geometry<Node >& geom = (*(result_begin+i))->GetGeometry();
316 
317 
318  //find local position
319  bool is_found = CalculatePosition(geom,coords[0],coords[1],coords[2],N);
320 
321  //KRATOS_WATCH("ln243");
322  //KRATOS_WATCH(N);
323 
324  if(is_found == true)
325  {
326  //pelement.clear();
327  //pelement.push_back( Element::WeakPointer((*(result_begin+i).base())));
328  pelement=Element::Pointer((*(result_begin+i).base()));
329  return true;
330  }
331  }
332  }
333 
334  //not found case
335  return false;
336  }
337 
338 
339 
340  //***************************************
341  //***************************************
342 
344  const double xc, const double yc, const double zc,
346  )
347  {
348  double x0 = geom[0].X();
349  double y0 = geom[0].Y();
350  double x1 = geom[1].X();
351  double y1 = geom[1].Y();
352  double x2 = geom[2].X();
353  double y2 = geom[2].Y();
354 
355  double area = CalculateVol(x0, y0, x1, y1, x2, y2);
356  double inv_area = 0.0;
357  if (area == 0.0)
358  {
359  KRATOS_THROW_ERROR(std::logic_error, "element with zero area found", "");
360  } else
361  {
362  inv_area = 1.0 / area;
363  }
364 
365 
366  N[0] = CalculateVol(x1, y1, x2, y2, xc, yc) * inv_area;
367  N[1] = CalculateVol(x2, y2, x0, y0, xc, yc) * inv_area;
368  N[2] = CalculateVol(x0, y0, x1, y1, xc, yc) * inv_area;
369  //KRATOS_WATCH(N);
370 
371  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
372  return true;
373 
374  return false;
375  }
376 
377  //***************************************
378  //***************************************
379 
381  const double xc, const double yc, const double zc,
383  )
384  {
385 
386  double x0 = geom[0].X();
387  double y0 = geom[0].Y();
388  double z0 = geom[0].Z();
389  double x1 = geom[1].X();
390  double y1 = geom[1].Y();
391  double z1 = geom[1].Z();
392  double x2 = geom[2].X();
393  double y2 = geom[2].Y();
394  double z2 = geom[2].Z();
395  double x3 = geom[3].X();
396  double y3 = geom[3].Y();
397  double z3 = geom[3].Z();
398 
399  double vol = CalculateVol(x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3);
400 
401  double inv_vol = 0.0;
402  if (vol < 0.0000000000001)
403  {
404  KRATOS_THROW_ERROR(std::logic_error, "element with zero vol found", "");
405  } else
406  {
407  inv_vol = 1.0 / vol;
408  }
409 
410  N[0] = CalculateVol(x1, y1, z1, x3, y3, z3, x2, y2, z2, xc, yc, zc) * inv_vol;
411  N[1] = CalculateVol(x0, y0, z0, x1, y1, z1, x2, y2, z2, xc, yc, zc) * inv_vol;
412  N[2] = CalculateVol(x3, y3, z3, x1, y1, z1, x0, y0, z0, xc, yc, zc) * inv_vol;
413  N[3] = CalculateVol(x3, y3, z3, x0, y0, z0, x2, y2, z2, xc, yc, zc) * inv_vol;
414 
415 
416  if (N[0] >= 0.0 && N[1] >= 0.0 && N[2] >= 0.0 && N[3] >= 0.0 &&
417  N[0] <= 1.0 && N[1] <= 1.0 && N[2] <= 1.0 && N[3] <= 1.0)
418  //if the xc yc zc is inside the tetrahedron return true
419  return true;
420 
421  return false;
422  }
423 
424  inline double CalculateVol(const double x0, const double y0,
425  const double x1, const double y1,
426  const double x2, const double y2
427  )
428  {
429  return 0.5 * ((x1 - x0)*(y2 - y0)- (y1 - y0)*(x2 - x0));
430  }
431  //***************************************
432  //***************************************
433 
434  inline double CalculateVol(const double x0, const double y0, const double z0,
435  const double x1, const double y1, const double z1,
436  const double x2, const double y2, const double z2,
437  const double x3, const double y3, const double z3
438  )
439  {
440  double x10 = x1 - x0;
441  double y10 = y1 - y0;
442  double z10 = z1 - z0;
443 
444  double x20 = x2 - x0;
445  double y20 = y2 - y0;
446  double z20 = z2 - z0;
447 
448  double x30 = x3 - x0;
449  double y30 = y3 - y0;
450  double z30 = z3 - z0;
451 
452  double detJ = x10 * y20 * z30 - x10 * y30 * z20 + y10 * z20 * x30 - y10 * x20 * z30 + z10 * x20 * y30 - z10 * y20 * x30;
453  return detJ * 0.1666666666666666666667;
454  }
455 
456 
457 
460 
462 
463  };
464 
465 } // namespace Kratos.
466 
467 #endif // KRATOS_MOVE_PART_UTILITY_DIFF2_INCLUDED defined
Short class definition.
Definition: bins_dynamic_objects.h:57
Geometry base class.
Definition: geometry.h:71
size_type size() const
Definition: global_pointers_vector.h:307
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
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
ElementsContainerType::ContainerType & ElementsArray(IndexType ThisIndex=0)
Definition: model_part.h:1209
Definition: transfer_utility.h:105
Configure::ResultContainerType ResultContainerType
Definition: transfer_utility.h:114
Configure::ResultIteratorType ResultIteratorType
Definition: transfer_utility.h:116
Configure::IteratorType IteratorType
Definition: transfer_utility.h:113
void GatherInformationFromTopographicDomain()
Definition: transfer_utility.h:164
TransferUtility(ModelPart &calculation_model_part, ModelPart &topographic_model_part)
Definition: transfer_utility.h:126
Configure::ContainerType ContainerType
Definition: transfer_utility.h:111
SpatialContainersConfigure< TDim > Configure
Definition: transfer_utility.h:108
Configure::PointType PointType
Definition: transfer_utility.h:109
~TransferUtility()
Definition: transfer_utility.h:160
Point class.
Definition: point.h:59
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Thhis class is a container for spatial search.
Definition: spatial_containers_configure.h:59
typename ContainerType::iterator IteratorType
Definition: spatial_containers_configure.h:82
typename ResultContainerType::iterator ResultIteratorType
Definition: spatial_containers_configure.h:85
typename PointerVectorSet< TEntity, IndexedObject >::ContainerType ContainerType
Container definition.
Definition: spatial_containers_configure.h:80
typename PointerVectorSet< TEntity, IndexedObject >::ContainerType ResultContainerType
Definition: spatial_containers_configure.h:83
#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
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
bool CalculatePosition(Geometry< Node > &geom, const double xc, const double yc, const double zc, array_1d< double, 3 > &N)
Definition: transfer_utility.h:343
double CalculateVol(const double x0, const double y0, const double x1, const double y1, const double x2, const double y2)
Definition: transfer_utility.h:424
ModelPart & mcalculation_model_part
Definition: transfer_utility.h:458
ModelPart & mtopographic_model_part
Definition: transfer_utility.h:459
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
class Kratos::MoveParticleUtilityDiffFluidOnly FindNodeOnMesh(array_1d< double, 3 > &position, array_1d< double, TDim+1 > &N, Element::Pointer &pelement, ResultIteratorType result_begin, const unsigned int MaxNumberOfResults)
Definition: transfer_utility.h:241
BinsObjectDynamic< Configure >::Pointer mpBinsObjectDynamic
Definition: transfer_utility.h:461
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
float delta_t
Definition: rotatingcone_PureConvectionBenchmarking.py:129
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17
Configure::ResultIteratorType ResultIteratorType
Definition: transfer_utility.h:252