26 #ifndef OOMPH_FSI_PRECONDITIONERS_HEADER 
   27 #define OOMPH_FSI_PRECONDITIONERS_HEADER 
   30 #include "../navier_stokes/navier_stokes_preconditioners.h" 
   75         new NavierStokesSchurComplementPreconditioner(problem_pt);
 
  166       const bool& allow_multiple_element_type_in_navier_stokes_mesh = 
false)
 
  173         allow_multiple_element_type_in_navier_stokes_mesh;
 
  181       const bool& allow_multiple_element_type_in_wall_mesh = 
false)
 
  188         allow_multiple_element_type_in_wall_mesh;
 
  275       std::ostringstream error_message;
 
  276       error_message << 
"Pointer to fluid mesh hasn't been set!\n";
 
  278         error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  282       std::ostringstream error_message;
 
  283       error_message << 
"Pointer to solid mesh hasn't been set!\n";
 
  285         error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  296     unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
 
  297     unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
 
  300     Vector<unsigned> dof_to_block_map(n_dof, 0);
 
  301     for (
unsigned i = n_fluid_dof; i < n_dof; i++)
 
  303       dof_to_block_map[i] = 1;
 
  307     this->block_setup(dof_to_block_map);
 
  312     Vector<unsigned> ns_dof_lookup(n_fluid_dof);
 
  313     for (
unsigned i = 0; i < n_fluid_dof; i++)
 
  315       ns_dof_lookup[i] = i;
 
  321       this, ns_dof_lookup);
 
  332     CRDoubleMatrix block_matrix_1_1;
 
  333     this->get_block(1, 1, block_matrix_1_1);
 
  336     double t_start = TimingHelpers::timer();
 
  338     double t_end = TimingHelpers::timer();
 
  339     block_matrix_1_1.clear();
 
  340     double setup_time = t_end - t_start;
 
  345       CRDoubleMatrix block_matrix_0_1 = get_block(0, 1);
 
  346       this->setup_matrix_vector_product(
 
  353       CRDoubleMatrix block_matrix_1_0 = get_block(1, 0);
 
  354       this->setup_matrix_vector_product(
 
  361       oomph_info << 
"Solid sub-preconditioner setup time [sec]: " << setup_time
 
  379       z.build(r.distribution_pt(), 0.0);
 
  391       DoubleVector temp_solid_vec;
 
  392       DoubleVector temp_fluid_vec;
 
  397       get_block_vector(1, res, temp_solid_vec);
 
  401       DoubleVector temp_solid_vec2;
 
  404       this->return_block_vector(1, temp_solid_vec2, z);
 
  410       temp_solid_vec.clear();
 
  413       DoubleVector another_temp_vec;
 
  414       this->get_block_vector(0, res, another_temp_vec);
 
  415       another_temp_vec -= temp_fluid_vec;
 
  416       this->return_block_vector(0, another_temp_vec, res);
 
  433       DoubleVector temp_solid_vec;
 
  436       get_block_vector(1, res, temp_solid_vec);
 
  441         DoubleVector temp_fluid_vec;
 
  442         get_block_vector(0, z, temp_fluid_vec);
 
  446         DoubleVector aux_vec;
 
  452         temp_solid_vec -= aux_vec;
 
  457       DoubleVector temp_solid_vec2;
 
  463       return_block_vector(1, temp_solid_vec2, z);
 
  483   template<
typename MATRIX>
 
  533       const bool& allow_multiple_element_type_in_navier_stokes_mesh = 
false)
 
  540         allow_multiple_element_type_in_navier_stokes_mesh;
 
  547       const bool& allow_multiple_element_type_in_wall_mesh = 
false)
 
  554         allow_multiple_element_type_in_wall_mesh;
 
  631   template<
typename MATRIX>
 
  633     DenseMatrix<bool>& required_blocks)
 
  636     unsigned n_dof = this->nblock_types();
 
  639     for (
unsigned i = 0; i < n_dof; i++)
 
  641       for (
unsigned j = 0; j < n_dof; j++)
 
  643         required_blocks(i, j) = 
false;
 
  648     required_blocks(0, 0) = 
true;
 
  649     required_blocks(1, 0) = 
