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.
embedded_ausas_navier_stokes.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 #if !defined(KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES)
14 #define KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES
15 
16 // System includes
17 
18 // External includes
19 
20 // Project includes
21 #include "includes/element.h"
22 #include "includes/kratos_flags.h"
23 #include "includes/cfd_variables.h"
24 #include "utilities/geometry_utilities.h"
27 
28 // Application includes
30 
31 namespace Kratos
32 {
33 
36 
40 
44 
48 
52 
53 // TODO: UPDATE THIS INFORMATION
60 template< unsigned int TDim, unsigned int TNumNodes = TDim + 1 >
62 {
63 public:
66 
67  typedef GeometryType::Pointer GeometryPointerType;
68 
70 
72 
75 
77 
80 
81  array_1d<double, TNumNodes> N; // Shape functions values on Gauss pt. container
82  BoundedMatrix<double, TNumNodes, TDim> DN_DX; // Shape functions gradients values on Gauss pt. container
83 
84  Matrix C; // Matrix to store the constitutive matrix in Voigt notation
85  Vector stress; // Vector to store the stress values in Voigt notation
86  Vector strain; // Vector to store the stain values in Voigt notation
87 
88  double bdf0; // BDF2 scheme coefficient 0
89  double bdf1; // BDF2 scheme coefficient 1
90  double bdf2; // BDF2 scheme coefficient 2
91  double c; // Wave velocity (needed if artificial compressibility is considered)
92  double h; // Element size
93  double volume; // In 2D: element area. In 3D: element volume
94  double dt; // Time increment
95  double dyn_tau; // Dynamic tau considered in ASGS stabilization coefficients
96  double mu; // Dynamic viscosity
97  double rho; // Density
98 
99  // No splitted elements geometry data containers
100  VectorType w_gauss; // No splitted element Gauss pts. weights values
101  MatrixType N_gauss; // No splitted element shape function values on Gauss pts.
102  ShapeFunctionsGradientsType DN_DX_gauss; // No splitted element shape function gradients values on Gauss pts.
103 
104  // Splitted element geometry data containers
105  // Positive side geometry data
106  MatrixType N_pos_side; // Positive distance element side shape functions values
107  ShapeFunctionsGradientsType DN_DX_pos_side; // Positive distance element side shape functions gradients values
108  VectorType w_gauss_pos_side; // Positive distance element side Gauss pts. weights
109 
110  // Negative side geometry data
111  MatrixType N_neg_side; // Negative distance element side shape functions values
112  ShapeFunctionsGradientsType DN_DX_neg_side; // Negative distance element side shape functions gradients values
113  VectorType w_gauss_neg_side; // Negative distance element side Gauss pts. weights
114 
115  // Positive interface geometry data
116  MatrixType N_pos_int; // Positive interface Gauss pts. shape functions values
117  ShapeFunctionsGradientsType DN_DX_pos_int; // Positive interface Gauss pts. shape functions gradients values
118  VectorType w_gauss_pos_int; // Positive interface Gauss pts. weights
119  std::vector<array_1d<double,3>> pos_int_unit_normals; // Positive interface unit normal vector in each Gauss pt.
120 
121  // Negative interface geometry data
122  MatrixType N_neg_int; // Positive interface Gauss pts. shape functions values
123  ShapeFunctionsGradientsType DN_DX_neg_int; // Positive interface Gauss pts. shape functions gradients values
124  VectorType w_gauss_neg_int; // Positive interface Gauss pts. weights
125  std::vector<array_1d<double,3>> neg_int_unit_normals; // Positive interface unit normal vector in each Gauss pt.
126 
127  std::vector<unsigned int> int_vec_identifiers; // Interior (fluid) nodes identifiers
128  std::vector<unsigned int> out_vec_identifiers; // Outside (stucture) nodes identifiers
129 
130  unsigned int n_pos = 0; // Number of postivie distance nodes
131  unsigned int n_neg = 0; // Number of negative distance nodes
132 
133  };
134 
138 
140 
141  EmbeddedAusasNavierStokes(IndexType NewId, GeometryType::Pointer pGeometry)
142  : Element(NewId, pGeometry)
143  {}
144 
145  EmbeddedAusasNavierStokes(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
146  : Element(NewId, pGeometry, pProperties)
147  {}
148 
151 
152 
156 
157 
161 
162  Element::Pointer Create(IndexType NewId, NodesArrayType const& rThisNodes, PropertiesType::Pointer pProperties) const override {
163  KRATOS_TRY
164  return Kratos::make_intrusive< EmbeddedAusasNavierStokes < TDim, TNumNodes > >(NewId, this->GetGeometry().Create(rThisNodes), pProperties);
165  KRATOS_CATCH("");
166  }
167 
168  Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override {
169  KRATOS_TRY
170  return Kratos::make_intrusive< EmbeddedAusasNavierStokes < TDim, TNumNodes > >(NewId, pGeom, pProperties);
171  KRATOS_CATCH("");
172  }
173 
174 
176  MatrixType& rLeftHandSideMatrix,
177  VectorType& rRightHandSideVector,
178  const ProcessInfo& rCurrentProcessInfo) override {
179 
180  KRATOS_TRY;
181 
182  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
183 
184  if (rLeftHandSideMatrix.size1() != MatrixSize) {
185  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false);
186  } else if (rLeftHandSideMatrix.size2() != MatrixSize) {
187  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false);
188  }
189 
190  if (rRightHandSideVector.size() != MatrixSize) {
191  rRightHandSideVector.resize(MatrixSize, false);
192  }
193 
194  // Initialize LHS and RHS
195  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
196  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize,MatrixSize);
197 
198  // Decides if the element is split and fills data structure accordingly
200  this->FillEmbeddedAusasElementData(data, rCurrentProcessInfo);
201 
202  // Element LHS and RHS contributions computation
203  CalculateLocalSystemContribution(rLeftHandSideMatrix, rRightHandSideVector, data, rCurrentProcessInfo);
204 
205  KRATOS_CATCH("Error in embedded Ausas Navier-Stokes element CalculateLocalSystem!")
206 
207  }
208 
210  VectorType& rRightHandSideVector,
211  const ProcessInfo& rCurrentProcessInfo) override {
212 
213  KRATOS_TRY;
214 
215  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
216 
217  if (rRightHandSideVector.size() != MatrixSize) {
218  rRightHandSideVector.resize(MatrixSize, false);
219  }
220 
221  // Initialize RHS
222  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
223 
224  // Decides if the element is split and fills data structure accordingly
226  this->FillEmbeddedAusasElementData(data, rCurrentProcessInfo);
227 
228  // Element LHS and RHS contributions computation
229  CalculateRightHandSideContribution(rRightHandSideVector, data, rCurrentProcessInfo);
230 
231  KRATOS_CATCH("");
232  }
233 
235 
243  int Check(const ProcessInfo& rCurrentProcessInfo) const override {
244  KRATOS_TRY;
245 
246  // Perform basic element checks
247  int ErrorCode = Kratos::Element::Check(rCurrentProcessInfo);
248  if(ErrorCode != 0) return ErrorCode;
249 
250  // Check that the element's nodes contain all required SolutionStepData and Degrees of freedom
251  for(unsigned int i_node = 0; i_node < this->GetGeometry().size(); ++i_node) {
252  if(this->GetGeometry()[i_node].SolutionStepsDataHas(VELOCITY) == false)
253  KRATOS_ERROR << "Missing VELOCITY variable on solution step data for node " << this->GetGeometry()[i_node].Id();
254  if(this->GetGeometry()[i_node].SolutionStepsDataHas(PRESSURE) == false)
255  KRATOS_ERROR << "Missing PRESSURE variable on solution step data for node " << this->GetGeometry()[i_node].Id();
256  if(this->GetGeometry()[i_node].HasDofFor(VELOCITY_X) == false ||
257  this->GetGeometry()[i_node].HasDofFor(VELOCITY_Y) == false ||
258  this->GetGeometry()[i_node].HasDofFor(VELOCITY_Z) == false)
259  KRATOS_ERROR << "Missing VELOCITY component degree of freedom on node " << this->GetGeometry()[i_node].Id();
260  if(this->GetGeometry()[i_node].HasDofFor(PRESSURE) == false)
261  KRATOS_ERROR << "Missing PRESSURE component degree of freedom on node " << this->GetGeometry()[i_node].Id();
262  }
263 
264  // Check constitutive law
265  if(mpConstitutiveLaw == nullptr)
266  KRATOS_ERROR << "The constitutive law was not set. Cannot proceed. Call the navier_stokes.h Initialize() method needs to be called.";
267 
268  mpConstitutiveLaw->Check(GetProperties(), this->GetGeometry(), rCurrentProcessInfo);
269 
270  return 0;
271 
272  KRATOS_CATCH("");
273  }
274 
275  void Calculate(
276  const Variable<array_1d<double, 3 > >& rVariable,
277  array_1d<double, 3 > & rOutput,
278  const ProcessInfo& rCurrentProcessInfo) override {
279 
280  rOutput = ZeroVector(3);
281 
282  // If the element is split, integrate sigma·n over the interface
283  // Note that in the ausas formulation, both interface sides need to be integrated
284  if (rVariable == DRAG_FORCE) {
285 
287  this->FillEmbeddedAusasElementData(data, rCurrentProcessInfo);
288 
289  // Check if the element is split
290  if (data.n_pos != 0 && data.n_neg != 0){
291 
292  // Integrate positive interface side drag
293  const unsigned int n_int_pos_gauss = (data.w_gauss_pos_int).size();
294  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
295  // Get Gauss pt. data
296  const double w_gauss = data.w_gauss_pos_int(i_gauss);
297  const array_1d<double, TNumNodes> aux_N = row(data.N_pos_int, i_gauss);
298  const array_1d<double, 3> side_normal = data.pos_int_unit_normals[i_gauss];
299 
300  // Obtain Gauss pt. pressure
301  const double p_gauss = inner_prod(aux_N, data.p);
302 
303  // Call the constitutive law to compute the shear contribution
304  // Recall to set data.N and data.DN_DX (required by the constitutive law)
305  noalias(data.N) = aux_N;
306  noalias(data.DN_DX) = data.DN_DX_pos_int[i_gauss];
307  this->ComputeConstitutiveResponse(data, rCurrentProcessInfo);
308 
309  // Get the Voigt notation normal projection matrix
310  BoundedMatrix<double, TDim, (TDim-1)*3> normal_proj_mat = ZeroMatrix(TDim, (TDim-1)*3);
311  this->SetVoigtNormalProjectionMatrix(side_normal, normal_proj_mat);
312 
313  // Add the shear and pressure drag contributions
314  const array_1d<double, TDim> shear_proj = w_gauss * prod(normal_proj_mat, data.stress);
315  for (unsigned int i = 0; i < TDim ; ++i){
316  rOutput(i) -= shear_proj(i);
317  }
318  rOutput += w_gauss*p_gauss*side_normal;
319  }
320 
321  // Integrate negative interface side drag
322  const unsigned int n_int_neg_gauss = (data.w_gauss_neg_int).size();
323  for (unsigned int i_gauss = 0; i_gauss < n_int_neg_gauss; ++i_gauss) {
324  // Get Gauss pt. data
325  const double w_gauss = data.w_gauss_neg_int(i_gauss);
326  const array_1d<double, TNumNodes> aux_N = row(data.N_neg_int, i_gauss);
327  const array_1d<double, 3> side_normal = data.neg_int_unit_normals[i_gauss];
328 
329  // Obtain Gauss pt. pressure
330  const double p_gauss = inner_prod(aux_N, data.p);
331 
332  // Call the constitutive law to compute the shear contribution
333  // Recall to set data.N and data.DN_DX (required by the constitutive law)
334  noalias(data.N) = aux_N;
335  noalias(data.DN_DX) = data.DN_DX_neg_int[i_gauss];
336  this->ComputeConstitutiveResponse(data, rCurrentProcessInfo);
337 
338  // Get the Voigt notation normal projection matrix
339  BoundedMatrix<double, TDim, (TDim-1)*3> normal_proj_mat = ZeroMatrix(TDim, (TDim-1)*3);
340  this->SetVoigtNormalProjectionMatrix(side_normal, normal_proj_mat);
341 
342  // Add the shear and pressure drag contributions
343  const array_1d<double, TDim> shear_proj = w_gauss * prod(normal_proj_mat, data.stress);
344  for (unsigned int i = 0; i < TDim ; ++i){
345  rOutput(i) -= shear_proj(i);
346  }
347  rOutput += w_gauss*p_gauss*side_normal;
348  }
349  }
350  } else {
351  KRATOS_ERROR << "Calculate method not implemented for the requested variable.";
352  }
353  }
354 
358 
359 
363 
364 
368 
370  std::string Info() const override {
371  std::stringstream buffer;
372  buffer << "EmbeddedAusasNavierStokesElement" << TDim << "D" << TNumNodes << "N";
373  return buffer.str();
374  }
375 
377  void PrintInfo(std::ostream& rOStream) const override {
378  rOStream << Info() << "\nElement id: " << Id();
379  }
380 
382  virtual void PrintData(std::ostream& rOStream) const override {}
383 
387 
388 
390 
391 protected:
394 
395 
399 
400  // Constitutive law pointer
401  ConstitutiveLaw::Pointer mpConstitutiveLaw = nullptr;
402 
403  // Symbolic function implementing the element
404  void GetDofList(DofsVectorType& ElementalDofList, const ProcessInfo& rCurrentProcessInfo) const override;
405  void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override;
406 
407  void ComputeGaussPointLHSContribution(BoundedMatrix<double,TNumNodes*(TDim+1),TNumNodes*(TDim+1)>& lhs, const EmbeddedAusasElementDataStruct& data);
409 
413 
415  {}
416 
420 
421  // Element initialization (constitutive law)
422  void Initialize(const ProcessInfo &rCurrentProcessInfo) override {
423  KRATOS_TRY;
424 
425  // Initalize the constitutive law pointer
426  mpConstitutiveLaw = GetProperties()[CONSTITUTIVE_LAW]->Clone();
427  mpConstitutiveLaw->InitializeMaterial( GetProperties(), this->GetGeometry(), row( this->GetGeometry().ShapeFunctionsValues(), 0 ) );
428 
429  // Initialize the ELEMENTAL_DISTANCES variable (make it threadsafe)
430  if (!this->Has(ELEMENTAL_DISTANCES)) {
431  Vector zero_vector(TNumNodes, 0.0);
432  this->SetValue(ELEMENTAL_DISTANCES, zero_vector);
433  }
434 
435  // Initialize the nodal EMBEDDED_VELOCITY variable (make it threadsafe)
436  const array_1d<double,3> zero_vel = ZeroVector(3);
437  for (auto &r_node : this->GetGeometry()) {
438  r_node.SetLock();
439  if (!r_node.Has(EMBEDDED_VELOCITY)) {
440  r_node.SetValue(EMBEDDED_VELOCITY, zero_vel);
441  }
442  r_node.UnSetLock();
443  }
444 
445  KRATOS_CATCH("");
446  }
447 
448 
449  // Auxiliar function to fill the element data structure
452  const ProcessInfo& rCurrentProcessInfo) {
453 
454  // Get the element geometry
455  GeometryType& r_geom = this->GetGeometry();
456 
457  // Compute characteristic parent element size
458  rData.h = ComputeH();
459 
460  // Database access to all of the variables needed
461  const Vector& BDFVector = rCurrentProcessInfo[BDF_COEFFICIENTS];
462  rData.bdf0 = BDFVector[0];
463  rData.bdf1 = BDFVector[1];
464  rData.bdf2 = BDFVector[2];
465 
466  rData.dyn_tau = rCurrentProcessInfo[DYNAMIC_TAU]; // Only, needed if the temporal dependent term is considered in the subscales
467  rData.dt = rCurrentProcessInfo[DELTA_TIME]; // Only, needed if the temporal dependent term is considered in the subscales
468 
469  rData.c = rCurrentProcessInfo[SOUND_VELOCITY]; // Wave velocity
470 
471  // Material properties
472  const auto& r_prop = GetProperties();
473  rData.rho = r_prop.GetValue(DENSITY);
474  rData.mu = r_prop.GetValue(DYNAMIC_VISCOSITY);
475 
476  for (unsigned int i = 0; i < TNumNodes; i++) {
477 
478  const array_1d<double,3>& body_force = r_geom[i].FastGetSolutionStepValue(BODY_FORCE);
479  const array_1d<double,3>& vel = r_geom[i].FastGetSolutionStepValue(VELOCITY);
480  const array_1d<double,3>& vel_n = r_geom[i].FastGetSolutionStepValue(VELOCITY,1);
481  const array_1d<double,3>& vel_nn = r_geom[i].FastGetSolutionStepValue(VELOCITY,2);
482  const array_1d<double,3>& vel_mesh = r_geom[i].FastGetSolutionStepValue(MESH_VELOCITY);
483 
484  for(unsigned int k=0; k<TDim; k++) {
485  rData.v(i,k) = vel[k];
486  rData.vn(i,k) = vel_n[k];
487  rData.vnn(i,k) = vel_nn[k];
488  rData.vmesh(i,k) = vel_mesh[k];
489  rData.f(i,k) = body_force[k];
490  }
491 
492  rData.p[i] = r_geom[i].FastGetSolutionStepValue(PRESSURE);
493  rData.pn[i] = r_geom[i].FastGetSolutionStepValue(PRESSURE,1);
494  rData.pnn[i] = r_geom[i].FastGetSolutionStepValue(PRESSURE,2);
495  }
496 
497  // Getting the nodal distances vector
498  const array_1d<double, TNumNodes>& distances = this->GetValue(ELEMENTAL_DISTANCES);
499 
500  (rData.int_vec_identifiers).clear();
501  (rData.out_vec_identifiers).clear();
502 
503  // Number of positive and negative distance function values
504  for (unsigned int inode = 0; inode<TNumNodes; inode++) {
505  if(distances[inode] > 0.0) {
506  rData.n_pos++;
507  (rData.int_vec_identifiers).push_back(inode);
508  } else {
509  rData.n_neg++;
510  (rData.out_vec_identifiers).push_back(inode);
511  }
512  }
513 
514  // If the element is split, get the modified shape functions
515  if (rData.n_pos != 0 && rData.n_neg != 0){
516 
517  GeometryPointerType p_geom = this->pGetGeometry();
518 
519  // Construct the modified shape fucntions utility
520  ModifiedShapeFunctions::Pointer p_ausas_modified_sh_func = nullptr;
521  if constexpr (TNumNodes == 4) {
522  p_ausas_modified_sh_func = Kratos::make_shared<Tetrahedra3D4AusasModifiedShapeFunctions>(p_geom, distances);
523  } else {
524  p_ausas_modified_sh_func = Kratos::make_shared<Triangle2D3AusasModifiedShapeFunctions>(p_geom, distances);
525  }
526 
527  // Call the positive side modified shape functions calculator
528  p_ausas_modified_sh_func->ComputePositiveSideShapeFunctionsAndGradientsValues(
529  rData.N_pos_side,
530  rData.DN_DX_pos_side,
531  rData.w_gauss_pos_side,
533 
534  // Call the negative side modified shape functions calculator
535  p_ausas_modified_sh_func->ComputeNegativeSideShapeFunctionsAndGradientsValues(
536  rData.N_neg_side,
537  rData.DN_DX_neg_side,
538  rData.w_gauss_neg_side,
540 
541  // Call the positive side interface modified shape functions calculator
542  p_ausas_modified_sh_func->ComputeInterfacePositiveSideShapeFunctionsAndGradientsValues(
543  rData.N_pos_int,
544  rData.DN_DX_pos_int,
545  rData.w_gauss_pos_int,
547 
548  // Call the negative side interface modified shape functions calculator
549  p_ausas_modified_sh_func->ComputeInterfaceNegativeSideShapeFunctionsAndGradientsValues(
550  rData.N_neg_int,
551  rData.DN_DX_neg_int,
552  rData.w_gauss_neg_int,
554 
555  // Call the positive side Gauss pts. unit normal calculator
556  p_ausas_modified_sh_func->ComputePositiveSideInterfaceAreaNormals(
557  rData.pos_int_unit_normals,
559 
560  // Call the negative side Gauss pts. unit normal calculator
561  p_ausas_modified_sh_func->ComputeNegativeSideInterfaceAreaNormals(
562  rData.neg_int_unit_normals,
564 
565  // Normalize the obtained positive and negative sides area normals
566  const double tol = std::pow(1e-3*rData.h, TDim-1); // Tolerance to avoid the unit normal to blow up
567  const unsigned int n_gauss_pos = (rData.pos_int_unit_normals).size();
568  const unsigned int n_gauss_neg = (rData.neg_int_unit_normals).size();
569 
570  for (unsigned int i_gauss = 0; i_gauss < n_gauss_pos; ++i_gauss) {
571  array_1d<double,3>& normal = rData.pos_int_unit_normals[i_gauss];
572  const double n_norm = norm_2(normal);
573  normal /= std::max(n_norm, tol);
574  }
575 
576  for (unsigned int i_gauss = 0; i_gauss < n_gauss_neg; ++i_gauss) {
577  array_1d<double,3>& normal = rData.neg_int_unit_normals[i_gauss];
578  const double n_norm = norm_2(normal);
579  normal /= std::max(n_norm, tol);
580  }
581 
582  } else {
583  // Fill the shape functions container
585 
586  // Fill the shape functions gradient container
587  Vector det_jacobian;
589 
590  // Fill the Gauss pts. weights container
591  const unsigned int n_gauss = r_geom.IntegrationPointsNumber(GeometryData::IntegrationMethod::GI_GAUSS_2);
593  rData.w_gauss.resize(n_gauss, false);
594  for (unsigned int i_gauss = 0; i_gauss<n_gauss; ++i_gauss) {
595  rData.w_gauss[i_gauss] = det_jacobian[i_gauss] * rIntegrationPoints[i_gauss].Weight();
596  }
597  }
598  }
599 
601  MatrixType &rLeftHandSideMatrix,
602  VectorType &rRightHandSideVector,
604  const ProcessInfo &rCurrentProcessInfo) {
605 
606  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
607 
608  // Allocate memory needed
611 
612  // Decide if the element is wether split or not and add the contribution accordingly
613  if (rData.n_pos != 0 && rData.n_neg != 0){
614 
615  // Add the positive side volume contribution
616  const unsigned int n_pos_gauss = (rData.w_gauss_pos_side).size();
617  for (unsigned int i_pos_gauss = 0; i_pos_gauss < n_pos_gauss; ++i_pos_gauss) {
618  // Gather Ausas Gauss pt. positive side values from data structure
619  noalias(rData.N) = row(rData.N_pos_side, i_pos_gauss);
620  noalias(rData.DN_DX) = rData.DN_DX_pos_side[i_pos_gauss];
621  const double w_gauss = rData.w_gauss_pos_side[i_pos_gauss];
622 
623  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
624 
625  ComputeGaussPointRHSContribution(rhs_local, rData);
626  ComputeGaussPointLHSContribution(lhs_local, rData);
627 
628  noalias(rLeftHandSideMatrix) += w_gauss * lhs_local;
629  noalias(rRightHandSideVector) += w_gauss * rhs_local;
630  }
631 
632  // Add the negative side volume contribution
633  const unsigned int n_neg_gauss = (rData.w_gauss_neg_side).size();
634  for (unsigned int i_neg_gauss = 0; i_neg_gauss < n_neg_gauss; ++i_neg_gauss) {
635  // Gather Ausas Gauss pt. negative side values from data structure
636  noalias(rData.N) = row(rData.N_neg_side, i_neg_gauss);
637  noalias(rData.DN_DX) = rData.DN_DX_neg_side[i_neg_gauss];
638  const double w_gauss = rData.w_gauss_neg_side[i_neg_gauss];
639 
640  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
641 
642  ComputeGaussPointRHSContribution(rhs_local, rData);
643  ComputeGaussPointLHSContribution(lhs_local, rData);
644 
645  noalias(rLeftHandSideMatrix) += w_gauss * lhs_local;
646  noalias(rRightHandSideVector) += w_gauss * rhs_local;
647  }
648 
649  // Add the intersection boundary fluxes contribution comping from the integration by parts
650  this->AddSystemBoundaryTermsContribution(rLeftHandSideMatrix, rRightHandSideVector, rData);
651 
652  // Add the normal component penalty contribution
653  this->AddSystemNormalVelocityPenaltyContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
654  } else {
655 
656  // If the element is not splitted, add the standard Navier-Stokes contribution
657  const unsigned int n_gauss = (rData.w_gauss).size();
658  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
659  // Gather the standard shape functions Gauss pt. values from data structure
660  const double w_gauss = rData.w_gauss[i_gauss];
661  noalias(rData.N) = row(rData.N_gauss, i_gauss);
662  noalias(rData.DN_DX) = rData.DN_DX_gauss[i_gauss];
663 
664  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
665 
666  ComputeGaussPointRHSContribution(rhs_local, rData);
667  ComputeGaussPointLHSContribution(lhs_local, rData);
668 
669  noalias(rLeftHandSideMatrix) += w_gauss * lhs_local;
670  noalias(rRightHandSideVector) += w_gauss * rhs_local;
671  }
672  }
673  }
674 
676  VectorType &rRightHandSideVector,
678  const ProcessInfo &rCurrentProcessInfo) {
679 
680  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
681 
682  // Allocate memory needed
684 
685  // Decide if the element is wether split or not and add the contribution accordingly
686  if (rData.n_pos != 0 && rData.n_neg != 0){
687 
688  // Add the positive side volume contribution
689  const unsigned int n_pos_gauss = (rData.w_gauss_pos_side).size();
690  for (unsigned int i_pos_gauss = 0; i_pos_gauss < n_pos_gauss; ++i_pos_gauss) {
691  // Gather Ausas Gauss pt. positive side values from data structure
692  noalias(rData.N) = row(rData.N_pos_side, i_pos_gauss);
693  noalias(rData.DN_DX) = rData.DN_DX_pos_side[i_pos_gauss];
694  const double w_gauss = rData.w_gauss_pos_side[i_pos_gauss];
695 
696  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
697 
698  ComputeGaussPointRHSContribution(rhs_local, rData);
699 
700  noalias(rRightHandSideVector) += w_gauss * rhs_local;
701  }
702 
703  // Add the negative side volume contribution
704  const unsigned int n_neg_gauss = (rData.w_gauss_neg_side).size();
705  for (unsigned int i_neg_gauss = 0; i_neg_gauss < n_neg_gauss; ++i_neg_gauss) {
706  // Gather Ausas Gauss pt. negative side values from data structure
707  noalias(rData.N) = row(rData.N_neg_side, i_neg_gauss);
708  noalias(rData.DN_DX) = rData.DN_DX_neg_side[i_neg_gauss];
709  const double w_gauss = rData.w_gauss_neg_side[i_neg_gauss];
710 
711  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
712 
713  ComputeGaussPointRHSContribution(rhs_local, rData);
714 
715  noalias(rRightHandSideVector) += w_gauss * rhs_local;
716  }
717 
718  // Add the intersection boundary fluxes contribution comping from the integration by parts
719  this->AddRHSBoundaryTermsContribution(rRightHandSideVector, rData);
720 
721  // Add the normal component penalty contribution
722  this->AddRHSNormalVelocityPenaltyContribution(rRightHandSideVector, rData, rCurrentProcessInfo);
723 
724  } else {
725 
726  // If the element is not splitted, add the standard Navier-Stokes contribution
727  const unsigned int n_gauss = (rData.w_gauss).size();
728  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
729  // Gather the standard shape functions Gauss pt. values from data structure
730  const double w_gauss = rData.w_gauss[i_gauss];
731  noalias(rData.N) = row(rData.N_gauss, i_gauss);
732  noalias(rData.DN_DX) = rData.DN_DX_gauss[i_gauss];
733 
734  ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
735 
736  ComputeGaussPointRHSContribution(rhs_local, rData);
737 
738  noalias(rRightHandSideVector) += w_gauss * rhs_local;
739  }
740  }
741  }
742 
753  MatrixType &rLeftHandSideMatrix,
754  VectorType &rRightHandSideVector,
755  const EmbeddedAusasElementDataStruct &rData) {
756 
757  constexpr unsigned int BlockSize = TDim + 1;
758  constexpr unsigned int MatrixSize = TNumNodes * BlockSize;
759 
760  // Obtain the previous iteration velocity solution
761  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
762  GetPreviousSolutionVector(rData, prev_sol);
763 
764  // Declare auxiliar arrays
765  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
766 
767  // Contribution coming from the positive side boundary term
768  const unsigned int n_int_pos_gauss = (rData.w_gauss_pos_int).size();
769 
770  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
771  const double w_gauss = rData.w_gauss_pos_int(i_gauss);
772 
773  // Get the positive side shape functions Gauss pt. values
774  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss);
775 
776  // Get the positive side shape functions gradients Gauss pt. values
777  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss];
778 
779  // Get the positive side Gauss pt. normal
780  const array_1d<double, 3> side_normal = rData.pos_int_unit_normals[i_gauss];
781 
782  // Pressure contribution
783  for (unsigned int i = 0; i < TNumNodes; ++i) {
784  for (unsigned int j = 0; j < TNumNodes; ++j) {
785  for (unsigned int d = 0; d < TDim; ++d) {
786  auxLeftHandSideMatrix(i * BlockSize + d, j * BlockSize + TDim) += w_gauss * aux_N(i) * aux_N(j) * side_normal(d);
787  }
788  }
789  }
790  }
791 
792  // Contribution coming from the negative side boundary term
793  const unsigned int n_int_neg_gauss = (rData.w_gauss_neg_int).size();
794 
795  for (unsigned int i_gauss = 0; i_gauss < n_int_neg_gauss; ++i_gauss) {
796  const double w_gauss = rData.w_gauss_neg_int(i_gauss);
797 
798  // Get the negative side shape functions Gauss pt. values
799  const array_1d<double, TNumNodes> aux_N = row(rData.N_neg_int, i_gauss);
800 
801  // Get the negative side shape functions gradients Gauss pt. values
802  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_neg_int[i_gauss];
803 
804  // Get the negative side Gauss pt. normal
805  const array_1d<double, 3> side_normal = rData.neg_int_unit_normals[i_gauss];
806 
807  // Pressure contribution
808  for (unsigned int i = 0; i < TNumNodes; ++i) {
809  for (unsigned int j = 0; j < TNumNodes; ++j) {
810  for (unsigned int d = 0; d < TDim; ++d) {
811  auxLeftHandSideMatrix(i * BlockSize + d, j * BlockSize + TDim) += w_gauss * aux_N(i) * aux_N(j) * side_normal(d);
812  }
813  }
814  }
815  }
816 
817  // LHS assembly
818  rLeftHandSideMatrix += auxLeftHandSideMatrix;
819 
820  // RHS assembly
821  rRightHandSideVector -= prod(auxLeftHandSideMatrix, prev_sol);
822  }
823 
833  VectorType &rRightHandSideVector,
834  const EmbeddedAusasElementDataStruct &rData) {
835 
836  constexpr unsigned int BlockSize = TDim + 1;
837  constexpr unsigned int MatrixSize = TNumNodes * BlockSize;
838 
839  // Obtain the previous iteration velocity solution
840  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
841  GetPreviousSolutionVector(rData, prev_sol);
842 
843  // Declare auxiliar arrays
844  array_1d<double, MatrixSize> auxRightHandSideVector = ZeroVector(MatrixSize);
845 
846  // Contribution coming from the positive side boundary term
847  const unsigned int n_int_pos_gauss = (rData.w_gauss_pos_int).size();
848 
849  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
850  const double w_gauss = rData.w_gauss_pos_int(i_gauss);
851 
852  // Get the positive side shape functions Gauss pt. values
853  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss);
854 
855  // Get the positive side shape functions gradients Gauss pt. values
856  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss];
857 
858  // Get the positive side Gauss pt. normal
859  const array_1d<double, 3> side_normal = rData.pos_int_unit_normals[i_gauss];
860 
861  // Pressure contribution
862  for (unsigned int i = 0; i < TNumNodes; ++i) {
863  for (unsigned int j = 0; j < TNumNodes; ++j) {
864  for (unsigned int d = 0; d < TDim; ++d) {
865  rRightHandSideVector(i * BlockSize + d) -= w_gauss * aux_N(i) * aux_N(j) * side_normal(d) * prev_sol(j * BlockSize + TDim);
866  }
867  }
868  }
869  }
870 
871  // Contribution coming from the negative side boundary term
872  const unsigned int n_int_neg_gauss = (rData.w_gauss_neg_int).size();
873 
874  for (unsigned int i_gauss = 0; i_gauss < n_int_neg_gauss; ++i_gauss) {
875  const double w_gauss = rData.w_gauss_neg_int(i_gauss);
876 
877  // Get the negative side shape functions Gauss pt. values
878  const array_1d<double, TNumNodes> aux_N = row(rData.N_neg_int, i_gauss);
879 
880  // Get the negative side shape functions gradients Gauss pt. values
881  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_neg_int[i_gauss];
882 
883  // Get the negative side Gauss pt. normal
884  const array_1d<double, 3> side_normal = rData.neg_int_unit_normals[i_gauss];
885 
886  // Pressure contribution
887  for (unsigned int i = 0; i < TNumNodes; ++i) {
888  for (unsigned int j = 0; j < TNumNodes; ++j) {
889  for (unsigned int d = 0; d < TDim; ++d) {
890  rRightHandSideVector(i * BlockSize + d) -= w_gauss * aux_N(i) * aux_N(j) * side_normal(d) * prev_sol(j * BlockSize + TDim);
891  }
892  }
893  }
894  }
895  }
896 
904  MatrixType &rLeftHandSideMatrix,
905  VectorType &rRightHandSideVector,
906  const EmbeddedAusasElementDataStruct &rData,
907  const ProcessInfo &rCurrentProcessInfo)
908  {
909  const auto &r_geom = this->GetGeometry();
910  constexpr unsigned int BlockSize = TDim + 1;
911  constexpr unsigned int MatrixSize = TNumNodes * BlockSize;
912 
913  // Compute the penalty coefficient
914  const double pen_coef = ComputePenaltyCoefficient(rData, rCurrentProcessInfo);
915 
916  // Compute the LHS and RHS penalty contributions
917  BoundedMatrix<double, MatrixSize, MatrixSize> P_gamma = ZeroMatrix(MatrixSize, MatrixSize);
918 
919  // Contribution coming from the positive side penalty term
920  const unsigned int n_int_pos_gauss = (rData.w_gauss_pos_int).size();
921  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
922  const double w_gauss = rData.w_gauss_pos_int(i_gauss);
923 
924  // Get the positive side shape functions Gauss pt. values
925  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss);
926 
927  // Get the positive side Gauss pt. normal
928  const array_1d<double, 3> side_normal = rData.pos_int_unit_normals[i_gauss];
929 
930  // Compute and assemble the LHS contribution
931  for (unsigned int i = 0; i < TNumNodes; ++i) {
932  for (unsigned int j = 0; j < TNumNodes; ++j) {
933  const auto j_v = row(rData.v, j);
934  const auto j_v_emb = r_geom[j].GetValue(EMBEDDED_VELOCITY);
935  for (unsigned int m = 0; m < TDim; ++m) {
936  const unsigned int row = i * BlockSize + m;
937  for (unsigned int n = 0; n < TDim; ++n) {
938  const unsigned int col = j * BlockSize + n;
939  const double aux_val = pen_coef * w_gauss * aux_N(i) * side_normal(m) * side_normal(n) * aux_N(j);
940  rLeftHandSideMatrix(row,col) += aux_val;
941  rRightHandSideVector(row) -= aux_val * j_v(n);
942  rRightHandSideVector(row) += aux_val * j_v_emb(n);
943  }
944  }
945  }
946  }
947  }
948 
949  // Contribution coming from the negative side penalty term
950  const unsigned int n_int_neg_gauss = (rData.w_gauss_neg_int).size();
951  for (unsigned int i_gauss = 0; i_gauss < n_int_neg_gauss; ++i_gauss) {
952  const double w_gauss = rData.w_gauss_neg_int(i_gauss);
953 
954  // Get the negative side shape functions Gauss pt. values
955  const array_1d<double, TNumNodes> aux_N = row(rData.N_neg_int, i_gauss);
956 
957  // Get the negative side Gauss pt. normal
958  const array_1d<double, 3> side_normal = rData.neg_int_unit_normals[i_gauss];
959 
960  // Compute and assemble the LHS contribution
961  for (unsigned int i = 0; i < TNumNodes; ++i) {
962  for (unsigned int j = 0; j < TNumNodes; ++j) {
963  const auto j_v = row(rData.v, j);
964  const auto j_v_emb = r_geom[j].GetValue(EMBEDDED_VELOCITY);
965  for (unsigned int m = 0; m < TDim; ++m) {
966  const unsigned int row = i * BlockSize + m;
967  for (unsigned int n = 0; n < TDim; ++n) {
968  const unsigned int col = j * BlockSize + n;
969  const double aux_val = pen_coef * w_gauss * aux_N(i) * side_normal(m) * side_normal(n) * aux_N(j);
970  rLeftHandSideMatrix(row,col) += aux_val;
971  rRightHandSideVector(row) -= aux_val * j_v(n);
972  rRightHandSideVector(row) += aux_val * j_v_emb(n);
973  }
974  }
975  }
976  }
977  }
978  }
979 
986  VectorType &rRightHandSideVector,
987  const EmbeddedAusasElementDataStruct &rData,
988  const ProcessInfo &rCurrentProcessInfo) {
989 
990  constexpr unsigned int BlockSize = TDim + 1;
991  constexpr unsigned int MatrixSize = TNumNodes * BlockSize;
992 
993  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
994  array_1d<double, MatrixSize> solution_jump = ZeroVector(MatrixSize);
995 
996  // Obtain the previous iteration velocity solution
997  GetPreviousSolutionVector(rData, prev_sol);
998 
999  // Compute the velocity diference to penalize
1000  const auto &r_geom = this->GetGeometry();
1001  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
1002  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
1003  for (unsigned int d = 0; d < TDim; ++d) {
1004  prev_sol(i_node * BlockSize + d) -= r_i_emb_vel(d);
1005  }
1006  }
1007 
1008  // Compute the penalty coefficient
1009  const double pen_coef = ComputePenaltyCoefficient(rData, rCurrentProcessInfo);
1010 
1011  // Contribution coming from the positive side penalty term
1012  const unsigned int n_int_pos_gauss = (rData.w_gauss_pos_int).size();
1013  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
1014  const double w_gauss = rData.w_gauss_pos_int(i_gauss);
1015 
1016  // Get the positive side shape functions Gauss pt. values
1017  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss);
1018 
1019  // Get the positive side Gauss pt. normal
1020  const array_1d<double, 3> side_normal = rData.pos_int_unit_normals[i_gauss];
1021 
1022  // Compute and assemble the LHS contribution
1023  for (unsigned int i = 0; i < TNumNodes; ++i) {
1024  for (unsigned int j = 0; j < TNumNodes; ++j) {
1025  for (unsigned int m = 0; m < TDim; ++m) {
1026  const unsigned int row = i * BlockSize + m;
1027  for (unsigned int n = 0; n < TDim; ++n) {
1028  rRightHandSideVector(row) -= pen_coef * w_gauss * aux_N(i) * side_normal(m) * side_normal(n) * aux_N(j) * solution_jump(row);
1029  }
1030  }
1031  }
1032  }
1033  }
1034 
1035  // Contribution coming from the negative side penalty term
1036  const unsigned int n_int_neg_gauss = (rData.w_gauss_neg_int).size();
1037  for (unsigned int i_gauss = 0; i_gauss < n_int_neg_gauss; ++i_gauss) {
1038  const double w_gauss = rData.w_gauss_neg_int(i_gauss);
1039 
1040  // Get the negative side shape functions Gauss pt. values
1041  const array_1d<double, TNumNodes> aux_N = row(rData.N_neg_int, i_gauss);
1042 
1043  // Get the negative side Gauss pt. normal
1044  const array_1d<double, 3> side_normal = rData.neg_int_unit_normals[i_gauss];
1045 
1046  // Compute and assemble the LHS contribution
1047  for (unsigned int i = 0; i < TNumNodes; ++i) {
1048  for (unsigned int j = 0; j < TNumNodes; ++j) {
1049  for (unsigned int m = 0; m < TDim; ++m) {
1050  const unsigned int row = i * BlockSize + m;
1051  for (unsigned int n = 0; n < TDim; ++n) {
1052  rRightHandSideVector(row) -= pen_coef * w_gauss * aux_N(i) * side_normal(m) * side_normal(n) * aux_N(j) * solution_jump(row);
1053  }
1054  }
1055  }
1056  }
1057  }
1058  }
1059 
1064  double ComputeH() {
1065 
1066  double aux_volume;
1069 
1070  GeometryUtils::CalculateGeometryData(this->GetGeometry(), aux_DN_DX, aux_N, aux_volume);
1071 
1072  double h=0.0;
1073  for(unsigned int i=0; i<TNumNodes; i++) {
1074  double h_inv = 0.0;
1075  for(unsigned int k=0; k<TDim; k++) {
1076  h_inv += aux_DN_DX(i,k)*aux_DN_DX(i,k);
1077  }
1078  h += 1.0/h_inv;
1079  }
1080 
1081  h = sqrt(h)/static_cast<double>(TNumNodes);
1082 
1083  return h;
1084  }
1085 
1091  const EmbeddedAusasElementDataStruct &rData,
1092  const ProcessInfo &rCurrentProcessInfo)
1093  {
1094  // Compute the intersection area using the Gauss pts. weights
1095  double intersection_area = 0.0;
1096  for (unsigned int i_gauss = 0; i_gauss < (rData.w_gauss_pos_int).size(); ++i_gauss) {
1097  intersection_area += rData.w_gauss_pos_int(i_gauss);
1098  }
1099 
1100  // Compute the element average values
1101  array_1d<double, TDim> avg_vel = ZeroVector(TDim);
1102  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
1103  avg_vel += row(rData.v, i_node);
1104  }
1105  avg_vel /= TNumNodes;
1106 
1107  const double v_norm = norm_2(avg_vel);
1108 
1109  // Compute the penalty constant
1110  const double pen_cons = rData.rho*std::pow(rData.h, TDim)/rData.dt +
1111  rData.mu*std::pow(rData.h,TDim-2) +
1112  rData.rho*v_norm*std::pow(rData.h, TDim-1);
1113 
1114  // Return the penalty coefficient
1115  const double K = rCurrentProcessInfo[PENALTY_COEFFICIENT];
1116  const double pen_coef = K * pen_cons / intersection_area;
1117 
1118  return pen_coef;
1119  }
1120 
1127  const EmbeddedAusasElementDataStruct& rData,
1128  array_1d<double, TNumNodes*(TDim+1)>& rPrevSolVector) {
1129 
1130  rPrevSolVector.clear();
1131 
1132  for (unsigned int i=0; i<TNumNodes; i++) {
1133  for (unsigned int comp=0; comp<TDim; comp++) {
1134  rPrevSolVector(i*(TDim+1)+comp) = rData.v(i,comp);
1135  }
1136  rPrevSolVector(i*(TDim+1)+TDim) = rData.p(i);
1137  }
1138  }
1139 
1147  const unsigned int StrainSize) {
1148 
1151 
1152  // Compute strain (B*v)
1153  if (StrainSize == 6) {
1154  // 3D strain computation
1155  rData.strain[0] = DN(0,0)*v(0,0) + DN(1,0)*v(1,0) + DN(2,0)*v(2,0) + DN(3,0)*v(3,0);
1156  rData.strain[1] = DN(0,1)*v(0,1) + DN(1,1)*v(1,1) + DN(2,1)*v(2,1) + DN(3,1)*v(3,1);
1157  rData.strain[2] = DN(0,2)*v(0,2) + DN(1,2)*v(1,2) + DN(2,2)*v(2,2) + DN(3,2)*v(3,2);
1158  rData.strain[3] = DN(0,0)*v(0,1) + DN(0,1)*v(0,0) + DN(1,0)*v(1,1) + DN(1,1)*v(1,0) + DN(2,0)*v(2,1) + DN(2,1)*v(2,0) + DN(3,0)*v(3,1) + DN(3,1)*v(3,0);
1159  rData.strain[4] = DN(0,1)*v(0,2) + DN(0,2)*v(0,1) + DN(1,1)*v(1,2) + DN(1,2)*v(1,1) + DN(2,1)*v(2,2) + DN(2,2)*v(2,1) + DN(3,1)*v(3,2) + DN(3,2)*v(3,1);
1160  rData.strain[5] = DN(0,0)*v(0,2) + DN(0,2)*v(0,0) + DN(1,0)*v(1,2) + DN(1,2)*v(1,0) + DN(2,0)*v(2,2) + DN(2,2)*v(2,0) + DN(3,0)*v(3,2) + DN(3,2)*v(3,0);
1161  } else if (StrainSize == 3) {
1162  // 2D strain computation
1163  rData.strain[0] = DN(0,0)*v(0,0) + DN(1,0)*v(1,0) + DN(2,0)*v(2,0);
1164  rData.strain[1] = DN(0,1)*v(0,1) + DN(1,1)*v(1,1) + DN(2,1)*v(2,1);
1165  rData.strain[2] = DN(0,1)*v(0,0) + DN(1,1)*v(1,0) + DN(2,1)*v(2,0) + DN(0,0)*v(0,1) + DN(1,0)*v(1,1) + DN(2,0)*v(2,1);
1166  }
1167  }
1168 
1176  const ProcessInfo& rCurrentProcessInfo) {
1177 
1178  const unsigned int strain_size = (TDim*3)-3;
1179 
1180  if(rData.C.size1() != strain_size) {
1181  rData.C.resize(strain_size, strain_size, false);
1182  } else if(rData.C.size2() != strain_size) {
1183  rData.C.resize(strain_size, strain_size, false);
1184  }
1185 
1186  if(rData.stress.size() != strain_size) {
1187  rData.stress.resize(strain_size,false);
1188  }
1189 
1190  if(rData.strain.size() != strain_size) {
1191  rData.strain.resize(strain_size,false);
1192  }
1193 
1194  this->ComputeStrain(rData, strain_size);
1195 
1196  // Create constitutive law parameters:
1197  ConstitutiveLaw::Parameters Values(this->GetGeometry(), GetProperties(), rCurrentProcessInfo);
1198 
1199  Values.SetShapeFunctionsValues(rData.N);
1200 
1201  // Set constitutive law flags:
1202  Flags& ConstitutiveLawOptions=Values.GetOptions();
1203  ConstitutiveLawOptions.Set(ConstitutiveLaw::COMPUTE_STRESS);
1204  ConstitutiveLawOptions.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR);
1205 
1206  Values.SetStrainVector(rData.strain); //this is the input parameter
1207  Values.SetStressVector(rData.stress); //this is an ouput parameter
1208  Values.SetConstitutiveMatrix(rData.C); //this is an ouput parameter
1209 
1210  //ATTENTION: here we assume that only one constitutive law is employed for all of the gauss points in the element.
1211  //this is ok under the hypothesis that no history dependent behaviour is employed
1212  mpConstitutiveLaw->CalculateMaterialResponseCauchy(Values);
1213 
1214  }
1215 
1222  double mu_eff = 0.0;
1223  const unsigned int strain_size = (TDim-1)*3;
1224  for (unsigned int i=TDim; i<strain_size; ++i){mu_eff += rData.C(i,i);}
1225  mu_eff /= (strain_size - TDim);
1226 
1227  return mu_eff;
1228  }
1229 
1236  const array_1d<double, 3>& rUnitNormal,
1237  BoundedMatrix<double, TDim, (TDim-1)*3>& rVoigtNormProjMatrix) {
1238 
1239  rVoigtNormProjMatrix.clear();
1240 
1241  if constexpr (TDim == 3) {
1242  rVoigtNormProjMatrix(0,0) = rUnitNormal(0);
1243  rVoigtNormProjMatrix(0,3) = rUnitNormal(1);
1244  rVoigtNormProjMatrix(0,5) = rUnitNormal(2);
1245  rVoigtNormProjMatrix(1,1) = rUnitNormal(1);
1246  rVoigtNormProjMatrix(1,3) = rUnitNormal(0);
1247  rVoigtNormProjMatrix(1,4) = rUnitNormal(2);
1248  rVoigtNormProjMatrix(2,2) = rUnitNormal(2);
1249  rVoigtNormProjMatrix(2,4) = rUnitNormal(1);
1250  rVoigtNormProjMatrix(2,5) = rUnitNormal(0);
1251  } else {
1252  rVoigtNormProjMatrix(0,0) = rUnitNormal(0);
1253  rVoigtNormProjMatrix(0,2) = rUnitNormal(1);
1254  rVoigtNormProjMatrix(1,1) = rUnitNormal(1);
1255  rVoigtNormProjMatrix(1,2) = rUnitNormal(0);
1256  }
1257  }
1258 
1262 
1263 
1267 
1268 
1272 
1273 
1275 private:
1278 
1282 
1286  friend class Serializer;
1287 
1288  void save(Serializer& rSerializer) const override
1289  {
1291  // TODO: Serialize constitutive law
1292  }
1293 
1294  void load(Serializer& rSerializer) override
1295  {
1297  // TODO: Serialize constitutive law
1298  }
1299 
1301 
1304 
1305 
1309 
1310 
1314 
1315 
1319 
1320 
1322 };
1323 
1325 
1328 
1329 
1333 
1334 
1336 } // namespace Kratos.
1337 
1338 #endif // KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES_ELEMENT_INCLUDED defined
Base class for all Elements.
Definition: element.h:60
PropertiesType & GetProperties()
Definition: element.h:1024
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:904
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
Definition: embedded_ausas_navier_stokes.h:62
Element::Pointer Create(IndexType NewId, NodesArrayType const &rThisNodes, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: embedded_ausas_navier_stokes.h:162
void ComputeGaussPointLHSContribution(BoundedMatrix< double, TNumNodes *(TDim+1), TNumNodes *(TDim+1)> &lhs, const EmbeddedAusasElementDataStruct &data)
void CalculateLocalSystemContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:600
void AddRHSNormalVelocityPenaltyContribution(VectorType &rRightHandSideVector, const EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:985
~EmbeddedAusasNavierStokes() override
Destructor.
Definition: embedded_ausas_navier_stokes.h:150
GeometryType::IntegrationPointsArrayType InteGrationPointsType
Definition: embedded_ausas_navier_stokes.h:69
std::string Info() const override
Turn back information as a string.
Definition: embedded_ausas_navier_stokes.h:370
double ComputeEffectiveViscosity(const EmbeddedAusasElementDataStruct &rData)
Definition: embedded_ausas_navier_stokes.h:1221
void FillEmbeddedAusasElementData(EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:450
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: embedded_ausas_navier_stokes.h:377
void ComputeStrain(EmbeddedAusasElementDataStruct &rData, const unsigned int StrainSize)
Definition: embedded_ausas_navier_stokes.h:1145
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_ausas_navier_stokes.h:209
EmbeddedAusasNavierStokes()
Definition: embedded_ausas_navier_stokes.h:414
void Initialize(const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_ausas_navier_stokes.h:422
void AddSystemNormalVelocityPenaltyContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:903
double ComputePenaltyCoefficient(const EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:1090
void AddRHSBoundaryTermsContribution(VectorType &rRightHandSideVector, const EmbeddedAusasElementDataStruct &rData)
Definition: embedded_ausas_navier_stokes.h:832
void SetVoigtNormalProjectionMatrix(const array_1d< double, 3 > &rUnitNormal, BoundedMatrix< double, TDim,(TDim-1) *3 > &rVoigtNormProjMatrix)
Definition: embedded_ausas_navier_stokes.h:1235
void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
void CalculateRightHandSideContribution(VectorType &rRightHandSideVector, EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:675
GeometryType::Pointer GeometryPointerType
Definition: embedded_ausas_navier_stokes.h:67
void ComputeConstitutiveResponse(EmbeddedAusasElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_ausas_navier_stokes.h:1174
virtual void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: embedded_ausas_navier_stokes.h:382
void AddSystemBoundaryTermsContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedAusasElementDataStruct &rData)
Definition: embedded_ausas_navier_stokes.h:752
void GetDofList(DofsVectorType &ElementalDofList, const ProcessInfo &rCurrentProcessInfo) const override
Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: embedded_ausas_navier_stokes.h:168
double ComputeH()
Definition: embedded_ausas_navier_stokes.h:1064
void GetPreviousSolutionVector(const EmbeddedAusasElementDataStruct &rData, array_1d< double, TNumNodes *(TDim+1)> &rPrevSolVector)
Definition: embedded_ausas_navier_stokes.h:1126
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_ausas_navier_stokes.h:175
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(EmbeddedAusasNavierStokes)
Counted pointer of.
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Checks the input and that all required Kratos variables have been registered.
Definition: embedded_ausas_navier_stokes.h:243
EmbeddedAusasNavierStokes(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Definition: embedded_ausas_navier_stokes.h:145
void Calculate(const Variable< array_1d< double, 3 > > &rVariable, array_1d< double, 3 > &rOutput, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_ausas_navier_stokes.h:275
GeometryType::ShapeFunctionsGradientsType ShapeFunctionsGradientsType
Definition: embedded_ausas_navier_stokes.h:71
EmbeddedAusasNavierStokes(IndexType NewId, GeometryType::Pointer pGeometry)
Default constructor.
Definition: embedded_ausas_navier_stokes.h:141
void ComputeGaussPointRHSContribution(array_1d< double, TNumNodes *(TDim+1)> &rhs, const EmbeddedAusasElementDataStruct &data)
ConstitutiveLaw::Pointer mpConstitutiveLaw
Definition: embedded_ausas_navier_stokes.h:401
Definition: flags.h:58
std::size_t IndexType
Definition: flags.h:74
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
GeometryType::Pointer pGetGeometry()
Returns the pointer to the geometry.
Definition: geometrical_object.h:140
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometrical_object.h:248
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
bool Has(const Variable< TDataType > &rThisVariable) const
Definition: geometrical_object.h:230
void SetValue(const TVariableType &rThisVariable, typename TVariableType::Type const &rValue)
Definition: geometrical_object.h:238
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
std::vector< IntegrationPointType > IntegrationPointsArrayType
Definition: geometry.h:161
const Matrix & ShapeFunctionsValues() const
Definition: geometry.h:3393
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
void ShapeFunctionsIntegrationPointsGradients(ShapeFunctionsGradientsType &rResult) const
Definition: geometry.h:3708
const IntegrationPointsArrayType & IntegrationPoints() const
Definition: geometry.h:2284
virtual Pointer Create(PointsArrayType const &rThisPoints) const
Creates a new geometry pointer.
Definition: geometry.h:813
SizeType IntegrationPointsNumber() const
Definition: geometry.h:2257
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
Definition: amatrix_interface.h:41
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
Variable class contains all information needed to store and retrive data from a data container.
Definition: variable.h:63
#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
#define KRATOS_ERROR
Definition: exception.h:161
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
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
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
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
v
Definition: generate_convection_diffusion_explicit_element.py:114
DN
Definition: generate_convection_diffusion_explicit_element.py:98
w_gauss
Definition: generate_convection_diffusion_explicit_element.py:136
p_gauss
Data interpolation to the Gauss points.
Definition: generate_droplet_dynamics.py:128
h
Definition: generate_droplet_dynamics.py:91
rhs
Definition: generate_frictional_mortar_condition.py:297
lhs
Definition: generate_frictional_mortar_condition.py:297
int strain_size
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:16
int tol
Definition: hinsberg_optimization.py:138
data
Definition: mesh_to_mdpa_converter.py:59
def load(f)
Definition: ode_solve.py:307
int d
Definition: ode_solve.py:397
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
vel
Definition: pure_conduction.py:76
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int m
Definition: run_marine_rain_substepping.py:8
body_force
Definition: script_ELASTIC.py:102
K
Definition: sensitivityMatrix.py:73
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31
Definition: constitutive_law.h:189
void SetConstitutiveMatrix(VoigtSizeMatrixType &rConstitutiveMatrix)
Definition: constitutive_law.h:403
void SetStrainVector(StrainVectorType &rStrainVector)
Definition: constitutive_law.h:401
Flags & GetOptions()
Definition: constitutive_law.h:412
void SetStressVector(StressVectorType &rStressVector)
Definition: constitutive_law.h:402
void SetShapeFunctionsValues(const Vector &rShapeFunctionsValues)
Definition: constitutive_law.h:396
Definition: embedded_ausas_navier_stokes.h:76
VectorType w_gauss_neg_side
Definition: embedded_ausas_navier_stokes.h:113
MatrixType N_pos_int
Definition: embedded_ausas_navier_stokes.h:116
std::vector< unsigned int > int_vec_identifiers
Definition: embedded_ausas_navier_stokes.h:127
double bdf1
Definition: embedded_ausas_navier_stokes.h:89
double rho
Definition: embedded_ausas_navier_stokes.h:97
BoundedMatrix< double, TNumNodes, TDim > vn
Definition: embedded_ausas_navier_stokes.h:78
BoundedMatrix< double, TNumNodes, TDim > vnn
Definition: embedded_ausas_navier_stokes.h:78
MatrixType N_neg_side
Definition: embedded_ausas_navier_stokes.h:111
ShapeFunctionsGradientsType DN_DX_neg_int
Definition: embedded_ausas_navier_stokes.h:123
array_1d< double, TNumNodes > N
Definition: embedded_ausas_navier_stokes.h:81
BoundedMatrix< double, TNumNodes, TDim > DN_DX
Definition: embedded_ausas_navier_stokes.h:82
array_1d< double, TNumNodes > p
Definition: embedded_ausas_navier_stokes.h:79
std::vector< array_1d< double, 3 > > pos_int_unit_normals
Definition: embedded_ausas_navier_stokes.h:119
array_1d< double, TNumNodes > pn
Definition: embedded_ausas_navier_stokes.h:79
ShapeFunctionsGradientsType DN_DX_gauss
Definition: embedded_ausas_navier_stokes.h:102
ShapeFunctionsGradientsType DN_DX_pos_int
Definition: embedded_ausas_navier_stokes.h:117
unsigned int n_pos
Definition: embedded_ausas_navier_stokes.h:130
double dyn_tau
Definition: embedded_ausas_navier_stokes.h:95
BoundedMatrix< double, TNumNodes, TDim > f
Definition: embedded_ausas_navier_stokes.h:78
BoundedMatrix< double, TNumNodes, TDim > vmesh
Definition: embedded_ausas_navier_stokes.h:78
array_1d< double, TNumNodes > pnn
Definition: embedded_ausas_navier_stokes.h:79
Vector strain
Definition: embedded_ausas_navier_stokes.h:86
Vector stress
Definition: embedded_ausas_navier_stokes.h:85
MatrixType N_gauss
Definition: embedded_ausas_navier_stokes.h:101
double c
Definition: embedded_ausas_navier_stokes.h:91
Matrix C
Definition: embedded_ausas_navier_stokes.h:84
double bdf2
Definition: embedded_ausas_navier_stokes.h:90
MatrixType N_neg_int
Definition: embedded_ausas_navier_stokes.h:122
VectorType w_gauss_neg_int
Definition: embedded_ausas_navier_stokes.h:124
double bdf0
Definition: embedded_ausas_navier_stokes.h:88
double dt
Definition: embedded_ausas_navier_stokes.h:94
VectorType w_gauss_pos_int
Definition: embedded_ausas_navier_stokes.h:118
VectorType w_gauss_pos_side
Definition: embedded_ausas_navier_stokes.h:108
unsigned int n_neg
Definition: embedded_ausas_navier_stokes.h:131
double h
Definition: embedded_ausas_navier_stokes.h:92
std::vector< array_1d< double, 3 > > neg_int_unit_normals
Definition: embedded_ausas_navier_stokes.h:125
MatrixType N_pos_side
Definition: embedded_ausas_navier_stokes.h:106
VectorType w_gauss
Definition: embedded_ausas_navier_stokes.h:100
std::vector< unsigned int > out_vec_identifiers
Definition: embedded_ausas_navier_stokes.h:128
double mu
Definition: embedded_ausas_navier_stokes.h:96
BoundedMatrix< double, TNumNodes, TDim > v
Definition: embedded_ausas_navier_stokes.h:78
double volume
Definition: embedded_ausas_navier_stokes.h:93
ShapeFunctionsGradientsType DN_DX_neg_side
Definition: embedded_ausas_navier_stokes.h:112
ShapeFunctionsGradientsType DN_DX_pos_side
Definition: embedded_ausas_navier_stokes.h:107