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_wall_condition.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 #ifndef KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES_WALL_CONDITION_H
14 #define KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES_WALL_CONDITION_H
15 
16 // System includes
17 #include <string>
18 #include <iostream>
19 
20 
21 // External includes
22 
23 
24 // Project includes
25 #include "includes/define.h"
26 #include "includes/condition.h"
27 #include "includes/model_part.h"
28 #include "includes/serializer.h"
29 #include "includes/process_info.h"
32 
33 // Application includes
36 #include "includes/cfd_variables.h"
37 
38 namespace Kratos
39 {
42 
45 
49 
53 
57 
61 
63 
69 template <unsigned int TDim, unsigned int TNumNodes = TDim>
70 class KRATOS_API(FLUID_DYNAMICS_APPLICATION) EmbeddedAusasNavierStokesWallCondition : public Condition
71 {
72 public:
75 
76  typedef Node NodeType;
77 
79 
81 
82  typedef GeometryType::Pointer GeometryPointerType;
83 
85 
87 
89 
90  typedef Element::WeakPointer ElementWeakPointerType;
91 
92  typedef Vector VectorType;
93 
94  typedef Matrix MatrixType;
95 
96  typedef std::size_t IndexType;
97 
98  typedef std::vector<std::size_t> EquationIdVectorType;
99 
100  typedef std::vector< Dof<double>::Pointer > DofsVectorType;
101 
104 
106  {
107  bool OutletInflowPreventionSwitch; // Outlet inflow (i.e. backflow) prevention switch
108  double charVel; // Problem characteristic velocity (used in the outlet inflow prevention)
109  double delta; // Non-dimensional positive sufficiently small constant (used in the outlet inflow prevention)
110 
111  // Data required in the RHS and LHS calculation
112  double wGauss; // Gauss point weight
113  array_1d<double, 3> Normal; // Condition normal
114  array_1d<double, TNumNodes> N; // Gauss point shape functions values
115  BoundedMatrix<double, TNumNodes, TDim> v; // Current step velocity
116 
117  // Data containers for no-split faces
120  std::vector<VectorType> area_normals_container;
121 
122  // Data containers for split faces
123  // Positive face geometry data
124  MatrixType N_pos_face; // Positive interface Gauss pts. shape functions values
125  ShapeFunctionsGradientsType DN_DX_pos_face; // Positive interface Gauss pts. shape functions gradients values
126  VectorType w_gauss_pos_face; // Positive interface Gauss pts. weights
127  std::vector<array_1d<double,3>> pos_face_area_normals; // Positive interface unit normal vector in each Gauss pt.
128 
129  // Negative face geometry data
130  MatrixType N_neg_face; // Positive interface Gauss pts. shape functions values
131  ShapeFunctionsGradientsType DN_DX_neg_face; // Positive interface Gauss pts. shape functions gradients values
132  VectorType w_gauss_neg_face; // Positive interface Gauss pts. weights
133  std::vector<array_1d<double,3>> neg_face_area_normals; // Positive interface unit normal vector in each Gauss pt.
134 
135  unsigned int n_pos = 0; // Number of positive distance nodes
136  unsigned int n_neg = 0; // Number of negative distance nodes
137  };
138 
142 
144 
148 
150 
155  Condition(NewId,ThisNodes) {}
156 
158 
162  EmbeddedAusasNavierStokesWallCondition(IndexType NewId, GeometryType::Pointer pGeometry) :
163  Condition(NewId,pGeometry) {}
164 
166 
171  EmbeddedAusasNavierStokesWallCondition(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties) :
172  Condition(NewId,pGeometry,pProperties) {}
173 
176  Condition(rOther) {}
177 
180 
181 
185 
188  Condition::operator=(rOther);
189  return *this;
190  }
191 
195 
197 
202  Condition::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer pProperties) const override {
203  return Kratos::make_intrusive<EmbeddedAusasNavierStokesWallCondition>(NewId, GetGeometry().Create(ThisNodes), pProperties);
204  }
205 
207 
212  Condition::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override {
213  return Kratos::make_intrusive< EmbeddedAusasNavierStokesWallCondition >(NewId, pGeom, pProperties);
214  }
215 
222  Condition::Pointer Clone(IndexType NewId, NodesArrayType const& rThisNodes) const override {
223  Condition::Pointer pNewCondition = Create(NewId, GetGeometry().Create( rThisNodes ), pGetProperties() );
224 
225  pNewCondition->SetData(this->GetData());
226  pNewCondition->SetFlags(this->GetFlags());
227 
228  return pNewCondition;
229  }
230 
236  void InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override {
237  KRATOS_TRY;
238 
239  // Set a reference to the current condition geometry
240  GeometryType &r_geometry = this->GetGeometry();
241 
242  // Check if the condition is split
243  unsigned int n_pos = 0, n_neg = 0;
244  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
245  const double aux_dist = r_geometry[i_node].FastGetSolutionStepValue(DISTANCE);
246  if (aux_dist < 0) {
247  n_neg++;
248  } else {
249  n_pos++;
250  }
251  }
252 
253  // If the condition is split, save a pointer to its parent element
254  if (n_pos != 0 && n_neg != 0){
255 
256  // Get all the possible element candidates
257  GlobalPointersVector<Element> element_candidates;
258  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
259  GlobalPointersVector<Element> &r_node_element_candidates = r_geometry[i_node].GetValue(NEIGHBOUR_ELEMENTS);
260  for (unsigned int j = 0; j < r_node_element_candidates.size(); j++) {
261  element_candidates.push_back(r_node_element_candidates(j));
262  }
263  }
264 
265  // Check that the condition has candidate parent elements
266  KRATOS_ERROR_IF(element_candidates.size() == 0) <<
267  "Condition " << this->Id() << " has no candidate parent elements.\n" <<
268  "Check that the FindNodalNeighboursProcess has been executed.";
269 
270  // Get a sort array with the current condition nodal ids
271  std::vector<unsigned int> node_ids(TNumNodes), element_nodes_ids;
272 
273  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
274  node_ids[i_node] = r_geometry[i_node].Id();
275  }
276  std::sort(node_ids.begin(), node_ids.end());
277 
278  // Iterate the candidate elements
279  for (unsigned int i_candidate = 0; i_candidate < element_candidates.size(); ++i_candidate) {
280  GeometryType &r_elem_geom = element_candidates[i_candidate].GetGeometry();
281  const unsigned int n_elem_nodes = r_elem_geom.PointsNumber();
282 
283  // Get a sort array with the iterated candidate element nodal ids
284  element_nodes_ids.resize(n_elem_nodes);
285  for (unsigned int j = 0; j < n_elem_nodes; ++j) {
286  element_nodes_ids[j] = r_elem_geom[j].Id();
287  }
288  std::sort(element_nodes_ids.begin(), element_nodes_ids.end());
289 
290  // Check if the current condition ids are included in the iterated candidate element nodal ids
291  if (std::includes(element_nodes_ids.begin(), element_nodes_ids.end(), node_ids.begin(), node_ids.end())) {
292  // Save a pointer to the parent element
293  mpParentElement = element_candidates(i_candidate);
294 
295  // Save the parent element local ids. corresponding to the condition nodes
296  mParentElementIds.resize(TNumNodes);
297 
298  std::vector<unsigned int > aux_elem_ids(n_elem_nodes);
299  for (unsigned int j = 0; j < n_elem_nodes; ++j) {
300  aux_elem_ids[j] = r_elem_geom[j].Id();
301  }
302 
303  for (unsigned int i = 0; i < TNumNodes; ++i) {
304  const unsigned int aux_id = r_geometry[i].Id();
305  const std::vector<unsigned int >::iterator aux_it = std::find(aux_elem_ids.begin(), aux_elem_ids.end(), aux_id);
306  mParentElementIds[i] = std::distance(aux_elem_ids.begin(), aux_it);
307  }
308 
309  // Leave the parent element search
310  return;
311  }
312  }
313 
314  KRATOS_ERROR << "Condition " << this->Id() << " cannot find parent element.";
315  }
316 
317  KRATOS_CATCH("Error in EmbeddedAusasNavierStokesWallCondition InitializeSolutionStep() method.");
318  }
319 
321 
327  void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix,
328  VectorType& rRightHandSideVector,
329  const ProcessInfo& rCurrentProcessInfo) override
330  {
331  KRATOS_TRY
332 
333  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
334 
335  if (rLeftHandSideMatrix.size1() != MatrixSize)
336  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false);
337 
338  if (rRightHandSideVector.size() != MatrixSize)
339  rRightHandSideVector.resize(MatrixSize, false);
340 
341  // Struct to pass around the data
343  this->FillConditionData(data);
344 
345  // Allocate memory needed
348 
349  // LHS and RHS contributions initialization
350  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize,MatrixSize);
351  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
352 
353  // Store the outlet inflow prevention constants in the data structure
354  data.delta = 1e-2; // TODO: Decide if this constant should be fixed or not
355  const ProcessInfo& rProcessInfo = rCurrentProcessInfo; // const to avoid race conditions on data_value_container access/initialization
356  data.OutletInflowPreventionSwitch = rProcessInfo.Has(OUTLET_INFLOW_CONTRIBUTION_SWITCH) ? rProcessInfo[OUTLET_INFLOW_CONTRIBUTION_SWITCH] : false;
357  if (data.OutletInflowPreventionSwitch) {
358  data.charVel = rProcessInfo[CHARACTERISTIC_VELOCITY];
359  }
360 
361  // Loop on gauss points
362  if (data.n_pos != 0 && data.n_neg != 0){
363 
364  // Positive side Gauss pts. loop
365  const unsigned int n_gauss_pos = (data.w_gauss_pos_face).size();
366  for (unsigned int i_gauss = 0; i_gauss < n_gauss_pos; ++i_gauss) {
367 
368  Vector aux_N = row(data.N_pos_face, i_gauss);
369  for (unsigned int i = 0; i < TNumNodes; ++i) {
370  data.N(i) = aux_N(mParentElementIds[i]);
371  }
372  data.wGauss = data.w_gauss_pos_face(i_gauss);
373  data.Normal = data.pos_face_area_normals[i_gauss];
374  data.Normal /= norm_2(data.Normal); // Normalize the area normal
375 
376  ComputeGaussPointRHSContribution(rhs_gauss, data);
377  ComputeGaussPointLHSContribution(lhs_gauss, data);
378 
379  noalias(rLeftHandSideMatrix) += lhs_gauss;
380  noalias(rRightHandSideVector) += rhs_gauss;
381  }
382 
383  // Negative side Gauss pts. loop
384  const unsigned int n_gauss_neg = (data.w_gauss_neg_face).size();
385  for (unsigned int i_gauss = 0; i_gauss < n_gauss_neg; ++i_gauss) {
386 
387  Vector aux_N = row(data.N_neg_face, i_gauss);
388  for (unsigned int i = 0; i < TNumNodes; ++i) {
389  data.N(i) = aux_N(mParentElementIds[i]);
390  }
391  data.wGauss = data.w_gauss_neg_face(i_gauss);
392  data.Normal = data.neg_face_area_normals[i_gauss];
393  data.Normal /= norm_2(data.Normal); // Normalize the area normal
394 
395  ComputeGaussPointRHSContribution(rhs_gauss, data);
396  ComputeGaussPointLHSContribution(lhs_gauss, data);
397 
398  noalias(rLeftHandSideMatrix) += lhs_gauss;
399  noalias(rRightHandSideVector) += rhs_gauss;
400  }
401  } else {
402  const unsigned int n_gauss = (data.w_gauss_container).size();
403  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
404 
405  data.N = row(data.N_container, i_gauss);
406  data.wGauss = data.w_gauss_container(i_gauss);
407  data.Normal = data.area_normals_container[i_gauss];
408  data.Normal /= norm_2(data.Normal); // Normalize the area normal
409 
410  ComputeGaussPointRHSContribution(rhs_gauss, data);
411  ComputeGaussPointLHSContribution(lhs_gauss, data);
412 
413  noalias(rLeftHandSideMatrix) += lhs_gauss;
414  noalias(rRightHandSideVector) += rhs_gauss;
415  }
416  }
417 
418  KRATOS_CATCH("")
419  }
420 
422 
427  void CalculateLeftHandSide(MatrixType& rLeftHandSideMatrix,
428  const ProcessInfo& rCurrentProcessInfo) override
429  {
430  KRATOS_TRY
431 
432  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
433 
434  if (rLeftHandSideMatrix.size1() != MatrixSize)
435  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false); //false says not to preserve existing storage!!
436 
437  // Struct to pass around the data
439  this->FillConditionData(data);
440 
441  // Allocate memory needed
443 
444  // LHS contributions initialization
445  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize, MatrixSize);
446 
447  // Loop on gauss points
448  if (data.n_pos != 0 && data.n_neg != 0){
449 
450  // Positive side Gauss pts. loop
451  const unsigned int n_gauss_pos = (data.w_gauss_pos_face).size();
452  for (unsigned int i_gauss = 0; i_gauss < n_gauss_pos; ++i_gauss) {
453 
454  Vector aux_N = row(data.N_pos_face, i_gauss);
455  for (unsigned int i = 0; i < TNumNodes; ++i) {
456  data.N(i) = aux_N(mParentElementIds[i]);
457  }
458  data.wGauss = data.w_gauss_pos_face(i_gauss);
459  data.Normal = data.pos_face_area_normals[i_gauss];
460  data.Normal /= norm_2(data.Normal); // Normalize the area normal
461 
462  ComputeGaussPointLHSContribution(lhs_gauss, data);
463 
464  noalias(rLeftHandSideMatrix) += lhs_gauss;
465  }
466 
467  // Negative side Gauss pts. loop
468  const unsigned int n_gauss_neg = (data.w_gauss_neg_face).size();
469  for (unsigned int i_gauss = 0; i_gauss < n_gauss_neg; ++i_gauss) {
470 
471  Vector aux_N = row(data.N_neg_face, i_gauss);
472  for (unsigned int i = 0; i < TNumNodes; ++i) {
473  data.N(i) = aux_N(mParentElementIds[i]);
474  }
475  data.wGauss = data.w_gauss_neg_face(i_gauss);
476  data.Normal = data.neg_face_area_normals[i_gauss];
477  data.Normal /= norm_2(data.Normal); // Normalize the area normal
478 
479  ComputeGaussPointLHSContribution(lhs_gauss, data);
480 
481  noalias(rLeftHandSideMatrix) += lhs_gauss;
482  }
483  } else {
484  const unsigned int n_gauss = (data.w_gauss_container).size();
485  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
486 
487  data.N = row(data.N_container, i_gauss);
488  data.wGauss = data.w_gauss_container(i_gauss);
489  data.Normal = data.area_normals_container[i_gauss];
490  data.Normal /= norm_2(data.Normal); // Normalize the area normal
491 
492  ComputeGaussPointLHSContribution(lhs_gauss, data);
493 
494  noalias(rLeftHandSideMatrix) += lhs_gauss;
495  }
496  }
497 
498  KRATOS_CATCH("")
499  }
500 
502 
507  void CalculateRightHandSide(VectorType& rRightHandSideVector,
508  const ProcessInfo& rCurrentProcessInfo) override
509  {
510  KRATOS_TRY
511 
512  constexpr unsigned int MatrixSize = TNumNodes*(TDim+1);
513 
514  if (rRightHandSideVector.size() != MatrixSize)
515  rRightHandSideVector.resize(MatrixSize, false); //false says not to preserve existing storage!!
516 
517  // Struct to pass around the data
519  this->FillConditionData(data);
520 
521  // Allocate memory needed
522  array_1d<double,MatrixSize> rhs_gauss;
523 
524  // RHS contributions initialization
525  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
526 
527  // Store the outlet inflow prevention constants in the data structure
528  data.delta = 1e-2; // TODO: Decide if this constant should be fixed or not
529  const ProcessInfo& rProcessInfo = rCurrentProcessInfo; // const to avoid race conditions on data_value_container access/initialization
530  data.OutletInflowPreventionSwitch = rProcessInfo.Has(OUTLET_INFLOW_CONTRIBUTION_SWITCH) ? rProcessInfo[OUTLET_INFLOW_CONTRIBUTION_SWITCH] : false;
531  if (data.OutletInflowPreventionSwitch) {
532  data.charVel = rProcessInfo[CHARACTERISTIC_VELOCITY];
533  }
534 
535  // Loop on gauss points
536  if (data.n_pos != 0 && data.n_neg != 0){
537 
538  // Positive side Gauss pts. loop
539  const unsigned int n_gauss_pos = (data.w_gauss_pos_face).size();
540  for (unsigned int i_gauss = 0; i_gauss < n_gauss_pos; ++i_gauss) {
541 
542  Vector aux_N = row(data.N_pos_face, i_gauss);
543  for (unsigned int i = 0; i < TNumNodes; ++i) {
544  data.N(i) = aux_N(mParentElementIds[i]);
545  }
546  data.wGauss = data.w_gauss_pos_face(i_gauss);
547  data.Normal = data.pos_face_area_normals[i_gauss];
548  data.Normal /= norm_2(data.Normal); // Normalize the area normal
549 
550  ComputeGaussPointRHSContribution(rhs_gauss, data);
551 
552  noalias(rRightHandSideVector) += rhs_gauss;
553  }
554 
555  // Negative side Gauss pts. loop
556  const unsigned int n_gauss_neg = (data.w_gauss_neg_face).size();
557  for (unsigned int i_gauss = 0; i_gauss < n_gauss_neg; ++i_gauss) {
558 
559  Vector aux_N = row(data.N_neg_face, i_gauss);
560  for (unsigned int i = 0; i < TNumNodes; ++i) {
561  data.N(i) = aux_N(mParentElementIds[i]);
562  }
563  data.wGauss = data.w_gauss_neg_face(i_gauss);
564  data.Normal = data.neg_face_area_normals[i_gauss];
565  data.Normal /= norm_2(data.Normal); // Normalize the area normal
566 
567  ComputeGaussPointRHSContribution(rhs_gauss, data);
568 
569  noalias(rRightHandSideVector) += rhs_gauss;
570  }
571  } else {
572  const unsigned int n_gauss = (data.w_gauss_container).size();
573  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
574 
575  data.N = row(data.N_container, i_gauss);
576  data.wGauss = data.w_gauss_container(i_gauss);
577  data.Normal = data.area_normals_container[i_gauss];
578  data.Normal /= norm_2(data.Normal); // Normalize the area normal
579 
580  ComputeGaussPointRHSContribution(rhs_gauss, data);
581 
582  noalias(rRightHandSideVector) += rhs_gauss;
583  }
584  }
585 
586  KRATOS_CATCH("")
587  }
588 
589 
591 
594  int Check(const ProcessInfo& rCurrentProcessInfo) const override
595  {
596  KRATOS_TRY;
597 
598  const GeometryType& rGeom = this->GetGeometry();
599 
600  int Check = Condition::Check(rCurrentProcessInfo); // Checks id > 0 and area > 0
601 
602  if (Check != 0) {
603  return Check;
604  } else {
605  // Checks on nodes
606  // Check that the element's nodes contain all required SolutionStepData and Degrees of freedom
607  for(unsigned int i = 0; i < rGeom.size(); ++i) {
608  if(rGeom[i].SolutionStepsDataHas(VELOCITY) == false)
609  KRATOS_ERROR << "Missing VELOCITY variable on solution step data for node " << rGeom[i].Id();
610  if(rGeom[i].SolutionStepsDataHas(PRESSURE) == false)
611  KRATOS_ERROR << "Missing PRESSURE variable on solution step data for node " << rGeom[i].Id();
612  if(rGeom[i].SolutionStepsDataHas(MESH_VELOCITY) == false)
613  KRATOS_ERROR << "Missing MESH_VELOCITY variable on solution step data for node " << rGeom[i].Id();
614  if(rGeom[i].SolutionStepsDataHas(ACCELERATION) == false)
615  KRATOS_ERROR << "Missing ACCELERATION variable on solution step data for node " << rGeom[i].Id();
616  if(rGeom[i].SolutionStepsDataHas(EXTERNAL_PRESSURE) == false)
617  KRATOS_ERROR << "Missing EXTERNAL_PRESSURE variable on solution step data for node " << rGeom[i].Id();
618  if(rGeom[i].SolutionStepsDataHas(DISTANCE) == false)
619  KRATOS_ERROR << "Missing DISTANCE variable on solution step data for node " << rGeom[i].Id();
620  if(rGeom[i].HasDofFor(VELOCITY_X) == false || rGeom[i].HasDofFor(VELOCITY_Y) == false || rGeom[i].HasDofFor(VELOCITY_Z) == false)
621  KRATOS_ERROR << "Missing VELOCITY component degree of freedom on node " << rGeom[i].Id();
622  if(rGeom[i].HasDofFor(PRESSURE) == false)
623  KRATOS_ERROR << "Missing PRESSURE component degree of freedom on node " << rGeom[i].Id();
624  }
625 
626  return Check;
627  }
628 
629  KRATOS_CATCH("");
630  }
631 
633 
637  void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override;
638 
640 
644  void GetDofList(DofsVectorType& ConditionDofList, const ProcessInfo& CurrentProcessInfo) const override;
645 
649 
650 
654 
655 
659 
661  std::string Info() const override {
662  std::stringstream buffer;
663  buffer << "EmbeddedAusasNavierStokesWallCondition" << TDim << "D";
664  return buffer.str();
665  }
666 
668  void PrintInfo(std::ostream& rOStream) const override {
669  rOStream << Info() << "\nCondition id: " << Id();
670  }
671 
673  void PrintData(std::ostream& rOStream) const override {}
674 
678 
680 
681 protected:
684 
688 
692 
696 
697  Element::Pointer pGetElement() {
698  return mpParentElement->shared_from_this();
699  }
700 
701  std::vector<unsigned int > GetParentElementIds() {
702  return mParentElementIds;
703  }
704 
705  void ComputeGaussPointLHSContribution(BoundedMatrix<double,TNumNodes*(TDim+1),TNumNodes*(TDim+1)>& lhs, const ConditionDataStruct& data);
706  void ComputeGaussPointRHSContribution(array_1d<double,TNumNodes*(TDim+1)>& rhs, const ConditionDataStruct& data);
707 
708  void ComputeRHSNeumannContribution(array_1d<double,TNumNodes*(TDim+1)>& rhs, const ConditionDataStruct& data);
709  void ComputeRHSOutletInflowContribution(array_1d<double,TNumNodes*(TDim+1)>& rhs, const ConditionDataStruct& rData);
710 
711  // Auxiliar function to fill the element data structure
713  {
714  const GeometryType& r_geometry = this->GetGeometry();
715 
716  // Check if the condition is split
717  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
718  const double aux_dist = r_geometry[i_node].FastGetSolutionStepValue(DISTANCE);
719  if (aux_dist < 0) {
720  rData.n_neg++;
721  } else {
722  rData.n_pos++;
723  }
724  }
725 
726  // If the element is split, take the values from the parent element modified shape functions utility
727  // Otherwise, take the values from the current condition geometry
728  if (rData.n_pos != 0 && rData.n_neg != 0){
729  // Get the parent element nodal distances
730  Element::Pointer p_parent_element = this->pGetElement();
731  GeometryPointerType p_parent_geometry = p_parent_element->pGetGeometry();
732  const Vector &distances = p_parent_element->GetValue(ELEMENTAL_DISTANCES);
733  const unsigned int n_parent_nodes = p_parent_geometry->PointsNumber();
734 
735  // Construct the modified shape functions utility with the parent element pointer
736  ModifiedShapeFunctions::Pointer p_ausas_modified_sh_func = nullptr;
737  if (n_parent_nodes == 4) {
738  p_ausas_modified_sh_func = Kratos::make_shared<Tetrahedra3D4AusasModifiedShapeFunctions>(p_parent_geometry, distances);
739  }
740  else if (n_parent_nodes == 3) {
741  p_ausas_modified_sh_func = Kratos::make_shared<Triangle2D3AusasModifiedShapeFunctions>(p_parent_geometry, distances);
742  } else {
743  KRATOS_ERROR << "Asking for a non-implemented geometry modified shape functions utility.";
744  }
745 
746  // Get the current condition global ids
747  std::vector<unsigned int> cond_ids(TNumNodes);
748  for (unsigned int i_node = 0; i_node < TNumNodes; ++i_node) {
749  cond_ids[i_node] = r_geometry[i_node].Id();
750  }
751  std::sort(cond_ids.begin(), cond_ids.end());
752 
753  DenseMatrix<unsigned int> elem_face_loc_ids;
754  DenseVector<unsigned int> elem_nodes_in_face;
755  p_parent_geometry->NodesInFaces(elem_face_loc_ids);
756  p_parent_geometry->NumberNodesInFaces(elem_nodes_in_face);
757  const unsigned int n_elem_faces = elem_face_loc_ids.size2();
758 
759  // Iterate the element faces to find the condition correspondent one
760  unsigned int face_id = n_elem_faces + 1;
761  for (unsigned int i_face = 0; i_face < n_elem_faces; ++i_face) {
762  const unsigned int n_face_nodes = elem_nodes_in_face(i_face);
763 
764  // Get the element face local nodal ids
765  // Note that the first index represent the node out of the face
766  // (check this in case quads or tetras are used).
767  std::vector<unsigned int> face_loc_ids(n_face_nodes);
768  for (unsigned int i_node = 0; i_node < n_face_nodes; ++i_node) {
769  face_loc_ids[i_node] = elem_face_loc_ids(i_node + 1, i_face);
770  }
771 
772  // Get the element face global nodal ids
773  std::vector<unsigned int> face_glob_ids(n_face_nodes);
774  for (unsigned int i_node = 0; i_node < n_face_nodes; ++i_node) {
775  const int aux_loc_id = face_loc_ids[i_node];
776  face_glob_ids[i_node] = (*p_parent_geometry)[aux_loc_id].Id();
777  }
778  std::sort(face_glob_ids.begin(), face_glob_ids.end());
779 
780  // Check if the element face global ids correspond with the current condition ones
781  if (std::includes(face_glob_ids.begin(), face_glob_ids.end(), cond_ids.begin(), cond_ids.end())) {
782  face_id = i_face;
783  break;
784  }
785  }
786 
787  KRATOS_ERROR_IF(face_id == n_elem_faces + 1) <<
788  "No parent element face found for condition " << this->Id() << " and parent element " << p_parent_element->Id();
789 
790  // Call the positive and negative sides modified shape functions face utilities
791  p_ausas_modified_sh_func->ComputePositiveExteriorFaceShapeFunctionsAndGradientsValues(
792  rData.N_pos_face,
793  rData.DN_DX_pos_face,
794  rData.w_gauss_pos_face,
795  face_id,
797 
798  p_ausas_modified_sh_func->ComputeNegativeExteriorFaceShapeFunctionsAndGradientsValues(
799  rData.N_neg_face,
800  rData.DN_DX_neg_face,
801  rData.w_gauss_neg_face,
802  face_id,
804 
805  p_ausas_modified_sh_func->ComputePositiveExteriorFaceAreaNormals(
806  rData.pos_face_area_normals,
807  face_id,
809 
810  p_ausas_modified_sh_func->ComputeNegativeExteriorFaceAreaNormals(
811  rData.neg_face_area_normals,
812  face_id,
814 
815  } else {
816  // If the condition is not split, take the geometry shape function values
818  const unsigned int n_gauss = integration_points.size();
819 
820  // Get the condition geometry shape functions values
822 
823  // Compute each Gauss pt. weight
824  Vector gauss_pts_J_det(n_gauss);
826  (rData.w_gauss_container).resize(n_gauss);
827  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
828  rData.w_gauss_container(i_gauss) = integration_points[i_gauss].Weight() * gauss_pts_J_det(i_gauss);
829  }
830 
831  // Compute each Gauss pt. area normal
832  (rData.area_normals_container).clear();
833  // We compute the area normal in each Gauss point
834  for (unsigned int i_gauss = 0; i_gauss < n_gauss; ++i_gauss) {
835  const CoordinatesArrayType& gauss_pt_loc_coords = integration_points[i_gauss].Coordinates();
836  (rData.area_normals_container).push_back(r_geometry.Normal(gauss_pt_loc_coords));
837  }
838  }
839 
840  // Fill the nodal velocity array
841  for (unsigned int i = 0; i < TNumNodes; i++) {
842  const array_1d<double, 3> &vel = r_geometry[i].FastGetSolutionStepValue(VELOCITY);
843 
844  for (unsigned int k = 0; k < TDim; k++) {
845  rData.v(i, k) = vel[k];
846  }
847  }
848  }
849 
853 
854 
858 
859 
863 
864 
866 
867 private:
870 
871 
875 
876  ElementWeakPointerType mpParentElement;
877  std::vector<unsigned int> mParentElementIds;
878 
882 
883  friend class Serializer;
884 
885  void save(Serializer& rSerializer) const override
886  {
888  }
889 
890  void load(Serializer& rSerializer) override
891  {
893  }
894 
898 
899 
903 
904 
908 
909 
913 
914 
918 
919 
921 
922 }; // Class EmbeddedAusasNavierStokesWallCondition
923 
924 
926 
929 
930 
934 
935 
937 template< unsigned int TDim, unsigned int TNumNodes >
938 inline std::istream& operator >> (std::istream& rIStream, EmbeddedAusasNavierStokesWallCondition<TDim,TNumNodes>& rThis)
939 {
940  return rIStream;
941 }
942 
944 template< unsigned int TDim, unsigned int TNumNodes >
945 inline std::ostream& operator << (std::ostream& rOStream, const EmbeddedAusasNavierStokesWallCondition<TDim,TNumNodes>& rThis)
946 {
947  rThis.PrintInfo(rOStream);
948  rOStream << std::endl;
949  rThis.PrintData(rOStream);
950 
951  return rOStream;
952 }
953 
955 
957 
958 
959 } // namespace Kratos.
960 
961 #endif // KRATOS_EMBEDDED_AUSAS_NAVIER_STOKES_WALL_CONDITION_H
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
Base class for all Conditions.
Definition: condition.h:59
std::vector< std::size_t > EquationIdVectorType
Definition: condition.h:98
std::vector< DofType::Pointer > DofsVectorType
Definition: condition.h:100
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const
Definition: condition.h:854
Condition & operator=(Condition const &rOther)
Assignment operator.
Definition: condition.h:181
bool Has(const Variable< TDataType > &rThisVariable) const
Checks if the data container has a value associated with a given variable.
Definition: data_value_container.h:382
Implements a wall condition for the Navier-Stokes monolithic formulation.
Definition: embedded_ausas_navier_stokes_wall_condition.h:71
Vector VectorType
Definition: embedded_ausas_navier_stokes_wall_condition.h:92
std::vector< Dof< double >::Pointer > DofsVectorType
Definition: embedded_ausas_navier_stokes_wall_condition.h:100
Geometry< NodeType > GeometryType
Definition: embedded_ausas_navier_stokes_wall_condition.h:80
void GetDofList(DofsVectorType &ConditionDofList, const ProcessInfo &CurrentProcessInfo) const override
Returns a list of the element's Dofs.
void CalculateLeftHandSide(MatrixType &rLeftHandSideMatrix, const ProcessInfo &rCurrentProcessInfo) override
Calculates the RHS condition contributions.
Definition: embedded_ausas_navier_stokes_wall_condition.h:427
Element::WeakPointer ElementWeakPointerType
Definition: embedded_ausas_navier_stokes_wall_condition.h:90
EmbeddedAusasNavierStokesWallCondition(IndexType NewId, const NodesArrayType &ThisNodes)
Constructor using an array of nodes.
Definition: embedded_ausas_navier_stokes_wall_condition.h:154
void InitializeSolutionStep(const ProcessInfo &rCurrentProcessInfo) override
Definition: embedded_ausas_navier_stokes_wall_condition.h:236
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: embedded_ausas_navier_stokes_wall_condition.h:668
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Condition check.
Definition: embedded_ausas_navier_stokes_wall_condition.h:594
GeometryType::Pointer GeometryPointerType
Definition: embedded_ausas_navier_stokes_wall_condition.h:82
void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
Provides the global indices for each one of this element's local rows.
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(EmbeddedAusasNavierStokesWallCondition)
Pointer definition of EmbeddedAusasNavierStokesWallCondition.
EmbeddedAusasNavierStokesWallCondition(EmbeddedAusasNavierStokesWallCondition const &rOther)
Copy constructor.
Definition: embedded_ausas_navier_stokes_wall_condition.h:175
std::string Info() const override
Turn back information as a string.
Definition: embedded_ausas_navier_stokes_wall_condition.h:661
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: embedded_ausas_navier_stokes_wall_condition.h:673
Matrix MatrixType
Definition: embedded_ausas_navier_stokes_wall_condition.h:94
~EmbeddedAusasNavierStokesWallCondition() override
Destructor.
Definition: embedded_ausas_navier_stokes_wall_condition.h:179
Node NodeType
Definition: embedded_ausas_navier_stokes_wall_condition.h:76
Element::Pointer pGetElement()
Definition: embedded_ausas_navier_stokes_wall_condition.h:697
EmbeddedAusasNavierStokesWallCondition(IndexType NewId=0)
Default constructor.
Definition: embedded_ausas_navier_stokes_wall_condition.h:147
GeometryType::CoordinatesArrayType CoordinatesArrayType
Definition: embedded_ausas_navier_stokes_wall_condition.h:86
Condition::Pointer Clone(IndexType NewId, NodesArrayType const &rThisNodes) const override
Definition: embedded_ausas_navier_stokes_wall_condition.h:222
GeometryType::PointsArrayType NodesArrayType
Definition: embedded_ausas_navier_stokes_wall_condition.h:84
EmbeddedAusasNavierStokesWallCondition & operator=(EmbeddedAusasNavierStokesWallCondition const &rOther)
Assignment operator.
Definition: embedded_ausas_navier_stokes_wall_condition.h:187
Condition::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
Create a new EmbeddedAusasNavierStokesWallCondition object.
Definition: embedded_ausas_navier_stokes_wall_condition.h:202
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Calculates the RHS condition contributions.
Definition: embedded_ausas_navier_stokes_wall_condition.h:507
void FillConditionData(ConditionDataStruct &rData)
Definition: embedded_ausas_navier_stokes_wall_condition.h:712
Condition::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
Create a new EmbeddedAusasNavierStokesWallCondition object.
Definition: embedded_ausas_navier_stokes_wall_condition.h:212
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Calculates the LHS and RHS condition contributions.
Definition: embedded_ausas_navier_stokes_wall_condition.h:327
std::size_t IndexType
Definition: embedded_ausas_navier_stokes_wall_condition.h:96
std::vector< std::size_t > EquationIdVectorType
Definition: embedded_ausas_navier_stokes_wall_condition.h:98
EmbeddedAusasNavierStokesWallCondition(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Constructor using Properties.
Definition: embedded_ausas_navier_stokes_wall_condition.h:171
EmbeddedAusasNavierStokesWallCondition(IndexType NewId, GeometryType::Pointer pGeometry)
Constructor using Geometry.
Definition: embedded_ausas_navier_stokes_wall_condition.h:162
GeometryType::ShapeFunctionsGradientsType ShapeFunctionsGradientsType
Definition: embedded_ausas_navier_stokes_wall_condition.h:88
std::vector< unsigned int > GetParentElementIds()
Definition: embedded_ausas_navier_stokes_wall_condition.h:701
Properties PropertiesType
Definition: embedded_ausas_navier_stokes_wall_condition.h:78
std::size_t IndexType
Definition: flags.h:74
Geometry base class.
Definition: geometry.h:71
SizeType PointsNumber() const
Definition: geometry.h:528
SizeType size() const
Definition: geometry.h:518
std::vector< IntegrationPointType > IntegrationPointsArrayType
Definition: geometry.h:161
virtual array_1d< double, 3 > Normal(const CoordinatesArrayType &rPointLocalCoordinates) const
It returns a vector that is normal to its corresponding geometry in the given local point.
Definition: geometry.h:1543
const Matrix & ShapeFunctionsValues() const
Definition: geometry.h:3393
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
Vector & DeterminantOfJacobian(Vector &rResult) const
Definition: geometry.h:3154
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
const IntegrationPointsArrayType & IntegrationPoints() const
Definition: geometry.h:2284
void push_back(TPointerType x)
Definition: global_pointers_vector.h:322
size_type size() const
Definition: global_pointers_vector.h:307
Definition: amatrix_interface.h:41
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
This class defines the node.
Definition: node.h:65
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
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
Short class definition.
Definition: array_1d.h:61
#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
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
Modeler::Pointer Create(const std::string &ModelerName, Model &rModel, const Parameters ModelParameters)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:30
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
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
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
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
rhs
Definition: generate_frictional_mortar_condition.py:297
lhs
Definition: generate_frictional_mortar_condition.py:297
data
Definition: mesh_to_mdpa_converter.py:59
def load(f)
Definition: ode_solve.py:307
vel
Definition: pure_conduction.py:76
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31
Definition: embedded_ausas_navier_stokes_wall_condition.h:106
unsigned int n_neg
Definition: embedded_ausas_navier_stokes_wall_condition.h:136
VectorType w_gauss_pos_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:126
unsigned int n_pos
Definition: embedded_ausas_navier_stokes_wall_condition.h:135
ShapeFunctionsGradientsType DN_DX_pos_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:125
ShapeFunctionsGradientsType DN_DX_neg_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:131
std::vector< VectorType > area_normals_container
Definition: embedded_ausas_navier_stokes_wall_condition.h:120
MatrixType N_neg_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:130
VectorType w_gauss_neg_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:132
bool OutletInflowPreventionSwitch
Definition: embedded_ausas_navier_stokes_wall_condition.h:107
MatrixType N_container
Definition: embedded_ausas_navier_stokes_wall_condition.h:118
std::vector< array_1d< double, 3 > > pos_face_area_normals
Definition: embedded_ausas_navier_stokes_wall_condition.h:127
MatrixType N_pos_face
Definition: embedded_ausas_navier_stokes_wall_condition.h:124
double delta
Definition: embedded_ausas_navier_stokes_wall_condition.h:109
double charVel
Definition: embedded_ausas_navier_stokes_wall_condition.h:108
BoundedMatrix< double, TNumNodes, TDim > v
Definition: embedded_ausas_navier_stokes_wall_condition.h:115
array_1d< double, 3 > Normal
Definition: embedded_ausas_navier_stokes_wall_condition.h:113
double wGauss
Definition: embedded_ausas_navier_stokes_wall_condition.h:112
std::vector< array_1d< double, 3 > > neg_face_area_normals
Definition: embedded_ausas_navier_stokes_wall_condition.h:133
array_1d< double, TNumNodes > N
Definition: embedded_ausas_navier_stokes_wall_condition.h:114
VectorType w_gauss_container
Definition: embedded_ausas_navier_stokes_wall_condition.h:119