true;
 
  650     required_blocks(0, 1) = 
true;
 
  653     required_blocks(2, 2) = 
true;
 
  656     if (Retain_solid_onto_fluid_terms)
 
  658       required_blocks(0, 2) = 
true;
 
  659       required_blocks(1, 2) = 
true;
 
  661     if (Retain_fluid_onto_solid_terms)
 
  663       required_blocks(2, 0) = 
true;
 
  664       required_blocks(2, 1) = 
true;
 
  665       if (Retain_solid_onto_fluid_terms)
 
  667         std::ostringstream error_message;
 
  668         error_message << 
"Can't retain all off-diagonal blocks!\n";
 
  669         throw OomphLibError(error_message.str(),
 
  670                             OOMPH_CURRENT_FUNCTION,
 
  671                             OOMPH_EXCEPTION_LOCATION);
 
  682   template<
typename MATRIX>
 
  686     if (Preconditioner_pt != 0)
 
  688       delete Preconditioner_pt;
 
  689       Preconditioner_pt = 0;
 
  692     if (Navier_stokes_mesh_pt == 0)
 
  694       std::ostringstream error_message;
 
  695       error_message << 
"Pointer to fluid mesh hasn't been set!\n";
 
  697         error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  699     if (Wall_mesh_pt == 0)
 
  701       std::ostringstream error_message;
 
  702       error_message << 
"Pointer to solid mesh hasn't been set!\n";
 
  704         error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  710                    Navier_stokes_mesh_pt,
 
  711                    Allow_multiple_element_type_in_navier_stokes_mesh);
 
  712     this->set_mesh(1, Wall_mesh_pt, Allow_multiple_element_type_in_wall_mesh);
 
  715     unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
 
  716     unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
 
  719     Vector<unsigned> dof_to_block_map(n_dof, 0);
 
  720     dof_to_block_map[n_fluid_dof - 1] = 1; 
 
  721     for (
unsigned i = n_fluid_dof; i < n_dof; i++) 
 
  723       dof_to_block_map[i] = 2;
 
  727     this->block_setup(dof_to_block_map);
 
  730     n_dof = this->nblock_types();
 
  733     DenseMatrix<bool> required_blocks(n_dof, n_dof);
 
  736     identify_required_blocks(required_blocks);
 
  738     VectorMatrix<BlockSelector> selected_blocks(n_dof, n_dof);
 
  740     for (
unsigned dof_i = 0; dof_i < n_dof; dof_i++)
 
  742       for (
unsigned dof_j = 0; dof_j < n_dof; dof_j++)
 
  744         selected_blocks[dof_i][dof_j].select_block(dof_i, dof_j, 
false, 0);
 
  746         if (required_blocks(dof_i, dof_j))
 
  748           selected_blocks[dof_i][dof_j].want_block();
 
  753     CRDoubleMatrix P_matrix = this->get_concatenated_block(selected_blocks);
 
  756     Preconditioner_pt = 
new SuperLUPreconditioner;
 
  757     Preconditioner_pt->setup(&P_matrix);
 
  764   template<
typename MATRIX>
 
  766     const DoubleVector& r, DoubleVector& z)
 
  769     DoubleVector temp_vec;
 
  772     this->get_block_ordered_preconditioner_vector(r, temp_vec);
 
  775     Preconditioner_pt->preconditioner_solve(temp_vec, temp_vec);
 
  778     this->return_block_ordered_preconditioner_vector(temp_vec, z);
 
