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);
79 ExactPreconditionerFactory::create_exact_preconditioner();
167 const bool& allow_multiple_element_type_in_navier_stokes_mesh =
false)
174 allow_multiple_element_type_in_navier_stokes_mesh;
182 const bool& allow_multiple_element_type_in_wall_mesh =
false)
189 allow_multiple_element_type_in_wall_mesh;
276 std::ostringstream error_message;
277 error_message <<
"Pointer to fluid mesh hasn't been set!\n";
279 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
283 std::ostringstream error_message;
284 error_message <<
"Pointer to solid mesh hasn't been set!\n";
286 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
297 unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
298 unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
301 Vector<unsigned> dof_to_block_map(n_dof, 0);
302 for (
unsigned i = n_fluid_dof; i < n_dof; i++)
304 dof_to_block_map[i] = 1;
308 this->block_setup(dof_to_block_map);
313 Vector<unsigned> ns_dof_lookup(n_fluid_dof);
314 for (
unsigned i = 0; i < n_fluid_dof; i++)
316 ns_dof_lookup[i] = i;
322 this, ns_dof_lookup);
333 CRDoubleMatrix block_matrix_1_1;
334 this->get_block(1, 1, block_matrix_1_1);
337 double t_start = TimingHelpers::timer();
339 double t_end = TimingHelpers::timer();
340 block_matrix_1_1.clear();
341 double setup_time = t_end - t_start;
346 CRDoubleMatrix block_matrix_0_1 = get_block(0, 1);
347 this->setup_matrix_vector_product(
354 CRDoubleMatrix block_matrix_1_0 = get_block(1, 0);
355 this->setup_matrix_vector_product(
362 oomph_info <<
"Solid sub-preconditioner setup time [sec]: " << setup_time
380 z.build(r.distribution_pt(), 0.0);
392 DoubleVector temp_solid_vec;
393 DoubleVector temp_fluid_vec;
398 get_block_vector(1, res, temp_solid_vec);
402 DoubleVector temp_solid_vec2;
405 this->return_block_vector(1, temp_solid_vec2, z);
411 temp_solid_vec.clear();
414 DoubleVector another_temp_vec;
415 this->get_block_vector(0, res, another_temp_vec);
416 another_temp_vec -= temp_fluid_vec;
417 this->return_block_vector(0, another_temp_vec, res);
434 DoubleVector temp_solid_vec;
437 get_block_vector(1, res, temp_solid_vec);
442 DoubleVector temp_fluid_vec;
443 get_block_vector(0, z, temp_fluid_vec);
447 DoubleVector aux_vec;
453 temp_solid_vec -= aux_vec;
458 DoubleVector temp_solid_vec2;
464 return_block_vector(1, temp_solid_vec2, z);
484 template<
typename MATRIX>
534 const bool& allow_multiple_element_type_in_navier_stokes_mesh =
false)
541 allow_multiple_element_type_in_navier_stokes_mesh;
548 const bool& allow_multiple_element_type_in_wall_mesh =
false)
555 allow_multiple_element_type_in_wall_mesh;
632 template<
typename MATRIX>
634 DenseMatrix<bool>& required_blocks)
637 unsigned n_dof = this->nblock_types();
640 for (
unsigned i = 0; i < n_dof; i++)
642 for (
unsigned j = 0; j < n_dof; j++)
644 required_blocks(i, j) =
false;
649 required_blocks(0, 0) =
true;
650 required_blocks(1, 0) =
true;
651 required_blocks(0, 1) =
true;
654 required_blocks(2, 2) =
true;
657 if (Retain_solid_onto_fluid_terms)
659 required_blocks(0, 2) =
true;
660 required_blocks(1, 2) =
true;
662 if (Retain_fluid_onto_solid_terms)
664 required_blocks(2, 0) =
true;
665 required_blocks(2, 1) =
true;
666 if (Retain_solid_onto_fluid_terms)
668 std::ostringstream error_message;
669 error_message <<
"Can't retain all off-diagonal blocks!\n";
670 throw OomphLibError(error_message.str(),
671 OOMPH_CURRENT_FUNCTION,
672 OOMPH_EXCEPTION_LOCATION);
683 template<
typename MATRIX>
687 if (Preconditioner_pt != 0)
689 delete Preconditioner_pt;
690 Preconditioner_pt = 0;
693 if (Navier_stokes_mesh_pt == 0)
695 std::ostringstream error_message;
696 error_message <<
"Pointer to fluid mesh hasn't been set!\n";
698 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
700 if (Wall_mesh_pt == 0)
702 std::ostringstream error_message;
703 error_message <<
"Pointer to solid mesh hasn't been set!\n";
705 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
711 Navier_stokes_mesh_pt,
712 Allow_multiple_element_type_in_navier_stokes_mesh);
713 this->set_mesh(1, Wall_mesh_pt, Allow_multiple_element_type_in_wall_mesh);
716 unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
717 unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
720 Vector<unsigned> dof_to_block_map(n_dof, 0);
721 dof_to_block_map[n_fluid_dof - 1] = 1;
722 for (
unsigned i = n_fluid_dof; i < n_dof; i++)
724 dof_to_block_map[i] = 2;
728 this->block_setup(dof_to_block_map);
731 n_dof = this->nblock_types();
734 DenseMatrix<bool> required_blocks(n_dof, n_dof);
737 identify_required_blocks(required_blocks);
739 VectorMatrix<BlockSelector> selected_blocks(n_dof, n_dof);
741 for (
unsigned dof_i = 0; dof_i < n_dof; dof_i++)
743 for (
unsigned dof_j = 0; dof_j < n_dof; dof_j++)
745 selected_blocks[dof_i][dof_j].select_block(dof_i, dof_j,
false, 0);
747 if (required_blocks(dof_i, dof_j))
749 selected_blocks[dof_i][dof_j].want_block();
754 CRDoubleMatrix P_matrix = this->get_concatenated_block(selected_blocks);
758 ExactPreconditionerFactory::create_exact_preconditioner();
759 Preconditioner_pt->setup(&P_matrix);
766 template<
typename MATRIX>
768 const DoubleVector& r, DoubleVector& z)
771 DoubleVector temp_vec;
774 this->get_block_ordered_preconditioner_vector(r, temp_vec);
777 Preconditioner_pt->preconditioner_solve(temp_vec, temp_vec);
780 this->return_block_ordered_preconditioner_vector(temp_vec, z);
FSI preconditioner. This extracts upper/lower triangular blocks in the 3x3 overall block matrix struc...
void set_solid_preconditioner_pt(Preconditioner *solid_preconditioner_pt)
Broken assignment operator.
Preconditioner * solid_preconditioner_pt() const
Read-only access to solid preconditoner (use set_... to set it)
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.
NavierStokesSchurComplementPreconditioner * navier_stokes_preconditioner_pt() const
Access function to the Navier Stokes preconditioner (inexact solver)
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.
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)
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....
FSI preconditioner. This extracts upper/lower triangular blocks in the 3x3 overall block matrix struc...
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...