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.
bfecc_elemental_limiter_convection.h
Go to the documentation of this file.
1 // KRATOS ___ ___ _ ___ __ ___ ___ ___ ___
2 // / __/ _ \| \| \ \ / /__| \_ _| __| __|
3 // | (_| (_) | .` |\ V /___| |) | || _|| _|
4 // \___\___/|_|\_| \_/ |___/___|_| |_| APPLICATION
5 //
6 // License: BSD License
7 // Kratos default license: kratos/license.txt
8 //
9 // Main authors: Riccardo Rossi
10 //
11 
12 #if !defined(KRATOS_BFECC_LIMITER_CONVECTION_INCLUDED )
13 #define KRATOS_BFECC_LIMITER_CONVECTION_INCLUDED
14 
15 #define PRESSURE_ON_EULERIAN_MESH
16 #define USE_FEW_PARTICLES
17 
18 // System includes
19 #include <string>
20 #include <iostream>
21 #include <algorithm>
22 
23 // External includes
24 #ifdef _OPENMP
25 #include "omp.h"
26 #endif
27 
28 // Project includes
29 #include "includes/define.h"
30 #include "includes/model_part.h"
31 #include "includes/node.h"
32 #include "utilities/geometry_utilities.h"
34 #include "includes/variables.h"
36 #include "utilities/timer.h"
39 
40 namespace Kratos
41 {
42 
43 template<std::size_t TDim> class BFECCLimiterConvection
44 {
45 public:
47 
49  : mpSearchStructure(pSearchStructure)
50  {
51  }
52 
54  {
55  }
56 
57  //**********************************************************************************************
58  //**********************************************************************************************
59  void BFECCconvect(ModelPart& rModelPart, const Variable< double >& rVar, const Variable<array_1d<double,3> >& conv_var, const double substeps)
60  {
62  const double dt = rModelPart.GetProcessInfo()[DELTA_TIME];
63 
64  //do movement
65  Vector N(TDim + 1);
66  const int max_results = 10000;
67  typename BinBasedFastPointLocator<TDim>::ResultContainerType results(max_results);
68 
69  const int nparticles = rModelPart.Nodes().size();
70 
71  PointerVector< Element > elem_backward( rModelPart.Nodes().size());
72  std::vector< Vector > Ns( rModelPart.Nodes().size());
73  std::vector< bool > found( rModelPart.Nodes().size());
74  std::vector< bool > foundf( rModelPart.Nodes().size());
75 
76  // Allocate non-historical variables
77  for (auto &r_node : rModelPart.Nodes()) {
78  r_node.SetValue(rVar, 0.0);
79  r_node.SetValue(BFECC_ERROR, 0.0);
80  r_node.SetValue(BFECC_ERROR_1, 0.0);
81  }
82 
83  //FIRST LOOP: estimate rVar(n+1)
84  #pragma omp parallel for firstprivate(results,N)
85  for (int i = 0; i < nparticles; i++)
86  {
87  typename BinBasedFastPointLocator<TDim>::ResultIteratorType result_begin = results.begin();
88 
89  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
90 
91  Element::Pointer pelement;
92  array_1d<double,3> bckPos = iparticle->Coordinates();
93  const array_1d<double,3>& vel = iparticle->FastGetSolutionStepValue(conv_var);
94  bool is_found = ConvectBySubstepping(dt,bckPos,vel, N, pelement, result_begin, max_results, -1.0, substeps);
95  found[i] = is_found;
96 
97  if(is_found) {
98  //save position backwards
99  elem_backward(i) = pelement;
100  Ns[i] = N;
101 
102  Geometry< Node >& geom = pelement->GetGeometry();
103  double phi1 = N[0] * ( geom[0].FastGetSolutionStepValue(rVar,1));
104  for (unsigned int k = 1; k < geom.size(); k++) {
105  phi1 += N[k] * ( geom[k].FastGetSolutionStepValue(rVar,1) );
106  }
107 
108  iparticle->FastGetSolutionStepValue(rVar) = phi1;
109  }
110  }
111 
112  //now obtain the value AT TIME STEP N by taking it from N+1
113  #pragma omp parallel for firstprivate(results,N)
114  for (int i = 0; i < nparticles; i++)
115  {
116  typename BinBasedFastPointLocator<TDim>::ResultIteratorType result_begin = results.begin();
117 
118  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
119 
120  Element::Pointer pelement;
121  array_1d<double,3> fwdPos = iparticle->Coordinates();
122  const array_1d<double,3>& vel = iparticle->FastGetSolutionStepValue(conv_var,1);
123  bool is_found = ConvectBySubstepping(dt,fwdPos,vel, N, pelement, result_begin, max_results, 1.0, substeps);
124  foundf[i] = is_found;
125 
126  if(is_found) {
127  Geometry< Node >& geom = pelement->GetGeometry();
128  double phi_old = N[0] * ( geom[0].FastGetSolutionStepValue(rVar));
129 
130  for (unsigned int k = 1; k < geom.size(); k++) {
131  phi_old += N[k] * ( geom[k].FastGetSolutionStepValue(rVar) );
132  }
133 
134  //Computing error 1 and modified solution at time N to be interpolated again
135  iparticle->GetValue(BFECC_ERROR_1) = 0.5*iparticle->FastGetSolutionStepValue(rVar,1) - 0.5*phi_old;//computing error1 as e1 = 0.5*(rVar(n) - phi_old)
136  iparticle->GetValue(rVar) = iparticle->FastGetSolutionStepValue(rVar,1) + iparticle->GetValue(BFECC_ERROR_1);//rVar(n)+e1
137  }
138  }
139  //Backward with modified solution
140  #pragma omp parallel for
141  for (int i = 0; i < nparticles; i++)
142  {
143  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
144  bool is_found = found[i];
145  if(is_found) {
146  Vector N = Ns[i];
147  Geometry< Node >& geom = elem_backward[i].GetGeometry();
148  double phi1 = N[0] * ( geom[0].GetValue(rVar));
149  for (unsigned int k = 1; k < geom.size(); k++) {
150  phi1 += N[k] * ( geom[k].GetValue(rVar) );
151  }
152  iparticle->FastGetSolutionStepValue(rVar) = phi1;
153  }
154 // else
155 // std::cout << "it should find it" << std::endl;
156  }
157 
158 
159 
160  // computing error 2 with forward of phi1
161  int nelements = rModelPart.NumberOfElements();
162  for(int i = 0 ; i < nelements; i++)
163  {
164  typename BinBasedFastPointLocator<TDim>::ResultIteratorType result_begin = results.begin();
165 
166  ModelPart::ElementsContainerType::iterator i_element = rModelPart.ElementsBegin() + i;
167  Element::GeometryType& element_geometry = i_element->GetGeometry();
168 
169  Element::Pointer pelement;
170  array_1d<double,3> fwdPos = i_element->GetGeometry().Center();
172 
173  for(unsigned int j = 0 ; j < element_geometry.size(); j++){
174  for(int k = 0 ; k < 3; k++){
175  vel[k] += element_geometry[j].GetSolutionStepValue(conv_var)[k] / element_geometry.size();
176  }
177  }
178 
179  bool is_found = ConvectBySubstepping(dt,fwdPos,vel, N, pelement, result_begin, max_results, 1.0, substeps);//seeking forwards
180  double e1 = 0.00f;
181 
182  for(unsigned int j = 0 ; j < element_geometry.size(); j++){
183  e1 += element_geometry[j].GetValue(BFECC_ERROR_1);
184  }
185  e1 /= element_geometry.size();
186 
187  double e2 = e1;
188  if(is_found) {
189  //Forward with
190  Geometry< Node >& geom = pelement->GetGeometry();
191  double phi2 = N[0] * ( geom[0].FastGetSolutionStepValue(rVar));
192  for (unsigned int k = 1; k < geom.size(); k++) {
193  phi2 += N[k] * ( geom[k].FastGetSolutionStepValue(rVar) );
194  }
195  double solution_in_center = 0;
196  //Computing error2 as e2 = rVar(n)-(phi2+e1)
197  for(unsigned int j = 0 ; j < element_geometry.size(); j++){
198  solution_in_center += i_element->GetGeometry()[j].FastGetSolutionStepValue(rVar,1);
199  }
200  solution_in_center /= element_geometry.size();
201 
202  e2 = solution_in_center - (phi2 + e1);
203 
204  if(std::abs(e2) > std::abs(e1)){
205  for(unsigned int j = 0 ; j < element_geometry.size(); j++){
206  element_geometry[j].GetValue(BFECC_ERROR) = minmod(e1,element_geometry[j].GetValue(BFECC_ERROR_1));
207  }
208  }
209  }
210 
211  }
212 
213  #pragma omp parallel for
214  for (int i = 0; i < nparticles; i++){
215  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
216  bool is_found = foundf[i];
217  if(is_found) {
218  iparticle->GetValue(rVar) = iparticle->FastGetSolutionStepValue(rVar,1) + iparticle->GetValue(BFECC_ERROR);
219  }
220  }
221  //Backward with modified solution
222  #pragma omp parallel for
223  for (int i = 0; i < nparticles; i++){
224  ModelPart::NodesContainerType::iterator iparticle = rModelPart.NodesBegin() + i;
225  bool is_found = found[i];
226  if(is_found) {
227  Vector N = Ns[i];
228  Geometry< Node >& geom = elem_backward[i].GetGeometry();
229  double phi1 = N[0] * ( geom[0].GetValue(rVar));
230  for (unsigned int k = 1; k < geom.size(); k++) {
231  phi1 += N[k] * ( geom[k].GetValue(rVar) );
232  }
233  iparticle->FastGetSolutionStepValue(rVar) = phi1;
234  }
235  }
236 
237  KRATOS_CATCH("")
238  }
239 
240  double minmod(double x, double y) {
241  double f;
242  if(x > 0.0f && y > 0.0f)
243  f = std::min(x,y);
244  else if(x < 0.0f && y < 0.0f)
245  f = std::max(x,y);
246  else
247  f = 0;
248  return f;
249  }
250 
252  const double dt,
253  array_1d<double,3>& position, //IT WILL BE MODIFIED
254  const array_1d<double,3>& initial_velocity,
255  Vector& N,
256  Element::Pointer& pelement,
258  const unsigned int max_results,
259  const double velocity_sign,
260  const double subdivisions)
261  {
262  bool is_found = false;
263  array_1d<double,3> veulerian;
264  const double small_dt = dt/subdivisions;
265 
266 
267  if(velocity_sign > 0.0) //going from the past to the future
268  {
269  noalias(position) += small_dt*initial_velocity;
270  unsigned int substep=0;
271  while(substep++ < subdivisions)
272  {
273  is_found = mpSearchStructure->FindPointOnMesh(position, N, pelement, result_begin, max_results);
274 
275  if (is_found == true)
276  {
277  Geometry< Node >& geom = pelement->GetGeometry();
278 
279  const double new_step_factor = static_cast<double>(substep)/subdivisions;
280  const double old_step_factor = (1.0 - new_step_factor);
281 
282  noalias(veulerian) = N[0] * ( new_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY,1));
283  for (unsigned int k = 1; k < geom.size(); k++)
284  noalias(veulerian) += N[k] * ( new_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY,1) );
285 
286  noalias(position) += small_dt*veulerian;
287 
288 
289  }
290  else
291  break;
292  }
293  }
294  else //going from the future to the past
295  {
296  noalias(position) -= small_dt*initial_velocity;
297  unsigned int substep=0;
298  while(substep++ < subdivisions)
299  {
300  is_found = mpSearchStructure->FindPointOnMesh(position, N, pelement, result_begin, max_results);
301 
302  if (is_found == true)
303  {
304  Geometry< Node >& geom = pelement->GetGeometry();
305 
306  //this factors get inverted from the other case
307  const double old_step_factor = static_cast<double>(substep)/subdivisions;
308  const double new_step_factor = (1.0 - old_step_factor);
309 
310  noalias(veulerian) = N[0] * ( new_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[0].FastGetSolutionStepValue(VELOCITY,1));
311  for (unsigned int k = 1; k < geom.size(); k++)
312  noalias(veulerian) += N[k] * ( new_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY) + old_step_factor*geom[k].FastGetSolutionStepValue(VELOCITY,1) );
313 
314  noalias(position) -= small_dt*veulerian;
315 
316 
317  }
318  else
319  break;
320  }
321  }
322 
323  return is_found;
324 
325  }
326 
327 private:
328  typename BinBasedFastPointLocator<TDim>::Pointer mpSearchStructure;
329 
330 
331 
332 };
333 
334 } // namespace Kratos.
335 
336 #endif // KRATOS_BFECC_LIMITER_CONVECTION_INCLUDED defined
Definition: bfecc_elemental_limiter_convection.h:44
KRATOS_CLASS_POINTER_DEFINITION(BFECCLimiterConvection< TDim >)
BFECCLimiterConvection(typename BinBasedFastPointLocator< TDim >::Pointer pSearchStructure)
Definition: bfecc_elemental_limiter_convection.h:48
bool ConvectBySubstepping(const double dt, array_1d< double, 3 > &position, const array_1d< double, 3 > &initial_velocity, Vector &N, Element::Pointer &pelement, typename BinBasedFastPointLocator< TDim >::ResultIteratorType &result_begin, const unsigned int max_results, const double velocity_sign, const double subdivisions)
Definition: bfecc_elemental_limiter_convection.h:251
void BFECCconvect(ModelPart &rModelPart, const Variable< double > &rVar, const Variable< array_1d< double, 3 > > &conv_var, const double substeps)
Definition: bfecc_elemental_limiter_convection.h:59
~BFECCLimiterConvection()
Definition: bfecc_elemental_limiter_convection.h:53
double minmod(double x, double y)
Definition: bfecc_elemental_limiter_convection.h:240
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
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
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
SizeType NumberOfElements(IndexType ThisIndex=0) const
Definition: model_part.h:1027
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
dt
Definition: DEM_benchmarks.py:173
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
Parameters GetValue(Parameters &rParameters, const std::string &rEntry)
Definition: add_kratos_parameters_to_python.cpp:53
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
phi_old
Definition: generate_convection_diffusion_explicit_element.py:103
f
Definition: generate_convection_diffusion_explicit_element.py:112
vel
Definition: pure_conduction.py:76
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
integer i
Definition: TensorModule.f:17