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.
ibqn_mvqn_convergence_accelerator.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 author: Ruben Zorrilla
11 //
12 
13 #if !defined(KRATOS_IBQN_MVQN_CONVERGENCE_ACCELERATOR)
14 #define KRATOS_IBQN_MVQN_CONVERGENCE_ACCELERATOR
15 
16 // System includes
17 
18 // External includes
19 
20 // Project includes
22 #include "utilities/math_utils.h"
25 
26 // Application includes
27 
28 namespace Kratos
29 {
32 
36 
40 
44 
48 
51 template<class TSparseSpace, class TDenseSpace>
52 class MVQNFullJacobianConvergenceAccelerator;
53 
59 template<class TSparseSpace, class TDenseSpace>
60 class IBQNMVQNConvergenceAccelerator: public ConvergenceAccelerator<TSparseSpace, TDenseSpace>
61 {
62 public:
63 
67 
69  typedef typename BaseType::Pointer BaseTypePointer;
70 
73 
76 
78  typedef typename MVQNType::Pointer MVQNPointerType;
79 
83 
84  explicit IBQNMVQNConvergenceAccelerator() = default;
85 
93  {
95  mInitialOmega = rParameters["w_0"].GetDouble();
96 
97  // Set the subdomains MVQN convergence accelerator pointers
98  // Note that we call the simplified constructor with default zero relaxation omega and IBQN switch
99  const double abs_cut_off_tol = rParameters["abs_cut_off_tol"].GetDouble();
100  mpConvergenceAcceleratorLeft = Kratos::make_unique<MVQNType>(abs_cut_off_tol);
101  mpConvergenceAcceleratorRight = Kratos::make_unique<MVQNType>(abs_cut_off_tol);
102  }
103 
108 
113 
117 
118 
122 
123  void Initialize() override
124  {
125  KRATOS_TRY;
126 
127  mpConvergenceAcceleratorLeft->Initialize();
128  mpConvergenceAcceleratorRight->Initialize();
129 
130  KRATOS_CATCH( "" );
131  }
132 
137  void InitializeSolutionStep() override
138  {
139  KRATOS_TRY;
140 
141  mConvergenceAcceleratorIteration = 0;
142 
143  mpConvergenceAcceleratorLeft->InitializeSolutionStep();
144  mpConvergenceAcceleratorRight->InitializeSolutionStep();
145 
146  KRATOS_CATCH( "" );
147  }
148 
150  {
151  KRATOS_TRY;
152 
153  mpConvergenceAcceleratorLeft->InitializeNonLinearIteration();
154  mpConvergenceAcceleratorRight->InitializeNonLinearIteration();
155 
156  KRATOS_CATCH( "" );
157  }
158 
167  const VectorType& rResidualVector,
168  VectorType& rIterationGuess) override
169  {
170  KRATOS_TRY;
171 
172  KRATOS_ERROR << "The UpdateSolution() method cannot be called in the interface block Newton case. Use either \'UpdateSolutionLeft\' or \'UpdateSolutionRight\'" << std::endl;
173 
174  KRATOS_CATCH("");
175  }
176 
177  //TODO: CREATE AN INTERMEDIATE IBQN BASE CLASS
178  virtual void UpdateSolutionRight(
179  const VectorType& rForceInputVector,
180  const VectorType& rDisplacementOutputVector,
181  VectorType& rIterationGuess)
182  {
183  KRATOS_TRY;
184 
185  // Save the uncorrected force vector for the displacement update
186  auto p_uncor_disp_aux = Kratos::make_shared<VectorType>(rDisplacementOutputVector);
187  std::swap(mpUncorrectedDisplacementVector, p_uncor_disp_aux);
188 
189  // Update right inverse Jacobian approximation with the current information
190  mpConvergenceAcceleratorRight->UpdateInverseJacobianApproximation(rForceInputVector, rDisplacementOutputVector);
191 
192  VectorType right_correction(TSparseSpace::Size(rIterationGuess));
193  if (!mFirstRightCorrectionPerformed) {
194  // Calculate the first correction as a fixed point relaxation
195  TSparseSpace::SetToZero(right_correction);
196  TSparseSpace::UnaliasedAdd(right_correction, mInitialOmega, rDisplacementOutputVector - rIterationGuess);
197 
198  // Update the first iteration correction flag
199  mFirstRightCorrectionPerformed = true;
200 
201  } else {
202  // Calculate the right (displacement) correction
203  SolveInterfaceBlockQuasiNewtonRightUpdate(rForceInputVector, rDisplacementOutputVector, rIterationGuess, right_correction);
204 
205  }
206 
207  // Update the iteration guess
208  TSparseSpace::UnaliasedAdd(rIterationGuess, 1.0, right_correction);
209 
210  KRATOS_CATCH("");
211  }
212 
213  //TODO: CREATE AN INTERMEDIATE IBQN BASE CLASS
214  virtual void UpdateSolutionLeft(
215  const VectorType& rDisplacementInputVector,
216  const VectorType& rForceOutputVector,
217  VectorType& rIterationGuess)
218  {
219  KRATOS_TRY;
220 
221  // Save the uncorrected force vector for the displacement update
222  auto p_uncor_force_aux = Kratos::make_shared<VectorType>(rForceOutputVector);
223  std::swap(mpUncorrectedForceVector, p_uncor_force_aux);
224 
225  // Update left inverse Jacobian approximation with the current information
226  mpConvergenceAcceleratorLeft->UpdateInverseJacobianApproximation(rDisplacementInputVector, rForceOutputVector);
227 
228  VectorType left_correction(TSparseSpace::Size(rIterationGuess));
229  if (!mFirstLeftCorrectionPerformed) {
230  // Do nothing in the first traction correction
231  // This means to set as correction the difference between the guess and the previous iteration
232  left_correction = rForceOutputVector - rIterationGuess;
233 
234  // Update the first iteration correction flag
235  mFirstLeftCorrectionPerformed = true;
236 
237  } else {
238  // Calculate the left (traction) correction
239  SolveInterfaceBlockQuasiNewtonLeftUpdate(rDisplacementInputVector, rForceOutputVector, rIterationGuess, left_correction);
240 
241  }
242 
243  // Update the iteration guess
244  TSparseSpace::UnaliasedAdd(rIterationGuess, 1.0, left_correction);
245 
246  KRATOS_CATCH("");
247  }
248 
254  {
255  KRATOS_TRY;
256 
257  mConvergenceAcceleratorIteration += 1;
258 
259  mpConvergenceAcceleratorLeft->FinalizeNonLinearIteration();
260  mpConvergenceAcceleratorRight->FinalizeNonLinearIteration();
261 
262  KRATOS_CATCH( "" );
263  }
264 
269  void FinalizeSolutionStep() override
270  {
271  KRATOS_TRY;
272 
273  mpConvergenceAcceleratorLeft->FinalizeSolutionStep();
274  mpConvergenceAcceleratorRight->FinalizeSolutionStep();
275 
276  KRATOS_CATCH( "" );
277  }
278 
279  void Finalize() override
280  {
281  KRATOS_TRY;
282 
283  mpConvergenceAcceleratorLeft->Finalize();
284  mpConvergenceAcceleratorRight->Finalize();
285 
286  KRATOS_CATCH( "" );
287  }
288 
289  void Clear() override
290  {
291  KRATOS_TRY;
292 
293  mpConvergenceAcceleratorLeft->Clear();
294  mpConvergenceAcceleratorRight->Clear();
295 
296  KRATOS_CATCH( "" );
297  }
298 
299  bool IsBlockNewton() const override
300  {
301  return true;
302  }
303 
305  {
306  Parameters ibqn_mvqn_default_parameters(R"({
307  "solver_type" : "IBQN_MVQN",
308  "w_0" : 0.825,
309  "abs_cut_off_tol" : 1e-8
310  })");
311 
312  return ibqn_mvqn_default_parameters;
313  }
314 
318 
319 
323 
324 
328 
329 
333 
334 
336 protected:
339 
340 
344 
346  const VectorType& rDisplacementInputVector,
347  const VectorType& rForceOutputVector,
348  const VectorType& rIterationGuess,
349  VectorType& rLeftCorrection)
350  {
351  // Get the interface problem size
352  std::size_t problem_size = mpConvergenceAcceleratorLeft->GetProblemSize();
353 
354  // Get both left and inverse Jacobian
355  auto p_inv_jac_left = mpConvergenceAcceleratorLeft->pGetInverseJacobianApproximation();
356  auto p_inv_jac_right = mpConvergenceAcceleratorRight->pGetInverseJacobianApproximation();
357 
358  // Set the residual of the update problem to be solved
359  VectorType aux_RHS = rForceOutputVector - rIterationGuess;
360  VectorType aux_left_onto_right(problem_size);
361  VectorType displacement_iteration_update = *mpUncorrectedDisplacementVector - rDisplacementInputVector;
362  TSparseSpace::Mult(*p_inv_jac_left, displacement_iteration_update, aux_left_onto_right);
363  TSparseSpace::UnaliasedAdd(aux_RHS, 1.0, aux_left_onto_right);
364 
365  // Set the LHS of the update problem to be solved
366  MatrixType aux_LHS = IdentityMatrix(problem_size, problem_size);
368  VectorType(problem_size),
369  [&aux_LHS, &p_inv_jac_left, &p_inv_jac_right, &problem_size](std::size_t Col, VectorType& rAuxColumnTLS)
370  {
371  TDenseSpace::GetColumn(Col, *p_inv_jac_right, rAuxColumnTLS);
372  for (std::size_t row = 0; row < problem_size; ++row) {
373  aux_LHS(row,Col) -= TDenseSpace::RowDot(row, *p_inv_jac_left, rAuxColumnTLS);
374  }
375  });
376 
377  // Calculate the correction
378  // Do the QR decomposition of (I - J_{F}J_{S}) and solve for the force update
380  qr_decomposition.Compute(aux_LHS);
381  qr_decomposition.Solve(aux_RHS, rLeftCorrection);
382  }
383 
385  const VectorType& rForceInputVector,
386  const VectorType& rDisplacementOutputVector,
387  const VectorType& rIterationGuess,
388  VectorType& rRightCorrection)
389  {
390  // Get the interface problem size
391  std::size_t problem_size = mpConvergenceAcceleratorRight->GetProblemSize();
392 
393  // Get both left and inverse Jacobian
394  auto p_inv_jac_right = mpConvergenceAcceleratorRight->pGetInverseJacobianApproximation();
395  auto p_inv_jac_left = mpConvergenceAcceleratorLeft->pGetInverseJacobianApproximation();
396 
397  // Set the residual of the update problem to be solved
398  VectorType aux_RHS = rDisplacementOutputVector - rIterationGuess;
399  VectorType aux_right_onto_left(problem_size);
400  VectorType force_iteration_update = *mpUncorrectedForceVector - rForceInputVector;
401  TSparseSpace::Mult(*p_inv_jac_right, force_iteration_update, aux_right_onto_left);
402  TSparseSpace::UnaliasedAdd(aux_RHS, 1.0, aux_right_onto_left);
403 
404  // Set the LHS of the update problem to be solved
405  MatrixType aux_LHS = IdentityMatrix(problem_size, problem_size);
407  VectorType(problem_size),
408  [&aux_LHS, &p_inv_jac_right, &p_inv_jac_left, &problem_size](std::size_t Col, VectorType& rAuxColumnTLS)
409  {
410  TDenseSpace::GetColumn(Col, *p_inv_jac_left, rAuxColumnTLS);
411  for (std::size_t row = 0; row < problem_size; ++row) {
412  aux_LHS(row,Col) -= TDenseSpace::RowDot(row, *p_inv_jac_right, rAuxColumnTLS);
413  }
414  });
415 
416  // Calculate the correction
417  // Do the QR decomposition of (I - J_{S}J_{F}) and solve for the force update
419  qr_decomposition.Compute(aux_LHS);
420  qr_decomposition.Solve(aux_RHS, rRightCorrection);
421  }
422 
426 
427  void SetInitialRelaxationOmega(const double Omega)
428  {
429  mInitialOmega = Omega;
430  }
431 
432  void SetLeftConvergenceAcceleratorPointer(MVQNPointerType pConvergenceAcceleratorLeft)
433  {
434  mpConvergenceAcceleratorLeft = pConvergenceAcceleratorLeft;
435  }
436 
437  void SetRightConvergenceAcceleratorPointer(MVQNPointerType pConvergenceAcceleratorRight)
438  {
439  mpConvergenceAcceleratorRight = pConvergenceAcceleratorRight;
440  }
441 
443  {
444  return mpUncorrectedForceVector;
445  }
446 
448  {
449  return mpUncorrectedDisplacementVector;
450  }
451 
453  {
454  return mpConvergenceAcceleratorLeft;
455  }
456 
458  {
459  return mpConvergenceAcceleratorRight;
460  }
461 
465 
466 
470 
471 
475 
476 
478 private:
481 
482 
486 
487  double mInitialOmega;
488 
489  bool mFirstLeftCorrectionPerformed = false; // Indicates that the initial fixed point iteration has been already performed
490  bool mFirstRightCorrectionPerformed = false; // Indicates that the initial fixed point iteration has been already performed
491  unsigned int mConvergenceAcceleratorIteration = 0; // Convergence accelerator iteration counter
492 
493  MVQNPointerType mpConvergenceAcceleratorLeft;
494  MVQNPointerType mpConvergenceAcceleratorRight;
495 
496  VectorPointerType mpUncorrectedForceVector;
497  VectorPointerType mpUncorrectedDisplacementVector;
498 
499 
503 
504 
508 
509 
513 
514 
518 
519 
523 
524 
528 
529 
531 }; /* Class IBQNMVQNConvergenceAccelerator */
532 
533 
537 
541 
543 
544 } /* namespace Kratos.*/
545 
546 #endif /* KRATOS_IBQN_MVQN_CONVERGENCE_ACCELERATOR defined */
Base class for convergence accelerators This class is intended to be the base of any convergence acce...
Definition: convergence_accelerator.h:43
Definition: dense_householder_qr_decomposition.h:45
void Compute(MatrixType &rInputMatrix) override
Compute the QR Computes the QR Decomposition (QR) of the given imput matrix Note that the input matri...
Definition: dense_householder_qr_decomposition.h:92
void Solve(MatrixType &rB, MatrixType &rX) const override
Solves the problem Ax=b Being A the input matrix, this method solves the problem Ax = b.
Definition: dense_householder_qr_decomposition.h:148
Interface Block Newton convergence accelerator Interface Block Newton equations convergence accelerat...
Definition: ibqn_mvqn_convergence_accelerator.h:61
BaseType::DenseMatrixType MatrixType
Definition: ibqn_mvqn_convergence_accelerator.h:74
ConvergenceAccelerator< TSparseSpace, TDenseSpace > BaseType
Definition: ibqn_mvqn_convergence_accelerator.h:68
virtual Parameters GetDefaultParameters() const
Definition: ibqn_mvqn_convergence_accelerator.h:304
virtual void UpdateSolutionLeft(const VectorType &rDisplacementInputVector, const VectorType &rForceOutputVector, VectorType &rIterationGuess)
Definition: ibqn_mvqn_convergence_accelerator.h:214
void SetLeftConvergenceAcceleratorPointer(MVQNPointerType pConvergenceAcceleratorLeft)
Definition: ibqn_mvqn_convergence_accelerator.h:432
VectorPointerType pGetUncorrectedForceVector()
Definition: ibqn_mvqn_convergence_accelerator.h:442
MVQNFullJacobianConvergenceAccelerator< TSparseSpace, TDenseSpace > MVQNType
Definition: ibqn_mvqn_convergence_accelerator.h:77
VectorPointerType pGetUncorrectedDisplacementVector()
Definition: ibqn_mvqn_convergence_accelerator.h:447
bool IsBlockNewton() const override
Checks if the update direction is unique or double For the current convergence accelerator,...
Definition: ibqn_mvqn_convergence_accelerator.h:299
BaseType::DenseVectorType VectorType
Definition: ibqn_mvqn_convergence_accelerator.h:71
IBQNMVQNConvergenceAccelerator(const IBQNMVQNConvergenceAccelerator &rOther)=delete
virtual void SolveInterfaceBlockQuasiNewtonRightUpdate(const VectorType &rForceInputVector, const VectorType &rDisplacementOutputVector, const VectorType &rIterationGuess, VectorType &rRightCorrection)
Definition: ibqn_mvqn_convergence_accelerator.h:384
KRATOS_CLASS_POINTER_DEFINITION(IBQNMVQNConvergenceAccelerator)
void FinalizeNonLinearIteration() override
Do the MVQN variables update Updates the MVQN iteration variables for the next non-linear iteration.
Definition: ibqn_mvqn_convergence_accelerator.h:253
void UpdateSolution(const VectorType &rResidualVector, VectorType &rIterationGuess) override
Performs the solution update This method computes the solution update using a Jacobian approximation....
Definition: ibqn_mvqn_convergence_accelerator.h:166
void InitializeSolutionStep() override
Initialize the internal iteration counter This method initializes the convergence acceleratior iterat...
Definition: ibqn_mvqn_convergence_accelerator.h:137
MVQNType::Pointer MVQNPointerType
Definition: ibqn_mvqn_convergence_accelerator.h:78
void SetInitialRelaxationOmega(const double Omega)
Definition: ibqn_mvqn_convergence_accelerator.h:427
void SetRightConvergenceAcceleratorPointer(MVQNPointerType pConvergenceAcceleratorRight)
Definition: ibqn_mvqn_convergence_accelerator.h:437
IBQNMVQNConvergenceAccelerator(Parameters rParameters)
Construct a new IBQNMVQNConvergenceAccelerator object MVQN convergence accelerator Json settings cons...
Definition: ibqn_mvqn_convergence_accelerator.h:92
void InitializeNonLinearIteration() override
Operations before each non-linear iteration Performs all the required operations that should be done ...
Definition: ibqn_mvqn_convergence_accelerator.h:149
MVQNPointerType pGetConvergenceAcceleratorRight()
Definition: ibqn_mvqn_convergence_accelerator.h:457
void Clear() override
Clear the internal storage Clears all the internal data (e.g. previous observation matrices)
Definition: ibqn_mvqn_convergence_accelerator.h:289
BaseType::Pointer BaseTypePointer
Definition: ibqn_mvqn_convergence_accelerator.h:69
virtual void UpdateSolutionRight(const VectorType &rForceInputVector, const VectorType &rDisplacementOutputVector, VectorType &rIterationGuess)
Definition: ibqn_mvqn_convergence_accelerator.h:178
virtual void SolveInterfaceBlockQuasiNewtonLeftUpdate(const VectorType &rDisplacementInputVector, const VectorType &rForceOutputVector, const VectorType &rIterationGuess, VectorType &rLeftCorrection)
Definition: ibqn_mvqn_convergence_accelerator.h:345
BaseType::DenseMatrixPointerType MatrixPointerType
Definition: ibqn_mvqn_convergence_accelerator.h:75
void FinalizeSolutionStep() override
Save the current step Jacobian This method saves the current step Jacobian as previous step Jacobian ...
Definition: ibqn_mvqn_convergence_accelerator.h:269
MVQNPointerType pGetConvergenceAcceleratorLeft()
Definition: ibqn_mvqn_convergence_accelerator.h:452
BaseType::DenseVectorPointerType VectorPointerType
Definition: ibqn_mvqn_convergence_accelerator.h:72
void Initialize() override
Initialize the convergence accelerator Operations that are required to be done once before the resolu...
Definition: ibqn_mvqn_convergence_accelerator.h:123
void Finalize() override
Finalize the convergence accelerator Perform all the operations required after the resolution of the ...
Definition: ibqn_mvqn_convergence_accelerator.h:279
virtual ~IBQNMVQNConvergenceAccelerator()
Definition: ibqn_mvqn_convergence_accelerator.h:112
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
MVQN acceleration scheme MultiVectorQuasiNewton convergence accelerator from Bogaers et al....
Definition: mvqn_convergence_accelerator.hpp:58
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
TDenseSpace::VectorType DenseVectorType
Definition: convergence_accelerator.h:56
TSparseSpace::VectorType VectorType
Definition: convergence_accelerator.h:50
#define KRATOS_ERROR
Definition: exception.h:161
TDenseSpace::MatrixPointerType DenseMatrixPointerType
Definition: convergence_accelerator.h:59
TDenseSpace::MatrixType DenseMatrixType
Definition: convergence_accelerator.h:57
TSparseSpace::VectorPointerType VectorPointerType
Definition: convergence_accelerator.h:53
TDenseSpace::VectorPointerType DenseVectorPointerType
Definition: convergence_accelerator.h:60
TSparseSpace::MatrixType MatrixType
Definition: convergence_accelerator.h:51
TSpaceType::IndexType Size(TSpaceType &dummy, typename TSpaceType::VectorType const &rV)
Definition: add_strategies_to_python.cpp:111
void Mult(TSpaceType &dummy, typename TSpaceType::MatrixType &rA, typename TSpaceType::VectorType &rX, typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:98
void UnaliasedAdd(TSpaceType &dummy, typename TSpaceType::VectorType &x, const double A, const typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:170
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649