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_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_NAVIER_STOKES)
14 #define KRATOS_EMBEDDED_NAVIER_STOKES
15 
16 // System includes
17 
18 // External includes
19 
20 // Project includes
24 
25 namespace Kratos
26 {
27 
30 
34 
38 
42 
46 
52 template< unsigned int TDim, unsigned int TNumNodes = TDim + 1 >
53 class EmbeddedNavierStokes : public NavierStokes<TDim, TNumNodes>
54 {
55 public:
58 
61 
63 
65 
66  typedef typename BaseType::VectorType VectorType;
67 
68  typedef typename BaseType::MatrixType MatrixType;
69 
70  typedef typename BaseType::IndexType IndexType;
71 
72  typedef typename BaseType::GeometryType::Pointer GeometryPointerType;
73 
75 
76  typedef typename BaseType::PropertiesType::Pointer PropertiesPointerType;
77 
80 
82  // Element geometry data
83  MatrixType N_pos_side; // Positive distance element side shape functions values
84  ShapeFunctionsGradientsType DN_DX_pos_side; // Positive distance element side shape functions gradients values
85  VectorType w_gauss_pos_side; // Positive distance element side Gauss pts. weights
86 
87  // Intersection geometry data
88  MatrixType N_pos_int; // Positive interface Gauss pts. shape functions values
89  ShapeFunctionsGradientsType DN_DX_pos_int; // Positive interface Gauss pts. shape functions gradients values
90  VectorType w_gauss_pos_int; // Positive interface Gauss pts. weights
91  std::vector<array_1d<double,3>> pos_int_unit_normals; // Positive interface unit normal vector in each Gauss pt.
92 
93  std::vector<unsigned int> int_vec_identifiers; // Interior (fluid) nodes identifiers
94  std::vector<unsigned int> out_vec_identifiers; // Outside (stucture) nodes identifiers
95 
96  unsigned int n_pos = 0; // Number of postivie distance nodes
97  unsigned int n_neg = 0; // Number of negative distance nodes
98  };
99 
103 
105 
107  : NavierStokes<TDim, TNumNodes>(NewId, pGeometry)
108  {}
109 
111  : NavierStokes<TDim, TNumNodes>(NewId, pGeometry, pProperties)
112  {}
113 
115  ~EmbeddedNavierStokes() override {};
116 
120 
121 
125 
126  Element::Pointer Create(IndexType NewId, NodesArrayType const& rThisNodes, Element::PropertiesType::Pointer pProperties) const override {
127  KRATOS_TRY
128  return Kratos::make_intrusive< EmbeddedNavierStokes < TDim, TNumNodes > >(NewId, this->GetGeometry().Create(rThisNodes), pProperties);
129  KRATOS_CATCH("");
130  }
131 
132 
133  Element::Pointer Create(IndexType NewId, Element::GeometryType::Pointer pGeom, Element::PropertiesType::Pointer pProperties) const override {
134  return Kratos::make_intrusive< EmbeddedNavierStokes < TDim, TNumNodes > >(NewId, pGeom, pProperties);
135  }
136 
137 
144  Element::Pointer Clone(IndexType NewId, NodesArrayType const& rThisNodes) const override {
145  Element::Pointer pNewElement = Create(NewId, this->GetGeometry().Create(rThisNodes), this->pGetProperties());
146 
147  pNewElement->SetData(this->GetData());
148  pNewElement->SetFlags(this->GetFlags());
149 
150  return pNewElement;
151  }
152 
161  const ProcessInfo& rCurrentProcessInfo) {
162 
163  // Fill the basic element data (base class call)
164  BaseType::FillElementData(rData, rCurrentProcessInfo);
165 
166  // Getting the nodal distance values
167  array_1d<double, TNumNodes> distances;
168  for(unsigned int i=0; i<TNumNodes; i++) {
169  distances[i] = this->GetGeometry()[i].FastGetSolutionStepValue(DISTANCE);
170  }
171 
172  (rData.int_vec_identifiers).clear();
173  (rData.out_vec_identifiers).clear();
174 
175  // Number of positive and negative distance function values
176  for (unsigned int inode = 0; inode<TNumNodes; inode++) {
177  if(distances[inode] > 0.0) {
178  rData.n_pos++;
179  (rData.int_vec_identifiers).push_back(inode);
180  } else {
181  rData.n_neg++;
182  (rData.out_vec_identifiers).push_back(inode);
183  }
184  }
185 
186  // If the element is split, get the modified shape functions
187  if (rData.n_pos != 0 && rData.n_neg != 0){
188 
189  GeometryPointerType p_geom = this->pGetGeometry();
190 
191  // Construct the modified shape fucntions utility
192  ModifiedShapeFunctions::Pointer p_modified_sh_func = nullptr;
193  if constexpr (TNumNodes == 4) {
194  p_modified_sh_func = Kratos::make_shared<Tetrahedra3D4ModifiedShapeFunctions>(p_geom, distances);
195  } else {
196  p_modified_sh_func = Kratos::make_shared<Triangle2D3ModifiedShapeFunctions>(p_geom, distances);
197  }
198 
199  // Call the fluid side modified shape functions calculator
200  p_modified_sh_func->ComputePositiveSideShapeFunctionsAndGradientsValues(
201  rData.N_pos_side,
202  rData.DN_DX_pos_side,
203  rData.w_gauss_pos_side,
205 
206  // Call the fluid side interface modified shape functions calculator
207  p_modified_sh_func->ComputeInterfacePositiveSideShapeFunctionsAndGradientsValues(
208  rData.N_pos_int,
209  rData.DN_DX_pos_int,
210  rData.w_gauss_pos_int,
212 
213  // Call the fluid side Gauss pts. unit normal calculator
214  p_modified_sh_func->ComputePositiveSideInterfaceAreaNormals(
215  rData.pos_int_unit_normals,
217 
218  // Normalize the obtained area normals
219  const double tol = std::pow(1e-3*rData.h, TDim-1); // Tolerance to avoid the unit normal to blow up
220  const unsigned int n_gauss = (rData.pos_int_unit_normals).size();
221 
222  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
223  array_1d<double,3>& normal = rData.pos_int_unit_normals[i_gauss];
224  const double n_norm = norm_2(normal);
225  normal /= std::max(n_norm, tol);
226  }
227  }
228  };
229 
237  MatrixType& rLeftHandSideMatrix,
238  VectorType& rRightHandSideVector,
239  const ProcessInfo& rCurrentProcessInfo) override {
240 
241  KRATOS_TRY;
242 
243  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
244 
245  // Initialize LHS and RHS
246  if (rLeftHandSideMatrix.size1() != MatrixSize) {
247  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false); // false says to not preserve existing storage!!
248  } else if (rLeftHandSideMatrix.size2() != MatrixSize) {
249  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false); // false says to not preserve existing storage!!
250  }
251 
252  if (rRightHandSideVector.size() != MatrixSize) {
253  rRightHandSideVector.resize(MatrixSize, false); // false says to not preserve existing storage!!
254  }
255 
256  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize, MatrixSize); // LHS initialization
257  noalias(rRightHandSideVector) = ZeroVector(MatrixSize); // RHS initialization
258 
259  // Embedded data struct filling
261  this->FillEmbeddedElementData(data, rCurrentProcessInfo);
262 
263  // Element LHS and RHS contributions computation
264  if(data.n_pos == TNumNodes) {
265  ComputeElementAsFluid<MatrixSize>(rLeftHandSideMatrix, rRightHandSideVector, data, rCurrentProcessInfo);
266  } else if ((data.n_pos != 0) && (data.n_neg != 0)) {
267  ComputeElementAsMixed<MatrixSize>(rLeftHandSideMatrix, rRightHandSideVector, data, rCurrentProcessInfo);
268  }
269 
270  KRATOS_CATCH("Error in embedded Navier-Stokes element CalculateLocalSystem method.");
271  }
272 
281  template<unsigned int MatrixSize>
283  MatrixType& rLeftHandSideMatrix,
284  VectorType& rRightHandSideVector,
286  const ProcessInfo& rCurrentProcessInfo) {
287 
288  // Allocate memory needed
291 
292  // Shape functions Gauss points values
293  // TODO: CHANGE THIS, USE THE GEOMETRY WITH A QUADRATURE
294  BoundedMatrix<double, TNumNodes, TNumNodes> Ncontainer; // Container with the evaluation of the n shape functions in the n Gauss pts.
296 
297  // Loop on gauss point
298  for(unsigned int igauss = 0; igauss<Ncontainer.size1(); igauss++) {
299  noalias(rData.N) = row(Ncontainer, igauss);
300 
301  BaseType::ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
302 
305 
306  // All the Gauss pts. have the same weight so the accumulated contributions can be multiplied by volume/n_nodes at the end
307  noalias(rLeftHandSideMatrix) += lhs_local;
308  noalias(rRightHandSideVector) += rhs_local;
309  }
310 
311  rLeftHandSideMatrix *= rData.volume/static_cast<double>(TNumNodes);
312  rRightHandSideVector *= rData.volume/static_cast<double>(TNumNodes);
313  }
314 
323  template<unsigned int MatrixSize>
325  MatrixType& rLeftHandSideMatrix,
326  VectorType& rRightHandSideVector,
328  const ProcessInfo& rCurrentProcessInfo) {
329 
330  // Allocate memory needed
333 
334  // Gauss points loop
335  const unsigned int n_gauss_pts = (rData.w_gauss_pos_side).size();
336 
337  for(unsigned int i_gauss = 0; i_gauss < n_gauss_pts; i_gauss++) {
338  noalias(rData.N) = row(rData.N_pos_side, i_gauss); // Take the new Gauss pts. shape functions values
339  noalias(rData.DN_DX) = rData.DN_DX_pos_side[i_gauss]; // Take the new Gauss pts. shape functions gradients values
340  const double weight = rData.w_gauss_pos_side(i_gauss); // Subvolume Gauss pt. weights
341 
342  BaseType::ComputeConstitutiveResponse(rData, rCurrentProcessInfo);
343 
346 
347  noalias(rLeftHandSideMatrix) += weight*lhs_local;
348  noalias(rRightHandSideVector) += weight*rhs_local;
349  }
350 
351  // Add level set boundary terms, penalty and modified Nitche contributions
352  AddBoundaryConditionElementContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
353  }
354 
363  int Check(const ProcessInfo &rCurrentProcessInfo) const override
364  {
365  KRATOS_TRY;
366 
367  // Base element check
368  int error_code = NavierStokes<TDim, TNumNodes>::Check(rCurrentProcessInfo);
369  if (error_code != 0){
370  return error_code;
371  }
372 
373  // Specific embedded element check
374  for (unsigned int i = 0; i < (this->GetGeometry()).size(); ++i){
375  if (this->GetGeometry()[i].SolutionStepsDataHas(DISTANCE) == false){
376  KRATOS_ERROR << "missing VELOCITY variable on solution step data for node " << this->GetGeometry()[i].Id();
377  }
378  }
379 
380  return 0;
381 
382  KRATOS_CATCH("");
383  }
384 
392  void Calculate(
393  const Variable<array_1d<double, 3>> &rVariable,
394  array_1d<double, 3> &rOutput,
395  const ProcessInfo &rCurrentProcessInfo) override {
396 
397  rOutput = ZeroVector(3);
398 
399  // If the element is split, integrate sigma·n over the interface
400  // Note that in the ausas formulation, both interface sides need to be integrated
401  if (rVariable == DRAG_FORCE) {
402 
404  this->FillEmbeddedElementData(data, rCurrentProcessInfo);
405 
406  // Check if the element is split
407  if (data.n_pos != 0 && data.n_neg != 0){
408 
409  // Integrate positive interface side drag
410  const unsigned int n_int_pos_gauss = (data.w_gauss_pos_int).size();
411  for (unsigned int i_gauss = 0; i_gauss < n_int_pos_gauss; ++i_gauss) {
412  // Get Gauss pt. data
413  const double w_gauss = data.w_gauss_pos_int(i_gauss);
414  const array_1d<double, TNumNodes> aux_N = row(data.N_pos_int, i_gauss);
415  const array_1d<double, 3> side_normal = data.pos_int_unit_normals[i_gauss];
416 
417  // Obtain Gauss pt. pressure
418  const double p_gauss = inner_prod(aux_N, data.p);
419 
420  // Call the constitutive law to compute the shear contribution
421  // Recall to set data.N and data.DN_DX (required by the constitutive law)
422  noalias(data.N) = aux_N;
423  noalias(data.DN_DX) = data.DN_DX_pos_int[i_gauss];
424  this->ComputeConstitutiveResponse(data, rCurrentProcessInfo);
425 
426  // Get the Voigt notation normal projection matrix
427  BoundedMatrix<double, TDim, (TDim - 1) * 3> normal_proj_mat = ZeroMatrix(TDim, (TDim - 1) * 3);
428  this->SetVoigtNormalProjectionMatrix(side_normal, normal_proj_mat);
429 
430  // Add the shear and pressure drag contributions
431  const array_1d<double, TDim> shear_proj = w_gauss * prod(normal_proj_mat, data.stress);
432  for (unsigned int i = 0; i < TDim ; ++i){
433  rOutput(i) -= shear_proj(i);
434  }
435  rOutput += w_gauss * p_gauss * side_normal;
436  }
437  }
438  }
439  else
440  {
441  KRATOS_ERROR << "Calculate method not implemented for the requested variable.";
442  }
443  }
444 
445  void Calculate(const Variable<double>& rVariable,
446  double& Output,
447  const ProcessInfo& rCurrentProcessInfo) override
448  {}
449 
450  void Calculate(const Variable<Vector >& rVariable,
451  Vector& Output,
452  const ProcessInfo& rCurrentProcessInfo) override
453  {}
454 
455  void Calculate(const Variable<Matrix >& rVariable,
456  Matrix& Output,
457  const ProcessInfo& rCurrentProcessInfo) override
458  {}
459 
463 
464 
468 
469 
473 
475 
476  std::string Info() const override {
477  return "EmbeddedNavierStokes3D #";
478  }
479 
483 
484 
486 
487 protected:
490 
494 
498 
499  EmbeddedNavierStokes() : NavierStokes<TDim, TNumNodes>() {}
500 
504 
514  MatrixType& rLeftHandSideMatrix,
515  VectorType& rRightHandSideVector,
516  const EmbeddedElementDataStruct& rData) {
517 
518  constexpr unsigned int BlockSize = TDim+1;
519  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
520 
521  // Obtain the previous iteration velocity solution
522  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
523  GetPreviousSolutionVector(rData, prev_sol);
524 
525  // Declare auxiliar arrays
526  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
527 
528  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
529 
530  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
531 
532  // Get the current Gauss pt. data
533  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int); // Shape function values
534  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss_int]; // Shape function gradient values
535  const double weight = rData.w_gauss_pos_int(i_gauss_int); // Intersection Gauss pt. weight
536  const array_1d<double, 3> aux_unit_normal = rData.pos_int_unit_normals[i_gauss_int]; // Gauss pt. unit normal
537 
538  // Set the current Gauss pt. Voigt notation normal projection matrix
539  BoundedMatrix<double, TDim, (TDim-1)*3> voigt_normal_projection_matrix = ZeroMatrix(TDim, (TDim-1)*3);
540  SetVoigtNormalProjectionMatrix(aux_unit_normal, voigt_normal_projection_matrix);
541 
542  // Set the current Gauss pt. strain matrix
543  BoundedMatrix<double, (TDim-1)*3, MatrixSize> B_matrix = ZeroMatrix((TDim-1)*3, MatrixSize);
544  SetInterfaceStrainMatrix(aux_DN_DX, B_matrix);
545 
546  // Compute some Gauss pt. auxiliar matrices
547  const BoundedMatrix<double, TDim, (TDim-1)*3> aux_matrix_AC = prod(voigt_normal_projection_matrix, rData.C);
548  const BoundedMatrix<double, (TDim-1)*3, MatrixSize> aux_matrix_ACB = prod(aux_matrix_AC, B_matrix);
549 
550  // Fill the pressure to Voigt notation operator matrix
551  BoundedMatrix<double, (TDim-1)*3, MatrixSize> pres_to_voigt_matrix_op = ZeroMatrix((TDim-1)*3, MatrixSize);
552  for (unsigned int i=0; i<TNumNodes; ++i) {
553  for (unsigned int comp=0; comp<TDim; ++comp) {
554  pres_to_voigt_matrix_op(comp, i*BlockSize+TDim) = aux_N(i);
555  }
556  }
557 
558  // Set the shape functions auxiliar transpose matrix
559  BoundedMatrix<double, MatrixSize, TDim> N_aux_trans = ZeroMatrix(MatrixSize, TDim);
560  for (unsigned int i=0; i<TNumNodes; ++i) {
561  for (unsigned int comp=0; comp<TDim; ++comp) {
562  N_aux_trans(i*BlockSize+comp, comp) = aux_N(i);
563  }
564  }
565 
566  // Contribution coming fron the shear stress operator
567  noalias(auxLeftHandSideMatrix) += weight*prod(N_aux_trans, aux_matrix_ACB);
568 
569  // Contribution coming from the pressure terms
570  const BoundedMatrix<double, MatrixSize, (TDim-1)*3> N_voigt_proj_matrix = prod(N_aux_trans, voigt_normal_projection_matrix);
571  noalias(auxLeftHandSideMatrix) -= weight*prod(N_voigt_proj_matrix, pres_to_voigt_matrix_op);
572  }
573 
574  // LHS assembly
575  noalias(rLeftHandSideMatrix) -= auxLeftHandSideMatrix;
576 
577  // RHS assembly
578  noalias(rRightHandSideVector) += prod(auxLeftHandSideMatrix, prev_sol);
579  }
580 
587  const EmbeddedElementDataStruct& rData,
588  const ProcessInfo &rCurrentProcessInfo)
589  {
590  // Compute the intersection area using the Gauss pts. weights
591  double intersection_area = 0.0;
592  for (unsigned int i_gauss = 0; i_gauss < (rData.w_gauss_pos_int).size(); ++i_gauss) {
593  intersection_area += rData.w_gauss_pos_int(i_gauss);
594  }
595 
596  // Compute the element average values
597  array_1d<double, TDim> avg_vel = ZeroVector(TDim);
598  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
599  avg_vel += row(rData.v, i_node);
600  }
601  avg_vel /= TNumNodes;
602 
603  const double v_norm = norm_2(avg_vel);
604 
605  // Compute the penalty constant
606  const double pen_cons = rData.rho*std::pow(rData.h, TDim)/rData.dt +
607  rData.rho*rData.mu*std::pow(rData.h,TDim-2) +
608  rData.rho*v_norm*std::pow(rData.h, TDim-1);
609 
610  // Return the penalty coefficient
611  const double K = rCurrentProcessInfo[PENALTY_COEFFICIENT];
612  const double pen_coef = K * pen_cons / intersection_area;
613 
614  return pen_coef;
615 
616  }
617 
625  MatrixType& rLeftHandSideMatrix,
626  VectorType& rRightHandSideVector,
627  const EmbeddedElementDataStruct& rData,
628  const ProcessInfo &rCurrentProcessInfo)
629  {
630  constexpr unsigned int BlockSize = TDim+1;
631  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
632 
633  // Obtain the previous iteration velocity solution
634  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
635  GetPreviousSolutionVector(rData, prev_sol);
636 
637  // Substract the embedded nodal velocity to the previous iteration solution
638  const auto &r_geom = this->GetGeometry();
639  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
640  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
641  for (unsigned int d = 0; d < TDim; ++d) {
642  prev_sol(i_node * BlockSize + d) -= r_i_emb_vel(d);
643  }
644  }
645 
646  // Set the penalty matrix
647  MatrixType P_gamma(TNumNodes, TNumNodes);
648  noalias(P_gamma) = ZeroMatrix(TNumNodes, TNumNodes);
649 
650  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
651 
652  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
653  const double weight = rData.w_gauss_pos_int(i_gauss_int);
654  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int);
655  P_gamma += weight*outer_prod(aux_N,aux_N);
656  }
657 
658  // Multiply the penalty matrix by the penalty coefficient
659  double pen_coef = ComputePenaltyCoefficient(rData, rCurrentProcessInfo);
660  P_gamma *= pen_coef;
661 
662  VectorType auxRightHandSideVector = ZeroVector(MatrixSize);
663  MatrixType auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
664 
665  // LHS penalty contribution assembly (symmetric mass matrix)
666  for (unsigned int i = 0; i<TNumNodes; i++) {
667  // Diagonal terms
668  for (unsigned int comp = 0; comp<TDim; comp++) {
669  auxLeftHandSideMatrix(i*BlockSize+comp, i*BlockSize+comp) = P_gamma(i,i);
670  }
671  // Off-diagonal terms
672  for (unsigned int j = i+1; j<TNumNodes; j++) {
673  for (unsigned int comp = 0; comp<TDim; comp++) {
674  auxLeftHandSideMatrix(i*BlockSize+comp, j*BlockSize+comp) = P_gamma(i,j);
675  auxLeftHandSideMatrix(j*BlockSize+comp, i*BlockSize+comp) = P_gamma(i,j);
676  }
677  }
678  }
679 
680  noalias(rLeftHandSideMatrix) += auxLeftHandSideMatrix;
681  noalias(rRightHandSideVector) -= prod(auxLeftHandSideMatrix, prev_sol); // Residual contribution assembly
682  }
683 
691  MatrixType& rLeftHandSideMatrix,
692  VectorType& rRightHandSideVector,
693  const EmbeddedElementDataStruct& rData) {
694 
695  constexpr unsigned int BlockSize = TDim+1; // Block size
696  constexpr unsigned int MatrixSize = TNumNodes*BlockSize; // Matrix size
697 
698  // Obtain the previous iteration velocity solution
699  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
700  GetPreviousSolutionVector(rData, prev_sol);
701 
702  // Compute the BCs imposition matrices
703  MatrixType M_gamma = ZeroMatrix(rData.n_neg, rData.n_neg); // Outside nodes matrix (Nitche contribution)
704  MatrixType N_gamma = ZeroMatrix(rData.n_neg, rData.n_pos); // Interior nodes matrix (Nitche contribution)
705  MatrixType f_gamma = ZeroMatrix(rData.n_neg, TNumNodes); // Matrix to compute the RHS (Nitche contribution)
706 
707  VectorType aux_out(rData.n_neg);
708  VectorType aux_int(rData.n_pos);
709 
710  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
711 
712  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
713  const double weight = rData.w_gauss_pos_int(i_gauss_int);
714 
715  const VectorType aux_cut = row(rData.N_pos_int, i_gauss_int);
716 
717  for (unsigned int i_out = 0; i_out < rData.n_neg; ++i_out) {
718  const unsigned int i_out_nodeid = rData.out_vec_identifiers[i_out];
719  aux_out(i_out) = aux_cut(i_out_nodeid);
720  }
721 
722  for (unsigned int i_int = 0; i_int < rData.n_pos; ++i_int) {
723  const unsigned int i_int_nodeid = rData.int_vec_identifiers[i_int];
724  aux_int(i_int) = aux_cut(i_int_nodeid);
725  }
726 
727  M_gamma += weight*outer_prod(aux_out,aux_out);
728  N_gamma += weight*outer_prod(aux_out,aux_int);
729  f_gamma += weight*outer_prod(aux_out,aux_cut);
730  }
731 
732  // Declare auxLeftHandSideMatrix
733  MatrixType auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
734 
735  // LHS outside nodes contribution assembly
736  // Outer nodes contribution assembly
737  for (unsigned int i = 0; i<rData.n_neg; i++) {
738  unsigned int out_node_row_id = rData.out_vec_identifiers[i];
739 
740  for (unsigned int j = 0; j<rData.n_neg; j++) {
741  unsigned int out_node_col_id = rData.out_vec_identifiers[j];
742 
743  for (unsigned int comp = 0; comp<TDim; comp++) {
744  auxLeftHandSideMatrix(out_node_row_id*BlockSize+comp, out_node_col_id*BlockSize+comp) = M_gamma(i, j);
745  }
746  }
747  }
748 
749  // Interior nodes contribution assembly
750  for (unsigned int i = 0; i<rData.n_neg; i++) {
751  unsigned int out_node_row_id = rData.out_vec_identifiers[i];
752 
753  for (unsigned int j = 0; j<rData.n_pos; j++) {
754  unsigned int int_node_col_id = rData.int_vec_identifiers[j];
755 
756  for (unsigned int comp = 0; comp<TDim; comp++) {
757  auxLeftHandSideMatrix(out_node_row_id*BlockSize+comp, int_node_col_id*BlockSize+comp) = N_gamma(i, j);
758  }
759  }
760  }
761 
762  // LHS outside Nitche contribution assembly
763  noalias(rLeftHandSideMatrix) += auxLeftHandSideMatrix;
764 
765  // RHS outside Nitche contribution assembly
766  // Note that since we work with a residualbased formulation, the RHS is f_gamma - LHS*prev_sol
767  noalias(rRightHandSideVector) -= prod(auxLeftHandSideMatrix, prev_sol);
768 
769  // Compute the level set velocity contribution
770  const auto &r_geom = this->GetGeometry();
771  for (unsigned int i_gauss = 0; i_gauss < n_gauss_total; ++i_gauss) {
772  // Current Gauss pt. intersection data
773  const auto N_cut = row(rData.N_pos_int, i_gauss);
774  const double weight = rData.w_gauss_pos_int(i_gauss);
775 
776  // Current Gauss pt. EMBEDDED_VELOCITY
777  array_1d<double,3> aux_emb_v = ZeroVector(3);
778  for (unsigned int i_node = 0; i_node < r_geom.PointsNumber(); ++i_node) {
779  aux_emb_v += N_cut(i_node) * r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
780  }
781 
782  // Assemble current Gauss pt. contribution
783  for (unsigned int i = 0; i < rData.n_neg; ++i) {
784  const unsigned int i_out_node_id = rData.out_vec_identifiers[i];
785  for (unsigned int j = 0; j < TNumNodes; ++j) {
786  const double aux = weight * N_cut(i_out_node_id) * N_cut(j);
787  for (unsigned int d = 0; d < TDim; ++d) {
788  rRightHandSideVector(i_out_node_id * BlockSize + d) += aux * aux_emb_v(d);
789  }
790  }
791  }
792  }
793  }
794 
802  MatrixType& rLeftHandSideMatrix,
803  VectorType& rRightHandSideVector,
804  const EmbeddedElementDataStruct& rData) {
805 
806  constexpr unsigned int BlockSize = TDim+1;
807  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
808 
809  // Set the LHS and RHS u_out rows to zero (outside nodes used to impose the BC)
810  for (unsigned int i=0; i<rData.n_neg; ++i) {
811  const unsigned int out_node_row_id = rData.out_vec_identifiers[i];
812 
813  for (unsigned int j=0; j<TDim; ++j) {
814  // LHS matrix u_out zero set (note that just the velocity rows are set to 0)
815  for (unsigned int col = 0; col<MatrixSize; col++) {
816  rLeftHandSideMatrix(out_node_row_id*BlockSize+j, col) = 0.0;
817  }
818 
819  // RHS vector u_out zero set (note that just the velocity rows are set to 0)
820  rRightHandSideVector(out_node_row_id*BlockSize+j) = 0.0;
821  }
822  }
823  }
824 
832  MatrixType& rLeftHandSideMatrix,
833  VectorType& rRightHandSideVector,
834  const EmbeddedElementDataStruct& rData,
835  const ProcessInfo &rCurrentProcessInfo)
836  {
837  constexpr unsigned int BlockSize = TDim+1;
838  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
839 
840  // Obtain the previous iteration velocity solution
841  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
842  GetPreviousSolutionVector(rData, prev_sol);
843 
844  // Substract the embedded nodal velocity to the previous iteration solution
845  const auto &r_geom = this->GetGeometry();
846  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
847  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
848  for (unsigned int d = 0; d < TDim; ++d) {
849  prev_sol(i_node * BlockSize + d) -= r_i_emb_vel(d);
850  }
851  }
852 
853  // Nitsche coefficient computation
854  const double eff_mu = BaseType::ComputeEffectiveViscosity(rData);
855 
856  // Compute the element average velocity norm
857  double v_norm = 0.0;
858  for (unsigned int comp=0; comp<TDim; ++comp) {
859  double aux_vel = 0.0;
860  for (unsigned int j=0; j<TNumNodes; ++j) {
861  aux_vel += rData.v(j,comp);
862  }
863  aux_vel /= TNumNodes;
864  v_norm += aux_vel*aux_vel;
865  }
866  v_norm = std::sqrt(v_norm);
867 
868  // Compute the Nitsche coefficient (considering the Winter stabilization term)
869  const double penalty = 1.0/rCurrentProcessInfo[PENALTY_COEFFICIENT];
870  const double cons_coef = (eff_mu + eff_mu + rData.rho*v_norm*rData.h + rData.rho*rData.h*rData.h/rData.dt)/(rData.h*penalty);
871 
872  // Declare auxiliar arrays
873  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
874  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
875 
876  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
877  // Get the Gauss pt. data
878  const double weight = rData.w_gauss_pos_int(i_gauss_int);
879  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int);
880  const array_1d<double, 3> aux_unit_normal = rData.pos_int_unit_normals[i_gauss_int];
881 
882  // Set the shape functions auxiliar matrices
883  BoundedMatrix<double, TDim, MatrixSize> N_aux = ZeroMatrix(TDim, MatrixSize);
884  for (unsigned int i=0; i<TNumNodes; ++i) {
885  for (unsigned int comp=0; comp<TDim; ++comp) {
886  N_aux(comp,i*BlockSize+comp) = aux_N(i);
887  }
888  }
889  const BoundedMatrix<double, MatrixSize, TDim> N_aux_trans = trans(N_aux);
890 
891  // Set the normal projection matrix nxn
892  BoundedMatrix<double, TDim, TDim> normal_projection_matrix;
893  SetNormalProjectionMatrix(aux_unit_normal, normal_projection_matrix);
894 
895  // Compute the current cut point auxLHS contribution
896  const BoundedMatrix<double, MatrixSize, TDim> aux_1 = prod(N_aux_trans, normal_projection_matrix);
897  const BoundedMatrix<double, MatrixSize, MatrixSize> aux_2 = prod(aux_1, N_aux);
898  noalias(auxLeftHandSideMatrix) += cons_coef*weight*aux_2;
899  }
900 
901  // LHS outside Nitche contribution assembly
902  noalias(rLeftHandSideMatrix) += auxLeftHandSideMatrix;
903 
904  // RHS outside Nitche contribution assembly
905  // Note that since we work with a residualbased formulation, the RHS is f_gamma - LHS*prev_sol
906  noalias(rRightHandSideVector) -= prod(auxLeftHandSideMatrix, prev_sol);
907  }
908 
916  MatrixType& rLeftHandSideMatrix,
917  VectorType& rRightHandSideVector,
918  const EmbeddedElementDataStruct& rData) {
919 
920  constexpr unsigned int BlockSize = TDim+1;
921  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
922 
923  // Obtain the previous iteration velocity solution
924  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
925  GetPreviousSolutionVector(rData, prev_sol);
926 
927  // Substract the embedded nodal velocity to the previous iteration solution
928  const auto &r_geom = this->GetGeometry();
929  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
930  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
931  for (unsigned int d = 0; d < TDim; ++d) {
932  prev_sol(i_node * BlockSize + d) -= r_i_emb_vel(d);
933  }
934  }
935 
936  // Set if the shear stress term is adjoint consistent (1.0) or not (-1.0)
937  const double adjoint_consistency_term = -1.0;
938 
939  // Declare auxiliar arrays
940  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix = ZeroMatrix(MatrixSize, MatrixSize);
941  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
942 
943  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
944  // Get the Gauss pt. data
945  const double weight = rData.w_gauss_pos_int(i_gauss_int);
946  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int);
947  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss_int];
948  const array_1d<double, 3> aux_unit_normal = rData.pos_int_unit_normals[i_gauss_int];
949 
950  // Fill the pressure to Voigt notation operator normal projected matrix
951  BoundedMatrix<double, MatrixSize, TDim> trans_pres_to_voigt_matrix_normal_op = ZeroMatrix(MatrixSize, TDim);
952  for (unsigned int i=0; i<TNumNodes; ++i) {
953  for (unsigned int comp=0; comp<TDim; ++comp) {
954  trans_pres_to_voigt_matrix_normal_op(i*BlockSize+TDim, comp) = aux_N(i)*aux_unit_normal(comp);
955  }
956  }
957 
958  // Set the shape functions auxiliar matrix
959  BoundedMatrix<double, TDim, MatrixSize> N_aux = ZeroMatrix(TDim, MatrixSize);
960  for (unsigned int i=0; i<TNumNodes; ++i) {
961  for (unsigned int comp=0; comp<TDim; ++comp) {
962  N_aux(comp,i*BlockSize+comp) = aux_N(i);
963  }
964  }
965 
966  // Get the strain matrix
967  BoundedMatrix<double, (TDim-1)*3, MatrixSize> B_matrix = ZeroMatrix((TDim-1)*3, MatrixSize);
968  SetInterfaceStrainMatrix(aux_DN_DX, B_matrix);
969 
970  // Get the normal projection matrix
971  BoundedMatrix<double, TDim, TDim> normal_projection_matrix = ZeroMatrix(TDim, TDim);
972  SetNormalProjectionMatrix(aux_unit_normal, normal_projection_matrix);
973 
974  // Get the normal projection matrix in Voigt notation
975  BoundedMatrix<double, TDim, (TDim-1)*3> voigt_normal_projection_matrix = ZeroMatrix(TDim, (TDim-1)*3);
976  SetVoigtNormalProjectionMatrix(aux_unit_normal, voigt_normal_projection_matrix);
977 
978  // Compute some Gauss pt. auxiliar matrices
979  const BoundedMatrix<double, MatrixSize, (TDim-1)*3> aux_matrix_BC = prod(trans(B_matrix), trans(rData.C));
980  const BoundedMatrix<double, (TDim-1)*3, TDim> aux_matrix_APnorm = prod(trans(voigt_normal_projection_matrix), normal_projection_matrix);
981  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_BCAPnorm = prod(aux_matrix_BC, aux_matrix_APnorm);
982 
983  // Contribution coming fron the shear stress operator
984  noalias(auxLeftHandSideMatrix) += adjoint_consistency_term*weight*prod(aux_matrix_BCAPnorm, N_aux);
985 
986  // Contribution coming from the pressure terms
987  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_VPnorm = prod(trans_pres_to_voigt_matrix_normal_op, normal_projection_matrix);
988  noalias(auxLeftHandSideMatrix) += weight*prod(aux_matrix_VPnorm, N_aux);
989 
990  }
991 
992  // LHS outside Nitche contribution assembly
993  noalias(rLeftHandSideMatrix) -= auxLeftHandSideMatrix; // The minus sign comes from the Nitsche formulation
994 
995  // RHS outside Nitche contribution assembly
996  noalias(rRightHandSideVector) += prod(auxLeftHandSideMatrix, prev_sol);
997  }
998 
1006  MatrixType& rLeftHandSideMatrix,
1007  VectorType& rRightHandSideVector,
1008  const EmbeddedElementDataStruct& rData,
1009  const ProcessInfo &rCurrentProcessInfo)
1010  {
1011  constexpr unsigned int BlockSize = TDim+1;
1012  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
1013 
1014  // Obtain the previous iteration velocity solution
1015  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
1016  GetPreviousSolutionVector(rData, prev_sol);
1017 
1018  // Compute the penalty coefficients
1019  const double eff_mu = BaseType::ComputeEffectiveViscosity(rData);
1020  const double penalty = 1.0/rCurrentProcessInfo[PENALTY_COEFFICIENT];
1021  const double slip_length = rCurrentProcessInfo[SLIP_LENGTH];
1022  const double coeff_1 = slip_length / (slip_length + penalty*rData.h);
1023  const double coeff_2 = eff_mu / (slip_length + penalty*rData.h);
1024 
1025  // Declare auxiliar arrays
1026  array_1d<double, MatrixSize> auxRightHandSideVector = ZeroVector(MatrixSize);
1027  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix_1 = ZeroMatrix(MatrixSize, MatrixSize); // Adds the contribution coming from the tangential component of the Cauchy stress vector
1028  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix_2 = ZeroMatrix(MatrixSize, MatrixSize); // Adds the contribution generated by the viscous shear force generated by the velocity
1029 
1030  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
1031 
1032  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
1033  // Get the Gauss pt. data
1034  const double weight = rData.w_gauss_pos_int(i_gauss_int);
1035  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int);
1036  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss_int];
1037  const array_1d<double, 3> aux_unit_normal = rData.pos_int_unit_normals[i_gauss_int];
1038 
1039  // Set the shape functions auxiliar matrix
1040  BoundedMatrix<double, MatrixSize, TDim> N_aux_trans = ZeroMatrix(MatrixSize, TDim);
1041  for (unsigned int i=0; i<TNumNodes; ++i) {
1042  for (unsigned int comp=0; comp<TDim; ++comp) {
1043  N_aux_trans(i*BlockSize+comp, comp) = aux_N(i);
1044  }
1045  }
1046 
1047  // Get the strain matrix
1048  BoundedMatrix<double, (TDim-1)*3, MatrixSize> B_matrix = ZeroMatrix((TDim-1)*3, MatrixSize);
1049  SetInterfaceStrainMatrix(aux_DN_DX, B_matrix);
1050 
1051  // Get the normal projection matrix
1052  BoundedMatrix<double, TDim, TDim> tangential_projection_matrix = ZeroMatrix(TDim, TDim);
1053  SetTangentialProjectionMatrix(aux_unit_normal, tangential_projection_matrix);
1054 
1055  // Get the normal projection matrix in Voigt notation
1056  BoundedMatrix<double, TDim, (TDim-1)*3> voigt_normal_projection_matrix = ZeroMatrix(TDim, (TDim-1)*3);
1057  SetVoigtNormalProjectionMatrix(aux_unit_normal, voigt_normal_projection_matrix);
1058 
1059  // Compute some Gauss pt. auxiliar matrices
1060  const BoundedMatrix<double, (TDim-1)*3, MatrixSize> aux_matrix_CB = prod(rData.C, B_matrix);
1061  const BoundedMatrix<double, (TDim-1)*3, TDim> aux_matrix_PtangA = prod(tangential_projection_matrix, voigt_normal_projection_matrix);
1062  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_PtangACB = prod(aux_matrix_PtangA, aux_matrix_CB);
1063 
1064  // Contribution coming from the traction vector tangencial component
1065  noalias(auxLeftHandSideMatrix_1) += coeff_1*weight*prod(N_aux_trans, aux_matrix_PtangACB);
1066 
1067  // Contribution coming from the shear force generated by the velocity jump
1068  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_N_trans_tang = prod(N_aux_trans, tangential_projection_matrix);
1069  noalias(auxLeftHandSideMatrix_2) += coeff_2*weight*prod(aux_matrix_N_trans_tang, trans(N_aux_trans));
1070  }
1071 
1072  // LHS outside Nitche contribution assembly
1073  noalias(rLeftHandSideMatrix) += auxLeftHandSideMatrix_1;
1074  noalias(rLeftHandSideMatrix) += auxLeftHandSideMatrix_2;
1075 
1076  // RHS outside Nitche contribution assembly
1077  // If level set velocity is not 0, add its contribution to the RHS
1078  const auto &r_geom = this->GetGeometry();
1079  array_1d<double, MatrixSize> embedded_vel_exp = ZeroVector(MatrixSize);
1080  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
1081  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
1082  for (unsigned int d = 0; d < TDim; ++d) {
1083  embedded_vel_exp(i_node * BlockSize + d) -= r_i_emb_vel(d);
1084  }
1085  }
1086 
1087  // Note that since we work with a residualbased formulation, the RHS is f_gamma - LHS*prev_sol
1088  noalias(rRightHandSideVector) += auxRightHandSideVector;
1089  noalias(rRightHandSideVector) -= prod(auxLeftHandSideMatrix_1, prev_sol);
1090  noalias(rRightHandSideVector) -= prod(auxLeftHandSideMatrix_2, prev_sol);
1091  noalias(auxRightHandSideVector) += prod(auxLeftHandSideMatrix_2, embedded_vel_exp);
1092  }
1093 
1101  MatrixType& rLeftHandSideMatrix,
1102  VectorType& rRightHandSideVector,
1103  const EmbeddedElementDataStruct& rData,
1104  const ProcessInfo &rCurrentProcessInfo)
1105  {
1106  constexpr unsigned int BlockSize = TDim+1;
1107  constexpr unsigned int MatrixSize = TNumNodes*BlockSize;
1108 
1109  // Obtain the previous iteration velocity solution
1110  array_1d<double, MatrixSize> prev_sol = ZeroVector(MatrixSize);
1111  GetPreviousSolutionVector(rData, prev_sol);
1112 
1113  // Set if the shear stress term is adjoint consistent (1.0) or not (-1.0)
1114  const double adjoint_consistency_term = -1.0;
1115 
1116  // Compute the coefficients
1117  const double eff_mu = BaseType::ComputeEffectiveViscosity(rData);
1118  const double penalty = 1.0/rCurrentProcessInfo[PENALTY_COEFFICIENT];
1119  const double slip_length = rCurrentProcessInfo[SLIP_LENGTH];
1120  const double coeff_1 = slip_length*penalty*rData.h / (slip_length + penalty*rData.h);
1121  const double coeff_2 = eff_mu*penalty*rData.h / (slip_length + penalty*rData.h);
1122 
1123  // Declare auxiliar arrays
1124  array_1d<double, MatrixSize> auxRightHandSideVector = ZeroVector(MatrixSize);
1125  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix_1 = ZeroMatrix(MatrixSize, MatrixSize); // Adds the contribution coming from the tangential component of the Cauchy stress vector
1126  BoundedMatrix<double, MatrixSize, MatrixSize> auxLeftHandSideMatrix_2 = ZeroMatrix(MatrixSize, MatrixSize); // Adds the contribution generated by the viscous shear force generated by the velocity
1127 
1128  const unsigned int n_gauss_total = (rData.w_gauss_pos_int).size();
1129 
1130  for (unsigned int i_gauss_int = 0; i_gauss_int < n_gauss_total; ++i_gauss_int) {
1131  // Get the Gauss pt. data
1132  const double weight = rData.w_gauss_pos_int(i_gauss_int);
1133  const array_1d<double, TNumNodes> aux_N = row(rData.N_pos_int, i_gauss_int);
1134  const BoundedMatrix<double, TNumNodes, TDim> aux_DN_DX = rData.DN_DX_pos_int[i_gauss_int];
1135  const array_1d<double, 3> aux_unit_normal = rData.pos_int_unit_normals[i_gauss_int];
1136 
1137  // Set the shape functions auxiliar matrix
1138  BoundedMatrix<double, TDim, MatrixSize> N_aux = ZeroMatrix(TDim, MatrixSize);
1139  for (unsigned int i=0; i<TNumNodes; ++i) {
1140  for (unsigned int comp=0; comp<TDim; ++comp) {
1141  N_aux(comp, i*BlockSize+comp) = aux_N(i);
1142  }
1143  }
1144 
1145  // Get the strain matrix
1146  BoundedMatrix<double, (TDim-1)*3, MatrixSize> B_matrix = ZeroMatrix((TDim-1)*3, MatrixSize);
1147  SetInterfaceStrainMatrix(aux_DN_DX, B_matrix);
1148 
1149  // Get the normal projection matrix
1150  BoundedMatrix<double, TDim, TDim> tangential_projection_matrix = ZeroMatrix(TDim, TDim);
1151  SetTangentialProjectionMatrix(aux_unit_normal, tangential_projection_matrix);
1152 
1153  // Get the normal projection matrix in Voigt notation
1154  BoundedMatrix<double, TDim, (TDim-1)*3> voigt_normal_projection_matrix = ZeroMatrix(TDim, (TDim-1)*3);
1155  SetVoigtNormalProjectionMatrix(aux_unit_normal, voigt_normal_projection_matrix);
1156 
1157  // Compute some Gauss pt. auxiliar matrices
1158  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_BtransAtrans = prod(trans(B_matrix), trans(voigt_normal_projection_matrix));
1159  const BoundedMatrix<double, MatrixSize, TDim> aux_matrix_BtransAtransPtan = prod(aux_matrix_BtransAtrans, tangential_projection_matrix);
1160  const BoundedMatrix<double, (TDim-1)*3, MatrixSize> aux_matrix_CB = prod(rData.C, B_matrix);
1161  const BoundedMatrix<double, TDim, MatrixSize> aux_matrix_ACB = prod(voigt_normal_projection_matrix, aux_matrix_CB);
1162  const BoundedMatrix<double, MatrixSize, MatrixSize> aux_matrix_BtransAtransPtanACB = prod(aux_matrix_BtransAtransPtan, aux_matrix_ACB);
1163 
1164  // Contribution coming from the traction vector tangencial component
1165  noalias(auxLeftHandSideMatrix_1) += adjoint_consistency_term*coeff_1*weight*aux_matrix_BtransAtransPtanACB;
1166 
1167  // Contribution coming from the shear force generated by the velocity jump
1168  noalias(auxLeftHandSideMatrix_2) += adjoint_consistency_term*coeff_2*weight*prod(aux_matrix_BtransAtransPtan, N_aux);
1169 
1170  }
1171 
1172  // LHS outside Nitche contribution assembly
1173  noalias(rLeftHandSideMatrix) -= auxLeftHandSideMatrix_1;
1174  noalias(rLeftHandSideMatrix) -= auxLeftHandSideMatrix_2;
1175 
1176  // RHS outside Nitche contribution assembly
1177  // If level set velocity is not 0, add its contribution to the RHS
1178  const auto &r_geom = this->GetGeometry();
1179  array_1d<double, MatrixSize> embedded_vel_exp = ZeroVector(MatrixSize);
1180  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
1181  const auto &r_i_emb_vel = r_geom[i_node].GetValue(EMBEDDED_VELOCITY);
1182  for (unsigned int d = 0; d < TDim; ++d) {
1183  embedded_vel_exp(i_node * BlockSize + d) -= r_i_emb_vel(d);
1184  }
1185  }
1186 
1187  // Note that since we work with a residualbased formulation, the RHS is f_gamma - LHS*prev_sol
1188  noalias(rRightHandSideVector) -= auxRightHandSideVector;
1189  noalias(rRightHandSideVector) += prod(auxLeftHandSideMatrix_1, prev_sol);
1190  noalias(rRightHandSideVector) += prod(auxLeftHandSideMatrix_2, prev_sol);
1191  noalias(auxRightHandSideVector) -= prod(auxLeftHandSideMatrix_2, embedded_vel_exp);
1192  }
1193 
1201  MatrixType& rLeftHandSideMatrix,
1202  VectorType& rRightHandSideVector,
1203  const EmbeddedElementDataStruct& rData,
1204  const ProcessInfo &rCurrentProcessInfo)
1205  {
1206  // Compute and assemble the boundary terms comping from the integration by parts
1207  AddIntersectionBoundaryTermsContribution(rLeftHandSideMatrix, rRightHandSideVector, rData);
1208 
1209  if (this->Is(SLIP)) {
1210  // Winter Navier-slip condition
1211  AddSlipWinterNormalPenaltyContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
1212  AddSlipWinterNormalSymmetricCounterpartContribution(rLeftHandSideMatrix, rRightHandSideVector, rData);
1213  AddSlipWinterTangentialPenaltyContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
1214  AddSlipWinterTangentialSymmetricCounterpartContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
1215 
1216  } else {
1217  // First, compute and assemble the penalty level set BC imposition contribution
1218  // Secondly, compute and assemble the modified Nitche method level set BC imposition contribution (Codina and Baiges, 2009)
1219  // Note that the Nitche contribution has to be computed the last since it drops the outer nodes rows previous constributions
1220  AddBoundaryConditionPenaltyContribution(rLeftHandSideMatrix, rRightHandSideVector, rData, rCurrentProcessInfo);
1221  DropOuterNodesVelocityContribution(rLeftHandSideMatrix, rRightHandSideVector, rData);
1222  AddBoundaryConditionModifiedNitcheContribution(rLeftHandSideMatrix, rRightHandSideVector, rData);
1223  }
1224  }
1225 
1233  BoundedMatrix<double, (TDim-1)*3, TNumNodes*(TDim+1)>& rB_matrix) {
1234 
1235  constexpr unsigned int BlockSize = TDim+1;
1236  rB_matrix.clear();
1237 
1238  if constexpr (TDim == 3) {
1239  for (unsigned int i=0; i<TNumNodes; i++) {
1240  rB_matrix(0,i*BlockSize) = rDN_DX(i,0);
1241  rB_matrix(1,i*BlockSize+1) = rDN_DX(i,1);
1242  rB_matrix(2,i*BlockSize+2) = rDN_DX(i,2);
1243  rB_matrix(3,i*BlockSize) = rDN_DX(i,1);
1244  rB_matrix(3,i*BlockSize+1) = rDN_DX(i,0);
1245  rB_matrix(4,i*BlockSize+1) = rDN_DX(i,2);
1246  rB_matrix(4,i*BlockSize+2) = rDN_DX(i,1);
1247  rB_matrix(5,i*BlockSize) = rDN_DX(i,2);
1248  rB_matrix(5,i*BlockSize+2) = rDN_DX(i,0);
1249  }
1250  } else {
1251  for (unsigned int i=0; i<TNumNodes; i++) {
1252  rB_matrix(0,i*BlockSize) = rDN_DX(i,0);
1253  rB_matrix(1,i*BlockSize+1) = rDN_DX(i,1);
1254  rB_matrix(2,i*BlockSize) = rDN_DX(i,1);
1255  rB_matrix(2,i*BlockSize+1) = rDN_DX(i,0);
1256  }
1257  }
1258  }
1259 
1266  const array_1d<double, 3>& rUnitNormal,
1267  BoundedMatrix<double, TDim, TDim>& rNormProjMatrix) {
1268 
1269  rNormProjMatrix.clear();
1270 
1271  // Fill the normal projection matrix (nxn)
1272  if constexpr (TDim == 3) {
1273  noalias(rNormProjMatrix) = outer_prod(rUnitNormal, rUnitNormal);
1274  } else {
1275  rNormProjMatrix(0,0) = rUnitNormal(0)*rUnitNormal(0);
1276  rNormProjMatrix(0,1) = rUnitNormal(0)*rUnitNormal(1);
1277  rNormProjMatrix(1,0) = rUnitNormal(1)*rUnitNormal(0);
1278  rNormProjMatrix(1,1) = rUnitNormal(1)*rUnitNormal(1);
1279  }
1280  }
1281 
1288  const array_1d<double, 3>& rUnitNormal,
1289  BoundedMatrix<double, TDim, TDim>& rTangProjMatrix) {
1290 
1291  rTangProjMatrix.clear();
1292 
1293  // Fill the tangential projection matrix (I - nxn)
1294  if constexpr (TDim == 3) {
1295  BoundedMatrix<double,3,3> id_matrix = IdentityMatrix(TDim,TDim);
1296  noalias(rTangProjMatrix) = id_matrix - outer_prod(rUnitNormal, rUnitNormal);
1297  } else {
1298  rTangProjMatrix(0,0) = 1.0 - rUnitNormal(0)*rUnitNormal(0);
1299  rTangProjMatrix(0,1) = - rUnitNormal(0)*rUnitNormal(1);
1300  rTangProjMatrix(1,0) = - rUnitNormal(1)*rUnitNormal(0);
1301  rTangProjMatrix(1,1) = 1.0 - rUnitNormal(1)*rUnitNormal(1);
1302  }
1303  }
1304 
1311  const array_1d<double, 3>& rUnitNormal,
1312  BoundedMatrix<double, TDim, (TDim-1)*3>& rVoigtNormProjMatrix) {
1313 
1314  rVoigtNormProjMatrix.clear();
1315 
1316  if constexpr (TDim == 3) {
1317  rVoigtNormProjMatrix(0,0) = rUnitNormal(0);
1318  rVoigtNormProjMatrix(0,3) = rUnitNormal(1);
1319  rVoigtNormProjMatrix(0,5) = rUnitNormal(2);
1320  rVoigtNormProjMatrix(1,1) = rUnitNormal(1);
1321  rVoigtNormProjMatrix(1,3) = rUnitNormal(0);
1322  rVoigtNormProjMatrix(1,4) = rUnitNormal(2);
1323  rVoigtNormProjMatrix(2,2) = rUnitNormal(2);
1324  rVoigtNormProjMatrix(2,4) = rUnitNormal(1);
1325  rVoigtNormProjMatrix(2,5) = rUnitNormal(0);
1326  } else {
1327  rVoigtNormProjMatrix(0,0) = rUnitNormal(0);
1328  rVoigtNormProjMatrix(0,2) = rUnitNormal(1);
1329  rVoigtNormProjMatrix(1,1) = rUnitNormal(1);
1330  rVoigtNormProjMatrix(1,2) = rUnitNormal(0);
1331  }
1332  }
1333 
1340  const ElementDataType& rData,
1341  array_1d<double, TNumNodes*(TDim+1)>& rPrevSolVector) {
1342 
1343  rPrevSolVector.clear();
1344 
1345  for (unsigned int i=0; i<TNumNodes; i++) {
1346  for (unsigned int comp=0; comp<TDim; comp++) {
1347  rPrevSolVector(i*(TDim+1)+comp) = rData.v(i,comp);
1348  }
1349  rPrevSolVector(i*(TDim+1)+TDim) = rData.p(i);
1350  }
1351  }
1352 
1356 
1360 
1364 
1366 private:
1369 
1373 
1377  friend class Serializer;
1378 
1379  void save(Serializer& rSerializer) const override {
1381  }
1382 
1383  void load(Serializer& rSerializer) override {
1385  }
1386 
1390 
1394 
1398 
1402 
1404 
1405 };
1406 
1408 
1411 
1415 
1417 
1418 } // namespace Kratos.
1419 
1420 #endif // KRATOS_EMBEDDED_NAVIER_STOKES defined
Vector VectorType
Definition: element.h:88
Geometry< NodeType >::PointsArrayType NodesArrayType
definition of nodes container type, redefined from GeometryType
Definition: element.h:86
Matrix MatrixType
Definition: element.h:90
PropertiesType::Pointer pGetProperties()
returns the pointer to the property of the element. Does not throw an error, to allow copying of elem...
Definition: element.h:1014
Definition: embedded_navier_stokes.h:54
~EmbeddedNavierStokes() override
Destructor.
Definition: embedded_navier_stokes.h:115
void Calculate(const Variable< array_1d< double, 3 >> &rVariable, array_1d< double, 3 > &rOutput, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_navier_stokes.h:392
void Calculate(const Variable< Matrix > &rVariable, Matrix &Output, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_navier_stokes.h:455
BaseType::IndexType IndexType
Definition: embedded_navier_stokes.h:70
void Calculate(const Variable< Vector > &rVariable, Vector &Output, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_navier_stokes.h:450
void AddSlipWinterTangentialPenaltyContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:1005
void AddSlipWinterNormalPenaltyContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:831
Element::Pointer Create(IndexType NewId, Element::GeometryType::Pointer pGeom, Element::PropertiesType::Pointer pProperties) const override
Definition: embedded_navier_stokes.h:133
void Calculate(const Variable< double > &rVariable, double &Output, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_navier_stokes.h:445
void AddBoundaryConditionModifiedNitcheContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData)
Definition: embedded_navier_stokes.h:690
BaseType::PropertiesType::Pointer PropertiesPointerType
Definition: embedded_navier_stokes.h:76
Element::Pointer Clone(IndexType NewId, NodesArrayType const &rThisNodes) const override
Definition: embedded_navier_stokes.h:144
void ComputeElementAsFluid(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:282
void SetInterfaceStrainMatrix(const BoundedMatrix< double, TNumNodes, TDim > &rDN_DX, BoundedMatrix< double,(TDim-1) *3, TNumNodes *(TDim+1)> &rB_matrix)
Definition: embedded_navier_stokes.h:1231
EmbeddedNavierStokes(IndexType NewId, GeometryPointerType pGeometry)
Default constructor.
Definition: embedded_navier_stokes.h:106
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Definition: embedded_navier_stokes.h:363
BaseType::MatrixType MatrixType
Definition: embedded_navier_stokes.h:68
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(EmbeddedNavierStokes)
Counted pointer of.
void AddSlipWinterTangentialSymmetricCounterpartContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:1100
BaseType::GeometryType::Pointer GeometryPointerType
Definition: embedded_navier_stokes.h:72
BaseType::ElementDataStruct ElementDataType
Definition: embedded_navier_stokes.h:64
EmbeddedNavierStokes()
Definition: embedded_navier_stokes.h:499
void AddIntersectionBoundaryTermsContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData)
Definition: embedded_navier_stokes.h:513
void SetTangentialProjectionMatrix(const array_1d< double, 3 > &rUnitNormal, BoundedMatrix< double, TDim, TDim > &rTangProjMatrix)
Definition: embedded_navier_stokes.h:1287
void AddSlipWinterNormalSymmetricCounterpartContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData)
Definition: embedded_navier_stokes.h:915
void ComputeElementAsMixed(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:324
void AddBoundaryConditionPenaltyContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:624
void GetPreviousSolutionVector(const ElementDataType &rData, array_1d< double, TNumNodes *(TDim+1)> &rPrevSolVector)
Definition: embedded_navier_stokes.h:1339
double ComputePenaltyCoefficient(const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:586
std::string Info() const override
Turn back information as a string.
Definition: embedded_navier_stokes.h:476
void FillEmbeddedElementData(EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:159
EmbeddedNavierStokes(IndexType NewId, GeometryPointerType pGeometry, PropertiesPointerType pProperties)
Definition: embedded_navier_stokes.h:110
BaseType::NodesArrayType NodesArrayType
Definition: embedded_navier_stokes.h:74
void SetVoigtNormalProjectionMatrix(const array_1d< double, 3 > &rUnitNormal, BoundedMatrix< double, TDim,(TDim-1) *3 > &rVoigtNormProjMatrix)
Definition: embedded_navier_stokes.h:1310
void SetNormalProjectionMatrix(const array_1d< double, 3 > &rUnitNormal, BoundedMatrix< double, TDim, TDim > &rNormProjMatrix)
Definition: embedded_navier_stokes.h:1265
NavierStokes< TDim, TNumNodes > BaseType
Definition: embedded_navier_stokes.h:62
Element::Pointer Create(IndexType NewId, NodesArrayType const &rThisNodes, Element::PropertiesType::Pointer pProperties) const override
Definition: embedded_navier_stokes.h:126
void DropOuterNodesVelocityContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData)
Definition: embedded_navier_stokes.h:801
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_navier_stokes.h:236
BaseType::VectorType VectorType
Definition: embedded_navier_stokes.h:66
void AddBoundaryConditionElementContribution(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const EmbeddedElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: embedded_navier_stokes.h:1200
BaseType::GeometryType::ShapeFunctionsGradientsType ShapeFunctionsGradientsType
Definition: embedded_navier_stokes.h:79
std::size_t IndexType
Definition: flags.h:74
bool Is(Flags const &rOther) const
Definition: flags.h:274
GeometryType::Pointer pGetGeometry()
Returns the pointer to the geometry.
Definition: geometrical_object.h:140
Flags & GetFlags()
Returns the flags of the object.
Definition: geometrical_object.h:176
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
std::size_t IndexType
Defines the index type.
Definition: geometrical_object.h:73
DataValueContainer & GetData()
Definition: geometrical_object.h:212
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
GeometryData::ShapeFunctionsGradientsType ShapeFunctionsGradientsType
Definition: geometry.h:189
virtual Pointer Create(PointsArrayType const &rThisPoints) const
Creates a new geometry pointer.
Definition: geometry.h:813
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
void clear()
Definition: amatrix_interface.h:284
Definition: navier_stokes.h:63
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 4, 4 > &Ncontainer)
Definition: navier_stokes.h:442
void ComputeGaussPointLHSContribution(BoundedMatrix< double, TNumNodes *(TDim+1), TNumNodes *(TDim+1)> &lhs, const ElementDataStruct &data)
void FillElementData(ElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: navier_stokes.h:374
void ComputeGaussPointRHSContribution(array_1d< double, TNumNodes *(TDim+1)> &rhs, const ElementDataStruct &data)
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Checks the input and that all required Kratos variables have been registered.
Definition: navier_stokes.h:239
virtual double ComputeEffectiveViscosity(const ElementDataStruct &rData)
Definition: navier_stokes.h:533
virtual void ComputeConstitutiveResponse(ElementDataStruct &rData, const ProcessInfo &rCurrentProcessInfo)
Definition: navier_stokes.h:499
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
typename CompressibleNavierStokesExplicit< TDim, TNumNodes >::ElementDataStruct ElementDataStruct
Definition: compressible_navier_stokes_explicit.h:705
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
AMatrix::VectorOuterProductExpression< TExpression1Type, TExpression2Type > outer_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:582
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
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
w_gauss
Definition: generate_convection_diffusion_explicit_element.py:136
p_gauss
Data interpolation to the Gauss points.
Definition: generate_droplet_dynamics.py:128
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 j
Definition: quadrature.py:648
K
Definition: sensitivityMatrix.py:73
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31
Definition: embedded_navier_stokes.h:81
ShapeFunctionsGradientsType DN_DX_pos_int
Definition: embedded_navier_stokes.h:89
ShapeFunctionsGradientsType DN_DX_pos_side
Definition: embedded_navier_stokes.h:84
MatrixType N_pos_int
Definition: embedded_navier_stokes.h:88
unsigned int n_neg
Definition: embedded_navier_stokes.h:97
std::vector< array_1d< double, 3 > > pos_int_unit_normals
Definition: embedded_navier_stokes.h:91
VectorType w_gauss_pos_side
Definition: embedded_navier_stokes.h:85
unsigned int n_pos
Definition: embedded_navier_stokes.h:96
MatrixType N_pos_side
Definition: embedded_navier_stokes.h:83
std::vector< unsigned int > out_vec_identifiers
Definition: embedded_navier_stokes.h:94
std::vector< unsigned int > int_vec_identifiers
Definition: embedded_navier_stokes.h:93
VectorType w_gauss_pos_int
Definition: embedded_navier_stokes.h:90
Definition: navier_stokes.h:72
double rho
Definition: navier_stokes.h:92
BoundedMatrix< double, TNumNodes, TDim > v
Definition: navier_stokes.h:73
array_1d< double, TNumNodes > N
Definition: navier_stokes.h:77
double dt
Definition: navier_stokes.h:89
Matrix C
Definition: navier_stokes.h:79
double volume
Definition: navier_stokes.h:88
array_1d< double, TNumNodes > p
Definition: navier_stokes.h:74
double mu
Definition: navier_stokes.h:91
double h
Definition: navier_stokes.h:87
BoundedMatrix< double, TNumNodes, TDim > DN_DX
Definition: navier_stokes.h:76