65     std::ostringstream error_message;
    66     error_message << 
"The fluid and pseudo elastic mesh must be set.";
    67     throw OomphLibError(error_message.str(),
    68                         OOMPH_CURRENT_FUNCTION,
    69                         OOMPH_EXCEPTION_LOCATION);
    74     std::ostringstream error_message;
    75     error_message << 
"The solid mesh must be set.";
    76     throw OomphLibError(error_message.str(),
    77                         OOMPH_CURRENT_FUNCTION,
    78                         OOMPH_EXCEPTION_LOCATION);
    82     std::ostringstream error_message;
    83     error_message << 
"The Lagrange multiplier mesh must be set.";
    84     throw OomphLibError(error_message.str(),
    85                         OOMPH_CURRENT_FUNCTION,
    86                         OOMPH_EXCEPTION_LOCATION);
    96   unsigned nfluid_dof = 
Dim + 1;
    99   unsigned npseudo_elastic_dof = this->ndof_types_in_mesh(0)-nfluid_dof;
   102   unsigned nsolid_dof = this->ndof_types_in_mesh(1);
   105   unsigned nlagr_mult_dof = this->ndof_types_in_mesh(2);
   108   unsigned ntotal_dof = nfluid_dof + npseudo_elastic_dof + nsolid_dof
   115   Vector<unsigned> dof_to_block_map(ntotal_dof,0);
   117   for (
unsigned i = 0; i < npseudo_elastic_dof; i++)
   119     dof_to_block_map[c] = 2;
   122   for (
unsigned i = 0; i < nsolid_dof; i++)
   124     dof_to_block_map[c] = 1;
   127   for (
unsigned i = 0; i < nlagr_mult_dof; i++)
   129     dof_to_block_map[c] = 3;
   134   CRDoubleMatrix* cr_matrix_pt = 
dynamic_cast<CRDoubleMatrix*
>(matrix_pt());
   138     std::ostringstream error_message;
   139     error_message << 
"FSIPreconditioner only works with"   140                   << 
" CRDoubleMatrix matrices" << std::endl;
   141     throw OomphLibError(error_message.str(),
   142                         OOMPH_CURRENT_FUNCTION,
   143                         OOMPH_EXCEPTION_LOCATION);
   148   this->block_setup(dof_to_block_map);
   159     Vector<unsigned> ns_dof_list(nfluid_dof,0);
   160     for (
unsigned i = 0; i < nfluid_dof; i++)
   166      turn_into_subsidiary_block_preconditioner(
this,ns_dof_list);
   169      Preconditioner::setup(matrix_pt());
   173     CRDoubleMatrix* ns_matrix_pt = 
