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.
levelset_convection_element_simplex.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: Pooyan Dadvand
11 // Riccardo Rossi
12 //
13 //
14 
15 
16 #if !defined(KRATOS_LEVELSET_CONVECTION_ELEMENT_SIMPLEX_INCLUDED )
17 #define KRATOS_LEVELSET_CONVECTION_ELEMENT_SIMPLEX_INCLUDED
18 
19 // System includes
20 
21 // External includes
22 
23 // Project includes
24 #include "includes/define.h"
25 #include "includes/element.h"
27 #include "includes/variables.h"
28 #include "includes/serializer.h"
29 #include "includes/cfd_variables.h"
31 #include "utilities/geometry_utilities.h"
32 
33 namespace Kratos
34 {
35 
38 
42 
46 
50 
54 
56 template< unsigned int TDim, unsigned int TNumNodes>
58  : public Element
59 {
60 public:
63 
66 
70 
73  {}
74 
75  LevelSetConvectionElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry)
76  : Element(NewId, pGeometry)
77  {}
78 
79  LevelSetConvectionElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
80  : Element(NewId, pGeometry, pProperties)
81  {}
82 
85 
86 
90 
91 
95 
96  Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer pProperties) const override
97  {
99  return Element::Pointer(new LevelSetConvectionElementSimplex(NewId, GetGeometry().Create(ThisNodes), pProperties));
100  KRATOS_CATCH("");
101  }
102 
103  Element::Pointer Create(
104  IndexType NewId,
105  GeometryType::Pointer pGeom,
106  PropertiesType::Pointer pProperties) const override
107  {
108  KRATOS_TRY
109  return Element::Pointer(new LevelSetConvectionElementSimplex(NewId, pGeom, pProperties));
110  KRATOS_CATCH("");
111  }
112 
113  void Initialize(const ProcessInfo& rProcessInfo) override
114  {
115  const auto& r_geometry = GetGeometry();
116  mElementTauNodal = std::all_of(r_geometry.begin(),
117  r_geometry.end(),
118  [](const auto& rNode) {
119  return rNode.Has(TAU);
120  });
121  }
122 
123  void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, const ProcessInfo& rCurrentProcessInfo) override
124  {
125  KRATOS_TRY
126 
127  if (rLeftHandSideMatrix.size1() != TNumNodes)
128  rLeftHandSideMatrix.resize(TNumNodes, TNumNodes, false); //false says not to preserve existing storage!!
129 
130  if (rRightHandSideVector.size() != TNumNodes)
131  rRightHandSideVector.resize(TNumNodes, false); //false says not to preserve existing storage!!
132 
133  const double delta_t = rCurrentProcessInfo[DELTA_TIME];
134  const double dt_inv = 1.0 / delta_t;
135  const double theta = rCurrentProcessInfo.Has(TIME_INTEGRATION_THETA) ? rCurrentProcessInfo[TIME_INTEGRATION_THETA] : 0.5;
136 
137  const ConvectionDiffusionSettings::Pointer& my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
138  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
139  const Variable<array_1d<double, 3 > >& rConvVar = my_settings->GetConvectionVariable();
140  const double dyn_st_beta = rCurrentProcessInfo[DYNAMIC_TAU];
141 
142 
143  //getting data for the given geometry
146  double Volume;
148  double h = ComputeH(DN_DX, Volume);
149 
150 
151  //here we get all the variables we will need
153  array_1d< array_1d<double,3 >, TNumNodes> v, vold;
154 
155  for (unsigned int i = 0; i < TNumNodes; i++)
156  {
157  phi[i] = GetGeometry()[i].FastGetSolutionStepValue(rUnknownVar);
158  phi_old[i] = GetGeometry()[i].FastGetSolutionStepValue(rUnknownVar,1);
159 // dphi_dt[i] = dt_inv*(phi[i] - phi_old [i];
160 
161  v[i] = GetGeometry()[i].FastGetSolutionStepValue(rConvVar);
162  vold[i] = GetGeometry()[i].FastGetSolutionStepValue(rConvVar,1);
163  }
164  array_1d<double,TDim> grad_phi_halfstep = prod(trans(DN_DX), 0.5*(phi+phi_old));
165  const double norm_grad = norm_2(grad_phi_halfstep);
166 
167  //here we use a term beta which takes into account a reaction term of the type "beta*div_v"
168 
169 
170  //compute the divergence of v
171  double div_v = 0.0;
172  for (unsigned int i = 0; i < TNumNodes; i++)
173  for(unsigned int k=0; k<TDim; k++)
174  div_v += 0.5*DN_DX(i,k)*(v[i][k] + vold[i][k]);
175 
176  double beta = 0.0; //1.0;
177 
178 // unsigned int nneg=0;
179 // for(unsigned int i=0; i<TNumNodes; i++) if(phi[i] < 0.0) nneg++;
180 // if(nneg > 0) beta = 1.0; //beta = 0.1;
181 
182  BoundedMatrix<double,TNumNodes, TNumNodes> aux1 = ZeroMatrix(TNumNodes, TNumNodes); //terms multiplying dphi/dt
183  BoundedMatrix<double,TNumNodes, TNumNodes> aux2 = ZeroMatrix(TNumNodes, TNumNodes); //terms multiplying phi
185 
186 
188  GetShapeFunctionsOnGauss(Ncontainer);
189  for(unsigned int igauss=0; igauss<TDim+1; igauss++)
190  {
191  noalias(N) = row(Ncontainer,igauss);
192 
193  //obtain the velocity in the middle of the tiem step
194  array_1d<double, TDim > vel_gauss=ZeroVector(TDim);
195  for (unsigned int i = 0; i < TNumNodes; i++)
196  {
197  for(unsigned int k=0; k<TDim; k++)
198  vel_gauss[k] += 0.5*N[i]*(v[i][k]+vold[i][k]);
199  }
200  const double norm_vel = norm_2(vel_gauss);
201  array_1d<double, TNumNodes > a_dot_grad = prod(DN_DX, vel_gauss);
202  double tau = 0.0;
203 
204  if (mElementTauNodal){
205 
206  for (unsigned int i = 0; i < TNumNodes; i++)
207  {
208  tau += N[i] * GetGeometry()[i].GetValue(TAU);
209  }
210  }
211  else{
212  const double tau_denom = std::max(dyn_st_beta * dt_inv + 2.0 * norm_vel / h + std::abs(/*beta**/ div_v), 1e-2); // the term std::abs(div_v) is added following Pablo Becker's suggestion
213  tau = 1.0 / (tau_denom);
214  }
215 
216 
217  //terms multiplying dphi/dt (aux1)
218  noalias(aux1) += (1.0+tau*beta*div_v)*outer_prod(N, N);
219  noalias(aux1) += tau*outer_prod(a_dot_grad, N);
220 
221  //terms which multiply the gradient of phi
222  noalias(aux2) += (1.0+tau*beta*div_v)*outer_prod(N, a_dot_grad);
223  noalias(aux2) += tau*outer_prod(a_dot_grad, a_dot_grad);
224 
225  //cross-wind term
226  if(norm_grad > 1e-3 && norm_vel > 1e-9)
227  {
228  const double C = rCurrentProcessInfo.GetValue(CROSS_WIND_STABILIZATION_FACTOR);
229  const double time_derivative = dt_inv*(inner_prod(N,phi)-inner_prod(N,phi_old));
230  const double res = -time_derivative -inner_prod(vel_gauss, grad_phi_halfstep);
231 
232  const double disc_capturing_coeff = 0.5*C*h*fabs(res/norm_grad);
233  BoundedMatrix<double,TDim,TDim> D = disc_capturing_coeff*( IdentityMatrix(TDim));
234  const double norm_vel_squared = norm_vel*norm_vel;
235  D += (std::max( disc_capturing_coeff - tau*norm_vel_squared , 0.0) - disc_capturing_coeff)/(norm_vel_squared) * outer_prod(vel_gauss,vel_gauss);
236 
237  noalias(tmp) = prod(DN_DX,D);
238  noalias(aux2) += prod(tmp,trans(DN_DX));
239  }
240  }
241 
242  //adding the second and third term in the formulation
243  noalias(rLeftHandSideMatrix) = (dt_inv + theta*beta*div_v)*aux1;
244  noalias(rRightHandSideVector) = (dt_inv - (1.0 - theta)*beta*div_v)*prod(aux1,phi_old);
245 
246  //terms in aux2
247  noalias(rLeftHandSideMatrix) += theta*aux2;
248  noalias(rRightHandSideVector) -= (1.0 - theta)*prod(aux2,phi_old);
249 
250  //take out the dirichlet part to finish computing the residual
251  noalias(rRightHandSideVector) -= prod(rLeftHandSideMatrix, phi);
252 
253  rRightHandSideVector *= Volume/static_cast<double>(TNumNodes);
254  rLeftHandSideMatrix *= Volume/static_cast<double>(TNumNodes);
255 
256  KRATOS_CATCH("Error in Levelset Element")
257  }
258 
259 
260 
261 
262 
263  void CalculateRightHandSide(VectorType& rRightHandSideVector, const ProcessInfo& rCurrentProcessInfo) override
264  {
265  KRATOS_THROW_ERROR(std::runtime_error, "CalculateRightHandSide not implemented","");
266  }
267 
268 
269 
270 
271 
272  void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override
273  {
274  KRATOS_TRY
275 
276  const ConvectionDiffusionSettings::Pointer& my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
277  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
278 
279  if (rResult.size() != TNumNodes)
280  rResult.resize(TNumNodes, false);
281 
282  for (unsigned int i = 0; i < TNumNodes; i++)
283  {
284  rResult[i] = GetGeometry()[i].GetDof(rUnknownVar).EquationId();
285  }
286  KRATOS_CATCH("")
287 
288  }
289 
290 
291 
292 
293 
294  void GetDofList(DofsVectorType& ElementalDofList, const ProcessInfo& rCurrentProcessInfo) const override
295  {
296  KRATOS_TRY
297 
298  const ConvectionDiffusionSettings::Pointer& my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
299  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
300 
301  if (ElementalDofList.size() != TNumNodes)
302  ElementalDofList.resize(TNumNodes);
303 
304  for (unsigned int i = 0; i < TNumNodes; i++)
305  {
306  ElementalDofList[i] = GetGeometry()[i].pGetDof(rUnknownVar);
307 
308  }
309  KRATOS_CATCH("");
310  }
311 
312 
316 
317 
321 
322 
326 
328 
329  std::string Info() const override
330  {
331  return "LevelSetConvectionElementSimplex #";
332  }
333 
335 
336  void PrintInfo(std::ostream& rOStream) const override
337  {
338  rOStream << Info() << Id();
339  }
340 
342  // virtual void PrintData(std::ostream& rOStream) const;
343 
344 
348 
349 
351 
352 protected:
355 
356 
360 
364 
368  double ComputeH(BoundedMatrix<double,TNumNodes, TDim>& DN_DX, const double Volume)
369  {
370  double h=0.0;
371  for(unsigned int i=0; i<TNumNodes; i++)
372  {
373  double h_inv = 0.0;
374  for(unsigned int k=0; k<TDim; k++)
375  {
376  h_inv += DN_DX(i,k)*DN_DX(i,k);
377  }
378  h = std::max(h, 1.0 / h_inv);
379  }
380  h = std::sqrt(h);
381  return h;
382  }
383 
384  //gauss points for the 3D case
386  {
387  Ncontainer(0,0) = 0.58541020; Ncontainer(0,1) = 0.13819660; Ncontainer(0,2) = 0.13819660; Ncontainer(0,3) = 0.13819660;
388  Ncontainer(1,0) = 0.13819660; Ncontainer(1,1) = 0.58541020; Ncontainer(1,2) = 0.13819660; Ncontainer(1,3) = 0.13819660;
389  Ncontainer(2,0) = 0.13819660; Ncontainer(2,1) = 0.13819660; Ncontainer(2,2) = 0.58541020; Ncontainer(2,3) = 0.13819660;
390  Ncontainer(3,0) = 0.13819660; Ncontainer(3,1) = 0.13819660; Ncontainer(3,2) = 0.13819660; Ncontainer(3,3) = 0.58541020;
391  }
392 
393  //gauss points for the 2D case
395  {
396  const double one_sixt = 1.0/6.0;
397  const double two_third = 2.0/3.0;
398  Ncontainer(0,0) = one_sixt; Ncontainer(0,1) = one_sixt; Ncontainer(0,2) = two_third;
399  Ncontainer(1,0) = one_sixt; Ncontainer(1,1) = two_third; Ncontainer(1,2) = one_sixt;
400  Ncontainer(2,0) = two_third; Ncontainer(2,1) = one_sixt; Ncontainer(2,2) = one_sixt;
401  }
402 
403 
404 
408 
409 
413 
414 
418 
419 
421 
422 
423 
424 
425 private:
428 
432 
433  bool mElementTauNodal; // Flag to indicate if the stabilization tau is evaluated at each Gauss point or interpolated
434 
438  friend class Serializer;
439  // ASGS2D() : Element()
440  // {
441  // }
442 
443  void save(Serializer& rSerializer) const override
444  {
446  }
447 
448  void load(Serializer& rSerializer) override
449  {
451  }
452 
454 
457 
458 
462 
463 
467 
468 
472 
473 
474 
475 
476 
478 
479 };
480 
482 
485 
486 
490 
491 
493 /* inline std::istream& operator >> (std::istream& rIStream,
494  Fluid2DASGS& rThis);
495  */
497 /* inline std::ostream& operator << (std::ostream& rOStream,
498  const Fluid2DASGS& rThis)
499  {
500  rThis.PrintInfo(rOStream);
501  rOStream << std::endl;
502  rThis.PrintData(rOStream);
503 
504  return rOStream;
505  }*/
507 
508 } // namespace Kratos.
509 
510 #endif // KRATOS_LEVELSET_CONVECTION_ELEMENT_SIMPLEX_INCLUDED defined
511 
512 
bool Has(const Variable< TDataType > &rThisVariable) const
Checks if the data container has a value associated with a given variable.
Definition: data_value_container.h:382
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
Base class for all Elements.
Definition: element.h:60
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
std::size_t IndexType
Definition: flags.h:74
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
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
IndexType Id() const
Definition: indexed_object.h:107
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
formulation described in https://docs.google.com/document/d/13a_zGLj6xORDuLgoOG5LwHI6BwShvfO166opZ815...
Definition: levelset_convection_element_simplex.h:59
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: levelset_convection_element_simplex.h:336
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 3, 3 > &Ncontainer)
Definition: levelset_convection_element_simplex.h:394
std::string Info() const override
Turn back information as a string.
Definition: levelset_convection_element_simplex.h:329
LevelSetConvectionElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry)
Definition: levelset_convection_element_simplex.h:75
void Initialize(const ProcessInfo &rProcessInfo) override
Definition: levelset_convection_element_simplex.h:113
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 4, 4 > &Ncontainer)
Definition: levelset_convection_element_simplex.h:385
double ComputeH(BoundedMatrix< double, TNumNodes, TDim > &DN_DX, const double Volume)
Definition: levelset_convection_element_simplex.h:368
LevelSetConvectionElementSimplex(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Definition: levelset_convection_element_simplex.h:79
LevelSetConvectionElementSimplex()
Default constructor.
Definition: levelset_convection_element_simplex.h:72
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: levelset_convection_element_simplex.h:123
~LevelSetConvectionElementSimplex() override
Destructor.
Definition: levelset_convection_element_simplex.h:84
void GetDofList(DofsVectorType &ElementalDofList, const ProcessInfo &rCurrentProcessInfo) const override
Definition: levelset_convection_element_simplex.h:294
Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: levelset_convection_element_simplex.h:103
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(LevelSetConvectionElementSimplex)
Counted pointer of.
void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
Definition: levelset_convection_element_simplex.h:272
Element::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: levelset_convection_element_simplex.h:96
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: levelset_convection_element_simplex.h:263
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
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_SERIALIZE_SAVE_BASE_CLASS(Serializer, BaseType)
Definition: define.h:812
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_SERIALIZE_LOAD_BASE_CLASS(Serializer, BaseType)
Definition: define.h:815
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
AMatrix::VectorOuterProductExpression< TExpression1Type, TExpression2Type > outer_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:582
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
res
Definition: generate_convection_diffusion_explicit_element.py:211
v
Definition: generate_convection_diffusion_explicit_element.py:114
div_v
Definition: generate_convection_diffusion_explicit_element.py:150
tau
Definition: generate_convection_diffusion_explicit_element.py:115
phi_old
Definition: generate_convection_diffusion_explicit_element.py:103
h
Definition: generate_droplet_dynamics.py:91
int C
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:27
int tau_denom
Definition: generate_stokes_twofluid_element.py:162
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
float aux2
Definition: isotropic_damage_automatic_differentiation.py:240
phi
Definition: isotropic_damage_automatic_differentiation.py:168
float aux1
Definition: isotropic_damage_automatic_differentiation.py:239
def load(f)
Definition: ode_solve.py:307
int k
Definition: quadrature.py:595
float delta_t
Definition: rotatingcone_PureConvectionBenchmarking.py:129
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31