30 #ifndef OOMPH_FSI_PRECONDITIONERS_HEADER    31 #define OOMPH_FSI_PRECONDITIONERS_HEADER    35 #include "../navier_stokes/navier_stokes_preconditioners.h"    84     new NavierStokesSchurComplementPreconditioner(problem_pt);
   119    BrokenCopy::broken_copy(
"FSIPreconditioner");
   179     const bool& allow_multiple_element_type_in_navier_stokes_mesh = 
false) 
   186      = allow_multiple_element_type_in_navier_stokes_mesh;
   193    Mesh* mesh_pt, 
const bool& allow_multiple_element_type_in_wall_mesh = 
false)
   200      = allow_multiple_element_type_in_wall_mesh;
   211  NavierStokesSchurComplementPreconditioner* 
   286     std::ostringstream error_message;
   287     error_message << 
"Pointer to fluid mesh hasn't been set!\n";
   288     throw OomphLibError(error_message.str(),
   289         OOMPH_CURRENT_FUNCTION,
   290         OOMPH_EXCEPTION_LOCATION);
   294     std::ostringstream error_message;
   295     error_message << 
"Pointer to solid mesh hasn't been set!\n";
   296     throw OomphLibError(error_message.str(),
   297         OOMPH_CURRENT_FUNCTION,
   298         OOMPH_EXCEPTION_LOCATION);
   308   unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
   309   unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
   312   Vector<unsigned> dof_to_block_map(n_dof,0);
   313   for (
unsigned i = n_fluid_dof; i < n_dof; i++)
   315     dof_to_block_map[i] = 1;
   319   this->block_setup(dof_to_block_map);
   324   Vector<unsigned> ns_dof_lookup(n_fluid_dof);
   325   for (
unsigned i = 0; i < n_fluid_dof; i++)
   327     ns_dof_lookup[i] = i;
   333     turn_into_subsidiary_block_preconditioner(
this,ns_dof_lookup);
   344   CRDoubleMatrix block_matrix_1_1;
   345   this->get_block(1,1,block_matrix_1_1);
   348   double t_start = TimingHelpers::timer();
   350   double t_end = TimingHelpers::timer();
   351   block_matrix_1_1.clear();
   352   double setup_time= t_end-t_start;
   357     CRDoubleMatrix block_matrix_0_1 = get_block(0,1);
   359         &block_matrix_0_1,1);
   365     CRDoubleMatrix block_matrix_1_0 = get_block(1,0);
   367         &block_matrix_1_0,0);
   373     oomph_info << 
"Solid sub-preconditioner setup time [sec]: "   374       << setup_time << 
"\n";
   391     z.build(r.distribution_pt(),0.0);
   403    DoubleVector temp_solid_vec;
   404    DoubleVector temp_fluid_vec;
   409    get_block_vector(1,res,temp_solid_vec);
   413    DoubleVector temp_solid_vec2;
   416    this->return_block_vector(1,temp_solid_vec2,z);
   422    temp_solid_vec.clear();
   425    DoubleVector another_temp_vec;
   426    this->get_block_vector(0,res,another_temp_vec);
   427    another_temp_vec -= temp_fluid_vec;
   428    this->return_block_vector(0,another_temp_vec,res);
   446    DoubleVector temp_solid_vec;
   449    get_block_vector(1,res,temp_solid_vec);
   454      DoubleVector temp_fluid_vec;
   455      get_block_vector(0,z,temp_fluid_vec);
   459      DoubleVector aux_vec;
   465      temp_solid_vec-=aux_vec;
   470    DoubleVector temp_solid_vec2;
   476    return_block_vector(1,temp_solid_vec2,z);   
   498 template<
typename MATRIX>
   517    Preconditioner_pt = 0;
   531    if (Preconditioner_pt != 0)
   533      delete Preconditioner_pt;
   534      Preconditioner_pt = 0;
   542    BrokenCopy::broken_copy(
"SimpleFSIPreconditioner");
   556     const bool& allow_multiple_element_type_in_navier_stokes_mesh = 
false) 
   563      = allow_multiple_element_type_in_navier_stokes_mesh;
   570     const bool& allow_multiple_element_type_in_wall_mesh = 
false) 
   577      = allow_multiple_element_type_in_wall_mesh;
   627  virtual void identify_required_blocks(DenseMatrix<bool>& required_blocks);
   657 template<
typename MATRIX>
   659   DenseMatrix<bool>& required_blocks)
   663  unsigned n_dof = this->nblock_types();
   666  for (
unsigned i=0;i<n_dof;i++)
   668    for (
unsigned j=0;j<n_dof;j++)
   670      required_blocks(i,j)=
false;
   675  required_blocks(0,0) = 
true;
   676  required_blocks(1,0) = 
true;
   677  required_blocks(0,1) = 
true;
   680  required_blocks(2,2) = 
true;
   685    required_blocks(0,2)=
true;
   686    required_blocks(1,2)=
true;
   690    required_blocks(2,0)=
true;
   691    required_blocks(2,1)=
true;
   694      std::ostringstream error_message;
   695      error_message << 
"Can't retain all off-diagonal blocks!\n";
   696      throw OomphLibError(error_message.str(),
   697                          OOMPH_CURRENT_FUNCTION,
   698                          OOMPH_EXCEPTION_LOCATION);
   710  template<
typename MATRIX>
   716   if (Preconditioner_pt != 0)
   718     delete Preconditioner_pt;
   719     Preconditioner_pt = 0;
   724     std::ostringstream error_message;
   725     error_message << 
