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.
fractional_step_strategy.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 #ifndef KRATOS_FRACTIONAL_STEP_STRATEGY
14 #define KRATOS_FRACTIONAL_STEP_STRATEGY
15 
16 // System includes
17 
18 // External includes
19 
20 // Project includes
21 #include "includes/define.h"
22 #include "includes/model_part.h"
23 #include "includes/cfd_variables.h"
24 #include "processes/process.h"
28 
29 // Application includes
30 #include "custom_utilities/solver_settings.h"
32 
33 namespace Kratos {
34 
37 
40 
41 
45 
46 
50 
51 
55 
56 
60 
75 template <class TSparseSpace, class TDenseSpace, class TLinearSolver>
76 class FractionalStepStrategy : public ImplicitSolvingStrategy<TSparseSpace, TDenseSpace, TLinearSolver>
77 {
78 public:
81 
84 
86 
88 
90 
92 
94 
98 
100  SolverSettingsType& rSolverConfig,
101  bool PredictorCorrector):
102  BaseType(rModelPart,false),
104  mrPeriodicIdVar(Kratos::Variable<int>::StaticObject())
105  {
106  KRATOS_WARNING("FractionalStepStrategy") << "This constructor is deprecated. Use the one with the \'CalculateReactionsFlag\' instead." << std::endl;
107  InitializeStrategy(rSolverConfig,PredictorCorrector);
108  }
109 
111  SolverSettingsType& rSolverConfig,
112  bool PredictorCorrector,
113  const Kratos::Variable<int>& PeriodicVar):
114  BaseType(rModelPart,false),
116  mrPeriodicIdVar(PeriodicVar)
117  {
118  KRATOS_WARNING("FractionalStepStrategy") << "This constructor is deprecated. Use the one with the \'CalculateReactionsFlag\' instead." << std::endl;
119  InitializeStrategy(rSolverConfig,PredictorCorrector);
120  }
121 
123  ModelPart& rModelPart,
124  SolverSettingsType& rSolverConfig,
125  bool PredictorCorrector,
126  bool CalculateReactionsFlag)
127  : BaseType(rModelPart,false)
128  , mCalculateReactionsFlag(CalculateReactionsFlag)
129  , mrPeriodicIdVar(Kratos::Variable<int>::StaticObject())
130  {
131  InitializeStrategy(rSolverConfig,PredictorCorrector);
132  }
133 
135  ModelPart& rModelPart,
136  SolverSettingsType& rSolverConfig,
137  bool PredictorCorrector,
138  bool CalculateReactionsFlag,
139  const Kratos::Variable<int>& PeriodicVar)
140  : BaseType(rModelPart,false)
141  , mCalculateReactionsFlag(CalculateReactionsFlag)
142  , mrPeriodicIdVar(PeriodicVar)
143  {
144  InitializeStrategy(rSolverConfig,PredictorCorrector);
145  }
146 
149 
153 
154 
158 
159  void Initialize() override
160  {
161  // Set up nodes to use slip conditions if needed.
162  if (mUseSlipConditions) {
163  auto& r_model_part = BaseType::GetModelPart();
164  const int n_conds = r_model_part.NumberOfConditions();
165 #pragma omp parallel for
166  for (int i_cond = 0; i_cond < n_conds; ++i_cond) {
167  auto it_cond = r_model_part.ConditionsBegin() + i_cond;
168  if (it_cond->Is(SLIP)) {
169  auto& r_geom = it_cond->GetGeometry();
170  for (auto& r_node : r_geom) {
171  r_node.SetLock();
172  r_node.Set(SLIP, true);
173  r_node.UnSetLock();
174  }
175  }
176  }
177  }
178 
179  // Initialize all the elemnets and conditions
181  }
182 
183  int Check() override
184  {
185  KRATOS_TRY;
186 
187  // Base strategy check
188  int ierr = BaseType::Check();
189  if (ierr != 0) {
190  return ierr;
191  }
192 
193  // Check time order and buffer size
194  const auto& r_model_part = BaseType::GetModelPart();
195  KRATOS_ERROR_IF(mTimeOrder == 2 && r_model_part.GetBufferSize() < 3)
196  << "Buffer size too small for fractional step strategy (BDF2), needed 3, got " << r_model_part.GetBufferSize() << std::endl;
197  KRATOS_ERROR_IF(mTimeOrder == 1 && r_model_part.GetBufferSize() < 2)
198  << "Buffer size too small for fractional step strategy (Backward Euler), needed 2, got " << r_model_part.GetBufferSize() << std::endl;
199 
200  // Check elements and conditions
201  const auto &r_current_process_info = r_model_part.GetProcessInfo();
202  for (const auto& r_element : r_model_part.Elements()) {
203  ierr = r_element.Check(r_current_process_info);
204  if (ierr != 0) {
205  break;
206  }
207  }
208 
209  for (const auto& r_condition : r_model_part.Conditions()) {
210  ierr = r_condition.Check(r_current_process_info);
211  if (ierr != 0) {
212  break;
213  }
214  }
215 
216  return ierr;
217 
218  KRATOS_CATCH("");
219  }
220 
221  void InitializeSolutionStep() override
222  {
223  // Initialize BDF2 coefficients
225  }
226 
227  bool SolveSolutionStep() override
228  {
229  bool converged = false;
230  if (mPredictorCorrector) {
231  const unsigned int echo_level = BaseType::GetEchoLevel();
232  // Iterative solution for pressure
233  for (unsigned int it = 0; it < mMaxPressureIter; ++it) {
234  KRATOS_INFO_IF("FractionalStepStrategy", echo_level > 1) << "Pressure iteration " << it << std::endl;
235  const auto convergence_output = this->SolveStep();
236  converged = this->CheckPressureConvergence(std::get<1>(convergence_output));
237  if (converged) {
238  KRATOS_INFO_IF("FractionalStepStrategy", echo_level > 0) << "Predictor-corrector converged in " << it + 1 << " iterations." << std::endl;
239  break;
240  }
241  }
242  KRATOS_WARNING_IF("FractionalStepStrategy", !converged && echo_level > 0) << "Predictor-corrector iterations did not converge." << std::endl;
243  } else {
244  // Solve for fractional step velocity, then update pressure once
245  const auto convergence_output = this->SolveStep();
246  // If not doing predictor corrector iterations, norm_dp will
247  // typically be "large" since we are not iterating on pressure.
248  // It makes no sense to report that the iteration didn't converge
249  // based on this. Hence, what we report is the convergence of the
250  // fractional step velocity.
251  converged = std::get<0>(convergence_output);
252  }
253 
254  // Calculate reactions
257  }
258 
259  return converged;
260  }
261 
262  void FinalizeSolutionStep() override
263  {
264  if (mReformDofSet) {
265  this->Clear();
266  }
267  }
268 
269  //TODO: Move to private section as soon as we remove the Python exposure
275  virtual void CalculateReactions()
276  {
277  auto &r_model_part = BaseType::GetModelPart();
278  auto &r_process_info = r_model_part.GetProcessInfo();
279  const int n_elems = r_model_part.NumberOfElements();
280 
281  // Set fractional step index to the momentum equation step
282  const int original_step = r_process_info[FRACTIONAL_STEP];
283  r_process_info.SetValue(FRACTIONAL_STEP, 1);
284 
285  // Allocate and initialize values for REACTION calculation
286  LocalSystemVectorType RHS_Contribution;
287  LocalSystemMatrixType LHS_Contribution;
288  const auto &r_const_process_info = r_process_info;
289  VariableUtils().SetHistoricalVariableToZero(REACTION, r_model_part.Nodes());
290 
291 #pragma omp parallel for private(RHS_Contribution, LHS_Contribution)
292  for (int i_elem = 0; i_elem < n_elems; ++i_elem) {
293  // Build local system
294  auto it_elem = r_model_part.ElementsBegin() + i_elem;
295  it_elem->CalculateLocalSystem(
296  LHS_Contribution,
297  RHS_Contribution,
298  r_const_process_info);
299 
300  // Accumulate minus the RHS as the reaction
301  unsigned int index = 0;
302  auto& r_geom = it_elem->GetGeometry();
303  const unsigned int n_nodes = r_geom.PointsNumber();
304  for (unsigned int i = 0; i < n_nodes; ++i) {
305  r_geom[i].SetLock();
306  auto& r_reaction = r_geom[i].FastGetSolutionStepValue(REACTION);
307  for (unsigned int d = 0; d < mDomainSize; ++d) {
308  r_reaction[d] -= RHS_Contribution[index++];
309  }
310  r_geom[i].UnSetLock();
311  }
312  }
313 
314  // Synchronize the local REACTION values
315  r_model_part.GetCommunicator().AssembleCurrentData(REACTION);
316 
317  // Reset original fractional step index
318  r_process_info.SetValue(FRACTIONAL_STEP, original_step);
319  }
320 
321  virtual void AddIterationStep(Process::Pointer pNewStep)
322  {
323  mExtraIterationSteps.push_back(pNewStep);
324  }
325 
327  {
328  mExtraIterationSteps.clear();
329  }
330 
331  void Clear() override
332  {
333  mpMomentumStrategy->Clear();
334  mpPressureStrategy->Clear();
335  }
336 
340 
341  void SetEchoLevel(int Level) override
342  {
343  BaseType::SetEchoLevel(Level);
344  int StrategyLevel = Level > 0 ? Level - 1 : 0;
345  mpMomentumStrategy->SetEchoLevel(StrategyLevel);
346  mpPressureStrategy->SetEchoLevel(StrategyLevel);
347  }
348 
353  void SetCalculateReactionsFlag(bool CalculateReactionsFlag)
354  {
355  mCalculateReactionsFlag = CalculateReactionsFlag;
356  }
357 
363  {
365  }
366 
370 
371 
375 
377  std::string Info() const override
378  {
379  std::stringstream buffer;
380  buffer << "FractionalStepStrategy" ;
381  return buffer.str();
382  }
383 
385  void PrintInfo(std::ostream& rOStream) const override
386  {
387  rOStream << Info();
388  }
389 
391  void PrintData(std::ostream& rOStream) const override {}
392 
396 
397 
399 protected:
402 
403 
407 
408 
412 
414 
416 
418 
419  unsigned int mMaxVelocityIter;
420 
421  unsigned int mMaxPressureIter;
422 
423  unsigned int mDomainSize;
424 
425  unsigned int mTimeOrder;
426 
428 
430 
432 
434 
437 
440 
441  std::vector< Process::Pointer > mExtraIterationSteps;
442 
444 
448 
449 
453 
460  {
461  KRATOS_TRY;
462 
463  auto &r_process_info = (BaseType::GetModelPart()).GetProcessInfo();
464 
465  if (mTimeOrder == 2)
466  {
467  //calculate the BDF coefficients
468  double Dt = r_process_info[DELTA_TIME];
469  double OldDt = r_process_info.GetPreviousTimeStepInfo(1)[DELTA_TIME];
470 
471  double Rho = OldDt / Dt;
472  double TimeCoeff = 1.0 / (Dt * Rho * Rho + Dt * Rho);
473 
474  Vector& BDFcoeffs = r_process_info[BDF_COEFFICIENTS];
475  BDFcoeffs.resize(3, false);
476 
477  BDFcoeffs[0] = TimeCoeff * (Rho * Rho + 2.0 * Rho); //coefficient for step n+1 (3/2Dt if Dt is constant)
478  BDFcoeffs[1] = -TimeCoeff * (Rho * Rho + 2.0 * Rho + 1.0); //coefficient for step n (-4/2Dt if Dt is constant)
479  BDFcoeffs[2] = TimeCoeff; //coefficient for step n-1 (1/2Dt if Dt is constant)
480  }
481  else if (mTimeOrder == 1)
482  {
483  double Dt = r_process_info[DELTA_TIME];
484  double TimeCoeff = 1.0 / Dt;
485 
486  Vector& BDFcoeffs = r_process_info[BDF_COEFFICIENTS];
487  BDFcoeffs.resize(2, false);
488 
489  BDFcoeffs[0] = TimeCoeff; //coefficient for step n+1 (1/Dt)
490  BDFcoeffs[1] = -TimeCoeff; //coefficient for step n (-1/Dt)
491  }
492 
493  KRATOS_CATCH("");
494  }
495 
496  virtual std::tuple<bool,double> SolveStep()
497  {
498  ModelPart& rModelPart = BaseType::GetModelPart();
499  const int n_nodes = rModelPart.NumberOfNodes();
500 
501  // 1. Fractional step momentum iteration
502  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,1);
503 
504  bool Converged = false;
505  for(unsigned int it = 0; it < mMaxVelocityIter; ++it)
506  {
507  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 1) << "Momentum iteration " << it << std::endl;
508 
509  // build momentum system and solve for fractional step velocity increment
510  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,1);
511  double NormDv = mpMomentumStrategy->Solve();
512 
513 // // Compute projections (for stabilization)
514 // rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,4);
515 // this->ComputeSplitOssProjections(rModelPart);
516 
517 // // Additional steps // Moved to end of step
518 // for (std::vector<Process::Pointer>::iterator iExtraSteps = mExtraIterationSteps.begin();
519 // iExtraSteps != mExtraIterationSteps.end(); ++iExtraSteps)
520 // (*iExtraSteps)->Execute();
521 
522  // Check convergence
523  Converged = this->CheckFractionalStepConvergence(NormDv);
524 
525  if (Converged)
526  {
527  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0) << "Fractional velocity converged in " << it + 1 << " iterations." << std::endl;
528  break;
529  }
530  }
531 
532  KRATOS_INFO_IF("FractionalStepStrategy", !Converged && BaseType::GetEchoLevel() > 0) << "Fractional velocity iterations did not converge." << std::endl;
533 
534  // Compute projections (for stabilization)
535  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,4);
536  this->ComputeSplitOssProjections(rModelPart);
537 
538  // 2. Pressure solution (store pressure variation in PRESSURE_OLD_IT)
539  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,5);
540 
541 #pragma omp parallel for
542  for (int i_node = 0; i_node < n_nodes; ++i_node) {
543  auto it_node = rModelPart.NodesBegin() + i_node;
544  const double old_press = it_node->FastGetSolutionStepValue(PRESSURE);
545  it_node->FastGetSolutionStepValue(PRESSURE_OLD_IT) = -mPressureGradientRelaxationFactor * old_press;
546  }
547 
548  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0) << "Calculating Pressure." << std::endl;
549  double NormDp = mpPressureStrategy->Solve();
550 
551 #pragma omp parallel for
552  for (int i_node = 0; i_node < n_nodes; ++i_node) {
553  auto it_node = rModelPart.NodesBegin() + i_node;
554  it_node->FastGetSolutionStepValue(PRESSURE_OLD_IT) += it_node->FastGetSolutionStepValue(PRESSURE);
555  }
556 
557  // 3. Compute end-of-step velocity
558  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0) << "Updating Velocity." << std::endl;
559  rModelPart.GetProcessInfo().SetValue(FRACTIONAL_STEP,6);
560 
562 
563  /*
564  mpPressureStrategy->Clear();
565  double NormDu = mpPressureStrategy->Solve();
566  mpPressureStrategy->Clear();
567  */
568 
569  // Additional steps
570  for (std::vector<Process::Pointer>::iterator iExtraSteps = mExtraIterationSteps.begin();
571  iExtraSteps != mExtraIterationSteps.end(); ++iExtraSteps)
572  (*iExtraSteps)->Execute();
573 
574  // Set the output tuple as the fractional velocity convergence and pressure norm
575  return std::make_tuple(Converged, NormDp);
576  }
577 
578  bool CheckFractionalStepConvergence(const double NormDv)
579  {
580  ModelPart& rModelPart = BaseType::GetModelPart();
581  const int n_nodes = rModelPart.NumberOfNodes();
582 
583  double NormV = 0.00;
584 #pragma omp parallel for reduction(+:NormV)
585  for (int i_node = 0; i_node < n_nodes; ++i_node) {
586  const auto it_node = rModelPart.NodesBegin() + i_node;
587  const auto &r_vel = it_node->FastGetSolutionStepValue(VELOCITY);
588  for (unsigned int d = 0; d < 3; ++d) {
589  NormV += r_vel[d] * r_vel[d];
590  }
591  }
592  NormV = BaseType::GetModelPart().GetCommunicator().GetDataCommunicator().SumAll(NormV);
593  NormV = sqrt(NormV);
594 
595  const double zero_tol = 1.0e-12;
596  const double Ratio = (NormV < zero_tol) ? NormDv : NormDv / NormV;
597 
598  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0) << "CONVERGENCE CHECK:" << std::endl;
599  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0)
600  << std::scientific << std::setprecision(8) << "FRAC VEL.: ratio = " << Ratio <<"; exp.ratio = " << mVelocityTolerance << " abs = " << NormDv << std::endl;
601 
602  if (Ratio < mVelocityTolerance)
603  return true;
604  else
605  return false;
606  }
607 
608  bool CheckPressureConvergence(const double NormDp)
609  {
610  ModelPart& rModelPart = BaseType::GetModelPart();
611  const int n_nodes = rModelPart.NumberOfNodes();
612 
613  double NormP = 0.00;
614 #pragma omp parallel for reduction(+:NormP)
615  for (int i_node = 0; i_node < n_nodes; ++i_node) {
616  const auto it_node = rModelPart.NodesBegin() + i_node;
617  const double Pr = it_node->FastGetSolutionStepValue(PRESSURE);
618  NormP += Pr * Pr;
619  }
620  NormP = BaseType::GetModelPart().GetCommunicator().GetDataCommunicator().SumAll(NormP);
621  NormP = sqrt(NormP);
622 
623  const double zero_tol = 1.0e-12;
624  const double Ratio = (NormP < zero_tol) ? NormDp : NormDp / NormP;
625 
626  KRATOS_INFO_IF("FractionalStepStrategy", BaseType::GetEchoLevel() > 0) << "Pressure relative error: " << Ratio << std::endl;
627 
628  if (Ratio < mPressureTolerance)
629  {
630  return true;
631  }
632  else
633  return false;
634  }
635 
636 
637  virtual void ComputeSplitOssProjections(ModelPart& rModelPart)
638  {
640  const int n_nodes = rModelPart.NumberOfNodes();
641  const int n_elems = rModelPart.NumberOfElements();
642 
643 #pragma omp parallel for
644  for (int i_node = 0; i_node < n_nodes; ++i_node) {
645  auto it_node = rModelPart.NodesBegin() + i_node;
646  it_node->FastGetSolutionStepValue(CONV_PROJ) = CONV_PROJ.Zero();
647  it_node->FastGetSolutionStepValue(PRESS_PROJ) = PRESS_PROJ.Zero();
648  it_node->FastGetSolutionStepValue(DIVPROJ) = 0.0;
649  it_node->FastGetSolutionStepValue(NODAL_AREA) = 0.0;
650  }
651 
652 #pragma omp parallel for
653  for (int i_elem = 0; i_elem < n_elems; ++i_elem) {
654  const auto it_elem = rModelPart.ElementsBegin() + i_elem;
655  it_elem->Calculate(CONV_PROJ, Out, rModelPart.GetProcessInfo());
656  }
657 
658  rModelPart.GetCommunicator().AssembleCurrentData(CONV_PROJ);
659  rModelPart.GetCommunicator().AssembleCurrentData(PRESS_PROJ);
660  rModelPart.GetCommunicator().AssembleCurrentData(DIVPROJ);
661  rModelPart.GetCommunicator().AssembleCurrentData(NODAL_AREA);
662 
663  // If there are periodic conditions, add contributions from both sides to the periodic nodes
664  this->PeriodicConditionProjectionCorrection(rModelPart);
665 
666 #pragma omp parallel for
667  for (int i_node = 0; i_node < n_nodes; ++i_node) {
668  auto it_node = rModelPart.NodesBegin() + i_node;
669  const double NodalArea = it_node->FastGetSolutionStepValue(NODAL_AREA);
670  it_node->FastGetSolutionStepValue(CONV_PROJ) /= NodalArea;
671  it_node->FastGetSolutionStepValue(PRESS_PROJ) /= NodalArea;
672  it_node->FastGetSolutionStepValue(DIVPROJ) /= NodalArea;
673  }
674  }
675 
677  {
678  ModelPart& rModelPart = BaseType::GetModelPart();
679  const int n_nodes = rModelPart.NumberOfNodes();
680  const int n_elems = rModelPart.NumberOfElements();
681 
683  VariableUtils().SetHistoricalVariableToZero(FRACT_VEL, rModelPart.Nodes());
684 
685 #pragma omp parallel for
686  for (int i_elem = 0; i_elem < n_elems; ++i_elem) {
687  const auto it_elem = rModelPart.ElementsBegin() + i_elem;
688  it_elem->Calculate(VELOCITY, Out, rModelPart.GetProcessInfo());
689  }
690 
691  rModelPart.GetCommunicator().AssembleCurrentData(FRACT_VEL);
692  this->PeriodicConditionVelocityCorrection(rModelPart);
693 
694  // Force the end of step velocity to verify slip conditions in the model
695  if (mUseSlipConditions)
696  this->EnforceSlipCondition(SLIP);
697 
698  if (mDomainSize > 2)
699  {
700 #pragma omp parallel for
701  for (int i_node = 0; i_node < n_nodes; ++i_node) {
702  auto it_node = rModelPart.NodesBegin() + i_node;
703  const double NodalArea = it_node->FastGetSolutionStepValue(NODAL_AREA);
704  if ( ! it_node->IsFixed(VELOCITY_X) )
705  it_node->FastGetSolutionStepValue(VELOCITY_X) += it_node->FastGetSolutionStepValue(FRACT_VEL_X) / NodalArea;
706  if ( ! it_node->IsFixed(VELOCITY_Y) )
707  it_node->FastGetSolutionStepValue(VELOCITY_Y) += it_node->FastGetSolutionStepValue(FRACT_VEL_Y) / NodalArea;
708  if ( ! it_node->IsFixed(VELOCITY_Z) )
709  it_node->FastGetSolutionStepValue(VELOCITY_Z) += it_node->FastGetSolutionStepValue(FRACT_VEL_Z) / NodalArea;
710  }
711  }
712  else
713  {
714 #pragma omp parallel for
715  for (int i_node = 0; i_node < n_nodes; ++i_node) {
716  auto it_node = rModelPart.NodesBegin() + i_node;
717  const double NodalArea = it_node->FastGetSolutionStepValue(NODAL_AREA);
718  if ( ! it_node->IsFixed(VELOCITY_X) )
719  it_node->FastGetSolutionStepValue(VELOCITY_X) += it_node->FastGetSolutionStepValue(FRACT_VEL_X) / NodalArea;
720  if ( ! it_node->IsFixed(VELOCITY_Y) )
721  it_node->FastGetSolutionStepValue(VELOCITY_Y) += it_node->FastGetSolutionStepValue(FRACT_VEL_Y) / NodalArea;
722  }
723  }
724  }
725 
730  void EnforceSlipCondition(const Kratos::Flags& rSlipWallFlag)
731  {
732  ModelPart& rModelPart = BaseType::GetModelPart();
733 
734  const int num_nodes_in_model_part = rModelPart.NumberOfNodes();
735 
736  #pragma omp parallel for
737  for (int i = 0; i < num_nodes_in_model_part; i++)
738  {
739  ModelPart::NodeIterator itNode = rModelPart.NodesBegin() + i;
740  const Node& r_const_node = *itNode;
741 
742  if ( r_const_node.Is(rSlipWallFlag) )
743  {
744  const array_1d<double,3>& rNormal = itNode->FastGetSolutionStepValue(NORMAL);
745  array_1d<double,3>& rDeltaVelocity = itNode->FastGetSolutionStepValue(FRACT_VEL);
746 
747  double Proj = rNormal[0] * rDeltaVelocity[0];
748  double Norm = rNormal[0] * rNormal[0];
749 
750  for (unsigned int d = 1; d < mDomainSize; ++d)
751  {
752  Proj += rNormal[d] * rDeltaVelocity[d];
753  Norm += rNormal[d] * rNormal[d];
754  }
755 
756  Proj /= Norm;
757  rDeltaVelocity -= Proj * rNormal;
758  }
759  }
760  }
761 
769  {
770  Communicator& r_comm = rModelPart.GetCommunicator();
772  {
773  int GlobalNodesNum = r_comm.LocalMesh().Nodes().size();
774  GlobalNodesNum = r_comm.GetDataCommunicator().SumAll(GlobalNodesNum);
775 
776  for (typename ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); itCond++ )
777  {
778  ModelPart::ConditionType::GeometryType& rGeom = itCond->GetGeometry();
779  if (rGeom.PointsNumber() == 2)
780  {
781  Node& rNode0 = rGeom[0];
782  int Node0Pair = rNode0.FastGetSolutionStepValue(mrPeriodicIdVar);
783 
784  Node& rNode1 = rGeom[1];
785  int Node1Pair = rNode1.FastGetSolutionStepValue(mrPeriodicIdVar);
786 
787  // If the nodes are marked as a periodic pair (this is to avoid acting on two-noded conditions that are not PeriodicCondition)
788  if ( ( static_cast<int>(rNode0.Id()) == Node1Pair ) && (static_cast<int>(rNode1.Id()) == Node0Pair ) )
789  {
790  double NodalArea = rNode0.FastGetSolutionStepValue(NODAL_AREA) + rNode1.FastGetSolutionStepValue(NODAL_AREA);
791  array_1d<double,3> ConvProj = rNode0.FastGetSolutionStepValue(CONV_PROJ) + rNode1.FastGetSolutionStepValue(CONV_PROJ);
792  array_1d<double,3> PressProj = rNode0.FastGetSolutionStepValue(PRESS_PROJ) + rNode1.FastGetSolutionStepValue(PRESS_PROJ);
793  double DivProj = rNode0.FastGetSolutionStepValue(DIVPROJ) + rNode1.FastGetSolutionStepValue(DIVPROJ);
794 
795  rNode0.GetValue(NODAL_AREA) = NodalArea;
796  rNode0.GetValue(CONV_PROJ) = ConvProj;
797  rNode0.GetValue(PRESS_PROJ) = PressProj;
798  rNode0.GetValue(DIVPROJ) = DivProj;
799  rNode1.GetValue(NODAL_AREA) = NodalArea;
800  rNode1.GetValue(CONV_PROJ) = ConvProj;
801  rNode1.GetValue(PRESS_PROJ) = PressProj;
802  rNode1.GetValue(DIVPROJ) = DivProj;
803  }
804  }
805  else if (rGeom.PointsNumber() == 4 && rGeom[0].FastGetSolutionStepValue(mrPeriodicIdVar) > GlobalNodesNum)
806  {
807  double NodalArea = rGeom[0].FastGetSolutionStepValue(NODAL_AREA);
808  array_1d<double,3> ConvProj = rGeom[0].FastGetSolutionStepValue(CONV_PROJ);
809  array_1d<double,3> PressProj = rGeom[0].FastGetSolutionStepValue(PRESS_PROJ);
810  double DivProj = rGeom[0].FastGetSolutionStepValue(DIVPROJ);
811 
812  for (unsigned int i = 1; i < 4; i++)
813  {
814  NodalArea += rGeom[i].FastGetSolutionStepValue(NODAL_AREA);
815  ConvProj += rGeom[i].FastGetSolutionStepValue(CONV_PROJ);
816  PressProj += rGeom[i].FastGetSolutionStepValue(PRESS_PROJ);
817  DivProj += rGeom[i].FastGetSolutionStepValue(DIVPROJ);
818  }
819 
820  for (unsigned int i = 0; i < 4; i++)
821  {
822  rGeom[i].GetValue(NODAL_AREA) = NodalArea;
823  rGeom[i].GetValue(CONV_PROJ) = ConvProj;
824  rGeom[i].GetValue(PRESS_PROJ) = PressProj;
825  rGeom[i].GetValue(DIVPROJ) = DivProj;
826  }
827  }
828  }
829 
830  rModelPart.GetCommunicator().AssembleNonHistoricalData(NODAL_AREA);
831  rModelPart.GetCommunicator().AssembleNonHistoricalData(CONV_PROJ);
832  rModelPart.GetCommunicator().AssembleNonHistoricalData(PRESS_PROJ);
833  rModelPart.GetCommunicator().AssembleNonHistoricalData(DIVPROJ);
834 
835  for (typename ModelPart::NodeIterator itNode = rModelPart.NodesBegin(); itNode != rModelPart.NodesEnd(); itNode++)
836  {
837  if (itNode->GetValue(NODAL_AREA) != 0.0)
838  {
839  itNode->FastGetSolutionStepValue(NODAL_AREA) = itNode->GetValue(NODAL_AREA);
840  itNode->FastGetSolutionStepValue(CONV_PROJ) = itNode->GetValue(CONV_PROJ);
841  itNode->FastGetSolutionStepValue(PRESS_PROJ) = itNode->GetValue(PRESS_PROJ);
842  itNode->FastGetSolutionStepValue(DIVPROJ) = itNode->GetValue(DIVPROJ);
843 
844  // reset for next iteration
845  itNode->GetValue(NODAL_AREA) = 0.0;
846  itNode->GetValue(CONV_PROJ) = CONV_PROJ.Zero();
847  itNode->GetValue(PRESS_PROJ) = PRESS_PROJ.Zero();
848  itNode->GetValue(DIVPROJ) = 0.0;
849  }
850  }
851  }
852  }
853 
855  {
856  Communicator& r_comm = rModelPart.GetCommunicator();
858  {
859  int GlobalNodesNum = r_comm.LocalMesh().Nodes().size();
860  GlobalNodesNum = r_comm.GetDataCommunicator().SumAll(GlobalNodesNum);
861 
862  for (typename ModelPart::ConditionIterator itCond = rModelPart.ConditionsBegin(); itCond != rModelPart.ConditionsEnd(); itCond++ )
863  {
864  ModelPart::ConditionType::GeometryType& rGeom = itCond->GetGeometry();
865  if (rGeom.PointsNumber() == 2)
866  {
867  Node& rNode0 = rGeom[0];
868  int Node0Pair = rNode0.FastGetSolutionStepValue(mrPeriodicIdVar);
869 
870  Node& rNode1 = rGeom[1];
871  int Node1Pair = rNode1.FastGetSolutionStepValue(mrPeriodicIdVar);
872 
873  // If the nodes are marked as a periodic pair (this is to avoid acting on two-noded conditions that are not PeriodicCondition)
874  if ( ( static_cast<int>(rNode0.Id()) == Node1Pair ) && (static_cast<int>(rNode1.Id()) == Node0Pair ) )
875  {
876  array_1d<double,3> DeltaVel = rNode0.FastGetSolutionStepValue(FRACT_VEL) + rNode1.FastGetSolutionStepValue(FRACT_VEL);
877 
878  rNode0.GetValue(FRACT_VEL) = DeltaVel;
879  rNode1.GetValue(FRACT_VEL) = DeltaVel;
880  }
881  }
882  else if (rGeom.PointsNumber() == 4 && rGeom[0].FastGetSolutionStepValue(mrPeriodicIdVar) > GlobalNodesNum)
883  {
884  array_1d<double,3> DeltaVel = rGeom[0].FastGetSolutionStepValue(FRACT_VEL);
885  for (unsigned int i = 1; i < 4; i++)
886  {
887  DeltaVel += rGeom[i].FastGetSolutionStepValue(FRACT_VEL);
888  }
889 
890  for (unsigned int i = 0; i < 4; i++)
891  {
892  rGeom[i].GetValue(FRACT_VEL) = DeltaVel;
893  }
894  }
895  }
896 
897  rModelPart.GetCommunicator().AssembleNonHistoricalData(FRACT_VEL);
898 
899  for (typename ModelPart::NodeIterator itNode = rModelPart.NodesBegin(); itNode != rModelPart.NodesEnd(); itNode++)
900  {
901  array_1d<double,3>& rDeltaVel = itNode->GetValue(FRACT_VEL);
902  if ( rDeltaVel[0]*rDeltaVel[0] + rDeltaVel[1]*rDeltaVel[1] + rDeltaVel[2]*rDeltaVel[2] != 0.0)
903  {
904  itNode->FastGetSolutionStepValue(FRACT_VEL) = itNode->GetValue(FRACT_VEL);
905  rDeltaVel = ZeroVector(3);
906  }
907  }
908  }
909  }
910 
911 
915 
916 
920 
921 
925 
926 
928 private:
931 
932 
936 
937 
941 
942 
946 
947  void InitializeStrategy(
948  SolverSettingsType& rSolverConfig,
949  bool PredictorCorrector)
950  {
951  KRATOS_TRY;
952 
953  mTimeOrder = rSolverConfig.GetTimeOrder();
954 
955  // Check that input parameters are reasonable and sufficient.
956  this->Check();
957 
958  mDomainSize = rSolverConfig.GetDomainSize();
959 
960  mPredictorCorrector = PredictorCorrector;
961 
962  mUseSlipConditions = rSolverConfig.UseSlipConditions();
963 
964  mReformDofSet = rSolverConfig.GetReformDofSet();
965 
966  auto& r_process_info = BaseType::GetModelPart().GetProcessInfo();
967  if (r_process_info.Has(FS_PRESSURE_GRADIENT_RELAXATION_FACTOR)) {
968  mPressureGradientRelaxationFactor = r_process_info[FS_PRESSURE_GRADIENT_RELAXATION_FACTOR];
969  KRATOS_INFO("FractionalStepStrategy") << "Using fractional step strategy with "
970  "pressure gradient relaxation = "
972  } else {
974  r_process_info.SetValue(FS_PRESSURE_GRADIENT_RELAXATION_FACTOR, mPressureGradientRelaxationFactor);
975  }
976 
977  BaseType::SetEchoLevel(rSolverConfig.GetEchoLevel());
978 
979  // Initialize strategies for each step
980  bool HaveVelStrategy = rSolverConfig.FindStrategy(SolverSettingsType::Velocity,mpMomentumStrategy);
981 
982  if (HaveVelStrategy)
983  {
984  rSolverConfig.FindTolerance(SolverSettingsType::Velocity,mVelocityTolerance);
985  rSolverConfig.FindMaxIter(SolverSettingsType::Velocity,mMaxVelocityIter);
986  }
987  else
988  {
989  KRATOS_ERROR << "FractionalStepStrategy error: No Velocity strategy defined in FractionalStepSettings" << std::endl;
990  }
991 
992  bool HavePressStrategy = rSolverConfig.FindStrategy(SolverSettingsType::Pressure,mpPressureStrategy);
993 
994  if (HavePressStrategy)
995  {
996  rSolverConfig.FindTolerance(SolverSettingsType::Pressure,mPressureTolerance);
997  rSolverConfig.FindMaxIter(SolverSettingsType::Pressure,mMaxPressureIter);
998  }
999  else
1000  {
1001  KRATOS_ERROR << "FractionalStepStrategy error: No Pressure strategy defined in FractionalStepSettings" << std::endl;
1002  }
1003 
1004  Process::Pointer pTurbulenceProcess;
1005  bool HaveTurbulence = rSolverConfig.GetTurbulenceModel(pTurbulenceProcess);
1006 
1007  if (HaveTurbulence)
1008  mExtraIterationSteps.push_back(pTurbulenceProcess);
1009 
1010 
1011  // Check input parameters
1012  this->Check();
1013 
1014  KRATOS_CATCH("");
1015  }
1016 
1017 
1021 
1022 
1026 
1027 
1031 
1033  FractionalStepStrategy& operator=(FractionalStepStrategy const& rOther){}
1034 
1037 
1038 
1040 
1041 };
1042 
1046 
1047 
1049 
1051 
1052 } // namespace Kratos.
1053 
1054 #endif // KRATOS_FRACTIONAL_STEP_STRATEGY
The Commmunicator class manages communication for distributed ModelPart instances.
Definition: communicator.h:67
virtual bool AssembleNonHistoricalData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:527
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
virtual bool AssembleCurrentData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:502
MeshType & LocalMesh()
Returns the reference to the mesh storing all local entities.
Definition: communicator.cpp:245
void SetValue(const Variable< TDataType > &rThisVariable, TDataType const &rValue)
Sets the value for a given variable.
Definition: data_value_container.h:320
Definition: flags.h:58
bool Is(Flags const &rOther) const
Definition: flags.h:274
Fractional-step strategy for incompressible Navier-Stokes formulation This strategy implements a spli...
Definition: fractional_step_strategy.h:77
virtual void CalculateReactions()
Calculates the reactions This methods calculates the reactions of the momentum equation....
Definition: fractional_step_strategy.h:275
FractionalStepStrategy(ModelPart &rModelPart, SolverSettingsType &rSolverConfig, bool PredictorCorrector)
Definition: fractional_step_strategy.h:99
double mVelocityTolerance
Definition: fractional_step_strategy.h:413
void Initialize() override
Initialization of member variables and prior operations.
Definition: fractional_step_strategy.h:159
unsigned int mMaxPressureIter
Definition: fractional_step_strategy.h:421
int Check() override
Function to perform expensive checks.
Definition: fractional_step_strategy.h:183
bool GetCalculateReactionsFlag()
This method returns the flag mCalculateReactionsFlag.
Definition: fractional_step_strategy.h:362
virtual void AddIterationStep(Process::Pointer pNewStep)
Definition: fractional_step_strategy.h:321
FractionalStepStrategy(ModelPart &rModelPart, SolverSettingsType &rSolverConfig, bool PredictorCorrector, const Kratos::Variable< int > &PeriodicVar)
Definition: fractional_step_strategy.h:110
std::vector< Process::Pointer > mExtraIterationSteps
Definition: fractional_step_strategy.h:441
const Kratos::Variable< int > & mrPeriodicIdVar
Definition: fractional_step_strategy.h:443
KRATOS_CLASS_POINTER_DEFINITION(FractionalStepStrategy)
Counted pointer of FractionalStepStrategy.
StrategyPointerType mpMomentumStrategy
Scheme for the solution of the momentum equation.
Definition: fractional_step_strategy.h:436
void EnforceSlipCondition(const Kratos::Flags &rSlipWallFlag)
Substract wall-normal component of velocity update to ensure that the final velocity satisfies slip c...
Definition: fractional_step_strategy.h:730
bool SolveSolutionStep() override
Solves the current step. This function returns true if a solution has been found, false otherwise.
Definition: fractional_step_strategy.h:227
double mPressureTolerance
Definition: fractional_step_strategy.h:415
void Clear() override
Clears the internal storage.
Definition: fractional_step_strategy.h:331
ImplicitSolvingStrategy< TSparseSpace, TDenseSpace, TLinearSolver > BaseType
Definition: fractional_step_strategy.h:85
ImplicitSolvingStrategy< TSparseSpace, TDenseSpace, TLinearSolver >::Pointer StrategyPointerType
Definition: fractional_step_strategy.h:91
bool CheckFractionalStepConvergence(const double NormDv)
Definition: fractional_step_strategy.h:578
void SetTimeCoefficients()
Set the Time Coefficients object Calculate the coefficients for the BDF2 time iteration....
Definition: fractional_step_strategy.h:459
void PeriodicConditionProjectionCorrection(ModelPart &rModelPart)
Definition: fractional_step_strategy.h:768
FractionalStepStrategy(ModelPart &rModelPart, SolverSettingsType &rSolverConfig, bool PredictorCorrector, bool CalculateReactionsFlag)
Definition: fractional_step_strategy.h:122
StrategyPointerType mpPressureStrategy
Scheme for the solution of the mass equation.
Definition: fractional_step_strategy.h:439
void SetEchoLevel(int Level) override
This sets the level of echo for the solving strategy.
Definition: fractional_step_strategy.h:341
virtual void CalculateEndOfStepVelocity()
Definition: fractional_step_strategy.h:676
bool mReformDofSet
Definition: fractional_step_strategy.h:431
void FinalizeSolutionStep() override
Performs all the required operations that should be done (for each step) after solving the solution s...
Definition: fractional_step_strategy.h:262
SolverSettings< TSparseSpace, TDenseSpace, TLinearSolver > SolverSettingsType
Definition: fractional_step_strategy.h:93
std::string Info() const override
Turn back information as a string.
Definition: fractional_step_strategy.h:377
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: fractional_step_strategy.h:385
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: fractional_step_strategy.h:89
void PeriodicConditionVelocityCorrection(ModelPart &rModelPart)
Definition: fractional_step_strategy.h:854
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: fractional_step_strategy.h:87
unsigned int mMaxVelocityIter
Definition: fractional_step_strategy.h:419
double mPressureGradientRelaxationFactor
Definition: fractional_step_strategy.h:417
bool CheckPressureConvergence(const double NormDp)
Definition: fractional_step_strategy.h:608
bool mPredictorCorrector
Definition: fractional_step_strategy.h:427
unsigned int mTimeOrder
Definition: fractional_step_strategy.h:425
~FractionalStepStrategy() override
Destructor.
Definition: fractional_step_strategy.h:148
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: fractional_step_strategy.h:391
virtual void ComputeSplitOssProjections(ModelPart &rModelPart)
Definition: fractional_step_strategy.h:637
FractionalStepStrategy(ModelPart &rModelPart, SolverSettingsType &rSolverConfig, bool PredictorCorrector, bool CalculateReactionsFlag, const Kratos::Variable< int > &PeriodicVar)
Definition: fractional_step_strategy.h:134
bool mUseSlipConditions
Definition: fractional_step_strategy.h:429
void SetCalculateReactionsFlag(bool CalculateReactionsFlag)
This method sets the flag mCalculateReactionsFlag.
Definition: fractional_step_strategy.h:353
virtual void ClearExtraIterationSteps()
Definition: fractional_step_strategy.h:326
virtual std::tuple< bool, double > SolveStep()
Definition: fractional_step_strategy.h:496
unsigned int mDomainSize
Definition: fractional_step_strategy.h:423
bool mCalculateReactionsFlag
Definition: fractional_step_strategy.h:433
void InitializeSolutionStep() override
Performs all the required operations that should be done (for each step) before solving the solution ...
Definition: fractional_step_strategy.h:221
Geometry base class.
Definition: geometry.h:71
SizeType PointsNumber() const
Definition: geometry.h:528
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometry.h:627
Implicit solving strategy base class This is the base class from which we will derive all the implici...
Definition: implicit_solving_strategy.h:61
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: implicit_solving_strategy.h:80
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: implicit_solving_strategy.h:78
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
NodesContainerType & Nodes()
Definition: mesh.h:346
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
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
SizeType NumberOfNodes(IndexType ThisIndex=0) const
Definition: model_part.h:341
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
MeshType::ConditionIterator ConditionIterator
Definition: model_part.h:189
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
ConditionIterator ConditionsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1371
This class defines the node.
Definition: node.h:65
TVariableType::Type & FastGetSolutionStepValue(const TVariableType &rThisVariable)
Definition: node.h:435
IndexType Id() const
Definition: node.h:262
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: node.h:466
size_type size() const
Returns the number of elements in the container.
Definition: pointer_vector_set.h:502
Helper class to define solution strategies for FS_Strategy.
Definition: solver_settings.h:53
@ Velocity
Definition: solver_settings.h:66
@ Pressure
Definition: solver_settings.h:66
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
virtual void SetEchoLevel(const int Level)
This sets the level of echo for the solving strategy.
Definition: solving_strategy.h:255
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
virtual int Check()
Function to perform expensive checks.
Definition: solving_strategy.h:377
TDenseSpace::VectorType LocalSystemVectorType
Definition: solving_strategy.h:81
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
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_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO(label)
Definition: logger.h:250
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
#define KRATOS_WARNING_IF(label, conditional)
Definition: logger.h:266
#define KRATOS_WARNING(label)
Definition: logger.h:265
void InitializeAllEntities(ModelPart &rModelPart)
This method initializes all the active entities (conditions, elements, constraints)
Definition: entities_utilities.cpp:199
ProcessInfo & GetProcessInfo(ModelPart &rModelPart)
Definition: add_model_part_to_python.cpp:54
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
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
def Norm(vector)
Definition: sand_production_post_process_tool.py:10
echo_level
Definition: script.py:68
integer i
Definition: TensorModule.f:17