//////////////////////////////////////////////////////////////////////////// ////////////////////////...
void set_solid_preconditioner_pt(Preconditioner *solid_preconditioner_pt)
Broken assignment operator.
void use_block_triangular_version_with_solid_on_fluid()
Switch to block-triangular preconditioner in which action of solid dofs onto fluid equations is retai...
Mesh * Navier_stokes_mesh_pt
Pointer to the navier stokes mesh.
void enable_doc_time()
Enable documentation of time.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
bool Doc_time
Set Doc_time to true for outputting results of timings.
bool Allow_multiple_element_type_in_navier_stokes_mesh
Flag to indicate if there are multiple element types in the Navier-Stokes mesh.
MatrixVectorProduct * Matrix_vector_product_0_1_pt
Pointer to fluid/solid interaction matrix.
FSIPreconditioner(const FSIPreconditioner &)=delete
Broken copy constructor.
void set_navier_stokes_mesh(Mesh *mesh_pt, const bool &allow_multiple_element_type_in_navier_stokes_mesh=false)
Setter function for the mesh containing the block-preconditionable Navier-Stokes elements....
void set_wall_mesh(Mesh *mesh_pt, const bool &allow_multiple_element_type_in_wall_mesh=false)
Setter function for the mesh containing the block-preconditionable FSI solid elements....
~FSIPreconditioner()
Destructor: Clean up.
bool Allow_multiple_element_type_in_wall_mesh
MatrixVectorProduct * Matrix_vector_product_1_0_pt
Pointer to solid/fluid solid interaction matrix.
NavierStokesSchurComplementPreconditioner * navier_stokes_preconditioner_pt() const
Access function to the Navier Stokes preconditioner (inexact solver)
void use_block_diagonal_version()
Switch to block-diagonal preconditioner.
void disable_doc_time()
Disable documentation of time.
Preconditioner * Solid_preconditioner_pt
Pointer to the solid preconditioner (inexact solver)
Preconditioner * solid_preconditioner_pt() const
Read-only access to solid preconditoner (use set_... to set it)
bool Retain_solid_onto_fluid_terms
Boolean flag used to indicate that the solid onto fluid interaction terms are to be retained.
void use_block_triangular_version_with_fluid_on_solid()
Switch to block-triangular preconditioner in which action of fluid dofs onto solid equations is retai...
bool Preconditioner_has_been_setup
Boolean indicating the preconditioner has been set up.
bool Retain_fluid_onto_solid_terms
Boolean flag used to indicate that the fluid onto solid interaction terms are to be retained.
void setup()
Setup the preconditioner.
NavierStokesSchurComplementPreconditioner * Navier_stokes_preconditioner_pt
Pointer the Navier Stokes preconditioner (inexact solver)
Mesh * Wall_mesh_pt
pointer to the solid mesh
FSIPreconditioner(Problem *problem_pt)
Constructor: By default use block triangular form with retained fluid on solid terms....
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
bool Retain_fluid_onto_solid_terms
Boolean flag used to indicate that the fluid onto solid interaction terms are to be retained.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
void set_wall_mesh(Mesh *mesh_pt, const bool &allow_multiple_element_type_in_wall_mesh=false)
Setter function for the mesh containing the block-preconditionable FSI solid elements.
Mesh * Wall_mesh_pt
pointer to the solid mesh
SimpleFSIPreconditioner()
Constructor.
bool Retain_solid_onto_fluid_terms
Boolean flag used to indicate that the solid onto fluid interaction terms are to be retained.
bool Allow_multiple_element_type_in_wall_mesh
Flag for multiple element types in the Wall mesh.
~SimpleFSIPreconditioner()
Destructor: Clean up.
void use_block_triangular_version_with_solid_on_fluid()
Switch to block-triangular preconditioner in which action of solid dofs onto fluid equations is retai...
SimpleFSIPreconditioner(const SimpleFSIPreconditioner &)=delete
Broken copy constructor.
Mesh * Navier_stokes_mesh_pt
Pointer to the navier stokes mesh.
bool Allow_multiple_element_type_in_navier_stokes_mesh
Flag for multiple element types in the Navier-Stokes mesh.
void use_block_diagonal_version()
Switch to block-diagonal preconditioner.
Preconditioner * Preconditioner_pt
Preconditioner (inexact solver)
void setup()
Setup the preconditioner.
void set_navier_stokes_mesh(Mesh *mesh_pt, const bool &allow_multiple_element_type_in_navier_stokes_mesh=false)
Broken assignment operator.
virtual void identify_required_blocks(DenseMatrix< bool > &required_blocks)
Identify the required blocks: Here we only need the momentum, gradient and divergence blocks of the 2...
void use_block_triangular_version_with_fluid_on_solid()
Switch to block-triangular preconditioner in which action of fluid dofs onto solid equations is retai...