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.
linear_log_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 // Jordi Cotela
12 // Riccardo Rossi
13 //
14 
15 #pragma once
16 
17 // System includes
18 
19 
20 // External includes
21 
22 
23 // Project includes
24 #include "includes/cfd_variables.h"
25 #include "includes/condition.h"
26 #include "includes/define.h"
27 #include "includes/process_info.h"
28 
29 // Application includes
31 
32 
33 namespace Kratos
34 {
37 
40 
49 template<std::size_t TDim, std::size_t TNumNodes>
51 {
52 public:
55 
58 
59  static constexpr std::size_t BlockSize = TDim+1;
60 
61  static constexpr std::size_t LocalSize = TNumNodes*BlockSize;
62 
64 
66 
68 
70 
74 
76  LinearLogWallLaw() = delete;
77 
79  LinearLogWallLaw(LinearLogWallLaw const& rOther) = delete;
80 
82  ~LinearLogWallLaw() = default;
83 
88 
99  MatrixType& rLeftHandSideMatrix,
100  VectorType& rRightHandSideVector,
101  const Condition* pCondition,
102  const ProcessInfo& rCurrentProcessInfo)
103  {
104  // Create and fill the wall law auxiliar data container
105  WallLawDataContainer wall_law_data;
106  wall_law_data.Initialize(*pCondition);
107 
108  // Calculate the linear-log law contribution
109  // Note that we use a second order Gauss-Lobatto quadrature in this case in order to obtain a diagonal matrix contribution
110  // This is of special interest to ease convergence by avoiding the off-diagonal terms in presence of large friction velocity
111  const auto& r_geom = pCondition->GetGeometry();
112  const double w_gauss_lobatto = r_geom.DomainSize() / TNumNodes;
113  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
114  // Calculate current Gauss-Lobatto point (node) wall velocity norm
115  const auto& r_aux_v = wall_law_data.NodalWallVelocities[i_node];
116  const double wall_vel_norm = norm_2(r_aux_v);
117 
118  // Do nothing in case of zero wall velocity
119  if (wall_vel_norm > ZeroTol) {
120  // Calculate the friction (shear) velocity
121  const double u_tau = wall_law_data.CalculateFrictionVelocity(wall_vel_norm, wall_law_data.NodalYWallValues[i_node]);
122 
123  // Assembly the current contribution
124  const double tmp = w_gauss_lobatto * std::pow(u_tau,2) * wall_law_data.Density / wall_vel_norm;
125  for (IndexType d = 0; d < TDim; ++d) {
126  rRightHandSideVector(i_node*BlockSize + d) -= tmp * r_aux_v[d];
127  rLeftHandSideMatrix(i_node*BlockSize + d, i_node*BlockSize + d) += tmp;
128  }
129  }
130  }
131  }
132 
141  MatrixType& rLeftHandSideMatrix,
142  const Condition* pCondition,
143  const ProcessInfo& rCurrentProcessInfo)
144  {
145  // Create and fill the wall law auxiliar data container
146  WallLawDataContainer wall_law_data;
147  wall_law_data.Initialize(*pCondition);
148 
149  // Calculate the linear-log law contribution
150  // Note that we use a second order Gauss-Lobatto quadrature in this case in order to obtain a diagonal matrix contribution
151  // This is of special interest to ease convergence by avoiding the off-diagonal terms in presence of large friction velocity
152  const auto& r_geom = pCondition->GetGeometry();
153  const double w_gauss_lobatto = r_geom.DomainSize() / TNumNodes;
154  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
155  // Calculate current Gauss-Lobatto point (node) wall velocity norm
156  const auto& r_aux_v = wall_law_data.NodalWallVelocities[i_node];
157  const double wall_vel_norm = norm_2(r_aux_v);
158 
159  // Do nothing in case of zero wall velocity
160  if (wall_vel_norm > ZeroTol) {
161  // Calculate the friction (shear) velocity
162  const double u_tau = wall_law_data.CalculateFrictionVelocity(wall_vel_norm, wall_law_data.NodalYWallValues[i_node]);
163 
164  // Assembly the current contribution
165  const double tmp = w_gauss_lobatto * std::pow(u_tau,2) * wall_law_data.Density / wall_vel_norm;
166  for (IndexType d = 0; d < TDim; ++d) {
167  rLeftHandSideMatrix(i_node*BlockSize + d, i_node*BlockSize + d) += tmp;
168  }
169  }
170  }
171  }
172 
181  VectorType& rRightHandSideVector,
182  const Condition* pCondition,
183  const ProcessInfo& rCurrentProcessInfo)
184  {
185  // Create and fill the wall law auxiliar data container
186  WallLawDataContainer wall_law_data;
187  wall_law_data.Initialize(*pCondition);
188 
189  // Calculate the linear-log law contribution
190  // Note that we use a second order Gauss-Lobatto quadrature in this case in order to obtain a diagonal matrix contribution
191  // This is of special interest to ease convergence by avoiding the off-diagonal terms in presence of large friction velocity
192  const auto& r_geom = pCondition->GetGeometry();
193  const double w_gauss_lobatto = r_geom.DomainSize() / TNumNodes;
194  for (IndexType i_node = 0; i_node < TNumNodes; ++i_node) {
195  // Calculate current Gauss-Lobatto point (node) wall velocity norm
196  const auto& r_aux_v = wall_law_data.NodalWallVelocities[i_node];
197  const double wall_vel_norm = norm_2(r_aux_v);
198 
199  // Do nothing in case of zero wall velocity
200  if (wall_vel_norm > ZeroTol) {
201  // Calculate the friction (shear) velocity
202  const double u_tau = wall_law_data.CalculateFrictionVelocity(wall_vel_norm, wall_law_data.NodalYWallValues[i_node]);
203 
204  // Assembly the current contribution
205  const double tmp = w_gauss_lobatto * std::pow(u_tau,2) * wall_law_data.Density / wall_vel_norm;
206  for (IndexType d = 0; d < TDim; ++d) {
207  rRightHandSideVector(i_node*BlockSize + d) -= tmp * r_aux_v[d];
208  }
209  }
210  }
211  }
212 
220  static int Check(
221  const Condition* pCondition,
222  const ProcessInfo& rCurrentProcessInfo)
223  {
224  return 0;
225  }
226 
230 
231 
235 
236 
240 
242  std::string Info() const
243  {
244  std::stringstream buffer;
245  buffer << "LinearLogWallLaw";
246  return buffer.str();
247  }
248 
250  void PrintInfo(std::ostream& rOStream) const
251  {
252  rOStream << "LinearLogWallLaw";
253  }
254 
256  void PrintData(std::ostream& rOStream) const {}
257 
261 
262 
264 private:
267 
268  static constexpr double BPlus = 5.2; // Dimensionless velocity u+ constant
269  static constexpr double InvKappa = 1.0/0.41; // Inverse of Von Karman's kappa
270  static constexpr double YPlusLimit = 10.9931899; // Limit between linear and log regions
271  static constexpr double ZeroTol = 1.0e-12; // Auxiliary tolerance to check zero values
272 
275 
280  struct WallLawDataContainer
281  {
282  double Density;
283  double KinematicViscosity;
284  array_1d<double,TNumNodes> NodalYWallValues;
285  array_1d<array_1d<double,3>,TNumNodes> NodalWallVelocities;
286 
287  void Initialize(const Condition& rCondition)
288  {
289  // Get fluid parameters from parent element properties
290  // Note that this assumes constant viscosity within the element
291  const auto& r_parent_element = rCondition.GetValue(NEIGHBOUR_ELEMENTS)[0];
292  Density = r_parent_element.GetProperties().GetValue(DENSITY);
293  KinematicViscosity = r_parent_element.GetProperties().GetValue(DYNAMIC_VISCOSITY) / Density;
294 
295  // Save the nodal velocities and interpolate the slip length at current integration point
296  const auto& r_geom = rCondition.GetGeometry();
297  for (std::size_t i_node = 0; i_node < TNumNodes; ++i_node) {
298  const auto& r_node = r_geom[i_node];
299  const double aux_y_wall = r_node.GetValue(Y_WALL);
300  KRATOS_ERROR_IF(aux_y_wall < ZeroTol) << "Negative or zero 'Y_WALL' in condition " << rCondition.Id() << "." << std::endl;
301  NodalYWallValues[i_node] = aux_y_wall;
302  noalias(NodalWallVelocities[i_node]) = r_node.FastGetSolutionStepValue(VELOCITY) - r_node.FastGetSolutionStepValue(MESH_VELOCITY);
303  }
304  }
305 
306  double CalculateFrictionVelocity(
307  const double WallVelocityNorm,
308  const double YWall)
309  {
310  // If wall velocity is non-zero add the wall contribution
311  double u_tau = 0.0;
312  if (WallVelocityNorm > ZeroTol) {
313  // Linear region
314  u_tau = sqrt(WallVelocityNorm * KinematicViscosity / YWall); // Friction velocity (shear velocity)
315  double y_plus = YWall * u_tau / KinematicViscosity; // Wall coordinate
316 
317  // Log region (local Newton-Raphson iterative problem)
318  if (y_plus > YPlusLimit) {
319  // Initialize the iterative procedure
320  double dx = 1e10;
321  const double rel_tol = 1e-6;
322  const std::size_t max_it = 100;
323  double u_plus = InvKappa * log(y_plus) + BPlus; // Dimensionless velocity
324 
325  std::size_t it = 0;
326  while (it < 100 && std::abs(dx) > rel_tol * u_tau) {
327  // Newton-Raphson iteration
328  double f = u_tau * u_plus - WallVelocityNorm;
329  double df = u_plus + InvKappa;
330  dx = f/df;
331 
332  // Update variables
333  u_tau -= dx;
334  y_plus = YWall * u_tau / KinematicViscosity;
335  u_plus = InvKappa * log(y_plus) + BPlus;
336  ++it;
337  }
338  KRATOS_WARNING_IF("LinearLogWallLaw", it == max_it) << "Wall condition Newton-Raphson did not converge. Residual is " << dx << "." << std::endl;
339  }
340  }
341 
342  return u_tau;
343  }
344  };
345 
347 }; // Class LinearLogWallLaw
348 
352 
353 
357 
358 
361 
362 } // 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
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
virtual double DomainSize() const
This method calculate and return length, area or volume of this geometry depending to it's dimension.
Definition: geometry.h:1371
IndexType Id() const
Definition: indexed_object.h:107
Linear-log law LHS and RHS contribution implementation This class implements the LHS and RHS Gauss po...
Definition: linear_log_wall_law.h:51
static constexpr std::size_t BlockSize
Definition: linear_log_wall_law.h:59
LinearLogWallLaw(LinearLogWallLaw const &rOther)=delete
Copy constructor.
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 Gauss poin...
Definition: linear_log_wall_law.h:98
void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: linear_log_wall_law.h:250
static void AddWallModelRightHandSide(VectorType &rRightHandSideVector, const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Add the RHS Navier-slip contribution This method adds the Navier-slip RHS Gauss point contribution to...
Definition: linear_log_wall_law.h:180
KRATOS_CLASS_POINTER_DEFINITION(LinearLogWallLaw)
Pointer definition of LinearLogWallLaw.
Condition::SizeType SizeType
Definition: linear_log_wall_law.h:63
static int Check(const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Check function This function checks the current wall law input parameters.
Definition: linear_log_wall_law.h:220
LinearLogWallLaw()=delete
Default constructor.
~LinearLogWallLaw()=default
Destructor.
void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: linear_log_wall_law.h:256
static void AddWallModelLeftHandSide(MatrixType &rLeftHandSideMatrix, const Condition *pCondition, const ProcessInfo &rCurrentProcessInfo)
Add the LHS Navier-slip contribution This method adds the Navier-slip LHS Gauss point contribution to...
Definition: linear_log_wall_law.h:140
static constexpr std::size_t LocalSize
Definition: linear_log_wall_law.h:61
Condition::IndexType IndexType
Definition: linear_log_wall_law.h:65
std::string Info() const
Turn back information as a string.
Definition: linear_log_wall_law.h:242
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_WARNING_IF(label, conditional)
Definition: logger.h:266
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
f
Definition: generate_convection_diffusion_explicit_element.py:112
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
int d
Definition: ode_solve.py:397
e
Definition: run_cpp_mpi_tests.py:31