"Pointer to fluid mesh hasn't been set!\n";
   726     throw OomphLibError(error_message.str(),
   727                         OOMPH_CURRENT_FUNCTION,
   728                         OOMPH_EXCEPTION_LOCATION);
   732     std::ostringstream error_message;
   733     error_message << 
"Pointer to solid mesh hasn't been set!\n";
   734     throw OomphLibError(error_message.str(),
   735                         OOMPH_CURRENT_FUNCTION,
   736                         OOMPH_EXCEPTION_LOCATION);
   746   unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
   747   unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
   750   Vector<unsigned> dof_to_block_map(n_dof,0);
   751   dof_to_block_map[n_fluid_dof-1]=1; 
   752   for (
unsigned i = n_fluid_dof; i < n_dof; i++) 
   754     dof_to_block_map[i] = 2;
   758   this->block_setup(dof_to_block_map);
   761   n_dof = this->nblock_types();
   764   DenseMatrix<bool> required_blocks(n_dof,n_dof);
   767   identify_required_blocks(required_blocks);
   769   VectorMatrix<BlockSelector> selected_blocks(n_dof,n_dof);
   771   for (
unsigned dof_i = 0; dof_i < n_dof; dof_i++) 
   773     for (
unsigned dof_j = 0; dof_j < n_dof; dof_j++) 
   775       selected_blocks[dof_i][dof_j].select_block(dof_i,dof_j,
false,0);
   777       if(required_blocks(dof_i,dof_j))
   779         selected_blocks[dof_i][dof_j].want_block();
   784   CRDoubleMatrix P_matrix = this->get_concatenated_block(selected_blocks);
   787   Preconditioner_pt = 
new SuperLUPreconditioner;
   788   Preconditioner_pt->setup(&P_matrix);
   795 template<
typename MATRIX>
   800  DoubleVector temp_vec;
   803  this->get_block_ordered_preconditioner_vector(r,temp_vec);
   806  Preconditioner_pt->preconditioner_solve(temp_vec,temp_vec);
   809  this->return_block_ordered_preconditioner_vector(temp_vec,z);
 Mesh * Navier_stokes_mesh_pt
Pointer to the navier stokes mesh. 
 
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...
 
Mesh * Wall_mesh_pt
pointer to the solid mesh 
 
bool Allow_multiple_element_type_in_navier_stokes_mesh
 
Preconditioner * Preconditioner_pt
Preconditioner (inexact solver) 
 
NavierStokesSchurComplementPreconditioner * Navier_stokes_preconditioner_pt
Pointer the Navier Stokes preconditioner (inexact solver) 
 
void disable_doc_time()
Disable documentation of time. 
 
Preconditioner * solid_preconditioner_pt() const
Read-only access to solid preconditoner (use set_... to set it) 
 
FSI preconditioner. This extracts upper/lower triangular blocks in the 3x3 overall block matrix struc...
 
bool Allow_multiple_element_type_in_navier_stokes_mesh
Flag for multiple element types in the Navier-Stokes mesh. 
 
void enable_doc_time()
Enable documentation of time. 
 
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. The optional argument indicates if there are more than one type of elements in the same mesh. 
 
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...
 
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 preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r. 
 
bool Allow_multiple_element_type_in_wall_mesh
Flag for multiple element types in the Wall mesh. 
 
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_solid_on_fluid()
Switch to block-triangular preconditioner in which action of solid dofs onto fluid equations is retai...
 
Preconditioner * Solid_preconditioner_pt
Pointer to the solid preconditioner (inexact solver) 
 
Mesh * Wall_mesh_pt
pointer to the solid mesh 
 
MatrixVectorProduct * Matrix_vector_product_0_1_pt
Pointer to fluid/solid interaction matrix. 
 
FSI preconditioner. This extracts upper/lower triangular blocks in the 3x3 overall block matrix struc...
 
bool Retain_solid_onto_fluid_terms
Boolean flag used to indicate that the solid onto fluid interaction terms are to be retained...
 
FSIPreconditioner(const FSIPreconditioner &)
Broken copy constructor. 
 
SimpleFSIPreconditioner(const SimpleFSIPreconditioner &)
Broken copy constructor. 
 
~SimpleFSIPreconditioner()
Destructor: Clean up. 
 
void setup()
Setup the preconditioner. 
 
bool Retain_fluid_onto_solid_terms
Boolean flag used to indicate that the fluid onto solid interaction terms are to be retained...
 
bool Allow_multiple_element_type_in_wall_mesh
 
FSIPreconditioner(Problem *problem_pt)
Constructor: By default use block triangular form with retained fluid on solid terms. A problem pointer is required for the underlying NavierStokesSchurComplementPreconditioner. 
 
bool Retain_fluid_onto_solid_terms
Boolean flag used to indicate that the fluid onto solid interaction terms are to be retained...
 
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. The optional argument indicates if there are more than one type of elements in same mesh. 
 
MatrixVectorProduct * Matrix_vector_product_1_0_pt
Pointer to solid/fluid solid interaction matrix. 
 
void use_block_diagonal_version()
Switch to block-diagonal preconditioner. 
 
bool Doc_time
Set Doc_time to true for outputting results of timings. 
 
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r. 
 
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...
 
~FSIPreconditioner()
Destructor: Clean up. 
 
bool Preconditioner_has_been_setup
Boolean indicating the preconditioner has been set up. 
 
void set_solid_preconditioner_pt(Preconditioner *solid_preconditioner_pt)
Broken assignment operator. 
 
void setup()
Setup the preconditioner. 
 
Mesh * Navier_stokes_mesh_pt
Pointer to the navier stokes mesh. 
 
SimpleFSIPreconditioner()
Constructor. 
 
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...