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...