13 #if !defined(KRATOS_IBQN_MVQN_RANDOMIZED_SVD_CONVERGENCE_ACCELERATOR)
14 #define KRATOS_IBQN_MVQN_RANDOMIZED_SVD_CONVERGENCE_ACCELERATOR
50 template<
class TSparseSpace,
class TDenseSpace>
51 class MVQNRandomizedSVDConvergenceAccelerator;
58 template<
class TSparseSpace,
class TDenseSpace>
98 , mpSmallMatrixDenseSVD(pDenseSVD)
104 MVQNPointerType p_convergence_accelerator_left = CreateMVQNPointer(pDenseQR, pDenseSVD, ConvAcceleratorParameters);
105 MVQNPointerType p_convergence_accelerator_right = CreateMVQNPointer(pDenseQR, pDenseSVD, ConvAcceleratorParameters);
134 "solver_type" : "IBQN_MVQN_randomized_SVD",
135 "automatic_jacobian_modes" : true,
136 "jacobian_modes" : 0,
138 "cut_off_tol" : 1e-8,
139 "limit_modes_to_iterations" : true,
140 "min_rand_svd_extra_modes" : 10
143 return ibqn_mvqn_default_parameters;
157 auto p_inv_jac_QU_left = p_conv_acc_left->pGetJacobianDecompositionMatrixQU();
158 auto p_inv_jac_SigmaV_left = p_conv_acc_left->pGetJacobianDecompositionMatrixSigmaV();
159 auto p_inv_jac_QU_right = p_conv_acc_right->pGetJacobianDecompositionMatrixQU();
160 auto p_inv_jac_SigmaV_right = p_conv_acc_right->pGetJacobianDecompositionMatrixSigmaV();
164 if (p_inv_jac_QU_left ==
nullptr && p_inv_jac_SigmaV_left ==
nullptr) {
165 p_inv_jac_QU_left = p_conv_acc_left->pGetOldJacobianDecompositionMatrixQU();
166 p_inv_jac_SigmaV_left = p_conv_acc_left->pGetOldJacobianDecompositionMatrixSigmaV();
169 if (p_inv_jac_QU_right ==
nullptr && p_inv_jac_SigmaV_right ==
nullptr) {
170 p_inv_jac_QU_right = p_conv_acc_right->pGetOldJacobianDecompositionMatrixQU();
171 p_inv_jac_SigmaV_right = p_conv_acc_right->pGetOldJacobianDecompositionMatrixSigmaV();
175 if (p_inv_jac_QU_left !=
nullptr && p_inv_jac_SigmaV_left !=
nullptr) {
180 VectorType displacement_iteration_update = *p_uncorrected_displacement_vector - rDisplacementInputVector;
183 VectorType aux_RHS = rForceOutputVector - rIterationGuess;
186 if (p_inv_jac_QU_right !=
nullptr && p_inv_jac_SigmaV_right !=
nullptr) {
189 const bool is_extended = CalculateAuxiliaryMatrixC(*p_inv_jac_SigmaV_left, *p_inv_jac_QU_right, aux_C);
193 if (n_modes_left > n_modes_right) {
195 const auto& r_inv_jac_SigmaV_right = *p_inv_jac_SigmaV_right;
198 [&extended_inv_jac_SigmaV_right, &r_inv_jac_SigmaV_right, &n_modes_right](std::size_t Col){
199 for (std::size_t
row = 0;
row < n_modes_right; ++
row) {
200 extended_inv_jac_SigmaV_right(
row, Col) = r_inv_jac_SigmaV_right(
row, Col);
206 ApplyWoodburyMatrixIdentity(*p_inv_jac_QU_left, extended_inv_jac_SigmaV_right, aux_C, aux_RHS, rLeftCorrection);
210 const auto& r_inv_jac_QU_left = *p_inv_jac_QU_left;
213 [&extended_inv_jac_QU_left, &r_inv_jac_QU_left, &n_modes_left](std::size_t Row){
214 for (std::size_t col = 0; col < n_modes_left; ++col) {
215 extended_inv_jac_QU_left(Row, col) = r_inv_jac_QU_left(Row, col);
221 ApplyWoodburyMatrixIdentity(extended_inv_jac_QU_left, *p_inv_jac_SigmaV_right, aux_C, aux_RHS, rLeftCorrection);
226 ApplyWoodburyMatrixIdentity(*p_inv_jac_QU_left, *p_inv_jac_SigmaV_right, aux_C, aux_RHS, rLeftCorrection);
229 rLeftCorrection = aux_RHS;
232 KRATOS_ERROR <<
"Calling \'SolveInterfaceBlockQuasiNewtonLeftUpdate\' with no Jacobian decomposition available. No update should be performed." << std::endl;
247 auto p_inv_jac_QU_left = p_conv_acc_left->pGetJacobianDecompositionMatrixQU();
248 auto p_inv_jac_SigmaV_left = p_conv_acc_left->pGetJacobianDecompositionMatrixSigmaV();
249 auto p_inv_jac_QU_right = p_conv_acc_right->pGetJacobianDecompositionMatrixQU();
250 auto p_inv_jac_SigmaV_right = p_conv_acc_right->pGetJacobianDecompositionMatrixSigmaV();
254 if (p_inv_jac_QU_right ==
nullptr && p_inv_jac_SigmaV_right ==
nullptr) {
255 p_inv_jac_QU_right = p_conv_acc_right->pGetOldJacobianDecompositionMatrixQU();
256 p_inv_jac_SigmaV_right = p_conv_acc_right->pGetOldJacobianDecompositionMatrixSigmaV();
261 if (p_inv_jac_QU_left ==
nullptr && p_inv_jac_SigmaV_left ==
nullptr) {
262 p_inv_jac_QU_left = p_conv_acc_left->pGetOldJacobianDecompositionMatrixQU();
263 p_inv_jac_SigmaV_left = p_conv_acc_left->pGetOldJacobianDecompositionMatrixSigmaV();
267 if (p_inv_jac_QU_right !=
nullptr && p_inv_jac_SigmaV_right !=
nullptr) {
272 VectorType force_iteration_update = *p_uncorrected_force_vector - rForceInputVector;
275 VectorType aux_RHS = rDisplacementOutputVector - rIterationGuess;
279 if (p_inv_jac_QU_left !=
nullptr && p_inv_jac_SigmaV_left !=
nullptr) {
281 const bool is_extended = CalculateAuxiliaryMatrixC(*p_inv_jac_SigmaV_right, *p_inv_jac_QU_left, aux_C);
285 if (n_modes_right > n_modes_left) {
287 const auto& r_inv_jac_SigmaV_left = *p_inv_jac_SigmaV_left;
290 [&extended_inv_jac_SigmaV_left, &r_inv_jac_SigmaV_left, &n_modes_left](std::size_t Col){
291 for (std::size_t
row = 0;
row < n_modes_left; ++
row) {
292 extended_inv_jac_SigmaV_left(
row, Col) = r_inv_jac_SigmaV_left(
row, Col);
298 ApplyWoodburyMatrixIdentity(*p_inv_jac_QU_right, extended_inv_jac_SigmaV_left, aux_C, aux_RHS, rRightCorrection);
302 const auto &r_inv_jac_QU_right = *p_inv_jac_QU_right;
305 [&extended_inv_jac_QU_right, &r_inv_jac_QU_right, n_modes_right](std::size_t Row) {
306 for (std::size_t col = 0; col < n_modes_right; ++col) {
307 extended_inv_jac_QU_right(Row, col) = r_inv_jac_QU_right(Row, col);
312 ApplyWoodburyMatrixIdentity(extended_inv_jac_QU_right, *p_inv_jac_SigmaV_left, aux_C, aux_RHS, rRightCorrection);
318 ApplyWoodburyMatrixIdentity(*p_inv_jac_QU_right, *p_inv_jac_SigmaV_left, aux_C, aux_RHS, rRightCorrection);
321 rRightCorrection = aux_RHS;
324 KRATOS_ERROR <<
"Calling \'SolveInterfaceBlockQuasiNewtonRightUpdate\' with no Jacobian decomposition available. Update should be performed with a fixed point iteration." << std::endl;
376 const double cut_off_tol = ConvAcceleratorParameters[
"cut_off_tol"].
GetDouble();
377 const bool automatic_jacobian_modes = ConvAcceleratorParameters[
"automatic_jacobian_modes"].
GetBool();
378 const unsigned int jacobian_modes = ConvAcceleratorParameters[
"jacobian_modes"].
GetInt();
379 const bool limit_modes_to_iterations = ConvAcceleratorParameters[
"limit_modes_to_iterations"].
GetBool();
380 const unsigned int min_rand_svd_extra_modes = ConvAcceleratorParameters[
"min_rand_svd_extra_modes"].
GetInt();
386 struct make_unique_enabler :
public MVQNType {
390 const bool AutomaticJacobianModes,
391 const unsigned int JacobianModes,
392 const double CutOffTolerance,
393 const bool LimitModesToIterations,
394 const unsigned int MinRandSVDExtraModes)
398 AutomaticJacobianModes,
401 LimitModesToIterations,
402 MinRandSVDExtraModes)
407 MVQNPointerType p_convergence_accelerator = Kratos::make_unique<make_unique_enabler>(
410 automatic_jacobian_modes,
413 limit_modes_to_iterations,
414 min_rand_svd_extra_modes);
416 return p_convergence_accelerator;
429 bool CalculateAuxiliaryMatrixC(
438 auto matrix_A_B_product = [&rC, &rA, &rB, &n_row_A](std::size_t Col,
VectorType& rAuxColumnTLS){
439 TDenseSpace::GetColumn(Col, rB, rAuxColumnTLS);
440 for (std::size_t
row = 0;
row < n_row_A; ++
row) {
441 rC(
row,Col) = TDenseSpace::RowDot(
row, rA, rAuxColumnTLS);
445 bool is_extended =
false;
446 if (n_row_A != n_col_B) {
447 if (n_row_A > n_col_B) {
451 IndexPartition<std::size_t>(n_col_B).for_each(
VectorType(
n_dofs), matrix_A_B_product);
452 for (std::size_t i_extra = n_col_B; i_extra < n_row_A; ++i_extra) {
453 rC(i_extra, i_extra) = 1.0;
459 IndexPartition<std::size_t>(n_col_B).for_each(
VectorType(
n_dofs), matrix_A_B_product);
460 for (std::size_t i_extra = n_row_A; i_extra < n_col_B; ++i_extra) {
461 rC(i_extra, i_extra) = 1.0;
466 IndexPartition<std::size_t>(n_col_B).for_each(
VectorType(
n_dofs), matrix_A_B_product);
476 void ApplyWoodburyMatrixIdentity(
485 KRATOS_ERROR_IF(n_row_C != n_col_C) <<
"C matrix is not square. Woodbury matrix identity cannot be applied." << std::endl;
490 CalculateMoorePenroseInverse(rC, aux_C_inv);
497 IndexPartition<std::size_t>(n_col_A).for_each(
499 [&aux_D, &rA, &rB, &aux_C_inv, &n_row_B](std::size_t Col,
VectorType& rAuxColumnTLS)
501 TDenseSpace::GetColumn(Col, rA, rAuxColumnTLS);
502 for (std::size_t
row = 0;
row < n_row_B; ++
row) {
503 aux_D(
row,Col) = aux_C_inv(
row,Col) - TDenseSpace::RowDot(
row, rB, rAuxColumnTLS);
508 CalculateMoorePenroseInverse(aux_D, aux_D_inv);
527 void CalculateMoorePenroseInverse(
533 KRATOS_ERROR_IF_NOT(aux_size_1 == aux_size_2) <<
"Input matrix is not squared." << std::endl;
538 Parameters svd_settings(R
"({
539 "compute_thin_u" : true,
540 "compute_thin_v" : true
542 mpSmallMatrixDenseSVD->Compute(const_cast<MatrixType&
>(rInputMatrix), s_svd, u_svd, v_svd, svd_settings);
543 const std::size_t n_sing_val = s_svd.size();
546 for (std::size_t
i = 0;
i < n_sing_val; ++
i) {
547 s_inv(
i,
i) = 1.0 / s_svd(
i);
551 rMoorePenroseInverse =
ZeroMatrix(aux_size_2, aux_size_1);
554 for (std::size_t
i = 0;
i < aux_size_2; ++
i) {
555 for (std::size_t
j = 0;
j < aux_size_1; ++
j) {
556 double& r_value = rMoorePenroseInverse(
i,
j);
557 for (std::size_t
k = 0;
k < n_sing_val; ++
k) {
558 const double v_ik = v_svd(
i,
k);
559 for (std::size_t
m = 0;
m < n_sing_val; ++
m) {
560 const double ut_mj = u_svd(
j,
m);
561 const double s_inv_km = s_inv(
k,
m);
562 r_value += v_ik * s_inv_km * ut_mj;
Base class for convergence accelerators This class is intended to be the base of any convergence acce...
Definition: convergence_accelerator.h:43
Definition: dense_qr_decomposition.h:44
Definition: dense_svd_decomposition.h:45
Interface Block Newton convergence accelerator Interface Block Newton equations convergence accelerat...
Definition: ibqn_mvqn_convergence_accelerator.h:61
void SetLeftConvergenceAcceleratorPointer(MVQNPointerType pConvergenceAcceleratorLeft)
Definition: ibqn_mvqn_convergence_accelerator.h:432
VectorPointerType pGetUncorrectedForceVector()
Definition: ibqn_mvqn_convergence_accelerator.h:442
VectorPointerType pGetUncorrectedDisplacementVector()
Definition: ibqn_mvqn_convergence_accelerator.h:447
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
MVQNPointerType pGetConvergenceAcceleratorRight()
Definition: ibqn_mvqn_convergence_accelerator.h:457
MVQNPointerType pGetConvergenceAcceleratorLeft()
Definition: ibqn_mvqn_convergence_accelerator.h:452
Interface Block Newton MVQN with randomized Jacobian convergence accelerator Interface Block Newton e...
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:60
BaseType::DenseVectorType VectorType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:70
Parameters GetDefaultParameters() const override
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:131
void SolveInterfaceBlockQuasiNewtonLeftUpdate(const VectorType &rDisplacementInputVector, const VectorType &rForceOutputVector, const VectorType &rIterationGuess, VectorType &rLeftCorrection) override
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:146
IBQNMVQNRandomizedSVDConvergenceAccelerator(DenseQRPointerType pDenseQR, DenseSVDPointerType pDenseSVD, Parameters ConvAcceleratorParameters)
Construct a new IBQNMVQNRandomizedSVDConvergenceAccelerator object IBQN-MVQN with randomized SVD Jaco...
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:93
IBQNMVQNConvergenceAccelerator< TSparseSpace, TDenseSpace > BaseType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:67
DenseSingularValueDecomposition< TDenseSpace >::Pointer DenseSVDPointerType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:80
void SolveInterfaceBlockQuasiNewtonRightUpdate(const VectorType &rForceInputVector, const VectorType &rDisplacementOutputVector, const VectorType &rIterationGuess, VectorType &rRightCorrection) override
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:236
virtual ~IBQNMVQNRandomizedSVDConvergenceAccelerator()
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:120
BaseType::Pointer BaseTypePointer
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:68
BaseType::MVQNPointerType MVQNPointerType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:77
BaseType::DenseMatrixPointerType MatrixPointerType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:74
BaseType::DenseVectorPointerType VectorPointerType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:71
IBQNMVQNRandomizedSVDConvergenceAccelerator(const IBQNMVQNRandomizedSVDConvergenceAccelerator &rOther)=delete
DenseQRDecomposition< TDenseSpace >::Pointer DenseQRPointerType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:79
BaseType::DenseMatrixType MatrixType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:73
KRATOS_CLASS_POINTER_DEFINITION(IBQNMVQNRandomizedSVDConvergenceAccelerator)
MVQNRandomizedSVDConvergenceAccelerator< TSparseSpace, TDenseSpace > MVQNType
Definition: ibqn_mvqn_randomized_svd_convergence_accelerator.h:76
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-RZ acceleration scheme RandomiZed Multi-Vector Quasi-Newton (MVQN-RZ) method convergence acceler...
Definition: mvqn_randomized_svd_convergence_accelerator.h:73
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
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
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
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
TDenseSpace::VectorType DenseVectorType
Definition: convergence_accelerator.h:56
TSparseSpace::VectorType VectorType
Definition: convergence_accelerator.h:50
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
TDenseSpace::MatrixPointerType DenseMatrixPointerType
Definition: convergence_accelerator.h:59
TDenseSpace::MatrixType DenseMatrixType
Definition: convergence_accelerator.h:57
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
TDenseSpace::VectorPointerType DenseVectorPointerType
Definition: convergence_accelerator.h:60
TSparseSpace::MatrixType MatrixType
Definition: convergence_accelerator.h:51
TSpaceType::IndexType Size1(TSpaceType &dummy, typename TSpaceType::MatrixType const &rM)
Definition: add_strategies_to_python.cpp:117
TSpaceType::IndexType Size2(TSpaceType &dummy, typename TSpaceType::MatrixType const &rM)
Definition: add_strategies_to_python.cpp:123
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
void Assign(const Expression &rExpression, const IndexType EntityIndex, const IndexType EntityDataBeginIndex, TDataType &rValue, std::index_sequence< TIndex... >)
Definition: variable_expression_data_io.cpp:41
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
n_dofs
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:151
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
int m
Definition: run_marine_rain_substepping.py:8
integer i
Definition: TensorModule.f:17