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.
convect_particles_utilities.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 //
12 //
13 
14 #if !defined(KRATOS_CONVECT_PARTICLES_UTILITIES_INCLUDED )
15 #define KRATOS_CONVECT_PARTICLES_UTILITIES_INCLUDED
16 
17 #define PRESSURE_ON_EULERIAN_MESH
18 #define USE_FEW_PARTICLES
19 
20 // System includes
21 #include <string>
22 #include <iostream>
23 #include <algorithm>
24 
25 // External includes
26 #ifdef _OPENMP
27 #include "omp.h"
28 #endif
29 
30 // Project includes
31 #include "includes/define.h"
32 #include "includes/model_part.h"
33 #include "includes/node.h"
34 #include "utilities/geometry_utilities.h"
36 #include "includes/variables.h"
38 #include "utilities/timer.h"
40 #include "utilities/timer.h"
41 
42 namespace Kratos
43 {
44 
45 template<std::size_t TDim> class ParticleConvectUtily
46 {
47 public:
49 
51  : mpSearchStructure(pSearchStructure)
52  {
53  }
54 
56  {
57  }
58 
59 
60 
61  //**********************************************************************************************
62  //**********************************************************************************************
67  void MoveParticles_Substepping(ModelPart& rModelPart, unsigned int subdivisions)
68  {
70  const double dt = rModelPart.GetProcessInfo()[DELTA_TIME];
71  const double small_dt = dt/ static_cast<double>(subdivisions);
72 
73  //do movement
74  array_1d<double, 3 > veulerian;
75  array_1d<double, 3 > acc_particle;
76  Vector N(TDim + 1);
77  const int max_results = rModelPart.Nodes().size();
78 
79  typename BinBasedFastPointLocator<TDim>::ResultContainerType results(max_results);
80 
81  const int nparticles = rModelPart.Nodes().size();
82 
83  #pragma omp parallel for firstprivate(results,N,veulerian,acc_particle)
84  for (int i = 0; i < nparticles; i++)
85  {
86  unsigned int substep = 0;
87 
88  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
89  Node ::Pointer pparticle = *(iparticle.base());
90 
91  array_1d<double,3> current_position = iparticle->GetInitialPosition() + iparticle->FastGetSolutionStepValue(DISPLACEMENT,1);
92 
93  Element::Pointer pelement;
94  bool is_found = false;
95 
96  array_1d<double, 3> aux_point_local_coordinates;
97 
98  while(substep++ < subdivisions)
99  {
100 
101  typename BinBasedFastPointLocator<TDim>::ResultIteratorType result_begin = results.begin();
102 
103  is_found = false;
104 
105 
106  if(substep > 1 ) //first check if it falls within the same element
107  {
108  Geometry< Node >& geom = pelement->GetGeometry();
109  is_found = geom.IsInside(current_position, aux_point_local_coordinates, 1.0e-5);
110  geom.ShapeFunctionsValues(N, aux_point_local_coordinates);
111 
112  if(is_found == false)
113  is_found = mpSearchStructure->FindPointOnMesh(current_position, N, pelement, result_begin, max_results);
114  }
115  else //if not found use the search structure
116  {
117  is_found = mpSearchStructure->FindPointOnMesh(current_position, N, pelement, result_begin, max_results);
118  }
119 
120  (iparticle)->Set(TO_ERASE, true);
121 
122  if (is_found == true)
123  {
124  Geometry< Node >& geom = pelement->GetGeometry();
125 
126  const double new_step_factor = static_cast<double>(substep)/subdivisions;
127  const double old_step_factor = 1.0 - new_step_factor;
128 
129  noalias(veulerian) = N[0] * ( new_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY,1));
130  for (unsigned int k = 1; k < geom.size(); k++)
131  noalias(veulerian) += N[k] * ( new_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY,1) );
132  noalias(current_position) += small_dt*veulerian;
133 
134  (iparticle)->Set(TO_ERASE, false);
135 
136  }
137  else
138  break;
139 
140 
141  }
142 
143  if (is_found == true)
144  {
145 
146 
147  iparticle->FastGetSolutionStepValue(DISPLACEMENT) = current_position - iparticle->GetInitialPosition();
148  noalias(pparticle->Coordinates()) = current_position;
149  }
150  }
151 
152  KRATOS_CATCH("")
153 
154  }
155 
156 
157  //**********************************************************************************************
158  //**********************************************************************************************
161  void MoveParticles_RK4(ModelPart& rModelPart)
162  {
163  KRATOS_TRY
164  const double dt = rModelPart.GetProcessInfo()[DELTA_TIME];
165 
166  //do movement
167  array_1d<double, 3 > v1,v2,v3,v4,vtot,x;
168  Vector N(TDim + 1);
169  const int max_results = 10000;
170  typename BinBasedFastPointLocator<TDim>::ResultContainerType results(max_results);
171 
172  const int nparticles = rModelPart.Nodes().size();
173 
174  #pragma omp parallel for firstprivate(results,N,v1,v2,v3,v4,vtot,x)
175  for (int i = 0; i < nparticles; i++)
176  {
177  typename BinBasedFastPointLocator<TDim>::ResultIteratorType result_begin = results.begin();
178 
179  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
180  Node ::Pointer pparticle = *(iparticle.base());
181 
182  array_1d<double,3> initial_position = iparticle->GetInitialPosition() + iparticle->FastGetSolutionStepValue(DISPLACEMENT,1);
183 
184  Element::Pointer pelement;
185  bool is_found = false;
186  //STEP1
187  {
188  is_found = mpSearchStructure->FindPointOnMesh(initial_position, N, pelement, result_begin, max_results);
189  if( is_found == false) goto end_of_particle;
190  Geometry< Node >& geom = pelement->GetGeometry();
191  noalias(v1) = N[0] * ( geom[0].FastGetSolutionStepValue(VELOCITY,1));
192  for (unsigned int k = 1; k < geom.size(); k++)
193  noalias(v1) += N[k] * ( geom[k].FastGetSolutionStepValue(VELOCITY,1) );
194  }
195 
196  //STEP2
197 // if(is_found == true)
198  {
199  noalias(x) = initial_position + (0.5*dt)*v1;
200  is_found = mpSearchStructure->FindPointOnMesh(x, N, pelement, result_begin, max_results);
201  if( is_found == false) goto end_of_particle;
202  Geometry< Node >& geom = pelement->GetGeometry();
203  const double new_step_factor = 0.5;
204  const double old_step_factor = 0.5;
205 
206  noalias(v2) = N[0] * ( new_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY,1));
207  for (unsigned int k = 1; k < geom.size(); k++)
208  noalias(v2) += N[k] * ( new_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY,1) );
209  }
210 
211  //STEP3
212 // if(is_found == true)
213  {
214  const array_1d<double,3> x = initial_position + (0.5*dt)*v2;
215  is_found = mpSearchStructure->FindPointOnMesh(x, N, pelement, result_begin, max_results);
216  if( is_found == false) goto end_of_particle;
217  Geometry< Node >& geom = pelement->GetGeometry();
218  const double new_step_factor = 0.5; //as the step before
219  const double old_step_factor = 0.5;
220 
221  noalias(v3) = N[0] * ( new_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY,1));
222  for (unsigned int k = 1; k < geom.size(); k++)
223  noalias(v3) += N[k] * ( new_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY,1) );
224  }
225 
226  //STEP4
227 // if(is_found == true)
228  {
229  const array_1d<double,3> x = initial_position + (dt)*v3;
230  is_found = mpSearchStructure->FindPointOnMesh(x, N, pelement, result_begin, max_results);
231  if( is_found == false) goto end_of_particle;
232  Geometry< Node >& geom = pelement->GetGeometry();
233  noalias(v4) = N[0] * ( geom[0].FastGetSolutionStepValue(VELOCITY));
234  for (unsigned int k = 1; k < geom.size(); k++)
235  noalias(v4) += N[k] * ( geom[k].FastGetSolutionStepValue(VELOCITY) );
236  }
237 
238 
239  (iparticle)->Set(TO_ERASE, false);
240  //finalize step
241  noalias(x) = initial_position;
242  noalias(x) += 0.16666666666666666666667*dt*v1;
243  noalias(x) += 0.33333333333333333333333*dt*v2;
244  noalias(x) += 0.33333333333333333333333*dt*v3;
245  noalias(x) += 0.16666666666666666666667*dt*v4;
246 
247  iparticle->FastGetSolutionStepValue(DISPLACEMENT) = x - iparticle->GetInitialPosition();
248  noalias(pparticle->Coordinates()) = x;
249 
250  end_of_particle: (iparticle)->Set(TO_ERASE, true);
251  }
252 
253  KRATOS_CATCH("")
254 
255  }
256 
257 //**********************************************************************************************
258 //**********************************************************************************************
261  void EraseOuterElements(ModelPart& rModelPart)
262  {
263  KRATOS_TRY
264  int nerased_el = 0;
265  for(ModelPart::ElementsContainerType::iterator it = rModelPart.ElementsBegin(); it!=rModelPart.ElementsEnd(); it++)
266  {
267  Geometry< Node >& geom = it->GetGeometry();
268 
269 // bool erase_el = false;
270  for(unsigned int i=0; i<geom.size(); i++)
271  {
272  if(geom[i].Is(TO_ERASE))
273  {
274  it->Set(TO_ERASE,true);
275  nerased_el++;
276  break;
277  }
278  }
279  }
280 
281  if(nerased_el > 0)
282  {
283  ModelPart::ElementsContainerType temp_elems_container;
284  temp_elems_container.reserve(rModelPart.Elements().size() - nerased_el);
285 
286  temp_elems_container.swap(rModelPart.Elements());
287 
288  for(ModelPart::ElementsContainerType::iterator it = temp_elems_container.begin() ; it != temp_elems_container.end() ; it++)
289  {
290  if( it->IsNot(TO_ERASE) )
291  (rModelPart.Elements()).push_back(*(it.base()));
292  }
293  }
294  KRATOS_CATCH("")
295  }
296 
297 private:
298  typename BinBasedFastPointLocator<TDim>::Pointer mpSearchStructure;
299 
300 
301 
302 };
303 
304 } // namespace Kratos.
305 
306 #endif // KRATOS_CONVECT_PARTICLES_UTILITIES_INCLUDED defined
307 
308 
This class is designed to allow the fast location of MANY points on the top of a 3D mesh.
Definition: binbased_fast_point_locator.h:68
ConfigureType::ResultIteratorType ResultIteratorType
Definition: binbased_fast_point_locator.h:82
ConfigureType::ResultContainerType ResultContainerType
Definition: binbased_fast_point_locator.h:81
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
const Matrix & ShapeFunctionsValues() const
Definition: geometry.h:3393
virtual bool IsInside(const CoordinatesArrayType &rPointGlobalCoordinates, CoordinatesArrayType &rResult, const double Tolerance=std::numeric_limits< double >::epsilon()) const
Checks if given point in global space coordinates is inside the geometry boundaries....
Definition: geometry.h:1918
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
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
Definition: convect_particles_utilities.h:46
~ParticleConvectUtily()
Definition: convect_particles_utilities.h:55
KRATOS_CLASS_POINTER_DEFINITION(ParticleConvectUtily< TDim >)
void MoveParticles_RK4(ModelPart &rModelPart)
Definition: convect_particles_utilities.h:161
void MoveParticles_Substepping(ModelPart &rModelPart, unsigned int subdivisions)
Definition: convect_particles_utilities.h:67
void EraseOuterElements(ModelPart &rModelPart)
Definition: convect_particles_utilities.h:261
ParticleConvectUtily(typename BinBasedFastPointLocator< TDim >::Pointer pSearchStructure)
Definition: convect_particles_utilities.h:50
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
void swap(PointerVectorSet &rOther)
Swaps the contents of this PointerVectorSet with another.
Definition: pointer_vector_set.h:532
iterator begin()
Returns an iterator pointing to the beginning of the container.
Definition: pointer_vector_set.h:278
void reserve(int reservedsize)
Reserves memory for a specified number of elements.
Definition: pointer_vector_set.h:733
iterator end()
Returns an iterator pointing to the end of the container.
Definition: pointer_vector_set.h:314
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
dt
Definition: DEM_benchmarks.py:173
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
int k
Definition: quadrature.py:595
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
integer i
Definition: TensorModule.f:17