39 namespace Pseudo_Elastic_Preconditioner_Subsidiary_Operator_Helper
41 #ifdef OOMPH_HAS_HYPRE 64 return hypre_preconditioner_pt;
77 #ifdef OOMPH_HAS_TRILINOS 85 return trilinos_prec_pt;
104 prec_pt->solver_pt()->disable_doc_time();
124 this->clean_up_memory();
128 if (Elastic_mesh_pt==0)
130 std::ostringstream error_message;
131 error_message <<
"The elastic mesh must be set.";
133 OOMPH_CURRENT_FUNCTION,
134 OOMPH_EXCEPTION_LOCATION);
137 if (Lagrange_multiplier_mesh_pt==0)
139 std::ostringstream error_message;
140 error_message <<
"The Lagrange multiplier mesh must be set.";
142 OOMPH_CURRENT_FUNCTION,
143 OOMPH_EXCEPTION_LOCATION);
149 this->set_mesh(0,Elastic_mesh_pt);
150 this->set_mesh(1,Lagrange_multiplier_mesh_pt);
153 unsigned n_solid_dof_types = 0;
154 unsigned n_dof_types = 0;
156 if (this->is_master_block_preconditioner())
159 n_solid_dof_types = this->ndof_types_in_mesh(0);
162 n_dof_types = n_solid_dof_types
163 + this->ndof_types_in_mesh(1);
167 n_dof_types = this->ndof_types();
168 n_solid_dof_types = n_dof_types - (n_dof_types/3);
171 if (n_dof_types%3 != 0)
173 std::ostringstream error_message;
174 error_message <<
"This preconditioner requires DIM*3 types of DOF";
176 OOMPH_CURRENT_FUNCTION,
177 OOMPH_EXCEPTION_LOCATION);
190 std::ostringstream error_message;
191 error_message <<
"FSIPreconditioner only works with" 192 <<
" CRDoubleMatrix matrices" << std::endl;
194 OOMPH_CURRENT_FUNCTION,
195 OOMPH_EXCEPTION_LOCATION);
215 for (
unsigned dim_i = 0; dim_i <
Dim; dim_i++)
218 dof_list_for_block_setup[dim_i] = 2*dim_i;
221 dof_list_for_block_setup[dim_i +
Dim] = 2*dim_i + 1;
224 dof_list_for_block_setup[dim_i + 2*
Dim] = 2*Dim + dim_i;
235 this->block_setup(dof_list_for_block_setup);
253 for (
unsigned dim_i = 0; dim_i <
Dim; dim_i++)
256 dof_list_for_subsidiary_prec[2*dim_i] = dim_i;
259 dof_list_for_subsidiary_prec[2*dim_i+1] = dim_i +
Dim;
264 n_solid_dof_types,0);
266 for (
unsigned row_i = 0; row_i < n_solid_dof_types; row_i++)
268 for (
unsigned col_i = 0; col_i < n_solid_dof_types; col_i++)
271 this->get_block(row_i,col_i,*solid_matrix_pt(row_i,col_i));
276 if (Use_inf_norm_of_s_scaling)
286 for(
unsigned d = 0; d <
Dim; d++)
289 unsigned block_i = 2*d+1;
292 double* s_values = solid_matrix_pt(block_i,block_i)->value();
293 int* s_column_index = solid_matrix_pt(block_i,block_i)->column_index();
294 int* s_row_start = solid_matrix_pt(block_i,block_i)->row_start();
295 int s_nrow_local = solid_matrix_pt(block_i,block_i)->nrow_local();
296 int s_first_row = solid_matrix_pt(block_i,block_i)->first_row();
299 for (
int i = 0;
i < s_nrow_local;
i++)
302 for (
int j = s_row_start[
i];
303 j < s_row_start[
i+1] && !found; j++)
305 if (s_column_index[j] ==
i + s_first_row)
307 s_values[j] += Scaling;
315 std::ostringstream error_message;
316 error_message <<
"The diagonal entry for the constained block(" 317 << block_i<<
","<<block_i<<
")\n" 318 <<
"on local row " <<
i <<
" does not exist." 321 OOMPH_CURRENT_FUNCTION,
322 OOMPH_EXCEPTION_LOCATION);
330 if (E_preconditioner_type == Exact_block_preconditioner)
342 for (
unsigned i = 0;
i < n_solid_dof_types;
i++)
344 doftype_to_doftype_map[
i][0] =
i;
348 this,dof_list_for_subsidiary_prec,doftype_to_doftype_map);
350 if (Elastic_subsidiary_preconditioner_function_pt != 0)
353 set_subsidiary_preconditioner_function
354 (Elastic_subsidiary_preconditioner_function_pt);
358 for (
unsigned d = 0; d <
Dim; d++)
361 unsigned block_i = 2*d+1;
364 unsigned dof_block_i = Dim + d;
365 this->set_replacement_dof_block(dof_block_i,dof_block_i,
366 solid_matrix_pt(block_i,block_i));
369 s_prec_pt->Preconditioner::setup(matrix_pt());
370 Elastic_preconditioner_pt = s_prec_pt;
378 switch (E_preconditioner_type)
380 case Block_diagonal_preconditioner:
385 case Block_upper_triangular_preconditioner:
391 s_prec_pt = block_triangular_prec_pt;
394 case Block_lower_triangular_preconditioner:
400 s_prec_pt = block_triangular_prec_pt;
405 std::ostringstream error_msg;
406 error_msg <<
"There is no such block based preconditioner.\n" 407 <<
"Candidates are:\n" 408 <<
"PseudoElasticPreconditioner::Block_diagonal_preconditioner\n" 409 <<
"PseudoElasticPreconditioner::Block_upper_triangular_preconditioner\n" 410 <<
"PseudoElasticPreconditioner::Block_lower_triangular_preconditioner\n";
412 OOMPH_CURRENT_FUNCTION,
413 OOMPH_EXCEPTION_LOCATION);
428 unsigned tmp_index = 0;
429 for (
unsigned d = 0; d <
Dim; d++)
431 s_prec_dof_to_block_map[d] = d;
432 doftype_to_doftype_map[d][0] = tmp_index++;
433 doftype_to_doftype_map[d][1] = tmp_index++;
437 (
this,dof_list_for_subsidiary_prec,doftype_to_doftype_map);
439 if(Elastic_subsidiary_preconditioner_function_pt != 0)
442 (Elastic_subsidiary_preconditioner_function_pt);
446 for (
unsigned d = 0; d <
Dim; d++)
449 unsigned block_i = 2*d+1;
452 unsigned dof_block_i = Dim + d;
453 this->set_replacement_dof_block(dof_block_i,dof_block_i,
454 solid_matrix_pt(block_i,block_i));
458 s_prec_pt->Preconditioner::setup(matrix_pt());
460 Elastic_preconditioner_pt = s_prec_pt;
464 for (
unsigned row_i = 0; row_i < n_solid_dof_types; row_i++)
466 for (
unsigned col_i = 0; col_i < n_solid_dof_types; col_i++)
468 delete solid_matrix_pt(row_i,col_i); solid_matrix_pt(row_i,col_i) = 0;
473 Lagrange_multiplier_preconditioner_pt.
resize(Dim);
474 for (
unsigned d = 0; d <
Dim; d++)
477 this->get_block(2*Dim+d,2*d+1,*b_pt);
481 if (Lagrange_multiplier_subsidiary_preconditioner_function_pt != 0)
483 Lagrange_multiplier_preconditioner_pt[d] =
484 (*Lagrange_multiplier_subsidiary_preconditioner_function_pt)();
493 Lagrange_multiplier_preconditioner_pt[d]->
setup(b_pt);
494 delete b_pt; b_pt = 0;
506 Elastic_preconditioner_pt->preconditioner_solve(r,z);
517 for (
unsigned d = 0; d <
Dim; d++)
520 this->get_block_vector(Dim*2+d,r,x);
522 Lagrange_multiplier_preconditioner_pt[d]->preconditioner_solve(x,y);
523 Lagrange_multiplier_preconditioner_pt[d]->preconditioner_solve(y,x);
526 for (
unsigned i = 0;
i < nrow_local;
i++)
528 x_pt[
i] = x_pt[
i] * Scaling;
530 this->return_block_vector(Dim*2+d,x,z);
540 this->clear_block_preconditioner_base();
543 delete Elastic_preconditioner_pt; Elastic_preconditioner_pt = 0;
546 unsigned sz = Lagrange_multiplier_preconditioner_pt.size();
547 for (
unsigned i = 0;
i < sz;
i++)
549 delete Lagrange_multiplier_preconditioner_pt[
i];
550 Lagrange_multiplier_preconditioner_pt[
i] = 0;
564 this->clean_up_memory();
568 if (Elastic_mesh_pt==0)
570 std::ostringstream error_message;
571 error_message <<
"The elastic mesh must be set.";
573 OOMPH_CURRENT_FUNCTION,
574 OOMPH_EXCEPTION_LOCATION);
577 if (Lagrange_multiplier_mesh_pt==0)
579 std::ostringstream error_message;
580 error_message <<
"The Lagrange multiplier mesh must be set.";
582 OOMPH_CURRENT_FUNCTION,
583 OOMPH_EXCEPTION_LOCATION);
588 unsigned n_solid_dof_types = 0;
589 unsigned n_dof_types = 0;
590 this->set_mesh(0,Elastic_mesh_pt);
591 this->set_mesh(1,Lagrange_multiplier_mesh_pt);
592 if (this->is_master_block_preconditioner())
596 n_solid_dof_types = this->ndof_types_in_mesh(0);
599 n_dof_types = n_solid_dof_types
600 + this->ndof_types_in_mesh(1);
604 n_dof_types = this->ndof_types();
605 n_solid_dof_types = n_dof_types - (n_dof_types/3);
608 if (n_dof_types%3 != 0)
610 std::ostringstream error_message;
611 error_message <<
"This preconditioner requires DIM*3 types of DOF";
613 OOMPH_CURRENT_FUNCTION,
614 OOMPH_EXCEPTION_LOCATION);
627 std::ostringstream error_message;
628 error_message <<
"FSIPreconditioner only works with" 629 <<
" CRDoubleMatrix matrices" << std::endl;
631 OOMPH_CURRENT_FUNCTION,
632 OOMPH_EXCEPTION_LOCATION);
642 for (
unsigned i = 0;
i < n_solid_dof_types;
i++)
644 dof_list_for_subsidiary_prec[
i] =
i;
648 if (Use_inf_norm_of_s_scaling)
651 for (
unsigned i = 0;
i < n_solid_dof_types;
i++)
663 delete helper_pt; helper_pt = 0;
673 if (E_preconditioner_type == Exact_block_preconditioner)
678 for (
unsigned i = 0;
i < n_solid_dof_types;
i++)
683 if (Elastic_subsidiary_preconditioner_function_pt != 0)
686 set_subsidiary_preconditioner_function
687 (Elastic_subsidiary_preconditioner_function_pt);
689 s_prec_pt->
scaling() = Scaling;
690 s_prec_pt->Preconditioner::setup(matrix_pt());
691 Elastic_preconditioner_pt = s_prec_pt;
702 for (
unsigned i = 0;
i < n_solid_dof_types;
i++)
709 if (Elastic_subsidiary_preconditioner_function_pt != 0)
712 set_subsidiary_preconditioner_function
713 (Elastic_subsidiary_preconditioner_function_pt);
717 s_prec_pt->
scaling() = Scaling;
720 switch (E_preconditioner_type)
722 case Block_diagonal_preconditioner:
725 case Block_upper_triangular_preconditioner:
728 case Block_lower_triangular_preconditioner:
736 s_prec_pt->Preconditioner::setup(matrix_pt());
737 Elastic_preconditioner_pt = s_prec_pt;
742 Lagrange_multiplier_preconditioner_pt.resize(Dim);
743 for (
unsigned d = 0; d <
Dim; d++)
746 this->get_block(2*Dim+d,Dim+d,*b_pt);
750 if (Lagrange_multiplier_subsidiary_preconditioner_function_pt != 0)
752 Lagrange_multiplier_preconditioner_pt[d] =
753 (*Lagrange_multiplier_subsidiary_preconditioner_function_pt)();
763 Lagrange_multiplier_preconditioner_pt[d]->
setup(b_pt);
764 delete b_pt; b_pt = 0;
776 Elastic_preconditioner_pt->preconditioner_solve(r,z);
788 for (
unsigned d = 0; d <
Dim; d++)
791 this->get_block_vector(Dim*2+d,r,x);
793 Lagrange_multiplier_preconditioner_pt[d]->preconditioner_solve(x,y);
794 Lagrange_multiplier_preconditioner_pt[d]->preconditioner_solve(y,x);
797 for (
unsigned i = 0;
i < nrow_local;
i++)
799 x_pt[
i] = x_pt[
i] * Scaling;
801 this->return_block_vector(Dim*2+d,x,z);
811 this->clear_block_preconditioner_base();
814 delete Elastic_preconditioner_pt;
815 Elastic_preconditioner_pt = 0;
818 unsigned sz = Lagrange_multiplier_preconditioner_pt.size();
819 for (
unsigned i = 0;
i < sz;
i++)
821 delete Lagrange_multiplier_preconditioner_pt[
i];
822 Lagrange_multiplier_preconditioner_pt[
i] = 0;
841 this->clean_up_memory();
845 if (this->ndof_types()%2 != 0)
847 std::ostringstream error_message;
849 <<
"This SUBSIDIARY preconditioner requires an even number of " 853 OOMPH_CURRENT_FUNCTION,
854 OOMPH_EXCEPTION_LOCATION);
859 unsigned ndof_types = this->ndof_types();
861 for (
unsigned i = ndof_types/2;
i < ndof_types;
i++)
863 dof_to_block_map[
i] = 1;
866 this->block_setup(dof_to_block_map);
870 this->get_block(1,1,*s11_pt);
873 double* s11_values = s11_pt->
value();
875 int* s11_row_start = s11_pt->
row_start();
878 for (
int i = 0;
i < s11_nrow_local;
i++)
881 for (
int j = s11_row_start[
i];
882 j < s11_row_start[
i+1] && !found; j++)
884 if (s11_column_index[j] ==
i + s11_first_row)
886 s11_values[j] += Scaling;
893 const bool want_block =
true;
894 for (
unsigned b_i = 0; b_i < 2; b_i++)
896 for (
unsigned b_j = 0; b_j < 2; b_j++)
898 required_blocks[b_i][b_j].select_block(b_i,b_j,want_block);
902 required_blocks[1][1].set_replacement_block_pt(s11_pt);
904 CRDoubleMatrix s_prec_pt = this->get_concatenated_block(required_blocks);
906 delete s11_pt; s11_pt = 0;
909 if (Subsidiary_preconditioner_function_pt != 0)
911 Preconditioner_pt = (*Subsidiary_preconditioner_function_pt)();
917 Preconditioner_pt->
setup(&s_prec_pt);
927 this->get_block_ordered_preconditioner_vector(r,x);
929 Preconditioner_pt->preconditioner_solve(x,y);
930 this->return_block_ordered_preconditioner_vector(y,z);
948 unsigned n_block = Diagonal_block_preconditioner_pt.size();
951 for (
unsigned i = 0 ;
i < n_block;
i++)
953 delete Diagonal_block_preconditioner_pt[
i];
954 Diagonal_block_preconditioner_pt[
i] = 0;
957 for (
unsigned j =
i+1; j < n_block; j++)
959 delete Off_diagonal_matrix_vector_products(
i,j);
960 Off_diagonal_matrix_vector_products(
i,j) = 0;
963 else if (Method == 2)
965 for (
unsigned j = 0; j <
i; j++)
967 delete Off_diagonal_matrix_vector_products(i,j);
968 Off_diagonal_matrix_vector_products(i,j) = 0;
974 this->clear_block_preconditioner_base();
984 this->clean_up_memory();
987 unsigned n_dof_types = this->ndof_types();
991 if (n_dof_types%2 != 0)
993 std::ostringstream error_message;
994 error_message <<
"This preconditioner requires DIM*3 types of DOF";
996 OOMPH_CURRENT_FUNCTION,
997 OOMPH_EXCEPTION_LOCATION);
1002 unsigned dim = n_dof_types/2;
1006 for (
unsigned d = 0; d < dim; d++)
1008 dof_to_block_map[d] = d;
1009 dof_to_block_map[d+dim] = d;
1013 this->block_setup(dof_to_block_map);
1016 Diagonal_block_preconditioner_pt.resize(dim);
1019 Off_diagonal_matrix_vector_products.resize(dim,dim,0);
1022 for (
unsigned d = 0; d < dim; d++)
1028 Diagonal_block_preconditioner_pt[d] =
new 1030 Diagonal_block_preconditioner_pt[d]->
1031 turn_into_subsidiary_block_preconditioner(
this,dof_list);
1032 if (Subsidiary_preconditioner_function_pt != 0)
1034 Diagonal_block_preconditioner_pt[d]->
1035 set_subsidiary_preconditioner_function
1036 (Subsidiary_preconditioner_function_pt);
1038 Diagonal_block_preconditioner_pt[d]->scaling() = Scaling;
1040 Diagonal_block_preconditioner_pt[d]->
1048 if (Method == 1 || Method == 2)
1057 for (
unsigned j = l; j < u; j++)
1060 this->get_block(d,j,*block_matrix_pt);
1061 Off_diagonal_matrix_vector_products(d,j)
1064 this->setup_matrix_vector_product(Off_diagonal_matrix_vector_products(d,j),
1067 delete block_matrix_pt; block_matrix_pt = 0;
1085 n_block = this->nblock_types();
1088 int start = n_block-1;
1112 for (
int i = start;
i != end;
i+=step)
1116 Diagonal_block_preconditioner_pt[
i]->preconditioner_solve(r,z);
1124 for (
int j =
i + step; j !=end; j+=step)
1127 this->get_block_vector(
i,z,x);
1129 Off_diagonal_matrix_vector_products(j,
i)->multiply(x,y);
1131 this->get_block_vector(j,r,x);
1133 this->return_block_vector(j,x,r);
int * column_index()
Access to C-style column index array.
void lagrange_multiplier_preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the lagrange multiplier subsidiary preconditioner.
An interface to the Trilinos ML class - provides a function to construct a serial ML object...
unsigned & amg_simple_smoother()
Access function to AMG_simple_smoother flag.
A helper class for PseudoElasticPreconditioner. Note that this is NOT actually a functioning precondi...
double s_inf_norm()
Broken assignment operator.
void clear()
wipes the DoubleVector
double inf_norm(const DenseMatrix< CRDoubleMatrix *> &matrix_pt)
Compute infinity (maximum) norm of sub blocks as if it was one matrix.
double & amg_damping()
Access function to AMG_damping parameter.
double * values_pt()
access function to the underlying values
void set_subsidiary_preconditioner_function(SubsidiaryPreconditionerFctPt sub_prec_fn)
access function to set the subsidiary preconditioner function.
void clean_up_memory()
Clears the memory.
void elastic_preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the elastic subsidiary preconditioner.
void lagrange_multiplier_preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the lagrange multiplier subsidiary preconditioner.
unsigned & amg_coarsening()
Access function to AMG_coarsening flag.
void setup()
Broken assignment operator.
static OomphCommunicator * communicator_pt()
access to the global oomph-lib communicator
void lower_triangular()
Use as a lower triangular preconditioner.
An interface to the Trilinos AztecOO classes allowing it to be used as an Oomph-lib LinearSolver...
void set_amg_iterations(const unsigned &amg_iterations)
Function to set the number of times to apply BoomerAMG.
double * value()
Access to C-style value array.
void setup()
Function to set up a preconditioner for the linear system defined by matrix_pt. This function must be...
unsigned Dim
Dimension of zeta tuples (set by get_dim_helper) – needed because we store the scalar coordinates in...
Matrix-based diagonal preconditioner.
void setup()
Broken assignment operator.
void amg_using_simple_smoothing()
Function to select use of 'simple' AMG smoothers as controlled by the flag AMG_simple_smoother.
void elastic_preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the elastic subsidiary preconditioner.
Preconditioner * get_elastic_preconditioner_hypre()
AMG w/ GS smoothing for the augmented elastic subsidiary linear systems.
Preconditioner * get_elastic_preconditioner()
AMG w/ GS smoothing for the augmented elastic subsidiary linear systems – calls Hypre version to sta...
void start(const unsigned &i)
(Re-)start i-th timer
A preconditioner for performing inner iteration preconditioner solves. The template argument SOLVER s...
double & scaling()
Specify the scaling. Default is 1.0 Must be set before setup(...).
void preconditioner_solve(const DoubleVector &res, DoubleVector &z)
Apply preconditioner to r.
unsigned first_row() const
access function for the first row on this processor
unsigned & hypre_method()
Access function to Hypre_method flag – specified via enumeration.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the preconditioner.
void setup()
Broken assignment operator.
An interface to allow SuperLU to be used as an (exact) Preconditioner.
void use_lower_triangular_approximation()
Use as a lower triangular preconditioner.
Preconditioner base class. Gives an interface to call all other preconditioners through and stores th...
void clean_up_memory()
Broken assignment operator.
double & scaling()
Specify the scaling. Default is 1.0 Must be called before setup(...).
Block diagonal preconditioner. By default SuperLU is used to solve the subsidiary systems...
void upper_triangular()
Use as an upper triangular preconditioner.
void use_upper_triangular_approximation()
Use as an upper triangular preconditioner.
void turn_into_subsidiary_block_preconditioner(BlockPreconditioner< MATRIX > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse)
Function to turn this preconditioner into a subsidiary preconditioner that operates within a bigger "...
Preconditioner * get_elastic_preconditioner_trilinos_ml()
TrilinosML smoothing for the augmented elastic subsidiary linear systems.
void setup()
Setup the preconditioner.
Matrix vector product helper class - primarily a wrapper to Trilinos's Epetra matrix vector product m...
virtual void setup()=0
Setup the preconditioner. Pure virtual generic interface function.
unsigned nrow_local() const
access function for the num of local rows on this processor.
Class for dense matrices, storing all the values of the matrix as a pointer to a pointer with assorte...
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
void set_dof_to_block_map(Vector< unsigned > &dof_to_block_map)
Specify a DOF to block map.
General purpose block triangular preconditioner By default this is Upper triangular. By default SuperLUPreconditioner (or SuperLUDistPreconditioner) is used to solve the subsidiary systems, but other preconditioners can be used by setting them using passing a pointer to a function of type SubsidiaryPreconditionerFctPt to the method subsidiary_preconditioner_function_pt().
int * row_start()
Access to C-style row_start array.
A class for compressed row matrices. This is a distributable object.
Preconditioner * get_lagrange_multiplier_preconditioner()
CG with diagonal preconditioner for the lagrange multiplier subsidiary linear systems.
void clean_up_memory()
Clears the memory.
void use_block_diagonal_approximation()
use as a block diagonal preconditioner
void resize(const unsigned long &n)