26 #include "utilities/geometry_utilities.h"
32 #ifndef KRATOS_DYNAMIC_SMAGORINSKY_UTILITIES_H_INCLUDED
33 #define KRATOS_DYNAMIC_SMAGORINSKY_UTILITIES_H_INCLUDED
76 mrModelPart(rModelPart),
77 mDomainSize(DomainSize),
99 for( ModelPart::ElementsContainerType::ptr_iterator itpElem = mrModelPart.
Elements().ptr_begin();
100 itpElem != mrModelPart.
Elements().ptr_end(); ++itpElem)
103 mCoarseMesh.push_back(*itpElem);
111 std::vector< std::vector<int> > LocalIndices(NumThreads);
116 ModelPart::ElementsContainerType::iterator ElemBegin = mCoarseMesh.begin() + ElementPartition[
k];
117 ModelPart::ElementsContainerType::iterator ElemEnd = mCoarseMesh.begin() + ElementPartition[
k+1];
121 this->AddNewIndex(LocalIndices[
k],itElem->GetValue(PATCH_INDEX));
127 std::pair<int, unsigned int> NewVal;
128 std::pair< std::map<int, unsigned int>::iterator,
bool > Result;
129 for( std::vector< std::vector<int> >::iterator itList = LocalIndices.begin(); itList != LocalIndices.end(); ++itList )
131 for( std::vector<int>::iterator itIndex = itList->begin(); itIndex != itList->end(); ++itIndex)
134 NewVal.first = *itIndex;
136 Result = mPatchIndices.insert(NewVal);
147 this->SetCoarseVel();
156 unsigned int PatchNumber = mPatchIndices.size();
158 std::vector< std::vector<double> > GlobalPatchNum(NumThreads);
159 std::vector< std::vector<double> > GlobalPatchDen(NumThreads);
161 const double EnergyTol = 0.005;
162 double TotalDissipation = 0;
164 #pragma omp parallel reduction(+:TotalDissipation)
169 ModelPart::ElementsContainerType::iterator CoarseElemBegin = mCoarseMesh.begin() + CoarseElementPartition[
k];
170 ModelPart::ElementsContainerType::iterator CoarseElemEnd = mCoarseMesh.begin() + CoarseElementPartition[
k+1];
172 ModelPart::ElementsContainerType::iterator FineElemBegin = mrModelPart.
ElementsBegin() + FineElementPartition[
k];
173 ModelPart::ElementsContainerType::iterator FineElemEnd = mrModelPart.
ElementsBegin() + FineElementPartition[
k+1];
176 Vector LocalValues, LocalCoarseVel;
180 double Residual,
Model;
181 unsigned int PatchPosition;
184 std::vector<double>& rPatchNum = GlobalPatchNum[
k];
185 std::vector<double>& rPatchDen = GlobalPatchDen[
k];
186 rPatchNum.resize(PatchNumber,0.0);
187 rPatchDen.resize(PatchNumber,0.0);
189 if (mDomainSize == 2)
193 LocalMassMatrix.
resize(9,9,
false);
199 for( ModelPart::ElementsContainerType::iterator itElem = CoarseElemBegin; itElem != CoarseElemEnd; ++itElem)
201 PatchPosition = mPatchIndices[ itElem->GetValue(PATCH_INDEX) ];
202 this->GermanoTerms2D(*itElem,
N,DN_DX,dv_dx,LocalValues,LocalCoarseVel,LocalMassMatrix,rProcessInfo,Residual,
Model);
204 rPatchNum[PatchPosition] += Residual;
205 rPatchDen[PatchPosition] +=
Model;
206 TotalDissipation += Residual;
210 for( ModelPart::ElementsContainerType::iterator itElem = FineElemBegin; itElem != FineElemEnd; ++itElem)
213 itElem->GetValue(C_SMAGORINSKY) = 0.0;
215 PatchPosition = mPatchIndices[ itElem->GetValue(PATCH_INDEX) ];
216 this->GermanoTerms2D(*itElem,
N,DN_DX,dv_dx,LocalValues,LocalCoarseVel,LocalMassMatrix,rProcessInfo,Residual,
Model);
218 rPatchNum[PatchPosition] -= Residual;
219 rPatchDen[PatchPosition] -=
Model;
225 LocalCoarseVel.
resize(16);
226 LocalMassMatrix.
resize(16,16,
false);
232 for( ModelPart::ElementsContainerType::iterator itElem = CoarseElemBegin; itElem != CoarseElemEnd; ++itElem)
234 PatchPosition = mPatchIndices[ itElem->GetValue(PATCH_INDEX) ];
235 this->GermanoTerms3D(*itElem,
N,DN_DX,dv_dx,LocalValues,LocalCoarseVel,LocalMassMatrix,rProcessInfo,Residual,
Model);
237 rPatchNum[PatchPosition] += Residual;
238 rPatchDen[PatchPosition] +=
Model;
239 TotalDissipation += Residual;
243 for( ModelPart::ElementsContainerType::iterator itElem = FineElemBegin; itElem != FineElemEnd; ++itElem)
246 itElem->GetValue(C_SMAGORINSKY) = 0.0;
248 PatchPosition = mPatchIndices[ itElem->GetValue(PATCH_INDEX) ];
249 this->GermanoTerms3D(*itElem,
N,DN_DX,dv_dx,LocalValues,LocalCoarseVel,LocalMassMatrix,rProcessInfo,Residual,
Model);
251 rPatchNum[PatchPosition] -= Residual;
252 rPatchDen[PatchPosition] -=
Model;
258 for( std::vector< std::vector<double> >::iterator itNum = GlobalPatchNum.begin()+1, itDen = GlobalPatchDen.begin()+1;
259 itNum != GlobalPatchNum.end(); ++itNum, ++itDen)
261 for( std::vector<double>::iterator TotalNum = GlobalPatchNum[0].begin(), LocalNum = itNum->begin(),
262 TotalDen = GlobalPatchDen[0].begin(), LocalDen = itDen->begin();
263 TotalNum != GlobalPatchNum[0].end(); ++TotalNum,++LocalNum,++TotalDen,++LocalDen)
265 *TotalNum += *LocalNum;
266 *TotalDen += *LocalDen;
271 std::vector<double> PatchC(PatchNumber);
272 double NumTol = EnergyTol * fabs(TotalDissipation);
273 for( std::vector<double>::iterator itNum = GlobalPatchNum[0].begin(), itDen = GlobalPatchDen[0].begin(), itC = PatchC.begin();
274 itC != PatchC.end(); ++itNum, ++itDen, ++itC)
277 if ( (fabs(*itNum) < NumTol) )
280 *itC = sqrt( 0.5 * fabs( *itNum / *itDen ) );
287 ModelPart::ElementsContainerType::iterator ElemBegin = mrModelPart.
ElementsBegin() + FineElementPartition[
k];
288 ModelPart::ElementsContainerType::iterator ElemEnd = mrModelPart.
ElementsBegin() + FineElementPartition[
k+1];
290 unsigned int PatchPosition;
294 PatchPosition = mPatchIndices[ itElem->GetValue(PATCH_INDEX) ];
295 itElem->GetValue(C_SMAGORINSKY) = PatchC[PatchPosition];
319 double Value0, Value1;
323 if( itNode->GetValue(FATHER_NODES).size() == 2 )
325 Value0 = itNode->GetValue(FATHER_NODES)[0].FastGetSolutionStepValue(rThisVariable);
326 Value1 = itNode->GetValue(FATHER_NODES)[1].FastGetSolutionStepValue(rThisVariable);
328 if( Value0 != Value1 )
330 if ( Value0 == 0.0 || Value1 == 0.0 )
333 itNode->FastGetSolutionStepValue(rThisVariable) = 0.0;
339 else if( Value0 == 3.0 )
341 itNode->FastGetSolutionStepValue(rThisVariable) = Value0;
343 else if( Value1 == 3.0 )
346 itNode->FastGetSolutionStepValue(rThisVariable) = Value1;
350 itNode->FastGetSolutionStepValue(rThisVariable) = Value0;
368 unsigned int mDomainSize;
372 std::map<int, unsigned int> mPatchIndices;
392 if( itNode->GetValue(FATHER_NODES).size() == 2 )
401 itNode->GetValue(COARSE_VELOCITY) = itNode->FastGetSolutionStepValue(VELOCITY);
407 void GermanoTerms2D(Element& rElem,
408 array_1d<double,3>& rShapeFunc,
409 BoundedMatrix<double,3,2>& rShapeDeriv,
410 BoundedMatrix<double,2,2>& rGradient,
411 Vector& rNodalResidualContainer,
412 Vector& rNodalVelocityContainer,
414 ProcessInfo& rProcessInfo,
418 const double Dim = 2;
419 const double NumNodes = 3;
423 double Density = 0.0;
430 this->CalculateResidual(rElem,rMassMatrix,rNodalVelocityContainer,rNodalResidualContainer,rProcessInfo);
431 this->GetCoarseVelocity2D(rElem,rNodalVelocityContainer);
433 for(
Vector::iterator itRHS = rNodalResidualContainer.begin(), itVel = rNodalVelocityContainer.begin(); itRHS != rNodalResidualContainer.end(); ++itRHS, ++itVel)
434 rResidual += (*itVel) * (*itRHS);
440 for (
unsigned int j = 0;
j < NumNodes; ++
j)
442 Density += rShapeFunc[
j] * rElem.GetGeometry()[
j].FastGetSolutionStepValue(DENSITY);
443 const array_1d< double,3 >& rNodeVel = rElem.GetGeometry()[
j].FastGetSolutionStepValue(VELOCITY);
445 for (
unsigned int i = 0;
i < NumNodes; ++
i)
447 const array_1d< double,3 >& rNodeTest = rElem.GetGeometry()[
i].GetValue(COARSE_VELOCITY);
449 for (
unsigned int k = 0;
k < Dim; ++
k)
450 rModel += rNodeTest[
k] * rShapeDeriv(
i,
k) * rShapeDeriv(
j,
k) * rNodeVel[
k];
453 for (
unsigned int m = 0;
m < Dim; ++
m)
455 for (
unsigned int n = 0;
n <
m; ++
n)
456 rGradient(
m,
n) += 0.5 * (rShapeDeriv(
j,
n) * rNodeVel[
m] + rShapeDeriv(
j,
m) * rNodeVel[
n]);
457 rGradient(
m,
m) += rShapeDeriv(
j,
m) * rNodeVel[
m];
465 for (
unsigned int i = 0;
i < Dim; ++
i)
467 for (
unsigned int j = 0;
j <
i; ++
j)
468 SqNorm += 2.0 * rGradient(
i,
j) * rGradient(
i,
j);
469 SqNorm += rGradient(
i,
i) * rGradient(
i,
i);
473 const double sqH = 2*Area;
474 rModel *= Density * sqH * sqrt(SqNorm);
478 void GermanoTerms3D(Element& rElem,
479 array_1d<double,4>& rShapeFunc,
480 BoundedMatrix<double,4,3>& rShapeDeriv,
481 BoundedMatrix<double,3,3>& rGradient,
482 Vector& rNodalResidualContainer,
483 Vector& rNodalVelocityContainer,
485 ProcessInfo& rProcessInfo,
489 const double Dim = 3;
490 const double NumNodes = 4;
494 double Density = 0.0;
501 this->CalculateResidual(rElem,rMassMatrix,rNodalVelocityContainer,rNodalResidualContainer,rProcessInfo);
502 this->GetCoarseVelocity3D(rElem,rNodalVelocityContainer);
504 for(
Vector::iterator itRHS = rNodalResidualContainer.begin(), itVel = rNodalVelocityContainer.begin(); itRHS != rNodalResidualContainer.end(); ++itRHS, ++itVel)
505 rResidual += (*itVel) * (*itRHS);
511 for (
unsigned int j = 0;
j < NumNodes; ++
j)
513 Density += rShapeFunc[
j] * rElem.GetGeometry()[
j].FastGetSolutionStepValue(DENSITY);
514 const array_1d< double,3 >& rNodeVel = rElem.GetGeometry()[
j].FastGetSolutionStepValue(VELOCITY);
516 for (
unsigned int i = 0;
i < NumNodes; ++
i)
518 const array_1d< double,3 >& rNodeTest = rElem.GetGeometry()[
i].GetValue(COARSE_VELOCITY);
520 for (
unsigned int k = 0;
k < Dim; ++
k)
521 rModel += rNodeTest[
k] * rShapeDeriv(
i,
k) * rShapeDeriv(
j,
k) * rNodeVel[
k];
524 for (
unsigned int m = 0;
m < Dim; ++
m)
526 for (
unsigned int n = 0;
n <
m; ++
n)
527 rGradient(
m,
n) += 0.5 * (rShapeDeriv(
j,
n) * rNodeVel[
m] + rShapeDeriv(
j,
m) * rNodeVel[
n]);
528 rGradient(
m,
m) += rShapeDeriv(
j,
m) * rNodeVel[
m];
536 for (
unsigned int i = 0;
i < Dim; ++
i)
538 for (
unsigned int j = 0;
j <
i; ++
j)
539 SqNorm += 2.0 * rGradient(
i,
j) * rGradient(
i,
j);
540 SqNorm += rGradient(
i,
i) * rGradient(
i,
i);
543 const double cubeH = 6*Volume;
544 rModel *= Density * pow(cubeH, 2.0/3.0) * sqrt(2.0 * SqNorm);
548 void GetCoarseVelocity2D(Element& rElement,
551 unsigned int LocalIndex = 0;
554 for (
unsigned int itNode = 0; itNode < 3; ++itNode)
556 const array_1d< double,3>& rCoarseVel = rGeom[itNode].GetValue(COARSE_VELOCITY);
557 rVar[LocalIndex++] = rCoarseVel[0];
558 rVar[LocalIndex++] = rCoarseVel[1];
559 rVar[LocalIndex++] = 0.0;
564 void GetCoarseVelocity3D(Element& rElement,
567 unsigned int LocalIndex = 0;
570 for (
unsigned int itNode = 0; itNode < 4; ++itNode)
572 const array_1d< double,3>& rCoarseVel = rGeom[itNode].GetValue(COARSE_VELOCITY);
573 rVar[LocalIndex++] = rCoarseVel[0];
574 rVar[LocalIndex++] = rCoarseVel[1];
575 rVar[LocalIndex++] = rCoarseVel[2];
576 rVar[LocalIndex++] = 0.0;
581 void CalculateResidual(Element& rElement,
585 const ProcessInfo& rCurrentProcessInfo)
587 const auto& r_const_elem_ref = rElement;
588 rElement.InitializeNonLinearIteration(rCurrentProcessInfo);
591 rElement.CalculateRightHandSide(rResidual,rCurrentProcessInfo);
594 rElement.CalculateMassMatrix(rMassMatrix,rCurrentProcessInfo);
595 r_const_elem_ref.GetSecondDerivativesVector(rAuxVector,0);
597 noalias(rResidual) -=
prod(rMassMatrix,rAuxVector);
600 rElement.CalculateLocalVelocityContribution(rMassMatrix,rResidual,rCurrentProcessInfo);
604 void AddNewIndex( std::vector<int>& rIndices,
608 for( std::vector<int>::iterator itIndex = rIndices.begin(); itIndex != rIndices.end(); ++itIndex)
610 if( ThisIndex == *itIndex)
618 rIndices.push_back(ThisIndex);
Short class definition.
Definition: counter.h:60
Helper class to dynamically determine a value for the Smagorinsly parameter.
Definition: dynamic_smagorinsky_utilities.h:64
~DynamicSmagorinskyUtils()
Destructor.
Definition: dynamic_smagorinsky_utilities.h:83
void CorrectFlagValues(Variable< double > &rThisVariable=FLAG_VARIABLE)
For the bridge analysis problem, correct the boundary flag after the refinement.
Definition: dynamic_smagorinsky_utilities.h:306
void CalculateC()
Provide a value for the Smagorinsky coefficient using the Variational Germano Identity.
Definition: dynamic_smagorinsky_utilities.h:144
void StoreCoarseMesh()
Store current mesh as coarse mesh. Call before refining.
Definition: dynamic_smagorinsky_utilities.h:93
DynamicSmagorinskyUtils(ModelPart &rModelPart, unsigned int DomainSize)
Constructor.
Definition: dynamic_smagorinsky_utilities.h:75
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: element.h:83
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
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
AMatrix::RandomAccessIterator< double > iterator
Definition: amatrix_interface.h:52
This class aims to manage different model parts across multi-physics simulations.
Definition: model.h:60
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
MeshType::NodeIterator NodeIterator
Definition: model_part.h:134
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::ElementIterator ElementIterator
Definition: model_part.h:174
SizeType NumberOfNodes(IndexType ThisIndex=0) const
Definition: model_part.h:341
This class defines the node.
Definition: node.h:65
TVariableType::Type & FastGetSolutionStepValue(const TVariableType &rThisVariable)
Definition: node.h:435
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: node.h:466
static void DivideInPartitions(const int NumTerms, const int NumThreads, PartitionVector &Partitions)
Divide an array of length NumTerms between NumThreads threads.
Definition: openmp_utils.h:158
static int ThisThread()
Wrapper for omp_get_thread_num().
Definition: openmp_utils.h:108
std::vector< int > PartitionVector
Vector type for the output of DivideInPartitions method.
Definition: openmp_utils.h:53
static int GetNumThreads()
Returns the current number of threads.
Definition: parallel_utilities.cpp:34
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
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
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int m
Definition: run_marine_rain_substepping.py:8
dictionary Model
TODO replace this "model" for real one once available in kratos core.
Definition: script.py:94
N
Definition: sensitivityMatrix.py:29
integer i
Definition: TensorModule.f:17