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.
three_step_v_p_strategy.h
Go to the documentation of this file.
1 //
2 // Project Name: KratosPFEMFluidDynamicsApplication $
3 // Last modified by: $Author: AFranci $
4 // Date: $Date: June 2021 $
5 // Revision: $Revision: 0.0 $
6 //
7 //
8 
9 #ifndef KRATOS_THREE_STEP_V_P_STRATEGY_H
10 #define KRATOS_THREE_STEP_V_P_STRATEGY_H
11 
12 #include "includes/define.h"
13 #include "includes/model_part.h"
15 #include "includes/cfd_variables.h"
16 #include "utilities/openmp_utils.h"
17 #include "processes/process.h"
22 
27 
28 #include "custom_utilities/solver_settings.h"
29 
31 
33 
34 #include "v_p_strategy.h"
35 
36 #include <stdio.h>
37 #include <cmath>
38 
39 namespace Kratos
40 {
41 
44 
47 
51 
53 
56 
60 
64 
65  template <class TSparseSpace,
66  class TDenseSpace,
67  class TLinearSolver>
68  class ThreeStepVPStrategy : public VPStrategy<TSparseSpace, TDenseSpace, TLinearSolver>
69  {
70  public:
74 
76 
77  typedef typename BaseType::TDataType TDataType;
78 
80 
82 
84 
86 
88 
90 
92 
96 
98  typename TLinearSolver::Pointer pVelocityLinearSolver,
99  typename TLinearSolver::Pointer pPressureLinearSolver,
100  bool ReformDofSet = true,
101  double VelTol = 0.0001,
102  double PresTol = 0.0001,
103  int MaxPressureIterations = 1, // Only for predictor-corrector
104  unsigned int TimeOrder = 2,
105  unsigned int DomainSize = 2) : BaseType(rModelPart, pVelocityLinearSolver, pPressureLinearSolver, ReformDofSet, DomainSize),
106  mVelocityTolerance(VelTol),
107  mPressureTolerance(PresTol),
108  mMaxPressureIter(MaxPressureIterations),
109  mDomainSize(DomainSize),
110  mTimeOrder(TimeOrder),
111  mReformDofSet(ReformDofSet)
112  {
113  KRATOS_TRY;
114 
116 
117  // Check that input parameters are reasonable and sufficient.
118  this->Check();
119 
120  bool CalculateNormDxFlag = true;
121 
122  bool ReformDofAtEachIteration = false; // DofSet modifiaction is managed by the fractional step strategy, auxiliary strategies should not modify the DofSet directly.
123 
124  // Additional Typedefs
125  typedef typename BuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>::Pointer BuilderSolverTypePointer;
127 
128  //initializing fractional velocity solution step
129  typedef Scheme<TSparseSpace, TDenseSpace> SchemeType;
130  typename SchemeType::Pointer pScheme;
131 
132  typename SchemeType::Pointer Temp = typename SchemeType::Pointer(new ResidualBasedIncrementalUpdateStaticScheme<TSparseSpace, TDenseSpace>());
133  pScheme.swap(Temp);
134 
135  //CONSTRUCTION OF VELOCITY
136  //BuilderSolverTypePointer vel_build = BuilderSolverTypePointer(new ResidualBasedEliminationBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>(pVelocityLinearSolver));
137  BuilderSolverTypePointer vel_build = BuilderSolverTypePointer(new ResidualBasedBlockBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver > (pVelocityLinearSolver));
138 
139  this->mpMomentumStrategy = typename BaseType::Pointer(new GaussSeidelLinearStrategy<TSparseSpace, TDenseSpace, TLinearSolver>(rModelPart, pScheme, pVelocityLinearSolver, vel_build, ReformDofAtEachIteration, CalculateNormDxFlag));
140 
141  this->mpMomentumStrategy->SetEchoLevel(BaseType::GetEchoLevel());
142 
143  vel_build->SetCalculateReactionsFlag(false);
144 
145  /* BuilderSolverTypePointer pressure_build = BuilderSolverTypePointer(new ResidualBasedEliminationBuilderAndSolverComponentwise<TSparseSpace, TDenseSpace, TLinearSolver, Variable<double> >(pPressureLinearSolver, PRESSURE)); */
146  BuilderSolverTypePointer pressure_build = BuilderSolverTypePointer(new ResidualBasedBlockBuilderAndSolver<TSparseSpace, TDenseSpace, TLinearSolver>(pPressureLinearSolver));
147 
148  this->mpPressureStrategy = typename BaseType::Pointer(new GaussSeidelLinearStrategy<TSparseSpace, TDenseSpace, TLinearSolver>(rModelPart, pScheme, pPressureLinearSolver, pressure_build, ReformDofAtEachIteration, CalculateNormDxFlag));
149 
150  this->mpPressureStrategy->SetEchoLevel(BaseType::GetEchoLevel());
151 
152  pressure_build->SetCalculateReactionsFlag(false);
153 
154  KRATOS_CATCH("");
155  }
156 
158  virtual ~ThreeStepVPStrategy() {}
159 
160  int Check() override
161  {
162  KRATOS_TRY;
163 
164  // Check elements and conditions in the model part
165  int ierr = BaseType::Check();
166  if (ierr != 0)
167  return ierr;
168 
169  if (DELTA_TIME.Key() == 0)
170  KRATOS_THROW_ERROR(std::runtime_error, "DELTA_TIME Key is 0. Check that the application was correctly registered.", "");
171 
172  ModelPart &rModelPart = BaseType::GetModelPart();
173 
174  const auto &r_current_process_info = rModelPart.GetProcessInfo();
175  for (const auto &r_element : rModelPart.Elements())
176  {
177  ierr = r_element.Check(r_current_process_info);
178  if (ierr != 0)
179  {
180  break;
181  }
182  }
183 
184  return ierr;
185 
186  KRATOS_CATCH("");
187  }
188 
189  void SetTimeCoefficients(ProcessInfo &rCurrentProcessInfo)
190  {
191  KRATOS_TRY;
192 
193  if (mTimeOrder == 2)
194  {
195  //calculate the BDF coefficients
196  double Dt = rCurrentProcessInfo[DELTA_TIME];
197  double OldDt = rCurrentProcessInfo.GetPreviousTimeStepInfo(1)[DELTA_TIME];
198 
199  double Rho = OldDt / Dt;
200  double TimeCoeff = 1.0 / (Dt * Rho * Rho + Dt * Rho);
201 
202  Vector &BDFcoeffs = rCurrentProcessInfo[BDF_COEFFICIENTS];
203  BDFcoeffs.resize(3, false);
204 
205  BDFcoeffs[0] = TimeCoeff * (Rho * Rho + 2.0 * Rho); //coefficient for step n+1 (3/2Dt if Dt is constant)
206  BDFcoeffs[1] = -TimeCoeff * (Rho * Rho + 2.0 * Rho + 1.0); //coefficient for step n (-4/2Dt if Dt is constant)
207  BDFcoeffs[2] = TimeCoeff; //coefficient for step n-1 (1/2Dt if Dt is constant)
208  }
209  else if (mTimeOrder == 1)
210  {
211  double Dt = rCurrentProcessInfo[DELTA_TIME];
212  double TimeCoeff = 1.0 / Dt;
213 
214  Vector &BDFcoeffs = rCurrentProcessInfo[BDF_COEFFICIENTS];
215  BDFcoeffs.resize(2, false);
216 
217  BDFcoeffs[0] = TimeCoeff; //coefficient for step n+1 (1/Dt)
218  BDFcoeffs[1] = -TimeCoeff; //coefficient for step n (-1/Dt)
219  }
220 
221  KRATOS_CATCH("");
222  }
223 
224  bool SolveSolutionStep() override
225  {
226  ModelPart &rModelPart = BaseType::GetModelPart();
227  ProcessInfo &rCurrentProcessInfo = rModelPart.GetProcessInfo();
228  double currentTime = rCurrentProcessInfo[TIME];
229  bool converged = false;
230  double NormV = 0;
231 
232  unsigned int maxNonLinearIterations = mMaxPressureIter;
233 
234  KRATOS_INFO("\nSolution with three_step_vp_strategy at t=") << currentTime << "s" << std::endl;
235 
236  bool momentumConverged = true;
237  bool continuityConverged = false;
238 
240 
241  // this->FreePressure();
242 
243  for (unsigned int it = 0; it < maxNonLinearIterations; ++it)
244  {
245  KRATOS_INFO("\n ------------------- ITERATION ") << it << " ------------------- " << std::endl;
246 
247  // 1. Compute first-step velocity
248  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP, 1);
249 
250  if (it == 0)
251  {
252  mpMomentumStrategy->InitializeSolutionStep();
253  // this->FixPressure();
254  }
255  else
256  {
258  }
259 
260  momentumConverged = this->SolveFirstVelocitySystem(NormV);
261 
262  // 2. Pressure solution
263  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP, 5);
264 
265  if (it == 0)
266  {
267  mpPressureStrategy->InitializeSolutionStep();
268  }
269  continuityConverged = this->SolveContinuityIteration();
270 
271  // 3. Compute end-of-step velocity
272  this->CalculateEndOfStepVelocity(NormV);
273 
274  this->UpdateTopology(rModelPart, BaseType::GetEchoLevel());
275 
276  if (continuityConverged && momentumConverged)
277  {
278  rCurrentProcessInfo.SetValue(BAD_VELOCITY_CONVERGENCE, false);
279  rCurrentProcessInfo.SetValue(BAD_PRESSURE_CONVERGENCE, false);
280  converged = true;
281  //double tensilStressSign = -1.0;
282  // ComputeErrorL2Norm(tensilStressSign);
283  this->UpdateStressStrain();
284  KRATOS_INFO("ThreeStepVPStrategy") << "V-P strategy converged in " << it + 1 << " iterations." << std::endl;
285  break;
286  }
287  else if (it == (maxNonLinearIterations - 1) && it != 0)
288  {
289  //double tensilStressSign = -1.0;
290  // ComputeErrorL2Norm(tensilStressSign);
291  this->UpdateStressStrain();
292  }
293  }
294 
295  if (!continuityConverged && !momentumConverged && BaseType::GetEchoLevel() > 0 && rModelPart.GetCommunicator().MyPID() == 0)
296  std::cout << "Convergence tolerance not reached." << std::endl;
297 
298  if (mReformDofSet)
299  this->Clear();
300 
301  return converged;
302  }
303 
304  void FinalizeSolutionStep() override
305  {
306  }
307 
308  void InitializeSolutionStep() override
309  {
310  }
311 
312  void UpdateStressStrain() override
313  {
314  ModelPart &rModelPart = BaseType::GetModelPart();
315  const ProcessInfo &rCurrentProcessInfo = rModelPart.GetProcessInfo();
316 
317 #pragma omp parallel
318  {
319  ModelPart::ElementIterator ElemBegin;
321  OpenMPUtils::PartitionedIterators(rModelPart.Elements(), ElemBegin, ElemEnd);
322  for (ModelPart::ElementIterator itElem = ElemBegin; itElem != ElemEnd; ++itElem)
323  {
324  itElem->InitializeNonLinearIteration(rCurrentProcessInfo);
325  }
326  }
327 
329  }
330 
332  {
333  ModelPart &rModelPart = BaseType::GetModelPart();
334  ProcessInfo &rCurrentProcessInfo = rModelPart.GetProcessInfo();
335 
336  for (ModelPart::NodeIterator i = rModelPart.NodesBegin();
337  i != rModelPart.NodesEnd(); ++i)
338  {
339 
340  array_1d<double, 3> &CurrentVelocity = (i)->FastGetSolutionStepValue(VELOCITY, 0);
341  array_1d<double, 3> &PreviousVelocity = (i)->FastGetSolutionStepValue(VELOCITY, 1);
342 
343  array_1d<double, 3> &CurrentAcceleration = (i)->FastGetSolutionStepValue(ACCELERATION, 0);
344  array_1d<double, 3> &PreviousAcceleration = (i)->FastGetSolutionStepValue(ACCELERATION, 1);
345 
346  /* if((i)->IsNot(ISOLATED) || (i)->Is(SOLID)){ */
347  if ((i)->IsNot(ISOLATED) && ((i)->IsNot(RIGID) || (i)->Is(SOLID)))
348  {
349  UpdateAccelerations(CurrentAcceleration, CurrentVelocity, PreviousAcceleration, PreviousVelocity);
350  }
351  else if ((i)->Is(RIGID))
352  {
353  array_1d<double, 3> Zeros(3, 0.0);
354  (i)->FastGetSolutionStepValue(ACCELERATION, 0) = Zeros;
355  (i)->FastGetSolutionStepValue(ACCELERATION, 1) = Zeros;
356  }
357  else
358  {
359  (i)->FastGetSolutionStepValue(PRESSURE, 0) = 0.0;
360  (i)->FastGetSolutionStepValue(PRESSURE, 1) = 0.0;
361  (i)->FastGetSolutionStepValue(PRESSURE_VELOCITY, 0) = 0.0;
362  (i)->FastGetSolutionStepValue(PRESSURE_VELOCITY, 1) = 0.0;
363  (i)->FastGetSolutionStepValue(PRESSURE_ACCELERATION, 0) = 0.0;
364  (i)->FastGetSolutionStepValue(PRESSURE_ACCELERATION, 1) = 0.0;
365  if ((i)->SolutionStepsDataHas(VOLUME_ACCELERATION))
366  {
367  array_1d<double, 3> &VolumeAcceleration = (i)->FastGetSolutionStepValue(VOLUME_ACCELERATION);
368  (i)->FastGetSolutionStepValue(ACCELERATION, 0) = VolumeAcceleration;
369  (i)->FastGetSolutionStepValue(VELOCITY, 0) += VolumeAcceleration * rCurrentProcessInfo[DELTA_TIME];
370  }
371  }
372 
373  const double timeInterval = rCurrentProcessInfo[DELTA_TIME];
374  unsigned int timeStep = rCurrentProcessInfo[STEP];
375  if (timeStep == 1)
376  {
377  (i)->FastGetSolutionStepValue(PRESSURE_VELOCITY, 0) = 0;
378  (i)->FastGetSolutionStepValue(PRESSURE_VELOCITY, 1) = 0;
379  (i)->FastGetSolutionStepValue(PRESSURE_ACCELERATION, 0) = 0;
380  (i)->FastGetSolutionStepValue(PRESSURE_ACCELERATION, 1) = 0;
381  }
382  else
383  {
384  double &CurrentPressure = (i)->FastGetSolutionStepValue(PRESSURE, 0);
385  double &PreviousPressure = (i)->FastGetSolutionStepValue(PRESSURE, 1);
386  double &CurrentPressureVelocity = (i)->FastGetSolutionStepValue(PRESSURE_VELOCITY, 0);
387  double &CurrentPressureAcceleration = (i)->FastGetSolutionStepValue(PRESSURE_ACCELERATION, 0);
388 
389  CurrentPressureAcceleration = CurrentPressureVelocity / timeInterval;
390 
391  CurrentPressureVelocity = (CurrentPressure - PreviousPressure) / timeInterval;
392 
393  CurrentPressureAcceleration += -CurrentPressureVelocity / timeInterval;
394  }
395  }
396  }
397 
398  inline void UpdateAccelerations(array_1d<double, 3> &CurrentAcceleration,
399  const array_1d<double, 3> &CurrentVelocity,
400  array_1d<double, 3> &PreviousAcceleration,
401  const array_1d<double, 3> &PreviousVelocity)
402  {
403  ModelPart &rModelPart = BaseType::GetModelPart();
404  ProcessInfo &rCurrentProcessInfo = rModelPart.GetProcessInfo();
405  double Dt = rCurrentProcessInfo[DELTA_TIME];
406  // noalias(CurrentAcceleration) = 2.0 * (CurrentVelocity - PreviousVelocity) / Dt - PreviousAcceleration; // 2nd order
407  noalias(CurrentAcceleration) = (CurrentVelocity - PreviousVelocity) / Dt; // 1st order
408  }
409 
410  void Clear() override
411  {
412  mpMomentumStrategy->Clear();
413  mpPressureStrategy->Clear();
414  }
415 
419 
420  void SetEchoLevel(int Level) override
421  {
422  BaseType::SetEchoLevel(Level);
423  int StrategyLevel = Level > 0 ? Level - 1 : 0;
424  mpMomentumStrategy->SetEchoLevel(StrategyLevel);
425  mpPressureStrategy->SetEchoLevel(StrategyLevel);
426  }
427 
431 
435 
437  std::string Info() const override
438  {
439  std::stringstream buffer;
440  buffer << "ThreeStepVPStrategy";
441  return buffer.str();
442  }
443 
445  void PrintInfo(std::ostream &rOStream) const override
446  {
447  rOStream << "ThreeStepVPStrategy";
448  }
449 
451  void PrintData(std::ostream &rOStream) const override
452  {
453  }
454 
458 
460 
461  protected:
464 
468 
472 
476 
480 
482 
486  bool SolveFirstVelocitySystem(double &NormV)
487  {
488  std::cout << "1. SolveFirstVelocitySystem " << std::endl;
489 
490  bool momentumConvergence = false;
491  double NormDv = 0;
492  // build momentum system and solve for fractional step velocity increment
493 
494  NormDv = mpMomentumStrategy->Solve();
495 
496  // Check convergence
497  momentumConvergence = this->CheckVelocityIncrementConvergence(NormDv, NormV);
498 
499  if (!momentumConvergence && BaseType::GetEchoLevel() > 0)
500  std::cout << "Momentum equations did not reach the convergence tolerance." << std::endl;
501 
502  return momentumConvergence;
503  }
504 
506  {
507  std::cout << "2. SolveContinuityIteration " << std::endl;
508  bool continuityConvergence = false;
509  double NormDp = 0;
510 
511  NormDp = mpPressureStrategy->Solve();
512 
513  continuityConvergence = CheckPressureIncrementConvergence(NormDp);
514 
515  // continuityConvergence = true;
516  if (!continuityConvergence && BaseType::GetEchoLevel() > 0)
517  std::cout << "Continuity equation did not reach the convergence tolerance." << std::endl;
518 
519  return continuityConvergence;
520  }
521 
522  void CalculateEndOfStepVelocity(const double NormV)
523  {
524 
525  std::cout << "3. CalculateEndOfStepVelocity()" << std::endl;
526  ModelPart &rModelPart = BaseType::GetModelPart();
527  const int n_nodes = rModelPart.NumberOfNodes();
528  const int n_elems = rModelPart.NumberOfElements();
529 
531  VariableUtils().SetHistoricalVariableToZero(FRACT_VEL, rModelPart.Nodes());
532  VariableUtils().SetHistoricalVariableToZero(NODAL_VOLUME, rModelPart.Nodes());
533 
534 #pragma omp parallel for
535  for (int i_elem = 0; i_elem < n_elems; ++i_elem)
536  {
537  const auto it_elem = rModelPart.ElementsBegin() + i_elem;
538  it_elem->Calculate(VELOCITY, Out, rModelPart.GetProcessInfo());
539  Element::GeometryType &geometry = it_elem->GetGeometry();
540  double elementalVolume = 0;
541 
542  if (mDomainSize == 2)
543  {
544  elementalVolume = geometry.Area() / 3.0;
545  }
546  else if (mDomainSize == 3)
547  {
548  elementalVolume = geometry.Volume() * 0.25;
549  }
550  // index = 0;
551  unsigned int numNodes = geometry.size();
552  for (unsigned int i = 0; i < numNodes; i++)
553  {
554  double &nodalVolume = geometry(i)->FastGetSolutionStepValue(NODAL_VOLUME);
555  nodalVolume += elementalVolume;
556  }
557  }
558 
559  rModelPart.GetCommunicator().AssembleCurrentData(FRACT_VEL);
560 
561  if (mDomainSize > 2)
562  {
563 #pragma omp parallel for
564  for (int i_node = 0; i_node < n_nodes; ++i_node)
565  {
566  auto it_node = rModelPart.NodesBegin() + i_node;
567  const double NodalVolume = it_node->FastGetSolutionStepValue(NODAL_VOLUME);
568  double fractionalVelocity = 0;
569  if (it_node->IsNot(ISOLATED))
570  {
571  if (!it_node->IsFixed(VELOCITY_X))
572  {
573  fractionalVelocity = it_node->FastGetSolutionStepValue(VELOCITY_X); // VELOCITY_X stores the velocity after the first step computation
574  it_node->FastGetSolutionStepValue(VELOCITY_X) += it_node->FastGetSolutionStepValue(FRACT_VEL_X) / NodalVolume; // here FRACT_VEL stores the gradient of pressure computed inside the element
575  it_node->FastGetSolutionStepValue(FRACT_VEL_X) = fractionalVelocity; // now FRACT_VEL stores the real fractional velocity (the ones after the first step computation)
576  }
577  if (!it_node->IsFixed(VELOCITY_Y))
578  {
579  fractionalVelocity = it_node->FastGetSolutionStepValue(VELOCITY_Y); // VELOCITY_Y stores the velocity after the first step computation
580  it_node->FastGetSolutionStepValue(VELOCITY_Y) += it_node->FastGetSolutionStepValue(FRACT_VEL_Y) / NodalVolume; // here FRACT_VEL stores the gradient of pressure computed inside the element
581  it_node->FastGetSolutionStepValue(FRACT_VEL_Y) = fractionalVelocity; // now FRACT_VEL stores the real fractional velocity (the ones after the first step computation)
582  }
583  if (!it_node->IsFixed(VELOCITY_Z))
584  {
585  fractionalVelocity = it_node->FastGetSolutionStepValue(VELOCITY_Z); // VELOCITY_Z stores the velocity after the first step computation
586  it_node->FastGetSolutionStepValue(VELOCITY_Z) += it_node->FastGetSolutionStepValue(FRACT_VEL_Z) / NodalVolume; // here FRACT_VEL stores the gradient of pressure computed inside the element
587  it_node->FastGetSolutionStepValue(FRACT_VEL_Z) = fractionalVelocity; // now FRACT_VEL stores the real fractional velocity (the ones after the first step computation)
588  }
589  }
590  }
591  }
592  else
593  {
594 #pragma omp parallel for
595  for (int i_node = 0; i_node < n_nodes; ++i_node)
596  {
597  auto it_node = rModelPart.NodesBegin() + i_node;
598  const double NodalArea = it_node->FastGetSolutionStepValue(NODAL_VOLUME);
599  double fractionalVelocity = 0;
600  if (it_node->IsNot(ISOLATED))
601  {
602  if (!it_node->IsFixed(VELOCITY_X))
603  {
604  fractionalVelocity = it_node->FastGetSolutionStepValue(VELOCITY_X); // VELOCITY_X stores the velocity after the first step computation
605  it_node->FastGetSolutionStepValue(VELOCITY_X) += it_node->FastGetSolutionStepValue(FRACT_VEL_X) / NodalArea; // here FRACT_VEL stores the gradient of pressure computed inside the element
606  it_node->FastGetSolutionStepValue(FRACT_VEL_X) = fractionalVelocity; // now FRACT_VEL stores the real fractional velocity (the ones after the first step computation)
607  }
608  if (!it_node->IsFixed(VELOCITY_Y))
609  {
610  fractionalVelocity = it_node->FastGetSolutionStepValue(VELOCITY_Y); // VELOCITY_Y stores the velocity after the first step computation
611  it_node->FastGetSolutionStepValue(VELOCITY_Y) += it_node->FastGetSolutionStepValue(FRACT_VEL_Y) / NodalArea; //here FRACT_VEL stores the gradient of pressure computed inside the element
612  it_node->FastGetSolutionStepValue(FRACT_VEL_Y) = fractionalVelocity; //now FRACT_VEL stores the real fractional velocity (the ones after the first step computation)
613  }
614  }
615  }
616  }
617  this->CheckVelocityConvergence(NormV);
618  }
619 
621  {
622 
623  ModelPart &rModelPart = BaseType::GetModelPart();
624  const int n_nodes = rModelPart.NumberOfNodes();
625 
626  rModelPart.GetCommunicator().AssembleCurrentData(FRACT_VEL);
627 
628  if (mDomainSize > 2)
629  {
630 #pragma omp parallel for
631  for (int i_node = 0; i_node < n_nodes; ++i_node)
632  {
633  auto it_node = rModelPart.NodesBegin() + i_node;
634  if (it_node->IsNot(ISOLATED))
635  {
636  if (!it_node->IsFixed(VELOCITY_X))
637  {
638  it_node->FastGetSolutionStepValue(VELOCITY_X) = it_node->FastGetSolutionStepValue(FRACT_VEL_X);
639  }
640  if (!it_node->IsFixed(VELOCITY_Y))
641  {
642  it_node->FastGetSolutionStepValue(VELOCITY_Y) = it_node->FastGetSolutionStepValue(FRACT_VEL_Y);
643  }
644  if (!it_node->IsFixed(VELOCITY_Z))
645  {
646  it_node->FastGetSolutionStepValue(VELOCITY_Z) = it_node->FastGetSolutionStepValue(FRACT_VEL_Z);
647  }
648  }
649  }
650  }
651  else
652  {
653 #pragma omp parallel for
654  for (int i_node = 0; i_node < n_nodes; ++i_node)
655  {
656  auto it_node = rModelPart.NodesBegin() + i_node;
657  if (it_node->IsNot(ISOLATED))
658  {
659  if (!it_node->IsFixed(VELOCITY_X))
660  {
661  it_node->FastGetSolutionStepValue(VELOCITY_X) = it_node->FastGetSolutionStepValue(FRACT_VEL_X);
662  }
663  if (!it_node->IsFixed(VELOCITY_Y))
664  {
665  it_node->FastGetSolutionStepValue(VELOCITY_Y) = it_node->FastGetSolutionStepValue(FRACT_VEL_Y);
666  }
667  }
668  }
669  }
670  }
671 
672  bool CheckVelocityIncrementConvergence(const double NormDv, double &NormV)
673  {
674  ModelPart &rModelPart = BaseType::GetModelPart();
675  const int n_nodes = rModelPart.NumberOfNodes();
676 
677  NormV = 0.00;
678  double errorNormDv = 0;
679  double temp_norm = NormV;
680 
681 #pragma omp parallel for reduction(+ : temp_norm)
682  for (int i_node = 0; i_node < n_nodes; ++i_node)
683  {
684  const auto it_node = rModelPart.NodesBegin() + i_node;
685  const auto &r_vel = it_node->FastGetSolutionStepValue(VELOCITY);
686  for (unsigned int d = 0; d < 3; ++d)
687  {
688  temp_norm += r_vel[d] * r_vel[d];
689  }
690  }
691  NormV = temp_norm;
692  NormV = BaseType::GetModelPart().GetCommunicator().GetDataCommunicator().SumAll(NormV);
693  NormV = sqrt(NormV);
694 
695  const double zero_tol = 1.0e-12;
696  errorNormDv = (NormV < zero_tol) ? NormDv : NormDv / NormV;
697 
698  if (BaseType::GetEchoLevel() > 0 && rModelPart.GetCommunicator().MyPID() == 0)
699  {
700  std::cout << "The norm of velocity increment is: " << NormDv << std::endl;
701  std::cout << "The norm of velocity is: " << NormV << std::endl;
702  std::cout << "Velocity error: " << errorNormDv << "mVelocityTolerance: " << mVelocityTolerance << std::endl;
703  }
704 
705  if (errorNormDv < mVelocityTolerance)
706  {
707  std::cout << "The norm of velocity is: " << NormV << " The norm of velocity increment is: " << NormDv << " Velocity error: " << errorNormDv << " Converged!" << std::endl;
708  return true;
709  }
710  else
711  {
712  std::cout << "The norm of velocity is: " << NormV << " The norm of velocity increment is: " << NormDv << " Velocity error: " << errorNormDv << " Not converged!" << std::endl;
713  return false;
714  }
715  }
716 
717  void CheckVelocityConvergence(const double NormOldV)
718  {
719  ModelPart &rModelPart = BaseType::GetModelPart();
720  const int n_nodes = rModelPart.NumberOfNodes();
721 
722  double NormV = 0.00;
723 #pragma omp parallel for reduction(+ \
724  : NormV)
725  for (int i_node = 0; i_node < n_nodes; ++i_node)
726  {
727  const auto it_node = rModelPart.NodesBegin() + i_node;
728  const auto &r_vel = it_node->FastGetSolutionStepValue(VELOCITY);
729  for (unsigned int d = 0; d < 3; ++d)
730  {
731  NormV += r_vel[d] * r_vel[d];
732  }
733  }
734  NormV = BaseType::GetModelPart().GetCommunicator().GetDataCommunicator().SumAll(NormV);
735  NormV = sqrt(NormV);
736 
737  std::cout << "The norm of velocity is: " << NormV << " Old velocity norm was: " << NormOldV << std::endl;
738  }
739 
740  bool CheckPressureIncrementConvergence(const double NormDp)
741  {
742  ModelPart &rModelPart = BaseType::GetModelPart();
743  const int n_nodes = rModelPart.NumberOfNodes();
744 
745  double NormP = 0.00;
746  double errorNormDp = 0;
747 
748 #pragma omp parallel for reduction(+ \
749  : NormP)
750  for (int i_node = 0; i_node < n_nodes; ++i_node)
751  {
752  const auto it_node = rModelPart.NodesBegin() + i_node;
753  const double Pr = it_node->FastGetSolutionStepValue(PRESSURE);
754  NormP += Pr * Pr;
755  }
756  NormP = BaseType::GetModelPart().GetCommunicator().GetDataCommunicator().SumAll(NormP);
757  NormP = sqrt(NormP);
758 
759  const double zero_tol = 1.0e-12;
760  errorNormDp = (NormP < zero_tol) ? NormDp : NormDp / NormP;
761 
762  if (BaseType::GetEchoLevel() > 0 && rModelPart.GetCommunicator().MyPID() == 0)
763  {
764  std::cout << " The norm of pressure increment is: " << NormDp << std::endl;
765  std::cout << " The norm of pressure is: " << NormP << std::endl;
766  std::cout << " The norm of pressure increment is: " << NormDp << " Pressure error: " << errorNormDp << std::endl;
767  }
768 
769  if (errorNormDp < mPressureTolerance)
770  {
771  std::cout << " The norm of pressure is: " << NormP << " The norm of pressure increment is: " << NormDp << " Pressure error: " << errorNormDp << " Converged!" << std::endl;
772  return true;
773  }
774  else
775  {
776  std::cout << " The norm of pressure is: " << NormP << " The norm of pressure increment is: " << NormDp << " Pressure error: " << errorNormDp << " Not converged!" << std::endl;
777  return false;
778  }
779  }
780 
781  void FixPressure()
782  {
783  ModelPart &rModelPart = BaseType::GetModelPart();
784  const int n_nodes = rModelPart.NumberOfNodes();
785  for (int i_node = 0; i_node < n_nodes; ++i_node)
786  {
787  const auto it_node = rModelPart.NodesBegin() + i_node;
788  // if (it_node->Is(RIGID) && (it_node->X() < 0.001 || it_node->X() > 0.999)) // for closed domain case with analytical solution
789  if (it_node->Is(FREE_SURFACE))
790  {
791  it_node->FastGetSolutionStepValue(PRESSURE) = 0;
792  it_node->Fix(PRESSURE);
793  }
794  }
795  }
796 
798  {
799  ModelPart &rModelPart = BaseType::GetModelPart();
800  const int n_nodes = rModelPart.NumberOfNodes();
801  for (int i_node = 0; i_node < n_nodes; ++i_node)
802  {
803  const auto it_node = rModelPart.NodesBegin() + i_node;
804  it_node->Free(PRESSURE);
805  }
806  }
807 
811 
815 
819 
821 
824 
828 
830 
832 
833  unsigned int mMaxPressureIter;
834 
835  unsigned int mDomainSize;
836 
837  unsigned int mTimeOrder;
838 
840 
841  // Fractional step index.
842  /* 1 : Momentum step (calculate fractional step velocity)
843  * 2-3 : Unused (reserved for componentwise calculation of frac step velocity)
844  * 4 : Pressure step
845  * 5 : Computation of projections
846  * 6 : End of step velocity
847  */
848  // unsigned int mStepId;
849 
852 
855 
859 
863 
867 
871 
875 
878 
881 
883 
884  };
885 
889 
891 
893 
894 } // namespace Kratos.
895 
896 #endif // KRATOS_THREE_STEP_V_P_STRATEGY_H
Current class provides an implementation for the base builder and solving operations.
Definition: builder_and_solver.h:64
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
virtual bool AssembleCurrentData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:502
virtual int MyPID() const
Definition: communicator.cpp:91
void SetValue(const Variable< TDataType > &rThisVariable, TDataType const &rValue)
Sets the value for a given variable.
Definition: data_value_container.h:320
Short class definition.
Definition: gauss_seidel_linear_strategy.h:83
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
virtual double Volume() const
This method calculate and return volume of this geometry.
Definition: geometry.h:1358
virtual double Area() const
This method calculate and return area or surface area of this geometry depending to it's dimension.
Definition: geometry.h:1345
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
Communicator & GetCommunicator()
Definition: model_part.h:1821
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
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
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
static void PartitionedIterators(TVector &rVector, typename TVector::iterator &rBegin, typename TVector::iterator &rEnd)
Generate a partition for an std::vector-like array, providing iterators to the begin and end position...
Definition: openmp_utils.h:179
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
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
ProcessInfo & GetPreviousTimeStepInfo(IndexType StepsBefore=1)
Definition: process_info.h:187
Current class provides an implementation for standard builder and solving operations.
Definition: residualbased_block_builder_and_solver.h:82
This class provides the implementation of a static scheme.
Definition: residualbased_incrementalupdate_static_scheme.h:57
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
Solving strategy base class This is the base class from which we will derive all the strategies (impl...
Definition: solving_strategy.h:64
TDenseSpace::MatrixType LocalSystemMatrixType
Definition: solving_strategy.h:79
TSparseSpace::DataType TDataType
Definition: solving_strategy.h:69
ModelPart & GetModelPart()
Operations to get the pointer to the model.
Definition: solving_strategy.h:350
int GetEchoLevel()
This returns the level of echo for the solving strategy.
Definition: solving_strategy.h:271
TSparseSpace::MatrixType TSystemMatrixType
Definition: solving_strategy.h:71
TSparseSpace::VectorType TSystemVectorType
Definition: solving_strategy.h:73
TDenseSpace::VectorType LocalSystemVectorType
Definition: solving_strategy.h:81
Definition: three_step_v_p_strategy.h:69
bool mReformDofSet
Definition: three_step_v_p_strategy.h:839
unsigned int mTimeOrder
Definition: three_step_v_p_strategy.h:837
void CheckVelocityConvergence(const double NormOldV)
Definition: three_step_v_p_strategy.h:717
SolvingStrategy< TSparseSpace, TDenseSpace >::Pointer StrategyPointerType
Definition: three_step_v_p_strategy.h:89
void SetTimeCoefficients(ProcessInfo &rCurrentProcessInfo)
Definition: three_step_v_p_strategy.h:189
BaseType::TDataType TDataType
Definition: three_step_v_p_strategy.h:77
double mVelocityTolerance
Definition: three_step_v_p_strategy.h:829
void RecoverFractionalVelocity()
Definition: three_step_v_p_strategy.h:620
StrategyPointerType mpMomentumStrategy
Scheme for the solution of the momentum equation.
Definition: three_step_v_p_strategy.h:851
virtual ~ThreeStepVPStrategy()
Destructor.
Definition: three_step_v_p_strategy.h:158
void InitializeSolutionStep() override
Performs all the required operations that should be done (for each step) before solving the solution ...
Definition: three_step_v_p_strategy.h:308
bool CheckPressureIncrementConvergence(const double NormDp)
Definition: three_step_v_p_strategy.h:740
std::string Info() const override
Turn back information as a string.
Definition: three_step_v_p_strategy.h:437
double mPressureTolerance
Definition: three_step_v_p_strategy.h:831
int Check() override
Function to perform expensive checks.
Definition: three_step_v_p_strategy.h:160
void UpdateStressStrain() override
Definition: three_step_v_p_strategy.h:312
TwoStepVPSolverSettings< TSparseSpace, TDenseSpace, TLinearSolver > SolverSettingsType
Definition: three_step_v_p_strategy.h:91
void FixPressure()
Definition: three_step_v_p_strategy.h:781
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: three_step_v_p_strategy.h:445
void UpdateAccelerations(array_1d< double, 3 > &CurrentAcceleration, const array_1d< double, 3 > &CurrentVelocity, array_1d< double, 3 > &PreviousAcceleration, const array_1d< double, 3 > &PreviousVelocity)
Definition: three_step_v_p_strategy.h:398
void CalculateTemporalVariables() override
Definition: three_step_v_p_strategy.h:331
unsigned int mMaxPressureIter
Definition: three_step_v_p_strategy.h:833
ThreeStepVPStrategy(ThreeStepVPStrategy const &rOther)
Copy constructor.
Definition: three_step_v_p_strategy.h:880
BaseType::TSystemMatrixType TSystemMatrixType
Definition: three_step_v_p_strategy.h:81
ThreeStepVPStrategy(ModelPart &rModelPart, typename TLinearSolver::Pointer pVelocityLinearSolver, typename TLinearSolver::Pointer pPressureLinearSolver, bool ReformDofSet=true, double VelTol=0.0001, double PresTol=0.0001, int MaxPressureIterations=1, unsigned int TimeOrder=2, unsigned int DomainSize=2)
Definition: three_step_v_p_strategy.h:97
void FreePressure()
Definition: three_step_v_p_strategy.h:797
ThreeStepVPStrategy & operator=(ThreeStepVPStrategy const &rOther)
Assignment operator.
Definition: three_step_v_p_strategy.h:877
bool SolveSolutionStep() override
Solves the current step. This function returns true if a solution has been found, false otherwise.
Definition: three_step_v_p_strategy.h:224
bool CheckVelocityIncrementConvergence(const double NormDv, double &NormV)
Definition: three_step_v_p_strategy.h:672
bool SolveContinuityIteration()
Definition: three_step_v_p_strategy.h:505
StrategyPointerType mpPressureStrategy
Scheme for the solution of the mass equation.
Definition: three_step_v_p_strategy.h:854
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: three_step_v_p_strategy.h:451
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: three_step_v_p_strategy.h:87
BaseType::DofsArrayType DofsArrayType
Definition: three_step_v_p_strategy.h:79
bool SolveFirstVelocitySystem(double &NormV)
Calculate the coefficients for time iteration.
Definition: three_step_v_p_strategy.h:486
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: three_step_v_p_strategy.h:85
VPStrategy< TSparseSpace, TDenseSpace, TLinearSolver > BaseType
Definition: three_step_v_p_strategy.h:75
unsigned int mDomainSize
Definition: three_step_v_p_strategy.h:835
void SetEchoLevel(int Level) override
This sets the level of echo for the solving strategy.
Definition: three_step_v_p_strategy.h:420
void Clear() override
Clears the internal storage.
Definition: three_step_v_p_strategy.h:410
void FinalizeSolutionStep() override
Performs all the required operations that should be done (for each step) after solving the solution s...
Definition: three_step_v_p_strategy.h:304
KRATOS_CLASS_POINTER_DEFINITION(ThreeStepVPStrategy)
BaseType::TSystemVectorType TSystemVectorType
Definition: three_step_v_p_strategy.h:83
void CalculateEndOfStepVelocity(const double NormV)
Definition: three_step_v_p_strategy.h:522
Helper class to define solution strategies for TwoStepVPStrategy.
Definition: solver_settings.h:57
Definition: v_p_strategy.h:59
virtual void SetEchoLevel(int Level) override
This sets the level of echo for the solving strategy.
Definition: v_p_strategy.h:436
void UpdateTopology(ModelPart &rModelPart, unsigned int echoLevel)
Definition: v_p_strategy.h:107
void SetBlockedAndIsolatedFlags()
Definition: v_p_strategy.h:116
virtual int Check() override
Function to perform expensive checks.
Definition: v_p_strategy.h:93
This class implements a set of auxiliar, already parallelized, methods to perform some common tasks r...
Definition: variable_utils.h:63
void SetHistoricalVariableToZero(const Variable< TType > &rVariable, NodesContainerType &rNodes)
Sets the nodal value of any variable to zero.
Definition: variable_utils.h:757
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_INFO(label)
Definition: logger.h:250
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
Temp
Definition: PecletTest.py:105
Dt
Definition: face_heat.py:78
int n_nodes
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:15
int d
Definition: ode_solve.py:397
integer i
Definition: TensorModule.f:17
ReformDofAtEachIteration
Definition: test_pureconvectionsolver_benchmarking.py:131