new CRDoubleMatrix;
   174     this->get_block(0,0,*ns_matrix_pt);
   177     delete ns_matrix_pt; ns_matrix_pt = 0;
   181   if (
dynamic_cast<BlockPreconditioner<CRDoubleMatrix>* 
>   185     GeneralPurposeBlockPreconditioner<CRDoubleMatrix>*
   186      solid_block_preconditioner_pt =
   187      dynamic_cast<GeneralPurposeBlockPreconditioner<CRDoubleMatrix>* 
>   190     if (solid_block_preconditioner_pt != 0)
   192       unsigned offset = nfluid_dof+npseudo_elastic_dof;
   193       Vector<unsigned> solid_prec_dof_list(nsolid_dof);
   194       for (
unsigned i = 0; i < nsolid_dof; i++)
   196         solid_prec_dof_list[i]=offset+i;
   198       solid_block_preconditioner_pt
   199        ->turn_into_subsidiary_block_preconditioner(
this,
   200                                                    solid_prec_dof_list);
   201       solid_block_preconditioner_pt->setup(cr_matrix_pt);
   205       std::ostringstream error_message;
   206       error_message << 
"If the (real) solid preconditioner is a "   207                     << 
"BlockPreconditioner then is must be a "   208                     << 
"GeneralPurposeBlockPreconditioner";
   209       throw OomphLibError(error_message.str(),
   210                           OOMPH_CURRENT_FUNCTION,
   211                           OOMPH_EXCEPTION_LOCATION);
   218     CRDoubleMatrix* s_matrix_pt = 
new CRDoubleMatrix;
   219     this->get_block(1,1,*s_matrix_pt);
   221     delete s_matrix_pt; s_matrix_pt = 0;
   225   unsigned ndof_for_pseudo_elastic_prec = 
Dim*3;
   226   Vector<unsigned> pseudo_elastic_prec_dof_list(ndof_for_pseudo_elastic_prec,0);
   227   for (
unsigned i = 0; i < 
Dim*2; i++)
   229     pseudo_elastic_prec_dof_list[i] = nfluid_dof+i;
   231   for (
unsigned i = 0; i < 
Dim; i++)
   233     pseudo_elastic_prec_dof_list[i+Dim*2] = nfluid_dof 
   234      + npseudo_elastic_dof + nsolid_dof + i;
   237    ->turn_into_subsidiary_block_preconditioner(
this,
   238                                                pseudo_elastic_prec_dof_list);
   244    Preconditioner::setup(matrix_pt());
   250   CRDoubleMatrix* fp_matrix_pt = 
new CRDoubleMatrix;
   251   get_block(0,2,*fp_matrix_pt);
   255   delete fp_matrix_pt; fp_matrix_pt = 0;
   258   CRDoubleMatrix* sf_matrix_pt = 
new CRDoubleMatrix;
   259   get_block(1,0,*sf_matrix_pt);
   262   delete sf_matrix_pt; sf_matrix_pt = 0;
   265   CRDoubleMatrix* sp_matrix_pt = 
new CRDoubleMatrix;
   266   get_block(1,2,*sp_matrix_pt);
   270   delete sp_matrix_pt; sp_matrix_pt = 0;
   273   CRDoubleMatrix* ls_matrix_pt = 
new CRDoubleMatrix;
   274   get_block(3,1,*ls_matrix_pt);
   278   delete ls_matrix_pt; ls_matrix_pt = 0;
   286  (
const DoubleVector& r,DoubleVector& z)
   293   this->get_block_vector(2,z,x);
   299   this->get_block_vector(0,r,x);
   310     this->return_block_vector(0,x,z_copy);
   320     this->return_block_vector(0,y,z);
   325   this->get_block_vector(0,z,x);
   328   this->get_block_vector(1,r,x);
   339     DoubleVector z_copy(z);
   340     this->return_block_vector(1,x,z_copy);
   342     (
dynamic_cast<GeneralPurposeBlockPreconditioner<CRDoubleMatrix>* 
>   344     this->get_block_vector(1,z,y);
   350     this->return_block_vector(1,y,z);
   356   this->get_block_vector(3,r,y);
   360   this->return_block_vector(3,y,z_copy);
   365    lagrange_multiplier_preconditioner_solve(z_copy,z);
 void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the preconditioner. 
 
MatrixVectorProduct * Solid_fluid_matvec_pt
solid onto fluid matrix vector operatio 
 
void clean_up_memory()
Broken assignment operator. 
 
Preconditioner * Navier_stokes_preconditioner_pt
pointer to the navier stokes precondtioner 
 
NavierStokesSchurComplementPreconditioner * Navier_stokes_schur_complement_preconditioner_pt
Navier Stokes Schur complement preconditioner. 
 
void elastic_preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the elastic subsidiary preconditioner. 
 
void setup()
Setup the precoonditioner. 
 
Mesh * Lagrange_multiplier_mesh_pt
Mesh containing the lagrange multiplier elements. 
 
unsigned Dim
the dimension of the fluid 
 
MatrixVectorProduct * Fluid_pseudo_elastic_matvec_pt
fluid onto pseudosolid matrix vector operator 
 
MatrixVectorProduct * Lagrange_solid_matvec_pt
 
bool Solid_preconditioner_is_block_preconditioner
boolean flag to indicate whether the Solid preconditioner is a block preconditioner ...
 
Mesh * Solid_mesh_pt
Mesh containing the solid elements. 
 
MatrixVectorProduct * Solid_pseudo_elastic_matvec_pt
solid onto pseudo solid matrix vector operatio 
 
Preconditioner * Solid_preconditioner_pt
pointer to the solid preconditioner 
 
bool Use_navier_stokes_schur_complement_preconditioner
If true the Navier Stokes Schur complement preconditioner is used. Otherwise SuperLUPreconditioner is...
 
PseudoElasticPreconditioner * Pseudo_elastic_preconditioner_pt
pointer to the pseudo solid preconditioner 
 
Mesh * Fluid_and_pseudo_elastic_mesh_pt
Mesh containing the combined fluid and pseudo solid element. 
 
void clean_up_memory()
Clears the memory.