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.
eulerian_diff.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 // Ruben Zorrilla
11 //
12 
13 #if !defined(KRATOS_EULERIAN_DIFFUSION_ELEMENT_INCLUDED )
14 #define KRATOS_EULERIAN_DIFFUSION_ELEMENT_INCLUDED
15 
16 
17 // System includes
18 
19 
20 // External includes
21 
22 
23 // Project includes
24 #include "includes/define.h"
25 #include "includes/element.h"
27 #include "includes/variables.h"
28 #include "includes/cfd_variables.h"
29 #include "includes/serializer.h"
32 #include "utilities/math_utils.h"
33 #include "utilities/geometry_utilities.h"
34 
35 
36 
37 namespace Kratos
38 {
39 
42 
46 
50 
54 
58 
60 template< unsigned int TDim, unsigned int TNumNodes>
62  : public Element
63 {
64 public:
67 
70 
74 
76 
77  EulerianDiffusionElement(IndexType NewId, GeometryType::Pointer pGeometry)
78  : Element(NewId, pGeometry)
79  {}
80 
81  EulerianDiffusionElement(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
82  : Element(NewId, pGeometry, pProperties)
83  {}
84 
87 
88 
92 
93 
97 
98  Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer pProperties) const override
99  {
100  return Kratos::make_intrusive<EulerianDiffusionElement>(NewId, GetGeometry().Create(ThisNodes), pProperties);
101  }
102 
103  Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
104  {
105  return Kratos::make_intrusive<EulerianDiffusionElement>(NewId, pGeom, pProperties);
106  }
107 
108 
110  MatrixType& rLeftHandSideMatrix,
111  VectorType& rRightHandSideVector,
112  const ProcessInfo& rCurrentProcessInfo) override
113  {
114  KRATOS_TRY
115 
116  if (rLeftHandSideMatrix.size1() != TNumNodes)
117  rLeftHandSideMatrix.resize(TNumNodes, TNumNodes, false); //false says not to preserve existing storage!!
118 
119  if (rRightHandSideVector.size() != TNumNodes)
120  rRightHandSideVector.resize(TNumNodes, false); //false says not to preserve existing storage!!
121 
122 
123 // noalias(rLeftHandSideMatrix) = ZeroMatrix(TNumNodes, TNumNodes);
124 // noalias(rRightHandSideVector) = ZeroVector(TNumNodes);
125 
126 // //Crank-Nicholson factor
127 // const double cr_nk = 0.5;
128 
129  const double delta_t = rCurrentProcessInfo[DELTA_TIME];
130  const double dt_inv = 1.0 / delta_t;
131  const double lumping_factor = 1.00 / double(TNumNodes);
132 
133  ConvectionDiffusionSettings::Pointer my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
134  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
135 
136  //getting data for the given geometry
139  double Volume;
141 
142  //here we get all the variables we will need
143  array_1d<double,TNumNodes> phi, phi_old, phi_convected;
144  //bool active_convection=false; // to kill some terms in case active_convection=false. For the moment it is inactive.
145  //using only one Gauss Point for the material properties and volumetric heat flux
146  double conductivity = 0.0;
147  double specific_heat = 0.0;
148  double density = 0.0;
149 
150  //storing locally the flags to avoid repeated check in the nodal loops
151  const bool IsDefinedDensityVariable = my_settings->IsDefinedDensityVariable();
152  const bool IsDefinedSpecificHeatVariableVariable = my_settings->IsDefinedSpecificHeatVariable();
153  const bool IsDefinedDiffusionVariable = my_settings->IsDefinedDiffusionVariable();
154  const bool IsDefinedProjectionVariable = my_settings->IsDefinedProjectionVariable();
155 
156  //if it is a convection diffusion problem, then the projection variable will exist and therefore we must use it instead of unknownVar(timestep n)
157  //that is, to take the convection into account.
158 
159  for (unsigned int i = 0; i < TNumNodes; i++)
160  {
161  phi[i] = GetGeometry()[i].FastGetSolutionStepValue(rUnknownVar);
162  phi_old[i] = GetGeometry()[i].FastGetSolutionStepValue(rUnknownVar,1);
163  if (IsDefinedProjectionVariable)
164  phi_convected[i] = GetGeometry()[i].FastGetSolutionStepValue((my_settings->GetProjectionVariable()),0);
165  else
166  phi_convected[i] = phi_old[i];
167 
168 
169 // dphi_dt[i] = dt_inv*(phi[i] - phi_old [i];
170 
171  if (IsDefinedDensityVariable)
172  {
173  const Variable<double>& rDensityVar = my_settings->GetDensityVariable();
174  density += GetGeometry()[i].FastGetSolutionStepValue(rDensityVar);
175  }
176  else
177  density += 1.0;
178 
179  if (IsDefinedSpecificHeatVariableVariable)
180  {
181  const Variable<double>& rSpecificHeatVar = my_settings->GetSpecificHeatVariable();
182  specific_heat += GetGeometry()[i].FastGetSolutionStepValue(rSpecificHeatVar);
183  }
184  else
185  specific_heat += 1.0;
186 
187  if (IsDefinedDiffusionVariable)
188  {
189  const Variable<double>& rDiffusionVar = my_settings->GetDiffusionVariable();
190  conductivity += GetGeometry()[i].FastGetSolutionStepValue(rDiffusionVar);
191  }
192  //if not, then the conductivity = 0
193  }
194 
195  conductivity *= lumping_factor;
196  density *= lumping_factor;
197  specific_heat *= lumping_factor;
198  //heat_flux *= lumping_factor;
199 
200  BoundedMatrix<double,TNumNodes, TNumNodes> aux1 = ZeroMatrix(TNumNodes, TNumNodes); //terms multiplying dphi/dt
201 
203  GetShapeFunctionsOnGauss(Ncontainer);
204  for(unsigned int igauss=0; igauss<TDim+1; igauss++)
205  {
206  noalias(N) = row(Ncontainer,igauss);
207  noalias(aux1) += outer_prod(N, N);
208  }
209 
210  //mass matrix
211  noalias(rLeftHandSideMatrix) = (dt_inv*density*specific_heat)*aux1;
212  noalias(rRightHandSideVector) = (dt_inv*density*specific_heat)*prod(aux1,phi_convected);
213  //adding the diffusion
214  noalias(rLeftHandSideMatrix) += (conductivity *0.5 * prod(DN_DX, trans(DN_DX)))*static_cast<double>(TNumNodes);
215  noalias(rRightHandSideVector) -= prod((conductivity *0.5 * prod(DN_DX, trans(DN_DX))),phi_convected)*static_cast<double>(TNumNodes) ;
216 
217 
218 
219  //take out the dirichlet part to finish computing the residual
220  noalias(rRightHandSideVector) -= prod(rLeftHandSideMatrix, phi);
221 
222  rRightHandSideVector *= Volume/static_cast<double>(TNumNodes);
223  rLeftHandSideMatrix *= Volume/static_cast<double>(TNumNodes);
224 
225  KRATOS_CATCH("Error in Eulerian ConvDiff Element")
226  }
227 
229  VectorType& rRightHandSideVector,
230  const ProcessInfo& rCurrentProcessInfo) override
231  {
232  KRATOS_TRY
233 
234  if (rRightHandSideVector.size() != TNumNodes) {
235  rRightHandSideVector.resize(TNumNodes, false); // False says not to preserve existing storage!!
236  }
237 
238  ConvectionDiffusionSettings::Pointer p_my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
239  const auto& r_unknown_var = p_my_settings->GetUnknownVariable();
240 
241  // Getting data for the given geometry
242  double volume;
246 
247  // Here we get all the variables we will need
248  // Using only one Gauss Point for the material properties and volumetric heat flux
249  double density = 0.0;
250  double conductivity = 0.0;
251  double specific_heat = 0.0;
252  array_1d<double,TNumNodes> phi, phi_old, phi_convected;
253 
254  // Storing locally the flags to avoid repeated check in the nodal loops
255  const bool is_defined_density_variable = p_my_settings->IsDefinedDensityVariable();
256  const bool is_defined_specific_heat_variable = p_my_settings->IsDefinedSpecificHeatVariable();
257  const bool is_defined_diffusion_variable = p_my_settings->IsDefinedDiffusionVariable();
258  const bool is_defined_projection_variable = p_my_settings->IsDefinedProjectionVariable();
259 
260  // Get nodal data
261  const auto& r_geom = GetGeometry();
262  for (unsigned int i = 0; i < TNumNodes; i++) {
263  const auto& r_node = r_geom[i];
264  phi[i] = r_node.FastGetSolutionStepValue(r_unknown_var);
265 
266  // If it is a convection diffusion problem, then the projection variable will exist and
267  // Therefore we must use it instead of UnknownVariable(timestep n), that is, to take the convection into account.
268  if (is_defined_projection_variable) {
269  const auto& r_projection_var = p_my_settings->GetProjectionVariable();
270  phi_convected[i] = r_node.FastGetSolutionStepValue(r_projection_var);
271  } else {
272  phi_old[i] = r_node.FastGetSolutionStepValue(r_unknown_var,1);
273  phi_convected[i] = phi_old[i];
274  }
275 
276  if (is_defined_density_variable) {
277  const auto& r_density_var = p_my_settings->GetDensityVariable();
278  density += r_node.FastGetSolutionStepValue(r_density_var);
279  } else {
280  density += 1.0;
281  }
282 
283  if (is_defined_specific_heat_variable) {
284  const auto& r_specific_heat_var = p_my_settings->GetSpecificHeatVariable();
285  specific_heat += r_node.FastGetSolutionStepValue(r_specific_heat_var);
286  } else {
287  specific_heat += 1.0;
288  }
289 
290  if (is_defined_diffusion_variable) {
291  const auto& r_diffusion_var = p_my_settings->GetDiffusionVariable();
292  conductivity += r_node.FastGetSolutionStepValue(r_diffusion_var);
293  } // If not, the conductivity is 0
294  }
295 
296  const double lumping_factor = 1.0 / static_cast<double>(TNumNodes);
297  density *= lumping_factor;
298  conductivity *= lumping_factor;
299  specific_heat *= lumping_factor;
300 
301  BoundedMatrix<double, TNumNodes, TNumNodes> aux_NxN = ZeroMatrix(TNumNodes, TNumNodes); // Terms multiplying dphi/dt
303  GetShapeFunctionsOnGauss(N_container);
304  for(unsigned int i_gauss=0; i_gauss < TDim+1; ++i_gauss){
305  noalias(N) = row(N_container, i_gauss);
306  noalias(aux_NxN) += outer_prod(N, N);
307  }
308 
309  const double dt_inv = 1.0 / rCurrentProcessInfo[DELTA_TIME];
310 
311  // Mass matrix
312  const double aux_1 = dt_inv * density * specific_heat * volume / static_cast<double>(TNumNodes);
313  noalias(rRightHandSideVector) = aux_1 * prod(aux_NxN, phi_convected - phi);
314  // Adding the diffusion
315  // Note 1: the diffusive term is computed using a Crank-Nicholson scheme
316  // Note 2: the gradients already include the corresponding Gauss point weight (no need to divide by TNumNodes)
317  const double aux_2 = conductivity * 0.5 * volume;
318  noalias(rRightHandSideVector) -= aux_2 * prod(prod(DN_DX, trans(DN_DX)), phi_convected + phi);
319 
320  KRATOS_CATCH("Error in Eulerian diffusion element CalculateRightHandSide")
321  }
322 
324  EquationIdVectorType& rResult,
325  const ProcessInfo& rCurrentProcessInfo) const override
326  {
327  KRATOS_TRY
328 
329  ConvectionDiffusionSettings::Pointer my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
330  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
331 
332  if (rResult.size() != TNumNodes)
333  rResult.resize(TNumNodes, false);
334 
335  for (unsigned int i = 0; i < TNumNodes; i++)
336  {
337  rResult[i] = GetGeometry()[i].GetDof(rUnknownVar).EquationId();
338  }
339  KRATOS_CATCH("")
340 
341  }
342 
344  DofsVectorType& ElementalDofList,
345  const ProcessInfo& rCurrentProcessInfo) const override
346  {
347  KRATOS_TRY
348 
349  ConvectionDiffusionSettings::Pointer my_settings = rCurrentProcessInfo.GetValue(CONVECTION_DIFFUSION_SETTINGS);
350  const Variable<double>& rUnknownVar = my_settings->GetUnknownVariable();
351 
352  if (ElementalDofList.size() != TNumNodes)
353  ElementalDofList.resize(TNumNodes);
354 
355  for (unsigned int i = 0; i < TNumNodes; i++)
356  {
357  ElementalDofList[i] = GetGeometry()[i].pGetDof(rUnknownVar);
358 
359  }
360  KRATOS_CATCH("");
361  }
362 
363 
367 
368 
372 
373 
377 
379 
380  std::string Info() const override
381  {
382  return "LevelSetConvectionElementSimplex #";
383  }
384 
386 
387  void PrintInfo(std::ostream& rOStream) const override
388  {
389  rOStream << Info() << Id();
390  }
391 
393  // virtual void PrintData(std::ostream& rOStream) const;
394 
395 
399 
400 
402 
403 protected:
406 
407 
411 
415 
417  {
418  }
419 
423 
424  //gauss points for the 3D case
426  {
427  Ncontainer(0,0) = 0.58541020; Ncontainer(0,1) = 0.13819660; Ncontainer(0,2) = 0.13819660; Ncontainer(0,3) = 0.13819660;
428  Ncontainer(1,0) = 0.13819660; Ncontainer(1,1) = 0.58541020; Ncontainer(1,2) = 0.13819660; Ncontainer(1,3) = 0.13819660;
429  Ncontainer(2,0) = 0.13819660; Ncontainer(2,1) = 0.13819660; Ncontainer(2,2) = 0.58541020; Ncontainer(2,3) = 0.13819660;
430  Ncontainer(3,0) = 0.13819660; Ncontainer(3,1) = 0.13819660; Ncontainer(3,2) = 0.13819660; Ncontainer(3,3) = 0.58541020;
431  }
432 
433  //gauss points for the 2D case
435  {
436  const double one_sixt = 1.0/6.0;
437  const double two_third = 2.0/3.0;
438  Ncontainer(0,0) = one_sixt; Ncontainer(0,1) = one_sixt; Ncontainer(0,2) = two_third;
439  Ncontainer(1,0) = one_sixt; Ncontainer(1,1) = two_third; Ncontainer(1,2) = one_sixt;
440  Ncontainer(2,0) = two_third; Ncontainer(2,1) = one_sixt; Ncontainer(2,2) = one_sixt;
441  }
442 
443 
444 
448 
449 
453 
454 
458 
459 
461 
462 
463 
464 
465 private:
468 
472 
476  friend class Serializer;
477  // ASGS2D() : Element()
478  // {
479  // }
480 
481  void save(Serializer& rSerializer) const override
482  {
484  }
485 
486  void load(Serializer& rSerializer) override
487  {
489  }
490 
492 
495 
496 
500 
501 
505 
506 
510 
511 
512 
513 
514 
516 
517 };
518 
520 
523 
524 
528 
529 
531 /* inline std::istream& operator >> (std::istream& rIStream,
532  Fluid2DASGS& rThis);
533  */
535 /* inline std::ostream& operator << (std::ostream& rOStream,
536  const Fluid2DASGS& rThis)
537  {
538  rThis.PrintInfo(rOStream);
539  rOStream << std::endl;
540  rThis.PrintData(rOStream);
541 
542  return rOStream;
543  }*/
545 
546 } // namespace Kratos.
547 
548 #endif // KRATOS_EULERIAN_CONVECTION_DIFFUSION_ELEMENT_INCLUDED defined
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
formulation described in https://docs.google.com/document/d/13a_zGLj6xORDuLgoOG5LwHI6BwShvfO166opZ815...
Definition: eulerian_diff.h:63
virtual ~EulerianDiffusionElement()
Destructor.
Definition: eulerian_diff.h:86
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: eulerian_diff.h:387
std::string Info() const override
Turn back information as a string.
Definition: eulerian_diff.h:380
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 4, 4 > &Ncontainer)
Definition: eulerian_diff.h:425
EulerianDiffusionElement(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Definition: eulerian_diff.h:81
Element::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: eulerian_diff.h:98
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 3, 3 > &Ncontainer)
Definition: eulerian_diff.h:434
void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
Definition: eulerian_diff.h:323
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: eulerian_diff.h:228
void GetDofList(DofsVectorType &ElementalDofList, const ProcessInfo &rCurrentProcessInfo) const override
Definition: eulerian_diff.h:343
Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: eulerian_diff.h:103
EulerianDiffusionElement(IndexType NewId, GeometryType::Pointer pGeometry)
Default constructor.
Definition: eulerian_diff.h:77
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(EulerianDiffusionElement)
Counted pointer of.
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: eulerian_diff.h:109
EulerianDiffusionElement()
Definition: eulerian_diff.h:416
std::size_t IndexType
Definition: flags.h:74
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
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
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_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
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
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
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
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
float specific_heat
Definition: face_heat.py:57
float conductivity
Definition: face_heat.py:55
float density
Definition: face_heat.py:56
phi_old
Definition: generate_convection_diffusion_explicit_element.py:103
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
float delta_t
Definition: rotatingcone_PureConvectionBenchmarking.py:129
N
Definition: sensitivityMatrix.py:29
volume
Definition: sp_statistics.py:15
integer i
Definition: TensorModule.f:17