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.
navier_slip_wall_law.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: Ruben Zorrilla
11 //
12 
13 #pragma once
14 
15 // System includes
16 
17 
18 // External includes
19 
20 
21 // Project includes
22 #include "includes/cfd_variables.h"
23 #include "includes/condition.h"
24 #include "includes/define.h"
25 #include "includes/process_info.h"
26 
27 // Application includes
29 
30 
31 namespace Kratos
32 {
35 
38 
42 
46 
50 
54 
64 template<std::size_t TDim, std::size_t TNumNodes>
66 {
67 public:
70 
73 
74  static constexpr std::size_t BlockSize = TDim+1;
75 
76  static constexpr std::size_t LocalSize = TNumNodes*BlockSize;
77 
79 
81 
83 
85 
89 
91  NavierSlipWallLaw() = delete;
92 
94  NavierSlipWallLaw(NavierSlipWallLaw const& rOther) = delete;
95 
97  ~NavierSlipWallLaw() = default;
98 
102 
103 
107 
117  MatrixType& rLeftHandSideMatrix,
118  VectorType& rRightHandSideVector,
119  const Condition* pCondition,
120  const ProcessInfo& rCurrentProcessInfo)
121  {
122  // Create and fill the wall law auxiliar data container
123  WallLawDataContainer wall_law_data;
124  wall_law_data.Initialize(*pCondition);
125 
126  // Set the tangential projection matrix
127  BoundedMatrix<double,TDim,TDim> tang_proj_mat;
128  SetTangentialProjectionMatrix(wall_law_data.Normal, tang_proj_mat);
129 
130  // Calculate the Navier-slip contribution
131  const SizeType n_gauss = wall_law_data.GaussPtsWeights.size();
132  for (IndexType i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
133  // Get current Gauss point data
134  const double w_gauss = wall_law_data.GaussPtsWeights[i_gauss];
135  const auto& N_gauss = row(wall_law_data.ShapeFunctionsContainer, i_gauss);
136 
137  // Interpolate slip length at current Gauss point
138  double gp_slip_length = 0.0;
139  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
140  gp_slip_length += N_gauss[i_node] * wall_law_data.NodalSlipLength[i_node];
141  }
142 
143  // Assemble RHS and LHS contributions
144  const double aux_val = w_gauss * wall_law_data.DynamicViscosity / gp_slip_length;
145  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
146  for (IndexType j_node = 0; j_node < TNumNodes; ++j_node) {
147  const auto& r_v_j = wall_law_data.NodalWallVelocities[j_node];
148  for (IndexType d1 = 0; d1 < TDim; ++d1) {
149  for (IndexType d2 = 0; d2 < TDim; ++d2) {
150  rRightHandSideVector[i_node*BlockSize + d2] += aux_val * N_gauss[i_node] * N_gauss[j_node] * tang_proj_mat(d1,d2) * r_v_j[d1];
151  rLeftHandSideMatrix(i_node*BlockSize + d1, j_node*BlockSize + d2) -= aux_val * N_gauss[i_node] * N_gauss[j_node] * tang_proj_mat(d1,d2);
152  }
153  }
154  }
155  }
156  }
157  }
158 
167  MatrixType& rLeftHandSideMatrix,
168  const Condition* pCondition,
169  const ProcessInfo& rCurrentProcessInfo)
170  {
171  // Create and fill the wall law auxiliar data container
172  WallLawDataContainer wall_law_data;
173  wall_law_data.Initialize(*pCondition);
174 
175  // Set the tangential projection matrix
176  BoundedMatrix<double,TDim,TDim> tang_proj_mat;
177  SetTangentialProjectionMatrix(wall_law_data.Normal, tang_proj_mat);
178 
179  // Calculate the Navier-slip contribution
180  const SizeType n_gauss = wall_law_data.GaussPtsWeights.size();
181  for (IndexType i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
182  // Get current Gauss point data
183  const double w_gauss = wall_law_data.GaussPtsWeights[i_gauss];
184  const auto& N_gauss = row(wall_law_data.ShapeFunctionsContainer, i_gauss);
185 
186  // Interpolate slip length at current Gauss point
187  double gp_slip_length = 0.0;
188  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
189  gp_slip_length += N_gauss[i_node] * wall_law_data.NodalSlipLength[i_node];
190  }
191 
192  // Assemble RHS and LHS contributions
193  const double aux_val = w_gauss * wall_law_data.DynamicViscosity / gp_slip_length;
194  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
195  for (IndexType j_node = 0; j_node < TNumNodes; ++j_node) {
196  for (IndexType d1 = 0; d1 < TDim; ++d1) {
197  for (IndexType d2 = 0; d2 < TDim; ++d2) {
198  rLeftHandSideMatrix(i_node*BlockSize + d1, j_node*BlockSize + d2) -= aux_val * N_gauss[i_node] * N_gauss[j_node] * tang_proj_mat(d1,d2);
199  }
200  }
201  }
202  }
203  }
204  }
205 
214  VectorType& rRightHandSideVector,
215  const Condition* pCondition,
216  const ProcessInfo& rCurrentProcessInfo)
217  {
218  // Create and fill the wall law auxiliar data container
219  WallLawDataContainer wall_law_data;
220  wall_law_data.Initialize(*pCondition);
221 
222  // Set the tangential projection matrix
223  BoundedMatrix<double,TDim,TDim> tang_proj_mat;
224  SetTangentialProjectionMatrix(wall_law_data.Normal, tang_proj_mat);
225 
226  // Calculate the Navier-slip contribution
227  const SizeType n_gauss = wall_law_data.GaussPtsWeights.size();
228  for (IndexType i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
229  // Get current Gauss point data
230  const double w_gauss = wall_law_data.GaussPtsWeights[i_gauss];
231  const auto& N_gauss = row(wall_law_data.ShapeFunctionsContainer, i_gauss);
232 
233  // Interpolate slip length at current Gauss point
234  double gp_slip_length = 0.0;
235  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
236  gp_slip_length += N_gauss[i_node] * wall_law_data.NodalSlipLength[i_node];
237  }
238 
239  // Assemble RHS and LHS contributions
240  const double aux_val = w_gauss * wall_law_data.DynamicViscosity / gp_slip_length;
241  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
242  for (IndexType j_node = 0; j_node < TNumNodes; ++j_node) {
243  const auto& r_v_j = wall_law_data.NodalWallVelocities[j_node];
244  for (IndexType d1 = 0; d1 < TDim; ++d1) {
245  for (IndexType d2 = 0; d2 < TDim; ++d2) {
246  rRightHandSideVector[i_node*BlockSize + d2] += aux_val * N_gauss[i_node] * N_gauss[j_node] * tang_proj_mat(d1,d2) * r_v_j[d1];
247  }
248  }
249  }
250  }
251  }
252  }
253 
261  static int Check(
262  const Condition* pCondition,
263  const ProcessInfo& rCurrentProcessInfo)
264  {
265  return 0;
266  }
267 
271 
272 
276 
277 
281 
283  std::string Info() const
284  {
285  std::stringstream buffer;
286  buffer << "NavierSlipWallLaw";
287  return buffer.str();
288  }
289 
291  void PrintInfo(std::ostream& rOStream) const
292  {
293  rOStream << "NavierSlipWallLaw";
294  }
295 
297  void PrintData(std::ostream& rOStream) const {}
298 
302 
303 
305 private:
308 
313  struct WallLawDataContainer
314  {
315  double DynamicViscosity;
316  array_1d<double,3> Normal;
317  Vector GaussPtsWeights;
318  Matrix ShapeFunctionsContainer;
319  array_1d<double, TNumNodes> NodalSlipLength;
320  array_1d<array_1d<double,3>,TNumNodes> NodalWallVelocities;
321 
322  void Initialize(const Condition& rCondition)
323  {
324  // Get dynamic viscosity from parent element properties
325  // Note that this assumes constant viscosity within the element
326  const auto& r_parent_element = rCondition.GetValue(NEIGHBOUR_ELEMENTS)[0];
327  DynamicViscosity = r_parent_element.GetProperties().GetValue(DYNAMIC_VISCOSITY);
328 
329  // Compute condition unit normal vector
330  // Note that in here we are assuming a constant normal over the entire condition
331  const auto& r_geom = rCondition.GetGeometry();
332  Normal = r_geom.UnitNormal(0, GeometryData::IntegrationMethod::GI_GAUSS_1);
333 
334  // Calculate the required Gauss points integration data
335  const auto& r_integration_pts = r_geom.IntegrationPoints(GeometryData::IntegrationMethod::GI_GAUSS_2);
336  const SizeType n_gauss = r_integration_pts.size();
337  r_geom.DeterminantOfJacobian(GaussPtsWeights, GeometryData::IntegrationMethod::GI_GAUSS_2);
338  for (IndexType i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
339  GaussPtsWeights[i_gauss] = GaussPtsWeights[i_gauss] * r_integration_pts[i_gauss].Weight();
340  }
341  ShapeFunctionsContainer = r_geom.ShapeFunctionsValues(GeometryData::IntegrationMethod::GI_GAUSS_2);
342 
343  // Save the nodal velocities and interpolate the slip length at current integration point
344  for (std::size_t i_node = 0; i_node < TNumNodes; ++i_node) {
345  const auto& r_node = r_geom[i_node];
346  const double aux_slip_length = r_node.GetValue(SLIP_LENGTH);
347  KRATOS_ERROR_IF(aux_slip_length < 1.0e-12) << "Negative or zero 'SLIP_LENGTH' at node " << r_node.Id() << "." << std::endl;
348  NodalSlipLength[i_node] = aux_slip_length;
349  noalias(NodalWallVelocities[i_node]) = r_node.FastGetSolutionStepValue(VELOCITY) - r_node.FastGetSolutionStepValue(MESH_VELOCITY);
350  }
351  }
352  };
353 
354  //TODO: Remove this by a common implementation (FluidElementUtilities cannot be used yet)
355  static void SetTangentialProjectionMatrix(
356  const array_1d<double,3>& rUnitNormal,
357  BoundedMatrix<double,TDim,TDim>& rTangProjMat)
358  {
359  noalias(rTangProjMat) = IdentityMatrix(TDim,TDim);
360  for (std::size_t d1 = 0; d1 < TDim; ++d1) {
361  for (std::size_t d2 = 0; d2 < TDim; ++d2) {
362  rTangProjMat(d1,d2) -= rUnitNormal[d1]*rUnitNormal[d2];
363  }
364  }
365  }
366 
368 }; // Class NavierSlipWallLaw
369 
373 
374 
378 
379 
382 
383 } // namespace Kratos.
Base class for all Conditions.
Definition: condition.h:59
std::size_t SizeType
Definition: condition.h:94
std::size_t IndexType
Definition: condition.h:92
Matrix MatrixType
Definition: condition.h:90
Vector VectorType
Definition: condition.h:88
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometrical_object.h:248
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
Navier-slip law LHS and RHS contribution implementation This class implements the LHS and RHS contrib...
Definition: navier_slip_wall_law.h:66
Condition::IndexType IndexType
Definition: navier_slip_wall_law.h:80
static constexpr std::size_t BlockSize
Definition: navier_slip_wall_law.h:74
KRATOS_CLASS_POINTER_DEFINITION(NavierSlipWallLaw)
Pointer definition of NavierSlipWallLaw.
NavierSlipWallLaw()=delete
Default constructor.
Condition::SizeType SizeType
Definition: navier_slip_wall_law.h:78
static void AddWallModelRightHandSide(VectorType &rRightHandSideVector, const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Add the RHS Navier-slip contribution This method adds the Navier-slip RHS contribution to the provide...
Definition: navier_slip_wall_law.h:213
static void AddWallModelLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Add the LHS and RHS Navier-slip contributions This method adds the Navier-slip LHS and RHS contributi...
Definition: navier_slip_wall_law.h:116
std::string Info() const
Turn back information as a string.
Definition: navier_slip_wall_law.h:283
static void AddWallModelLeftHandSide(MatrixType &rLeftHandSideMatrix, const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Add the LHS Navier-slip contribution This method adds the Navier-slip LHS contribution to the provide...
Definition: navier_slip_wall_law.h:166
~NavierSlipWallLaw()=default
Destructor.
void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: navier_slip_wall_law.h:291
void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: navier_slip_wall_law.h:297
NavierSlipWallLaw(NavierSlipWallLaw const &rOther)=delete
Copy constructor.
static int Check(const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Check function This function checks the current wall law input parameters.
Definition: navier_slip_wall_law.h:261
static constexpr std::size_t LocalSize
Definition: navier_slip_wall_law.h:76
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
BOOST_UBLAS_INLINE size_type size() const
Definition: array_1d.h:370
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
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
w_gauss
Definition: generate_convection_diffusion_explicit_element.py:136
subroutine d1(DSTRAN, D, dtime, NDI, NSHR, NTENS)
Definition: TensorModule.f:594