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.
bdf2_turbulent_scheme.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: Jordi Cotela
11 //
12 
13 #if !defined(KRATOS_BDF2_TURBULENT_SCHEME_H_INCLUDED )
14 #define KRATOS_BDF2_TURBULENT_SCHEME_H_INCLUDED
15 
16 // System includes
17 #include <string>
18 #include <iostream>
19 
20 // External includes
21 
22 // Project includes
24 #include "includes/define.h"
25 // #include "includes/serializer.h"
26 #include "includes/dof.h"
27 #include "processes/process.h"
30 
31 // Application includes
33 
34 
35 namespace Kratos
36 {
39 
42 
46 
50 
54 
58 
60 
62 template<class TSparseSpace,class TDenseSpace>
63 class BDF2TurbulentScheme : public Scheme<TSparseSpace, TDenseSpace>
64 {
65 public:
68 
72  typedef typename TSparseSpace::DataType TDataType;
75 
78 
81 
83  typedef typename RotationToolType::UniquePointer RotationToolPointerType;
84 
88 
91  : Scheme<TSparseSpace, TDenseSpace>()
92  , mrPeriodicIdVar(Kratos::Variable<int>::StaticObject())
93  {}
94 
96 
102  BDF2TurbulentScheme(Process::Pointer pTurbulenceModel)
103  : Scheme<TSparseSpace, TDenseSpace>()
104  , mpTurbulenceModel(pTurbulenceModel)
105  , mrPeriodicIdVar(Kratos::Variable<int>::StaticObject())
106  {}
107 
109 
113  : Scheme<TSparseSpace, TDenseSpace>()
114  , mrPeriodicIdVar(rPeriodicVar)
115  {}
116 
117 
120  {}
121 
125 
126 
130 
132 
136  int Check(ModelPart& rModelPart) override
137  {
138  KRATOS_TRY
139 
140  // Base scheme check
141  int error_code = BaseType::Check(rModelPart);
142  if (error_code != 0) {
143  return error_code;
144  }
145 
146  // Check buffer size
147  KRATOS_ERROR_IF(rModelPart.GetBufferSize() < 3)
148  << "Insufficient buffer size for BDF2, should be at least 3, got " << rModelPart.GetBufferSize() << std::endl;
149 
150  return 0;
151 
152  KRATOS_CATCH("");
153  }
154 
155  void Initialize(ModelPart& rModelPart) override
156  {
157  // Set up the rotation tool pointer
158  const auto& r_proces_info = rModelPart.GetProcessInfo();
159  const unsigned int domain_size = r_proces_info[DOMAIN_SIZE];
160  auto p_aux = Kratos::make_unique<RotationToolType>(domain_size, domain_size + 1, SLIP);
161  mpRotationTool.swap(p_aux);
162 
163  // Base initialize call
164  BaseType::Initialize(rModelPart);
165  }
166 
169  ModelPart& rModelPart,
171  TSystemVectorType& Dx,
172  TSystemVectorType& b) override
173  {
174  this->SetTimeCoefficients(rModelPart.GetProcessInfo());
175 
176  // Base function initializes elements and conditions
177  BaseType::InitializeSolutionStep(rModelPart,A,Dx,b);
178 
179  // Recalculate mesh velocity (to account for variable time step)
180  const double tol = 1.0e-12;
181  const double Dt = rModelPart.GetProcessInfo()[DELTA_TIME];
182  const double OldDt = rModelPart.GetProcessInfo().GetPreviousSolutionStepInfo(1)[DELTA_TIME];
183  if(std::abs(Dt - OldDt) > tol) {
184  const int n_nodes = rModelPart.NumberOfNodes();
185  const Vector& BDFcoefs = rModelPart.GetProcessInfo()[BDF_COEFFICIENTS];
186 
187 #pragma omp parallel for
188  for(int i_node = 0; i_node < n_nodes; ++i_node) {
189  auto it_node = rModelPart.NodesBegin() + i_node;
190  auto& rMeshVel = it_node->FastGetSolutionStepValue(MESH_VELOCITY);
191  const auto& rDisp0 = it_node->FastGetSolutionStepValue(DISPLACEMENT);
192  const auto& rDisp1 = it_node->FastGetSolutionStepValue(DISPLACEMENT,1);
193  const auto& rDisp2 = it_node->FastGetSolutionStepValue(DISPLACEMENT,2);
194  rMeshVel = BDFcoefs[0] * rDisp0 + BDFcoefs[1] * rDisp1 + BDFcoefs[2] * rDisp2;
195  }
196  }
197  }
198 
200  ModelPart& rModelPart,
202  TSystemVectorType& Dx,
203  TSystemVectorType& b) override
204  {
205  KRATOS_TRY
206 
207  if (mpTurbulenceModel != 0) mpTurbulenceModel->Execute();
208 
209  KRATOS_CATCH("")
210  }
211 
213  ModelPart &rModelPart,
215  TSystemVectorType &Dx,
216  TSystemVectorType &b) override
217  {
218  const ProcessInfo& CurrentProcessInfo = rModelPart.GetProcessInfo();
219 
220  //if orthogonal subscales are computed
221  if (CurrentProcessInfo[OSS_SWITCH] == 1.0)
222  {
223  this->LumpedProjection(rModelPart);
224  //this->FullProjection(rModelPart);
225  }
226 
227  }
228 
230  void Predict(
231  ModelPart& rModelPart,
232  DofsArrayType& rDofSet,
234  TSystemVectorType& Dx,
235  TSystemVectorType& b) override
236  {
237  KRATOS_TRY
238 
239  const int n_nodes = rModelPart.NumberOfNodes();
240  const Vector& BDFcoefs = rModelPart.GetProcessInfo()[BDF_COEFFICIENTS];
241 
242 #pragma omp parallel for
243  for(int i_node = 0; i_node < n_nodes; ++i_node) {
244  auto it_node = rModelPart.NodesBegin() + i_node;
245  auto& rVel0 = it_node->FastGetSolutionStepValue(VELOCITY);
246  const auto& rVel1 = it_node->FastGetSolutionStepValue(VELOCITY,1);
247  const auto& rVel2 = it_node->FastGetSolutionStepValue(VELOCITY,2);
248  auto& rAcceleration = it_node->FastGetSolutionStepValue(ACCELERATION);
249 
250  // Predict velocities
251  if(!it_node->IsFixed(VELOCITY_X))
252  rVel0[0] = 2.00 * rVel1[0] - rVel2[0];
253  if(!it_node->IsFixed(VELOCITY_Y))
254  rVel0[1] = 2.00 * rVel1[1] - rVel2[1];
255  if(!it_node->IsFixed(VELOCITY_Z))
256  rVel0[2] = 2.00 * rVel1[2] - rVel2[2];
257 
258  // Predict acceleration
259  rAcceleration = BDFcoefs[0] * rVel0 + BDFcoefs[1] * rVel1 + BDFcoefs[2] * rVel2;
260  }
261 
262  KRATOS_CATCH("")
263  }
264 
266 
273  void Update(
274  ModelPart& rModelPart,
275  DofsArrayType& rDofSet,
277  TSystemVectorType& Dx,
278  TSystemVectorType& b) override
279  {
280  KRATOS_TRY
281 
282  mpRotationTool->RotateVelocities(rModelPart);
283 
284  mpDofUpdater->UpdateDofs(rDofSet,Dx);
285 
286  mpRotationTool->RecoverVelocities(rModelPart);
287 
288  const Vector& BDFCoefs = rModelPart.GetProcessInfo()[BDF_COEFFICIENTS];
289  this->UpdateAcceleration(rModelPart,BDFCoefs);
290 
291  KRATOS_CATCH("")
292  }
293 
295  Element& rCurrentElement,
296  LocalSystemMatrixType& LHS_Contribution,
297  LocalSystemVectorType& RHS_Contribution,
298  Element::EquationIdVectorType& rEquationId,
299  const ProcessInfo& rCurrentProcessInfo) override
300  {
301  KRATOS_TRY
302 
305 
306  // Get Equation Id
307  rCurrentElement.EquationIdVector(rEquationId,rCurrentProcessInfo);
308 
309  // Get matrix contributions
310  rCurrentElement.CalculateLocalSystem(LHS_Contribution,RHS_Contribution,rCurrentProcessInfo);
311  rCurrentElement.CalculateMassMatrix(Mass,rCurrentProcessInfo);
312  rCurrentElement.CalculateLocalVelocityContribution(Damp,RHS_Contribution,rCurrentProcessInfo);
313 
314  // Add the dynamic contributions to the local system using BDF2 coefficients
315  this->CombineLHSContributions(LHS_Contribution,Mass,Damp,rCurrentProcessInfo);
316  this->AddDynamicRHSContribution<Kratos::Element>(rCurrentElement,RHS_Contribution,Mass,rCurrentProcessInfo);
317 
318  // Apply slip condition
319  mpRotationTool->Rotate(LHS_Contribution, RHS_Contribution, rCurrentElement.GetGeometry());
320  mpRotationTool->ApplySlipCondition(LHS_Contribution, RHS_Contribution, rCurrentElement.GetGeometry());
321 
322  KRATOS_CATCH("")
323  }
324 
326  Element& rCurrentElement,
327  LocalSystemVectorType &RHS_Contribution,
328  Element::EquationIdVectorType &rEquationId,
329  const ProcessInfo &rCurrentProcessInfo) override
330  {
331  KRATOS_TRY
332 
335 
336  // Get Equation Id
337  rCurrentElement.EquationIdVector(rEquationId,rCurrentProcessInfo);
338 
339  // Get matrix contributions
340  rCurrentElement.CalculateRightHandSide(RHS_Contribution,rCurrentProcessInfo);
341  rCurrentElement.CalculateMassMatrix(Mass,rCurrentProcessInfo);
342  rCurrentElement.CalculateLocalVelocityContribution(Damp,RHS_Contribution,rCurrentProcessInfo);
343 
344  // Add the dynamic contributions to the local system using BDF2 coefficients
345  this->AddDynamicRHSContribution<Kratos::Element>(rCurrentElement,RHS_Contribution,Mass,rCurrentProcessInfo);
346 
347  // Apply slip condition
348  mpRotationTool->Rotate(RHS_Contribution, rCurrentElement.GetGeometry());
349  mpRotationTool->ApplySlipCondition(RHS_Contribution, rCurrentElement.GetGeometry());
350 
351  KRATOS_CATCH("")
352  }
353 
355  Condition& rCurrentCondition,
356  LocalSystemMatrixType& LHS_Contribution,
357  LocalSystemVectorType& RHS_Contribution,
358  Element::EquationIdVectorType& rEquationId,
359  const ProcessInfo& rCurrentProcessInfo) override
360  {
361  KRATOS_TRY
362 
365 
366  // Get Equation Id
367  rCurrentCondition.EquationIdVector(rEquationId,rCurrentProcessInfo);
368 
369  // Get matrix contributions
370  rCurrentCondition.CalculateLocalSystem(LHS_Contribution,RHS_Contribution,rCurrentProcessInfo);
371  rCurrentCondition.CalculateMassMatrix(Mass,rCurrentProcessInfo);
372  rCurrentCondition.CalculateLocalVelocityContribution(Damp,RHS_Contribution,rCurrentProcessInfo);
373 
374  // Add the dynamic contributions to the local system using BDF2 coefficients
375  this->CombineLHSContributions(LHS_Contribution,Mass,Damp,rCurrentProcessInfo);
376  this->AddDynamicRHSContribution<Kratos::Condition>(rCurrentCondition,RHS_Contribution,Mass,rCurrentProcessInfo);
377 
378  // Apply slip condition
379  mpRotationTool->Rotate(LHS_Contribution, RHS_Contribution, rCurrentCondition.GetGeometry());
380  mpRotationTool->ApplySlipCondition(LHS_Contribution, RHS_Contribution, rCurrentCondition.GetGeometry());
381 
382  KRATOS_CATCH("")
383  }
384 
386  Condition &rCurrentCondition,
387  LocalSystemVectorType &RHS_Contribution,
388  Element::EquationIdVectorType &rEquationId,
389  const ProcessInfo &rCurrentProcessInfo) override
390  {
391  KRATOS_TRY
392 
395 
396  // Get Equation Id
397  rCurrentCondition.EquationIdVector(rEquationId,rCurrentProcessInfo);
398 
399  // Get matrix contributions
400  rCurrentCondition.CalculateRightHandSide(RHS_Contribution,rCurrentProcessInfo);
401  rCurrentCondition.CalculateMassMatrix(Mass,rCurrentProcessInfo);
402  rCurrentCondition.CalculateLocalVelocityContribution(Damp,RHS_Contribution,rCurrentProcessInfo);
403 
404  // Add the dynamic contributions to the local system using BDF2 coefficients
405  this->AddDynamicRHSContribution<Kratos::Condition>(rCurrentCondition,RHS_Contribution,Mass,rCurrentProcessInfo);
406 
407  // Apply slip condition
408  mpRotationTool->Rotate(RHS_Contribution, rCurrentCondition.GetGeometry());
409  mpRotationTool->ApplySlipCondition(RHS_Contribution, rCurrentCondition.GetGeometry());
410 
411  KRATOS_CATCH("")
412  }
413 
415  void Clear() override
416  {
417  this->mpDofUpdater->Clear();
418  }
419 
423 
424 
428 
429 
433 
435  std::string Info() const override
436  {
437  std::stringstream buffer;
438  buffer << "BDF2TurbulentScheme";
439  return buffer.str();
440  }
441 
443  void PrintInfo(std::ostream& rOStream) const override
444  {
445  rOStream << Info();
446  }
447 
449  void PrintData(std::ostream& rOStream) const override
450  {}
451 
455 
456 
458 protected:
461 
462 
466 
467 
471 
472 
476 
478 
481  void SetTimeCoefficients(ProcessInfo& rCurrentProcessInfo)
482  {
483  KRATOS_TRY;
484 
485  //calculate the BDF coefficients
486  double Dt = rCurrentProcessInfo[DELTA_TIME];
487  double OldDt = rCurrentProcessInfo.GetPreviousTimeStepInfo(1)[DELTA_TIME];
488 
489  double Rho = OldDt / Dt;
490  double TimeCoeff = 1.0 / (Dt * Rho * Rho + Dt * Rho);
491 
492  Vector& BDFcoeffs = rCurrentProcessInfo[BDF_COEFFICIENTS];
493  BDFcoeffs.resize(3, false);
494 
495  BDFcoeffs[0] = TimeCoeff * (Rho * Rho + 2.0 * Rho); //coefficient for step n+1 (3/2Dt if Dt is constant)
496  BDFcoeffs[1] = -TimeCoeff * (Rho * Rho + 2.0 * Rho + 1.0); //coefficient for step n (-4/2Dt if Dt is constant)
497  BDFcoeffs[2] = TimeCoeff; //coefficient for step n-1 (1/2Dt if Dt is constant)
498 
499  KRATOS_CATCH("");
500  }
501 
503 
507  virtual void UpdateDofs(
508  DofsArrayType& rDofSet,
509  TSystemVectorType& Dx)
510  {
511  KRATOS_TRY
512 
513  const int n_dof = rDofSet.size();
514 
515 #pragma omp parallel for
516  for (int i_dof = 0; i_dof < n_dof; ++i_dof) {
517  auto it_dof = rDofSet.begin() + i_dof;
518  if (it_dof->IsFree()) {
519  it_dof->GetSolutionStepValue() += TSparseSpace::GetValue(Dx, it_dof->EquationId());
520  }
521  }
522 
523  KRATOS_CATCH("")
524  }
525 
527 
532  ModelPart& rModelPart,
533  const Vector& rBDFcoefs)
534  {
535  KRATOS_TRY
536 
537  const double Coef0 = rBDFcoefs[0];
538  const double Coef1 = rBDFcoefs[1];
539  const double Coef2 = rBDFcoefs[2];
540  const int n_nodes = rModelPart.NumberOfNodes();
541 
542 #pragma omp parallel for
543  for (int i_node = 0; i_node < n_nodes; ++i_node) {
544  auto it_node = rModelPart.NodesBegin() + i_node;
545  const auto& rVel0 = it_node->FastGetSolutionStepValue(VELOCITY);
546  const auto& rVel1 = it_node->FastGetSolutionStepValue(VELOCITY,1);
547  const auto& rVel2 = it_node->FastGetSolutionStepValue(VELOCITY,2);
548  auto& rAcceleration = it_node->FastGetSolutionStepValue(ACCELERATION);
549 
550  rAcceleration = Coef0 * rVel0 + Coef1 * rVel1 + Coef2 * rVel2;
551  }
552 
553  KRATOS_CATCH("")
554  }
555 
557  LocalSystemMatrixType& rLHS,
558  LocalSystemMatrixType& rMass,
559  LocalSystemMatrixType& rDamp,
560  const ProcessInfo& rCurrentProcessInfo)
561  {
562  const double Coef0 = rCurrentProcessInfo.GetValue(BDF_COEFFICIENTS)[0];
563  if (rMass.size1() != 0) noalias(rLHS) += Coef0 * rMass;
564  if (rDamp.size1() != 0) noalias(rLHS) += rDamp;
565  }
566 
567  template<class TObject>
569  TObject& rObject,
570  LocalSystemVectorType& rRHS,
571  LocalSystemMatrixType& rMass,
572  const ProcessInfo& rCurrentProcessInfo)
573  {
574  if (rMass.size1() != 0)
575  {
576  const Vector& rCoefs = rCurrentProcessInfo.GetValue(BDF_COEFFICIENTS);
577  const auto& r_const_obj_ref = rObject;
579  r_const_obj_ref.GetFirstDerivativesVector(Acc);
580  Acc *= rCoefs[0];
581 
582  for(unsigned int n = 1; n < 3; ++n)
583  {
585  r_const_obj_ref.GetFirstDerivativesVector(rVel,n);
586  noalias(Acc) += rCoefs[n] * rVel;
587  }
588 
589  noalias(rRHS) -= prod(rMass,Acc);
590  }
591  }
592 
593  void FullProjection(ModelPart& rModelPart)
594  {
595  const ProcessInfo& rCurrentProcessInfo = rModelPart.GetProcessInfo();
596 
597  // Initialize containers
598  const int n_nodes = rModelPart.NumberOfNodes();
599  const int n_elems = rModelPart.NumberOfElements();
600  const array_1d<double,3> zero_vect = ZeroVector(3);
601 #pragma omp parallel for firstprivate(zero_vect)
602  for (int i_node = 0; i_node < n_nodes; ++i_node) {
603  auto ind = rModelPart.NodesBegin() + i_node;
604  noalias(ind->FastGetSolutionStepValue(ADVPROJ)) = zero_vect; // "x"
605  ind->FastGetSolutionStepValue(DIVPROJ) = 0.0; // "x"
606  ind->FastGetSolutionStepValue(NODAL_AREA) = 0.0; // "Ml"
607  }
608 
609  // Newton-Raphson parameters
610  const double RelTol = 1e-4 * rModelPart.NumberOfNodes();
611  const double AbsTol = 1e-6 * rModelPart.NumberOfNodes();
612  const unsigned int MaxIter = 100;
613 
614  // iteration variables
615  unsigned int iter = 0;
616  array_1d<double,3> dMomProj = zero_vect;
617  double dMassProj = 0.0;
618 
619  double RelMomErr = 1000.0 * RelTol;
620  double RelMassErr = 1000.0 * RelTol;
621  double AbsMomErr = 1000.0 * AbsTol;
622  double AbsMassErr = 1000.0 * AbsTol;
623 
624  while( ( (AbsMomErr > AbsTol && RelMomErr > RelTol) || (AbsMassErr > AbsTol && RelMassErr > RelTol) ) && iter < MaxIter)
625  {
626  // Reinitialize RHS
627 #pragma omp parallel for firstprivate(zero_vect)
628  for (int i_node = 0; i_node < n_nodes; ++i_node)
629  {
630  auto ind = rModelPart.NodesBegin() + i_node;
631  noalias(ind->GetValue(ADVPROJ)) = zero_vect; // "b"
632  ind->GetValue(DIVPROJ) = 0.0; // "b"
633  ind->FastGetSolutionStepValue(NODAL_AREA) = 0.0; // Reset because Calculate will overwrite it
634  }
635 
636  // Reinitialize errors
637  RelMomErr = 0.0;
638  RelMassErr = 0.0;
639  AbsMomErr = 0.0;
640  AbsMassErr = 0.0;
641 
642  // Compute new values
644 #pragma omp parallel for private(output)
645  for (int i_elem = 0; i_elem < n_elems; ++i_elem) {
646  auto it_elem = rModelPart.ElementsBegin() + i_elem;
647  it_elem->Calculate(SUBSCALE_VELOCITY, output, rCurrentProcessInfo);
648  }
649 
650  rModelPart.GetCommunicator().AssembleCurrentData(NODAL_AREA);
651  rModelPart.GetCommunicator().AssembleCurrentData(DIVPROJ);
652  rModelPart.GetCommunicator().AssembleCurrentData(ADVPROJ);
653  rModelPart.GetCommunicator().AssembleNonHistoricalData(DIVPROJ);
654  rModelPart.GetCommunicator().AssembleNonHistoricalData(ADVPROJ);
655 
656  // Update iteration variables
657 #pragma omp parallel for
658  for (int i_node = 0; i_node < n_nodes; ++i_node) {
659  auto ind = rModelPart.NodesBegin() + i_node;
660  const double Area = ind->FastGetSolutionStepValue(NODAL_AREA); // Ml dx = b - Mc x
661  dMomProj = ind->GetValue(ADVPROJ) / Area;
662  dMassProj = ind->GetValue(DIVPROJ) / Area;
663 
664  RelMomErr += sqrt( dMomProj[0]*dMomProj[0] + dMomProj[1]*dMomProj[1] + dMomProj[2]*dMomProj[2]);
665  RelMassErr += fabs(dMassProj);
666 
667  auto& rMomRHS = ind->FastGetSolutionStepValue(ADVPROJ);
668  double& rMassRHS = ind->FastGetSolutionStepValue(DIVPROJ);
669  rMomRHS += dMomProj;
670  rMassRHS += dMassProj;
671 
672  AbsMomErr += sqrt( rMomRHS[0]*rMomRHS[0] + rMomRHS[1]*rMomRHS[1] + rMomRHS[2]*rMomRHS[2]);
673  AbsMassErr += fabs(rMassRHS);
674  }
675 
676  if(AbsMomErr > 1e-10)
677  RelMomErr /= AbsMomErr;
678  else // If residual is close to zero, force absolute convergence to avoid division by zero errors
679  RelMomErr = 1000.0;
680 
681  if(AbsMassErr > 1e-10)
682  RelMassErr /= AbsMassErr;
683  else
684  RelMassErr = 1000.0;
685 
686  iter++;
687  }
688 
689  KRATOS_INFO("BDF2TurbulentScheme") << "Performed OSS Projection in " << iter << " iterations" << std::endl;
690  }
691 
692  void LumpedProjection(ModelPart& rModelPart)
693  {
694  const int n_nodes = rModelPart.NumberOfNodes();
695  const int n_elems = rModelPart.NumberOfElements();
696  const ProcessInfo& rCurrentProcessInfo = rModelPart.GetProcessInfo();
697 
698  const array_1d<double,3> zero_vect = ZeroVector(3);
699 #pragma omp parallel for firstprivate(zero_vect)
700  for (int i_node = 0; i_node < n_nodes; ++i_node) {
701  auto itNode = rModelPart.NodesBegin() + i_node;
702  noalias(itNode->FastGetSolutionStepValue(ADVPROJ)) = zero_vect;
703  itNode->FastGetSolutionStepValue(DIVPROJ) = 0.0;
704  itNode->FastGetSolutionStepValue(NODAL_AREA) = 0.0;
705  }
706 
708 #pragma omp parallel for private(Out)
709  for (int i_elem = 0; i_elem < n_elems; ++i_elem) {
710  auto itElem = rModelPart.ElementsBegin() + i_elem;
711  itElem->Calculate(ADVPROJ, Out, rCurrentProcessInfo);
712  }
713 
714  rModelPart.GetCommunicator().AssembleCurrentData(NODAL_AREA);
715  rModelPart.GetCommunicator().AssembleCurrentData(DIVPROJ);
716  rModelPart.GetCommunicator().AssembleCurrentData(ADVPROJ);
717 
718  // Correction for periodic conditions
719  if (mrPeriodicIdVar.Key() != 0) {
720  this->PeriodicConditionProjectionCorrection(rModelPart);
721  }
722 
723  const double zero_tol = 1.0e-12;
724 #pragma omp parallel for firstprivate(zero_tol)
725  for (int i_node = 0; i_node < n_nodes; ++i_node){
726  auto iNode = rModelPart.NodesBegin() + i_node;
727  if (iNode->FastGetSolutionStepValue(NODAL_AREA) < zero_tol) {
728  iNode->FastGetSolutionStepValue(NODAL_AREA) = 1.0;
729  }
730  const double Area = iNode->FastGetSolutionStepValue(NODAL_AREA);
731  iNode->FastGetSolutionStepValue(ADVPROJ) /= Area;
732  iNode->FastGetSolutionStepValue(DIVPROJ) /= Area;
733  }
734 
735  KRATOS_INFO("BDF2TurbulentScheme") << "Computing OSS projections" << std::endl;
736  }
737 
745  {
746  const int num_nodes = rModelPart.NumberOfNodes();
747  const int num_conditions = rModelPart.NumberOfConditions();
748 
749  #pragma omp parallel for
750  for (int i = 0; i < num_nodes; i++) {
751  auto it_node = rModelPart.NodesBegin() + i;
752 
753  it_node->SetValue(NODAL_AREA,0.0);
754  it_node->SetValue(ADVPROJ,ZeroVector(3));
755  it_node->SetValue(DIVPROJ,0.0);
756  }
757 
758  #pragma omp parallel for
759  for (int i = 0; i < num_conditions; i++) {
760  auto it_cond = rModelPart.ConditionsBegin() + i;
761 
762  if(it_cond->Is(PERIODIC)) {
763  this->AssemblePeriodicContributionToProjections(it_cond->GetGeometry());
764  }
765  }
766 
767  rModelPart.GetCommunicator().AssembleNonHistoricalData(NODAL_AREA);
768  rModelPart.GetCommunicator().AssembleNonHistoricalData(ADVPROJ);
769  rModelPart.GetCommunicator().AssembleNonHistoricalData(DIVPROJ);
770 
771  #pragma omp parallel for
772  for (int i = 0; i < num_nodes; i++) {
773  auto it_node = rModelPart.NodesBegin() + i;
774  this->CorrectContributionsOnPeriodicNode(*it_node);
775  }
776  }
777 
779  {
780  unsigned int nodes_in_cond = rGeometry.PointsNumber();
781 
782  double nodal_area = 0.0;
783  array_1d<double,3> momentum_projection = ZeroVector(3);
784  double mass_projection = 0.0;
785  for ( unsigned int i = 0; i < nodes_in_cond; i++ )
786  {
787  auto& r_node = rGeometry[i];
788  nodal_area += r_node.FastGetSolutionStepValue(NODAL_AREA);
789  noalias(momentum_projection) += r_node.FastGetSolutionStepValue(ADVPROJ);
790  mass_projection += r_node.FastGetSolutionStepValue(DIVPROJ);
791  }
792 
793  for ( unsigned int i = 0; i < nodes_in_cond; i++ )
794  {
795  auto& r_node = rGeometry[i];
796  /* Note that this loop is expected to be threadsafe in normal conditions,
797  * since each node should belong to a single periodic link. However, I am
798  * setting the locks for openmp in case that we try more complicated things
799  * in the future (like having different periodic conditions for different
800  * coordinate directions).
801  */
802  r_node.SetLock();
803  r_node.GetValue(NODAL_AREA) = nodal_area;
804  noalias(r_node.GetValue(ADVPROJ)) = momentum_projection;
805  r_node.GetValue(DIVPROJ) = mass_projection;
806  r_node.UnSetLock();
807  }
808  }
809 
811  {
812  //TODO: This needs to be done in another manner as soon as we start using non-historical NODAL_AREA
813  if (rNode.GetValue(NODAL_AREA) != 0.0) // Only periodic nodes will have a non-historical NODAL_AREA set.
814  {
815  rNode.FastGetSolutionStepValue(NODAL_AREA) = rNode.GetValue(NODAL_AREA);
816  noalias(rNode.FastGetSolutionStepValue(ADVPROJ)) = rNode.GetValue(ADVPROJ);
817  rNode.FastGetSolutionStepValue(DIVPROJ) = rNode.GetValue(DIVPROJ);
818  }
819  }
820 
824 
825 
829 
830 
834 
835 
837 private:
840 
841 
845 
847  Process::Pointer mpTurbulenceModel = nullptr;
848 
849  RotationToolPointerType mpRotationTool = nullptr;
850 
851  typename TSparseSpace::DofUpdaterPointerType mpDofUpdater = TSparseSpace::CreateDofUpdater();
852 
853  const Kratos::Variable<int>& mrPeriodicIdVar;
854 
855 // ///@}
856 // ///@name Serialization
857 // ///@{
858 //
859 // friend class Serializer;
860 //
861 // virtual void save(Serializer& rSerializer) const
862 // {
863 // KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, BaseType );
864 // rSerializer.save("mpTurbulenceModel",mpTurbulenceModel);
865 // }
866 //
867 // virtual void load(Serializer& rSerializer)
868 // {
869 // KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, BaseType );
870 // rSerializer.load("mpTurbulenceModel",mpTurbulenceModel);
871 // }
872 
876 
877 
881 
882 
886 
887 
891 
892 
896 
898  BDF2TurbulentScheme & operator=(BDF2TurbulentScheme const& rOther)
899  {}
900 
903  {}
904 
906 
907 }; // Class BDF2TurbulentScheme
908 
910 
913 
914 
918 
920 template<class TSparseSpace,class TDenseSpace>
921 inline std::istream& operator >>(std::istream& rIStream,BDF2TurbulentScheme<TSparseSpace,TDenseSpace>& rThis)
922 {
923  return rIStream;
924 }
925 
927 template<class TSparseSpace,class TDenseSpace>
928 inline std::ostream& operator <<(std::ostream& rOStream,const BDF2TurbulentScheme<TSparseSpace,TDenseSpace>& rThis)
929 {
930  rThis.PrintInfo(rOStream);
931  rOStream << std::endl;
932  rThis.PrintData(rOStream);
933 
934  return rOStream;
935 }
936 
938 
940 
941 } // namespace Kratos.
942 
943 #endif // KRATOS_BDF2_TURBULENT_SCHEME_H_INCLUDED defined
A scheme for BDF2 time integration.
Definition: bdf2_turbulent_scheme.h:64
~BDF2TurbulentScheme() override
Destructor.
Definition: bdf2_turbulent_scheme.h:119
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: bdf2_turbulent_scheme.h:443
TDenseSpace::VectorType LocalSystemVectorType
Definition: bdf2_turbulent_scheme.h:77
RotationToolType::UniquePointer RotationToolPointerType
Definition: bdf2_turbulent_scheme.h:83
void SetTimeCoefficients(ProcessInfo &rCurrentProcessInfo)
Calculate the coefficients for time iteration.
Definition: bdf2_turbulent_scheme.h:481
void Initialize(ModelPart &rModelPart) override
This is the place to initialize the Scheme.
Definition: bdf2_turbulent_scheme.h:155
void FullProjection(ModelPart &rModelPart)
Definition: bdf2_turbulent_scheme.h:593
Scheme< TSparseSpace, TDenseSpace > BaseType
Definition: bdf2_turbulent_scheme.h:71
BDF2TurbulentScheme()
Default constructor.
Definition: bdf2_turbulent_scheme.h:90
BDF2TurbulentScheme(const Kratos::Variable< int > &rPeriodicVar)
Constructor for periodic boundary conditions.
Definition: bdf2_turbulent_scheme.h:112
TDenseSpace::MatrixType LocalSystemMatrixType
Definition: bdf2_turbulent_scheme.h:76
void AssemblePeriodicContributionToProjections(Geometry< Node > &rGeometry)
Definition: bdf2_turbulent_scheme.h:778
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: bdf2_turbulent_scheme.h:449
void CalculateRHSContribution(Element &rCurrentElement, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &rEquationId, const ProcessInfo &rCurrentProcessInfo) override
This function is designed to calculate just the RHS contribution.
Definition: bdf2_turbulent_scheme.h:325
void InitializeSolutionStep(ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
Set the time iteration coefficients.
Definition: bdf2_turbulent_scheme.h:168
std::string Info() const override
Turn back information as a string.
Definition: bdf2_turbulent_scheme.h:435
void CalculateSystemContributions(Condition &rCurrentCondition, LocalSystemMatrixType &LHS_Contribution, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &rEquationId, const ProcessInfo &rCurrentProcessInfo) override
Functions totally analogous to the precedent but applied to the "condition" objects.
Definition: bdf2_turbulent_scheme.h:354
void FinalizeNonLinIteration(ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
Function to be called when it is needed to finalize an iteration. It is designed to be called at the ...
Definition: bdf2_turbulent_scheme.h:212
BaseType::DofsArrayType DofsArrayType
Definition: bdf2_turbulent_scheme.h:80
BDF2TurbulentScheme(Process::Pointer pTurbulenceModel)
Constructor to use the formulation combined with a turbulence model.
Definition: bdf2_turbulent_scheme.h:102
void UpdateAcceleration(ModelPart &rModelPart, const Vector &rBDFcoefs)
Update Dof values after a Newton-Raphson iteration.
Definition: bdf2_turbulent_scheme.h:531
void InitializeNonLinIteration(ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
unction to be called when it is needed to initialize an iteration. It is designed to be called at the...
Definition: bdf2_turbulent_scheme.h:199
void CombineLHSContributions(LocalSystemMatrixType &rLHS, LocalSystemMatrixType &rMass, LocalSystemMatrixType &rDamp, const ProcessInfo &rCurrentProcessInfo)
Definition: bdf2_turbulent_scheme.h:556
TSparseSpace::VectorType TSystemVectorType
Definition: bdf2_turbulent_scheme.h:74
TSparseSpace::MatrixType TSystemMatrixType
Definition: bdf2_turbulent_scheme.h:73
void LumpedProjection(ModelPart &rModelPart)
Definition: bdf2_turbulent_scheme.h:692
void CalculateSystemContributions(Element &rCurrentElement, LocalSystemMatrixType &LHS_Contribution, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &rEquationId, const ProcessInfo &rCurrentProcessInfo) override
This function is designed to be called in the builder and solver to introduce the selected time integ...
Definition: bdf2_turbulent_scheme.h:294
void AddDynamicRHSContribution(TObject &rObject, LocalSystemVectorType &rRHS, LocalSystemMatrixType &rMass, const ProcessInfo &rCurrentProcessInfo)
Definition: bdf2_turbulent_scheme.h:568
virtual void UpdateDofs(DofsArrayType &rDofSet, TSystemVectorType &Dx)
Update Dof values after a Newton-Raphson iteration.
Definition: bdf2_turbulent_scheme.h:507
Dof< TDataType > TDofType
Definition: bdf2_turbulent_scheme.h:79
void Update(ModelPart &rModelPart, DofsArrayType &rDofSet, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
Store the iteration results as solution step variables and update acceleration after a Newton-Raphson...
Definition: bdf2_turbulent_scheme.h:273
int Check(ModelPart &rModelPart) override
Check input data for errors.
Definition: bdf2_turbulent_scheme.h:136
void CalculateRHSContribution(Condition &rCurrentCondition, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &rEquationId, const ProcessInfo &rCurrentProcessInfo) override
Functions totally analogous to the precedent but applied to the "condition" objects.
Definition: bdf2_turbulent_scheme.h:385
void Clear() override
Free memory allocated by this object.
Definition: bdf2_turbulent_scheme.h:415
void Predict(ModelPart &rModelPart, DofsArrayType &rDofSet, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
Start the iteration by providing a first approximation to the solution.
Definition: bdf2_turbulent_scheme.h:230
void CorrectContributionsOnPeriodicNode(Node &rNode)
Definition: bdf2_turbulent_scheme.h:810
CoordinateTransformationUtils< LocalSystemMatrixType, LocalSystemVectorType, double > RotationToolType
Definition: bdf2_turbulent_scheme.h:82
TSparseSpace::DataType TDataType
Definition: bdf2_turbulent_scheme.h:72
void PeriodicConditionProjectionCorrection(ModelPart &rModelPart)
Definition: bdf2_turbulent_scheme.h:744
KRATOS_CLASS_POINTER_DEFINITION(BDF2TurbulentScheme)
Pointer definition of BDF2TurbulentScheme.
virtual bool AssembleNonHistoricalData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:527
virtual bool AssembleCurrentData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:502
Base class for all Conditions.
Definition: condition.h:59
virtual void CalculateLocalVelocityContribution(MatrixType &rDampingMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: condition.h:922
virtual void CalculateMassMatrix(MatrixType &rMassMatrix, const ProcessInfo &rCurrentProcessInfo)
Definition: condition.h:574
virtual void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const
Definition: condition.h:260
virtual void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: condition.h:440
virtual void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: condition.h:408
TDataType & GetValue(const Variable< TDataType > &rThisVariable)
Gets the value associated with a given variable.
Definition: data_value_container.h:268
Dof represents a degree of freedom (DoF).
Definition: dof.h:86
Base class for all Elements.
Definition: element.h:60
virtual void CalculateMassMatrix(MatrixType &rMassMatrix, const ProcessInfo &rCurrentProcessInfo)
Definition: element.h:570
virtual void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: element.h:437
virtual void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:258
virtual void CalculateLocalVelocityContribution(MatrixType &rDampingMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: element.h:972
virtual void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo)
Definition: element.h:405
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
GeometryType & GetGeometry()
Returns the reference of the geometry.
Definition: geometrical_object.h:158
Geometry base class.
Definition: geometry.h:71
SizeType PointsNumber() const
Definition: geometry.h:528
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
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
ConditionIterator ConditionsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1361
Communicator & GetCommunicator()
Definition: model_part.h:1821
IndexType GetBufferSize() const
This method gets the suffer size of the model part database.
Definition: model_part.h:1876
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
SizeType NumberOfElements(IndexType ThisIndex=0) const
Definition: model_part.h:1027
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
SizeType NumberOfConditions(IndexType ThisIndex=0) const
Definition: model_part.h:1218
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
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
size_type size() const
Returns the number of elements in the container.
Definition: pointer_vector_set.h:502
iterator begin()
Returns an iterator pointing to the beginning of the container.
Definition: pointer_vector_set.h:278
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
ProcessInfo & GetPreviousSolutionStepInfo(IndexType StepsBefore=1)
Definition: process_info.h:258
ProcessInfo & GetPreviousTimeStepInfo(IndexType StepsBefore=1)
Definition: process_info.h:187
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
typename TSparseSpace::MatrixType TSystemMatrixType
Matrix type definition.
Definition: scheme.h:71
typename TSparseSpace::VectorType TSystemVectorType
Vector type definition.
Definition: scheme.h:74
typename TDenseSpace::VectorType LocalSystemVectorType
Local system vector type definition.
Definition: scheme.h:80
virtual void InitializeSolutionStep(ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b)
Function called once at the beginning of each solution step.
Definition: scheme.h:272
virtual void Initialize(ModelPart &rModelPart)
This is the place to initialize the Scheme.
Definition: scheme.h:168
typename TDenseSpace::MatrixType LocalSystemMatrixType
Local system matrix type definition.
Definition: scheme.h:77
virtual int Check(const ModelPart &rModelPart) const
This function is designed to be called once to perform all the checks needed on the input provided....
Definition: scheme.h:508
KeyType Key() const
Definition: variable_data.h:187
Variable class contains all information needed to store and retrive data from a data container.
Definition: variable.h:63
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO(label)
Definition: logger.h:250
Vector VectorType
Definition: geometrical_transformation_utilities.h:56
Matrix MatrixType
Definition: geometrical_transformation_utilities.h:55
Parameters GetValue(Parameters &rParameters, const std::string &rEntry)
Definition: add_kratos_parameters_to_python.cpp:53
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int domain_size
Definition: face_heat.py:4
Dt
Definition: face_heat.py:78
output
Definition: generate_frictional_mortar_condition.py:444
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
int n_nodes
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:15
int tol
Definition: hinsberg_optimization.py:138
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31