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.
stokes_3D_twofluid.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: Riccardo Rossi
11 //
12 
13 
14 
15 #if !defined(KRATOS_STOKES_ELEMENT_TWOFLUID_3D_INCLUDED )
16 #define KRATOS_STOKES_ELEMENT_TWOFLUID_3D_INCLUDED
17 
18 
19 // System includes
20 
21 
22 // External includes
23 #include "boost/smart_ptr.hpp"
24 
25 
26 // Project includes
27 #include "includes/define.h"
28 #include "includes/element.h"
29 #include "includes/variables.h"
30 #include "includes/serializer.h"
31 #include "utilities/geometry_utilities.h"
32 #include "utilities/math_utils.h"
33 #include "includes/cfd_variables.h"
36 
38 
39 namespace Kratos
40 {
41 
44 
48 
52 
56 
60 
68  : public Stokes3D
69 {
70 public:
73 
76 
80 
82 
83  Stokes3DTwoFluid(IndexType NewId, GeometryType::Pointer pGeometry)
84  : Stokes3D(NewId, pGeometry)
85  {}
86 
87  Stokes3DTwoFluid(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
88  : Stokes3D(NewId, pGeometry, pProperties)
89  {}
90 
92  ~Stokes3DTwoFluid() override {};
93 
94 
98 
99 
103 
104  Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer pProperties) const override
105  {
106  KRATOS_TRY
107  return Kratos::make_intrusive< Stokes3DTwoFluid >(NewId, GetGeometry().Create(ThisNodes), pProperties);
108  KRATOS_CATCH("");
109  }
110 
111  Element::Pointer Create(IndexType NewId,
112  GeometryType::Pointer pGeom,
113  PropertiesType::Pointer pProperties) const override
114  {
115  return Kratos::make_intrusive< Stokes3DTwoFluid >(NewId, pGeom, pProperties);
116  }
117 
118 
119  void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, const ProcessInfo& rCurrentProcessInfo) override
120  {
121  KRATOS_TRY
122  bool compute_lhs_matrix = true;
123  CalculateAll(rLeftHandSideMatrix, rRightHandSideVector, rCurrentProcessInfo, compute_lhs_matrix);
124  KRATOS_CATCH("Error in StokesTwoFluid Element Symbolic CalculateLocalSystem")
125  }
126 
127  void CalculateRightHandSide(VectorType& rRightHandSideVector, const ProcessInfo& rCurrentProcessInfo) override
128  {
129  KRATOS_TRY
130 
131  MatrixType temp = Matrix();
132  bool compute_lhs_matrix = false;
133  CalculateAll(temp, rRightHandSideVector, rCurrentProcessInfo, compute_lhs_matrix);
134 
135  KRATOS_CATCH("Error in StokesTwoFluid Element Symbolic CalculateRightHandSide")
136 
137  }
138 
140  MatrixType& rLeftHandSideMatrix,
141  VectorType& rRightHandSideVector,
142  const ProcessInfo& rCurrentProcessInfo,
143  bool ComputeLHSMatrix)
144  {
145  KRATOS_TRY
146 
147  const unsigned int NumNodes = 4;
148  const unsigned int Dim = 3;
149  const int ndofs = Dim + 1;
150  const unsigned int MatrixSize = NumNodes*ndofs;
151 
152  if (rLeftHandSideMatrix.size1() != MatrixSize)
153  rLeftHandSideMatrix.resize(MatrixSize, MatrixSize, false); //false says not to preserve existing storage!!
154 
155  if (rRightHandSideVector.size() != MatrixSize)
156  rRightHandSideVector.resize(MatrixSize, false); //false says not to preserve existing storage!!
157 
158  //struct to pass around the data
160 
161  //getting data for the given geometry
162 
163  double Volume;
165 
166  //compute element size
167 // data.h = ComputeH<4,3>(data.DN_DX, Volume);
168 
169  //gauss point position
171  GetShapeFunctionsOnGauss(Ncontainer);
172 
173  //database access to all of the variables needed
174  const Vector& BDFVector = rCurrentProcessInfo[BDF_COEFFICIENTS];
175  data.bdf0 = BDFVector[0];
176  data.bdf1 = BDFVector[1];
177  data.bdf2 = BDFVector[2];
178  data.dyn_tau_coeff = rCurrentProcessInfo[DYNAMIC_TAU] * data.bdf0;
179 
180  array_1d<double, NumNodes> distances;
181  for (unsigned int i = 0; i < NumNodes; i++)
182  {
183  const array_1d<double,3>& vel = GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
184  const array_1d<double,3>& body_force = GetGeometry()[i].FastGetSolutionStepValue(BODY_FORCE);
185  const array_1d<double,3>& vel_n = GetGeometry()[i].FastGetSolutionStepValue(VELOCITY,1);
186  const array_1d<double,3>& vel_nn = GetGeometry()[i].FastGetSolutionStepValue(VELOCITY,2);
187 
188  for(unsigned int k=0; k<Dim; k++)
189  {
190  data.v(i,k) = vel[k];
191  data.vn(i,k) = vel_n[k];
192  data.vnn(i,k) = vel_nn[k];
193  data.f(i,k) = body_force[k];
194  }
195 
196  data.p[i] = GetGeometry()[i].FastGetSolutionStepValue(PRESSURE);
197  data.rho[i] = GetGeometry()[i].FastGetSolutionStepValue(DENSITY);
198  distances[i] = GetGeometry()[i].FastGetSolutionStepValue(DISTANCE);
199  }
200 
201  //allocate memory needed
203  array_1d<double,MatrixSize> rhs_local;
204 
205  unsigned int npos=0, nneg=0;
206  for (unsigned int i = 0; i < NumNodes; i++)
207  {
208  if(distances[i] > 0)
209  npos++;
210  else
211  nneg++;
212  }
213 
214 
215  //here we decide if the element is all FLUID/AIR/MIXED
216  if(npos == NumNodes) //all AIR
217  {
218  ComputeElementAsAIR<MatrixSize,NumNodes>(lhs_local, rhs_local, rLeftHandSideMatrix, rRightHandSideVector, Volume, data, Ncontainer, rCurrentProcessInfo, ComputeLHSMatrix);
219  }
220  else if (nneg == NumNodes) //all FLUID
221  {
222  ComputeElementAsFLUID<MatrixSize,NumNodes>(lhs_local, rhs_local, rLeftHandSideMatrix, rRightHandSideVector, Volume, data, Ncontainer, rCurrentProcessInfo, ComputeLHSMatrix);
223  }
224  else //element includes both FLUID and AIR
225  {
226  ComputeElementAsMIXED<MatrixSize,NumNodes>(lhs_local, rhs_local, rLeftHandSideMatrix, rRightHandSideVector, Volume, data, rCurrentProcessInfo, distances, ComputeLHSMatrix);
227  }
228 
229  KRATOS_CATCH("Error in StokesTwoFluid Element Symbolic")
230  }
231 
233 
241  int Check(const ProcessInfo& rCurrentProcessInfo) const override
242  {
243  KRATOS_TRY
244 
245  // Perform basic element checks
246  int ErrorCode = Kratos::Element::Check(rCurrentProcessInfo);
247  if(ErrorCode != 0) return ErrorCode;
248 
249  //check Properties
250  if(GetProperties().Has(DENSITY_AIR) == false)
251  KRATOS_THROW_ERROR(std::invalid_argument,"DENSITY_AIR is not set","");
252  if(GetProperties().Has(CONSTITUTIVE_LAW) == false)
253  KRATOS_THROW_ERROR(std::invalid_argument,"CONSTITUTIVE_LAW is not set","");
254 
255  //check constitutive CONSTITUTIVE_LAW
256  GetProperties().GetValue(CONSTITUTIVE_LAW)->Check(GetProperties(),GetGeometry(),rCurrentProcessInfo);
257 
258  // Check that the element's nodes contain all required SolutionStepData and Degrees of freedom
259  for(unsigned int i=0; i<this->GetGeometry().size(); ++i)
260  {
261  if(this->GetGeometry()[i].SolutionStepsDataHas(VELOCITY) == false)
262  KRATOS_THROW_ERROR(std::invalid_argument,"missing VELOCITY variable on solution step data for node ",this->GetGeometry()[i].Id());
263  if(this->GetGeometry()[i].SolutionStepsDataHas(DISTANCE) == false)
264  KRATOS_THROW_ERROR(std::invalid_argument,"missing DISTANCE variable on solution step data for node ",this->GetGeometry()[i].Id());
265  if(this->GetGeometry()[i].SolutionStepsDataHas(DENSITY) == false)
266  KRATOS_THROW_ERROR(std::invalid_argument,"missing DENSITY variable on solution step data for node ",this->GetGeometry()[i].Id());
267  if(this->GetGeometry()[i].SolutionStepsDataHas(PRESSURE) == false)
268  KRATOS_THROW_ERROR(std::invalid_argument,"missing PRESSURE variable on solution step data for node ",this->GetGeometry()[i].Id());
269  if(this->GetGeometry()[i].HasDofFor(VELOCITY_X) == false ||
270  this->GetGeometry()[i].HasDofFor(VELOCITY_Y) == false ||
271  this->GetGeometry()[i].HasDofFor(VELOCITY_Z) == false)
272  KRATOS_THROW_ERROR(std::invalid_argument,"missing VELOCITY component degree of freedom on node ",this->GetGeometry()[i].Id());
273  if(this->GetGeometry()[i].HasDofFor(PRESSURE) == false)
274  KRATOS_THROW_ERROR(std::invalid_argument,"missing PRESSURE component degree of freedom on node ",this->GetGeometry()[i].Id());
275  }
276 
277  return 0;
278 
279  KRATOS_CATCH("");
280  }
281 
282  void Calculate(const Variable<double>& rVariable,
283  double& Output,
284  const ProcessInfo& rCurrentProcessInfo) override
285  {
286  KRATOS_TRY
287 
288  if(rVariable == HEAT_FLUX) //compute the heat flux per unit volume induced by the shearing
289  {
290  double distance_center = 0.0;
291  for(unsigned int i=0; i<GetGeometry().size(); i++)
292  distance_center += GetGeometry()[i].FastGetSolutionStepValue(DISTANCE);
293  distance_center/=static_cast<double>(GetGeometry().size());
294 
295  if(distance_center > 0) //AIR
296  {
297  Output=0.0;
298  }
299  else //OTHER MATERIAL
300  {
301  const unsigned int NumNodes = 4;
302  const unsigned int strain_size = 6;
303 
304  //create constitutive law parameters:
305  const Properties& r_properties = GetProperties();
306  ConstitutiveLaw::Parameters Values(GetGeometry(),r_properties,rCurrentProcessInfo);
307 
308  //set constitutive law flags:
309  Flags& ConstitutiveLawOptions=Values.GetOptions();
310  ConstitutiveLawOptions.Set(ConstitutiveLaw::COMPUTE_STRESS);
311  ConstitutiveLawOptions.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR, false);
312 
313  Vector Nvec(NumNodes);
314  for(unsigned int i=0; i<NumNodes; i++) Nvec[i]=0.25;
315  Values.SetShapeFunctionsValues(Nvec);
316 
317  Vector strain = CalculateStrain();
318  Values.SetStrainVector(strain);
319 
321  Values.SetStressVector(stress); //this is an ouput parameter
322 
323  // Values.SetConstitutiveMatrix(data.C); //this is an ouput parameter
324 
325  //ATTENTION: here we assume that only one constitutive law is employed for all of the gauss points in the element.
326  //this is ok under the hypothesis that no history dependent behaviour is employed
327  mp_constitutive_law->CalculateMaterialResponseCauchy(Values);
328 
329  Output = inner_prod(stress, strain);
330  }
331  }
332  else if(rVariable == EQ_STRAIN_RATE) //compute effective strain rate
333  {
334  const unsigned int NumNodes = 4;
335 
336  const Properties& r_properties = GetProperties();
337  ConstitutiveLaw::Parameters Values(GetGeometry(),r_properties,rCurrentProcessInfo);
338 
339  Vector Nvec(NumNodes);
340  for(unsigned int i=0; i<NumNodes; i++) Nvec[i]=0.25;
341  Values.SetShapeFunctionsValues(Nvec);
342 
343  Vector strain = CalculateStrain();
344  Values.SetStrainVector(strain);
345 
346  Output = mp_constitutive_law->CalculateValue(Values,rVariable, Output);
347  }
348  else if(rVariable == EFFECTIVE_VISCOSITY) //compute the heat flux per unit volume induced by the shearing
349  {
350  double distance_center = 0.0;
351  for(unsigned int i=0; i<GetGeometry().size(); i++)
352  distance_center += GetGeometry()[i].FastGetSolutionStepValue(DISTANCE);
353  distance_center/=static_cast<double>(GetGeometry().size());
354 
355  if(distance_center > 0) //AIR
356  {
357  const Properties& r_properties = GetProperties();
358  Output = r_properties[DYNAMIC_VISCOSITY];
359  }
360  else //OTHER MATERIAL
361  {
362  const unsigned int NumNodes = 4;
363 
364  const Properties& r_properties = GetProperties();
365  ConstitutiveLaw::Parameters Values(GetGeometry(),r_properties,rCurrentProcessInfo);
366 
367  Vector Nvec(NumNodes);
368  for(unsigned int i=0; i<NumNodes; i++) Nvec[i]=0.25;
369  Values.SetShapeFunctionsValues(Nvec);
370 
371  Vector strain = CalculateStrain();
372  Values.SetStrainVector(strain);
373 
374  Output = mp_constitutive_law->CalculateValue(Values,rVariable, Output);
375  }
376  }
377 
378  KRATOS_CATCH("")
379  }
380 
381  template<int MatrixSize, int NumNodes>
383  array_1d<double,MatrixSize>& rhs_local,
384  Matrix& rLeftHandSideMatrix,
385  Vector& rRightHandSideVector,
386  const double& Volume,
389  const ProcessInfo& rCurrentProcessInfo,
390  bool ComputeLHSMatrix)
391  {
392  const double air_density = GetProperties()[DENSITY_AIR];
393  for (unsigned int i = 0; i < NumNodes; i++)
394  data.rho[i] = air_density;
395  const double air_nu = GetProperties()[DYNAMIC_VISCOSITY]; //ATTENTION: not using here the real visosity of air
396 
397  const double weight = Volume/static_cast<double>(NumNodes);
398  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize,MatrixSize);
399  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
400  for(unsigned int igauss = 0; igauss<Ncontainer.size1(); igauss++)
401  {
402  noalias(data.N) = row(Ncontainer, igauss);
403 
404  ComputeConstitutiveResponse_AIR(data, air_density, air_nu, rCurrentProcessInfo);
405 
407  if (ComputeLHSMatrix) {
409  noalias(rLeftHandSideMatrix) += weight*lhs_local;
410  }
411 
412  //here we assume that all the weights of the gauss points are the same so we multiply at the end by Volume/NumNodes
413  noalias(rRightHandSideVector) += weight*rhs_local;
414  }
415 
416 // //assign AIR_DENSITY to density
417 // const double air_density = GetProperties()[DENSITY_AIR];
418 // for (unsigned int i = 0; i < NumNodes; i++)
419 // data.rho[i] = air_density;
420 // const double air_nu = GetProperties()[DYNAMIC_VISCOSITY]; //ATTENTION: not using here the real visosity of air
421 //
422 // for (unsigned int i = 0; i < NumNodes; i++) //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
423 // data.N[i] = 0.25;
424 //
425 // for(unsigned int igauss = 0; igauss<1; igauss++)
426 // {
427 // ComputeConstitutiveResponse_AIR(data,air_density, air_nu, rCurrentProcessInfo);
428 //
429 // Stokes3D::ComputeGaussPointRHSContribution(rhs_local, data);
430 // Stokes3D::ComputeGaussPointLHSContribution(lhs_local, data);
431 //
432 // //here we assume that all the weights of the gauss points are the same so we multiply at the end by Volume/NumNodes
433 // noalias(rLeftHandSideMatrix) = lhs_local; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
434 // noalias(rRightHandSideVector) = rhs_local; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
435 // }
436 //
437 // rLeftHandSideMatrix *= Volume; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
438 // rRightHandSideVector *= Volume; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
439 
440  }
441 
442 
443  template<int MatrixSize, int NumNodes>
445  array_1d<double,MatrixSize>& rhs_local,
446  Matrix& rLeftHandSideMatrix,
447  Vector& rRightHandSideVector,
448  const double& Volume,
451  const ProcessInfo& rCurrentProcessInfo,
452  bool ComputeLHSMatrix)
453  {
454  const double weight = Volume/static_cast<double>(NumNodes);
455  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize,MatrixSize);
456  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
457  for(unsigned int igauss = 0; igauss<Ncontainer.size1(); igauss++)
458  {
459  noalias(data.N) = row(Ncontainer, igauss);
460 
461  ComputeConstitutiveResponse(data, rCurrentProcessInfo);
462 
464  if (ComputeLHSMatrix) {
466  noalias(rLeftHandSideMatrix) += weight*lhs_local;
467  }
468  //here we assume that all the weights of the gauss points are the same so we multiply at the end by Volume/NumNodes
469  noalias(rRightHandSideVector) += weight*rhs_local;
470  }
471 
472 
473  }
474 
475 
476 
477 // for (unsigned int i = 0; i < NumNodes; i++) //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
478 // data.N[i] = 0.25;
479 //
480 // for(unsigned int igauss = 0; igauss<1; igauss++) //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
481 // {
482 //
483 // ComputeConstitutiveResponse(data, rCurrentProcessInfo);
484 //
485 // Stokes3D::ComputeGaussPointRHSContribution(rhs_local, data);
486 // Stokes3D::ComputeGaussPointLHSContribution(lhs_local, data);
487 //
488 // //here we assume that all the weights of the gauss points are the same so we multiply at the end by Volume/NumNodes
489 // noalias(rLeftHandSideMatrix) = lhs_local; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
490 // noalias(rRightHandSideVector) = rhs_local; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
491 // }
492 //
493 // rLeftHandSideMatrix *= Volume; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
494 // rRightHandSideVector *= Volume; //ATTENTION DELIBERATELY USING ONE SINGLE GAUSS POINT!!
495 //
496 // }
497 //
498 
499 
500  //ATTENTION: here multiple integration points are used. For this reason the methods used must be reimplemented in the current element
501  template<int MatrixSize, int NumNodes>
503  array_1d<double,MatrixSize>& rhs_local,
504  Matrix& rLeftHandSideMatrix,
505  Vector& rRightHandSideVector,
506  const double& Volume,
508  const ProcessInfo& rCurrentProcessInfo,
509  const array_1d<double,NumNodes>& distances,
510  bool ComputeLHSMatrix
511  )
512  {
513  //here do the splitting to determine the gauss points
514  Matrix Ncontainer;
515  Vector volumes;
516  Vector signs(6); //ATTENTION: this shall be initialized of size 6
517  std::vector< Matrix > DNenr;
518  Matrix Nenr;
519  unsigned int ndivisions = ComputeSplitting(data,Ncontainer, volumes, DNenr, Nenr, signs, distances);
520 
521 
522  if(ndivisions == 1)
523  {
524  //gauss point position
526  GetShapeFunctionsOnGauss(Ncontainer);
527 
528  //cases exist when the element is like not subdivided due to the characteristics of the provided distance
529  //in this cases the element is treated as AIR or FLUID depending on the side
531  for(unsigned int i=0; i<NumNodes; i++) Ncenter[i]=0.25;
532  const double dgauss = inner_prod(distances, Ncenter);
533  if(dgauss > 0)
534  {
535  ComputeElementAsAIR<MatrixSize,NumNodes>(lhs_local, rhs_local, rLeftHandSideMatrix, rRightHandSideVector, Volume, data, Ncontainer,rCurrentProcessInfo, ComputeLHSMatrix);
536  }
537  else
538  {
539  ComputeElementAsFLUID<MatrixSize,NumNodes>(lhs_local, rhs_local, rLeftHandSideMatrix, rRightHandSideVector, Volume, data, Ncontainer, rCurrentProcessInfo, ComputeLHSMatrix);
540  }
541  }
542  else
543  {
548  Vtot.clear();
549  Htot.clear();
550  Kee_tot.clear();
551  rhs_ee_tot.clear();
552 
553  //loop on gauss points
554  noalias(rLeftHandSideMatrix) = ZeroMatrix(MatrixSize,MatrixSize);
555  noalias(rRightHandSideVector) = ZeroVector(MatrixSize);
556  for(unsigned int igauss = 0; igauss<signs.size(); igauss++)
557  {
558  noalias(data.N) = row(Ncontainer, igauss);
559 
560  const double dgauss = inner_prod(distances, data.N); //compute the distance on the gauss point
561 
562  if(dgauss >= 0) //gauss is AIR
563  {
564  //assign AIR_DENSITY to density
565  const double air_density = GetProperties()[DENSITY_AIR];
566  for (unsigned int i = 0; i < NumNodes; i++)
567  data.rho[i] = air_density;
568  const double air_nu = GetProperties()[DYNAMIC_VISCOSITY];
569 
570  ComputeConstitutiveResponse_AIR(data, air_density, air_nu, rCurrentProcessInfo);
571  }
572  else
573  {
574  for (unsigned int i = 0; i < NumNodes; i++)
575  data.rho[i] = GetGeometry()[i].FastGetSolutionStepValue(DENSITY);
576  ComputeConstitutiveResponse(data, rCurrentProcessInfo);
577  }
578 
579  ComputeGaussPointRHSContribution(rhs_local, data); //ATTENTION: uses implementation within the current element since a general integration rule must be employed
580  ComputeGaussPointLHSContribution(lhs_local, data); //ATTENTION: uses implementation within the current element since a general integration rule must be employed
581  const array_1d<double,4> Nenriched = row(Nenr,igauss);
582  ComputeGaussPointEnrichmentContributions(H,V,Kee,rhs_ee, data, distances, Nenriched, DNenr[igauss]);
583 
584  const double weight = volumes[igauss];
585  if (ComputeLHSMatrix) {
586  noalias(rLeftHandSideMatrix) += weight*lhs_local;
587  }
588  noalias(rRightHandSideVector) += weight*rhs_local;
589 
590  noalias(Htot) += weight*H;
591  noalias(Vtot) += weight*V;
592  noalias(Kee_tot) += weight*Kee;
593  noalias(rhs_ee_tot) += weight*rhs_ee;
594  }
595 
596  CondenseEnrichment(rLeftHandSideMatrix,rRightHandSideVector,Htot,Vtot,Kee_tot, rhs_ee_tot, volumes, signs, distances, ComputeLHSMatrix);
597  }
598 
599  }
603 
604 
608 
609 
613 
615 
616  std::string Info() const override
617  {
618  return "Stokes3DTwoFluid #";
619  }
620 
622 
623  void PrintInfo(std::ostream& rOStream) const override
624  {
625  rOStream << Info() << Id();
626  }
627 
629  // virtual void PrintData(std::ostream& rOStream) const;
630 
631 
635 
636 
640 
641 
645 
646  //this is the symbolic function implementing the element
647  virtual void ComputeGaussPointLHSContribution(BoundedMatrix<double,16,16>& lhs, const element_data<4,3>& data);
648  virtual void ComputeGaussPointRHSContribution(array_1d<double,16>& rhs, const element_data<4,3>& data);
654  const element_data<4,3>& data,
655  const array_1d<double,4>& distances,
656  const array_1d<double,4>& Nenr,
658  );
659 
663 
665  {
666  }
667 
671 
672 
673 
674  unsigned int ComputeSplitting(
675  const element_data<4,3>& data,
676  Matrix& Ncontainer, Vector& volumes,
677  std::vector< Matrix >& DNenr,
678  Matrix& Nenr, Vector& signs,
679  const array_1d<double,4>& distances)
680  {
681  Vector el_distances = distances;
682  const unsigned int NumNodes = 4;
683  const unsigned int Dim = 3;
684  Matrix coords(NumNodes, Dim);
685 
686  //fill coordinates
687  for (unsigned int i = 0; i < NumNodes; i++)
688  {
689  const array_1d<double, 3 > & xyz = this->GetGeometry()[i].Coordinates();
690  for (unsigned int j = 0; j < Dim; j++)
691  coords(i, j) = xyz[j];
692  }
693 
694  unsigned int ndivisions = EnrichmentUtilitiesDuplicateDofs::CalculateTetrahedraEnrichedShapeFuncions(coords, data.DN_DX, el_distances, volumes, Ncontainer, signs, DNenr, Nenr);
695  return ndivisions;
696  }
697 
698  void CondenseEnrichment(Matrix& rLeftHandSideMatrix,Vector& rRightHandSideVector,
699  const BoundedMatrix<double,4,16>& Htot,
700  const BoundedMatrix<double,16,4>& Vtot,
701  BoundedMatrix<double,4,4>& Kee_tot,
702  array_1d<double,4>& Renr,
703  const Vector& volumes,
704  const Vector& signs,
705  const array_1d<double,4> distances,
706  bool ComputeLHSMatrix
707  )
708  {
709  const double Dim = 3;
710  const double min_area_ratio = 1e-6;
711 
712  double positive_volume = 0.0;
713  double negative_volume = 0.0;
714  for (unsigned int igauss = 0; igauss < volumes.size(); igauss++)
715  {
716  double wGauss = volumes[igauss];
717 
718  if(signs[igauss] >= 0) //check positive and negative volume
719  positive_volume += wGauss;
720  else
721  negative_volume += wGauss;
722  }
723  const double Vol = positive_volume + negative_volume;
724 
725  double max_diag = 0.0;
726  for(unsigned int k=0; k<Dim+1; k++)
727  if(std::abs(Kee_tot(k,k) ) > max_diag) max_diag = std::abs(Kee_tot(k,k) );
728  if(max_diag == 0) max_diag = 1.0;
729 
730  if(positive_volume/Vol < min_area_ratio)
731  {
732  for(unsigned int i=0; i<Dim+1; i++)
733  {
734  if(distances[i] >= 0.0)
735  {
736  Kee_tot(i,i) += 1000.0*max_diag;
737  }
738  }
739  }
740  if(negative_volume/Vol < min_area_ratio)
741  {
742  for(unsigned int i=0; i<Dim+1; i++)
743  {
744  if(distances[i] < 0.0)
745  {
746  Kee_tot(i,i) += 1000.0*max_diag;
747  }
748  }
749  }
750 
751  //"weakly" impose continuity
752  for(unsigned int i=0; i<Dim; i++)
753  {
754  const double di = std::abs(distances[i]);
755 
756  for(unsigned int j=i+1; j<Dim+1; j++)
757  {
758  const double dj = std::abs(distances[j]);
759 
760  if( distances[i]*distances[j] < 0.0) //cut edge
761  {
762  double sum_d = di+dj;
763  double Ni = dj/sum_d;
764  double Nj = di/sum_d;
765 
766  double penalty_coeff = max_diag*0.001; // h/BDFVector[0];
767  Kee_tot(i,i) += penalty_coeff * Ni*Ni;
768  Kee_tot(i,j) -= penalty_coeff * Ni*Nj;
769  Kee_tot(j,i) -= penalty_coeff * Nj*Ni;
770  Kee_tot(j,j) += penalty_coeff * Nj*Nj;
771 
772  }
773  }
774  }
775 
776  //add to LHS enrichment contributions
777  double det;
778  BoundedMatrix<double,4,4> inverse_diag;
779  MathUtils<double>::InvertMatrix(Kee_tot, inverse_diag,det);
780 
781  if (ComputeLHSMatrix) {
782  const BoundedMatrix<double,4,16> tmp = prod(inverse_diag,Htot);
783  noalias(rLeftHandSideMatrix) -= prod(Vtot,tmp);
784  }
785 
786  const array_1d<double,4> tmp2 = prod(inverse_diag,Renr);
787  noalias(rRightHandSideVector) -= prod(Vtot,tmp2);
788 
789  }
790 
794 
795 
799 
800 
804 
805 
807 private:
810 
814 
818  friend class Serializer;
819 
820  void save(Serializer& rSerializer) const override
821  {
823  }
824 
825  void load(Serializer& rSerializer) override
826  {
828  }
829 
831 
834  virtual void ComputeConstitutiveResponse_AIR(element_data<4,3>& data, const double rho, const double nu, const ProcessInfo& rCurrentProcessInfo)
835  {
836  const unsigned int strain_size = 6;
837 
838  if(data.C.size1() != strain_size)
839  data.C.resize(strain_size,strain_size,false);
840  if(data.stress.size() != strain_size)
841  data.stress.resize(strain_size,false);
842 
843  //compute strain
844  Vector strain = CalculateStrain();
845 
846  //here we shall call the constitutive law
847  data.C.clear();
848  data.C(0,0) = 2.0*nu;
849  data.C(1,1) = 2.0*nu;
850  data.C(2,2) = 2.0*nu;
851  data.C(3,3) = nu;
852  data.C(4,4) = nu;
853  data.C(5,5) = nu;
854 
855  const double c2 = nu;
856  const double c1 = 2.0*c2;
857  data.stress[0] = c1*strain[0];
858  data.stress[1] = c1*strain[1];
859  data.stress[2] = c1*strain[2];
860  data.stress[3] = c2*strain[3];
861  data.stress[4] = c2*strain[4];
862  data.stress[5] = c2*strain[5];
863  }
864 
865  //compute strain
866 
867  Vector CalculateStrain()
868  {
869  const unsigned int NumNodes = 4;
870  const unsigned int Dim = 3;
871  const unsigned int strain_size = 6;
872 
873  //struct to pass around the data
874  element_data<NumNodes,Dim> data;
875 
876  //getting data for the given geometry
877  double Volume;
878  BoundedMatrix<double,NumNodes,Dim> v, DN;
879  array_1d<double,NumNodes> N;
881 
882  for (unsigned int i = 0; i < NumNodes; i++)
883  {
884  const array_1d<double,3>& vel = GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
885  for(unsigned int k=0; k<Dim; k++)
886  v(i,k) = vel[k];
887  }
888 
890  strain[0] = DN(0,0)*v(0,0) + DN(1,0)*v(1,0) + DN(2,0)*v(2,0) + DN(3,0)*v(3,0);
891  strain[1] = DN(0,1)*v(0,1) + DN(1,1)*v(1,1) + DN(2,1)*v(2,1) + DN(3,1)*v(3,1);
892  strain[2] = DN(0,2)*v(0,2) + DN(1,2)*v(1,2) + DN(2,2)*v(2,2) + DN(3,2)*v(3,2);
893  strain[3] = DN(0,0)*v(0,1) + DN(0,1)*v(0,0) + DN(1,0)*v(1,1) + DN(1,1)*v(1,0) + DN(2,0)*v(2,1) + DN(2,1)*v(2,0) + DN(3,0)*v(3,1) + DN(3,1)*v(3,0);
894  strain[4] = DN(0,1)*v(0,2) + DN(0,2)*v(0,1) + DN(1,1)*v(1,2) + DN(1,2)*v(1,1) + DN(2,1)*v(2,2) + DN(2,2)*v(2,1) + DN(3,1)*v(3,2) + DN(3,2)*v(3,1);
895  strain[5] = DN(0,0)*v(0,2) + DN(0,2)*v(0,0) + DN(1,0)*v(1,2) + DN(1,2)*v(1,0) + DN(2,0)*v(2,2) + DN(2,2)*v(2,0) + DN(3,0)*v(3,2) + DN(3,2)*v(3,0);
896  return strain;
897  }
898 
899 
903 
904 
908 
909 
913 
914 
915 
916 
917 
919 
920 };
921 
923 
926 
927 
931 
932 
934 /* inline std::istream& operator >> (std::istream& rIStream,
935  Fluid2DASGS& rThis);
936  */
938 /* inline std::ostream& operator << (std::ostream& rOStream,
939  const Fluid2DASGS& rThis)
940  {
941  rThis.PrintInfo(rOStream);
942  rOStream << std::endl;
943  rThis.PrintData(rOStream);
944 
945  return rOStream;
946  }*/
948 
949 } // namespace Kratos.
950 
951 #endif // KRATOS_STOKES_ELEMENT_TWOFLUID_3D_INCLUDED defined
952 
953 
Base class for all Elements.
Definition: element.h:60
PropertiesType & GetProperties()
Definition: element.h:1024
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:904
static int CalculateTetrahedraEnrichedShapeFuncions(TMatrixType const &rPoints, TGradientType const &DN_DX, TVectorType &rDistances, TVectorType &rVolumes, TMatrixType &rShapeFunctionValues, TVectorType &rPartitionsSign, std::vector< TMatrixType > &rGradientsValue, TMatrixType &NEnriched)
Definition: enrichment_utilities_duplicate_dofs.h:89
Definition: flags.h:58
std::size_t IndexType
Definition: flags.h:74
void Set(const Flags ThisFlag)
Definition: flags.cpp:33
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
bool Has(const Variable< TDataType > &rThisVariable) const
Definition: geometrical_object.h:230
SizeType size() const
Definition: geometry.h:518
IndexType const & Id() const
Id of this Geometry.
Definition: geometry.h:964
static void CalculateGeometryData(const GeometryType &rGeometry, BoundedMatrix< double, 4, 3 > &rDN_DX, array_1d< double, 4 > &rN, double &rVolume)
This function is designed to compute the shape function derivatives, shape functions and volume in 3D...
Definition: geometry_utilities.h:176
IndexType Id() const
Definition: indexed_object.h:107
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
static BoundedMatrix< double, TDim, TDim > InvertMatrix(const BoundedMatrix< double, TDim, TDim > &rInputMatrix, double &rInputMatrixDet, const double Tolerance=ZeroTolerance)
Calculates the inverse of a 2x2, 3x3 and 4x4 matrices (using bounded matrix for performance)
Definition: math_utils.h:197
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
TVariableType::Type & GetValue(const TVariableType &rVariable)
Definition: properties.h:228
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
Definition: stokes_3D.h:62
virtual void ComputeConstitutiveResponse(element_data< 4, 3 > &data, const ProcessInfo &rCurrentProcessInfo)
Definition: stokes_3D.h:564
ConstitutiveLaw::Pointer mp_constitutive_law
Definition: stokes_3D.h:653
void GetShapeFunctionsOnGauss(BoundedMatrix< double, 4, 4 > &Ncontainer)
Definition: stokes_3D.h:546
Definition: stokes_3D_twofluid.h:69
virtual void ComputeGaussPointRHSContribution(array_1d< double, 16 > &rhs, const element_data< 4, 3 > &data)
Definition: stokes_3D_twofluid.cpp:1022
~Stokes3DTwoFluid() override
Destructor.
Definition: stokes_3D_twofluid.h:92
void ComputeElementAsMIXED(BoundedMatrix< double, MatrixSize, MatrixSize > &lhs_local, array_1d< double, MatrixSize > &rhs_local, Matrix &rLeftHandSideMatrix, Vector &rRightHandSideVector, const double &Volume, element_data< 4, 3 > &data, const ProcessInfo &rCurrentProcessInfo, const array_1d< double, NumNodes > &distances, bool ComputeLHSMatrix)
Definition: stokes_3D_twofluid.h:502
void ComputeElementAsFLUID(BoundedMatrix< double, MatrixSize, MatrixSize > &lhs_local, array_1d< double, MatrixSize > &rhs_local, Matrix &rLeftHandSideMatrix, Vector &rRightHandSideVector, const double &Volume, element_data< 4, 3 > &data, BoundedMatrix< double, NumNodes, NumNodes > &Ncontainer, const ProcessInfo &rCurrentProcessInfo, bool ComputeLHSMatrix)
Definition: stokes_3D_twofluid.h:444
void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: stokes_3D_twofluid.h:119
void CondenseEnrichment(Matrix &rLeftHandSideMatrix, Vector &rRightHandSideVector, const BoundedMatrix< double, 4, 16 > &Htot, const BoundedMatrix< double, 16, 4 > &Vtot, BoundedMatrix< double, 4, 4 > &Kee_tot, array_1d< double, 4 > &Renr, const Vector &volumes, const Vector &signs, const array_1d< double, 4 > distances, bool ComputeLHSMatrix)
Definition: stokes_3D_twofluid.h:698
Stokes3DTwoFluid(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Definition: stokes_3D_twofluid.h:87
void Calculate(const Variable< double > &rVariable, double &Output, const ProcessInfo &rCurrentProcessInfo) override
Definition: stokes_3D_twofluid.h:282
virtual void ComputeGaussPointLHSContribution(BoundedMatrix< double, 16, 16 > &lhs, const element_data< 4, 3 > &data)
Definition: stokes_3D_twofluid.cpp:6
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(Stokes3DTwoFluid)
Counted pointer of.
Stokes3DTwoFluid(IndexType NewId, GeometryType::Pointer pGeometry)
Default constructor.
Definition: stokes_3D_twofluid.h:83
std::string Info() const override
Turn back information as a string.
Definition: stokes_3D_twofluid.h:616
Element::Pointer Create(IndexType NewId, GeometryType::Pointer pGeom, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: stokes_3D_twofluid.h:111
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: stokes_3D_twofluid.h:623
void ComputeElementAsAIR(BoundedMatrix< double, MatrixSize, MatrixSize > &lhs_local, array_1d< double, MatrixSize > &rhs_local, Matrix &rLeftHandSideMatrix, Vector &rRightHandSideVector, const double &Volume, element_data< 4, 3 > &data, BoundedMatrix< double, NumNodes, NumNodes > &Ncontainer, const ProcessInfo &rCurrentProcessInfo, bool ComputeLHSMatrix)
Definition: stokes_3D_twofluid.h:382
void CalculateAll(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo, bool ComputeLHSMatrix)
Definition: stokes_3D_twofluid.h:139
unsigned int ComputeSplitting(const element_data< 4, 3 > &data, Matrix &Ncontainer, Vector &volumes, std::vector< Matrix > &DNenr, Matrix &Nenr, Vector &signs, const array_1d< double, 4 > &distances)
Definition: stokes_3D_twofluid.h:674
int Check(const ProcessInfo &rCurrentProcessInfo) const override
Checks the input and that all required Kratos variables have been registered.
Definition: stokes_3D_twofluid.h:241
void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Definition: stokes_3D_twofluid.h:127
virtual void ComputeGaussPointEnrichmentContributions(BoundedMatrix< double, 4, 16 > &H, BoundedMatrix< double, 16, 4 > &V, BoundedMatrix< double, 4, 4 > &Kee, array_1d< double, 4 > &rhs_ee, const element_data< 4, 3 > &data, const array_1d< double, 4 > &distances, const array_1d< double, 4 > &Nenr, const BoundedMatrix< double, 4, 4 > &DNenr)
Definition: stokes_3D_twofluid.cpp:1203
Stokes3DTwoFluid()
Definition: stokes_3D_twofluid.h:664
Element::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
It creates a new element pointer.
Definition: stokes_3D_twofluid.h:104
BOOST_UBLAS_INLINE void clear()
Definition: array_1d.h:325
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#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
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
Internals::Matrix< double, AMatrix::dynamic, AMatrix::dynamic > Matrix
Definition: amatrix_interface.h:470
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
ProcessInfo
Definition: edgebased_PureConvection.py:116
v
Definition: generate_convection_diffusion_explicit_element.py:114
DN
Definition: generate_convection_diffusion_explicit_element.py:98
V
Definition: generate_droplet_dynamics.py:256
H
Definition: generate_droplet_dynamics.py:257
stress
Stress vector definition.
Definition: generate_droplet_dynamics.py:82
Kee
Definition: generate_droplet_dynamics.py:258
Nenr
Definition: generate_droplet_dynamics.py:57
rho
Definition: generate_droplet_dynamics.py:86
rhs_ee
Definition: generate_droplet_dynamics.py:257
DNenr
Definition: generate_droplet_dynamics.py:56
rhs
Definition: generate_frictional_mortar_condition.py:297
lhs
Definition: generate_frictional_mortar_condition.py:297
int strain_size
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:16
strain
HERE WE MUST SUBSTITUTE EXPRESSIONS.
Definition: generate_stokes_twofluid_element.py:104
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
nu
Definition: isotropic_damage_automatic_differentiation.py:135
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
float temp
Definition: rotating_cone.py:85
body_force
Definition: script_ELASTIC.py:102
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31
Definition: constitutive_law.h:189
void SetStrainVector(StrainVectorType &rStrainVector)
Definition: constitutive_law.h:401
Flags & GetOptions()
Definition: constitutive_law.h:412
void SetStressVector(StressVectorType &rStressVector)
Definition: constitutive_law.h:402
void SetShapeFunctionsValues(const Vector &rShapeFunctionsValues)
Definition: constitutive_law.h:396
Definition: stokes_3D.h:72