fsi_preconditioners.h
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26#ifndef OOMPH_FSI_PRECONDITIONERS_HEADER
27#define OOMPH_FSI_PRECONDITIONERS_HEADER
28
29
30#include "../navier_stokes/navier_stokes_preconditioners.h"
31
32namespace oomph
33{
34 /// ////////////////////////////////////////////////////////////////////////////
35 /// ////////////////////////////////////////////////////////////////////////////
36 /// ////////////////////////////////////////////////////////////////////////////
37
38
39 //============================================================================
40 /// FSI preconditioner. This extracts upper/lower triangular
41 /// blocks in the 3x3 overall block matrix structure arising from
42 /// the monolithic discretisation of FSI problems with algebraic
43 /// node updates. Dofs are decomposed into fluid velocity, pressure
44 /// and solid unknowns. NavierStokesSchurComplementPreconditioner is used
45 /// as the inexact solver for the fluid block; SuperLU (in
46 /// its incarnation as an "exact" preconditioner) is used for
47 /// the solid block. By default we retain the fluid on solid off
48 /// diagonal blocks.
49 //=============================================================================
50 class FSIPreconditioner : public BlockPreconditioner<CRDoubleMatrix>
51 {
52 public:
53 /// Constructor: By default use block triangular form with retained
54 /// fluid on solid terms. A problem pointer is required for the underlying
55 /// NavierStokesSchurComplementPreconditioner.
56 FSIPreconditioner(Problem* problem_pt)
57 {
58 // set the mesh pointers
59 this->set_nmesh(2);
61 Wall_mesh_pt = 0;
62
63 // Initially assume that there are no multiple element types in the
64 // meshes.
67
68 // Default setting: Fluid onto solid as it this was shown to be
69 // marginally faster than solid onto fluid; see Heil CMAME 193 (2004)
72
73 // Create the Navier Stokes Schur complement preconditioner
75 new NavierStokesSchurComplementPreconditioner(problem_pt);
76
77 // Create the Solid preconditioner
78 Solid_preconditioner_pt = new SuperLUPreconditioner;
79
80 // Preconditioner hasn't been set up yet.
82
83 // Create the matrix vector product operators
84 Matrix_vector_product_0_1_pt = new MatrixVectorProduct;
85 Matrix_vector_product_1_0_pt = new MatrixVectorProduct;
86
87 // set Doc_time to false
88 Doc_time = false;
89 }
90
91
92 /// Destructor: Clean up.
94 {
95 // Delete the Navier-Stokes preconditioner (inexact solver)
97
98 // Delete the solid preconditioner (inexact solver)
100
101 // delete the matrix vector product operators
104 }
105
106
107 /// Broken copy constructor
109
110
111 /// Broken assignment operator
112 // Commented out broken assignment operator because this can lead to a
113 // conflict warning when used in the virtual inheritence hierarchy.
114 // Essentially the compiler doesn't realise that two separate
115 // implementations of the broken function are the same and so, quite
116 // rightly, it shouts.
117 /*void operator=(const FSIPreconditioner&) =
118 delete;*/
119
120 /// Set solid preconditioner (deletes existing one)
122 {
123 // Kill existing one
125 {
127 }
129 }
130
131 /// Read-only access to solid preconditoner (use set_... to set it)
132 Preconditioner* solid_preconditioner_pt() const
133 {
135 }
136
137
138 /// Switch to block-diagonal preconditioner
144
145 /// Switch to block-triangular preconditioner in which
146 /// action of fluid dofs onto solid equations is retained
152
153 /// Switch to block-triangular preconditioner in which
154 /// action of solid dofs onto fluid equations is retained
160
161 /// Setter function for the mesh containing the
162 /// block-preconditionable Navier-Stokes elements. The optional argument
163 /// indicates if there are more than one type of elements in same mesh.
165 Mesh* mesh_pt,
166 const bool& allow_multiple_element_type_in_navier_stokes_mesh = false)
167 {
168 // Store the mesh pointer.
169 Navier_stokes_mesh_pt = mesh_pt;
170
171 // Are there multiple element types in the Navier-Stokes mesh?
173 allow_multiple_element_type_in_navier_stokes_mesh;
174 }
175
176 /// Setter function for the mesh containing the
177 /// block-preconditionable FSI solid elements. The optional argument
178 /// indicates if there are more than one type of elements in the same mesh.
180 Mesh* mesh_pt,
181 const bool& allow_multiple_element_type_in_wall_mesh = false)
182 {
183 // Store the mesh pointer
184 Wall_mesh_pt = mesh_pt;
185
186 // Are there multiple element types in the wall mesh?
188 allow_multiple_element_type_in_wall_mesh;
189 }
190
191 /// Setup the preconditioner
192 void setup();
193
194 /// Apply preconditioner to r
195 void preconditioner_solve(const DoubleVector& r, DoubleVector& z);
196
197 /// Access function to the Navier Stokes preconditioner (inexact solver)
198 NavierStokesSchurComplementPreconditioner* navier_stokes_preconditioner_pt()
199 const
200 {
202 }
203
204 /// Enable documentation of time
206 {
207 Doc_time = true;
208 }
209
210 /// Disable documentation of time
212 {
213 Doc_time = false;
214 }
215
216
217 private:
218 /// Pointer the Navier Stokes preconditioner (inexact solver)
219 NavierStokesSchurComplementPreconditioner* Navier_stokes_preconditioner_pt;
220
221 /// Pointer to the solid preconditioner (inexact solver)
222 Preconditioner* Solid_preconditioner_pt;
223
224 /// Pointer to fluid/solid interaction matrix
225 MatrixVectorProduct* Matrix_vector_product_0_1_pt;
226
227 /// Pointer to solid/fluid solid interaction matrix
228 MatrixVectorProduct* Matrix_vector_product_1_0_pt;
229
230 /// Boolean indicating the preconditioner has been set up
232
233 /// Boolean flag used to indicate that the solid onto fluid
234 /// interaction terms are to be retained
236
237 /// Boolean flag used to indicate that the fluid onto solid
238 /// interaction terms are to be retained
240
241 /// Set Doc_time to true for outputting results of timings
243
244 /// Pointer to the navier stokes mesh
246
247 /// pointer to the solid mesh
249
250 /// Flag to indicate if there are multiple element types in the
251 /// Navier-Stokes mesh.
253
254 // Flag to indicate if there are multiple element types in the Wall mesh.
256 };
257
258
259 /// ///////////////////////////////////////////////////////////////////////////
260 /// ///////////////////////////////////////////////////////////////////////////
261 // FSI preconditioner member functions
262 /// ///////////////////////////////////////////////////////////////////////////
263 /// ///////////////////////////////////////////////////////////////////////////
264
265
266 //=============================================================================
267 /// Setup the preconditioner. Note: Matrix must be a CRDoubleMatrix.
268 //=============================================================================
270 {
271 // check the meshes have been set
272#ifdef PARANOID
273 if (Navier_stokes_mesh_pt == 0)
274 {
275 std::ostringstream error_message;
276 error_message << "Pointer to fluid mesh hasn't been set!\n";
277 throw OomphLibError(
278 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
279 }
280 if (Wall_mesh_pt == 0)
281 {
282 std::ostringstream error_message;
283 error_message << "Pointer to solid mesh hasn't been set!\n";
284 throw OomphLibError(
285 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
286 }
287#endif
288
289 // setup the meshes
290 this->set_mesh(0,
294
295 // get the number of fluid dofs from teh first element in the mesh
296 unsigned n_fluid_dof = this->ndof_types_in_mesh(0);
297 unsigned n_dof = n_fluid_dof + this->ndof_types_in_mesh(1);
298
299 // this fsi preconditioner has two types of DOF fluid dofs and solid dofs
300 Vector<unsigned> dof_to_block_map(n_dof, 0);
301 for (unsigned i = n_fluid_dof; i < n_dof; i++)
302 {
303 dof_to_block_map[i] = 1;
304 }
305
306 // Call block setup for this preconditioner
307 this->block_setup(dof_to_block_map);
308
309 // Block mapping for the subsidiary Navier Stokes preconditioner:
310 // blocks 0 and 1 in the FSI preconditioner are also blocks 0 and 1
311 // in the subsidiary Navier Stokes one.
312 Vector<unsigned> ns_dof_lookup(n_fluid_dof);
313 for (unsigned i = 0; i < n_fluid_dof; i++)
314 {
315 ns_dof_lookup[i] = i;
316 }
317
318 // Turn the Navier Stokes Schur complement preconditioner into a
319 // subsidiary preconditioner of this preconditioner
320 Navier_stokes_preconditioner_pt->turn_into_subsidiary_block_preconditioner(
321 this, ns_dof_lookup);
322
323 // Setup the navier stokes preconditioner: Tell it about the
324 // Navier Stokes mesh and set it up.
325 Navier_stokes_preconditioner_pt->set_navier_stokes_mesh(
327 Navier_stokes_preconditioner_pt->setup(matrix_pt());
328
329 // Extract the additional blocks we need for FSI:
330
331 // Solid tangent stiffness matrix
332 CRDoubleMatrix block_matrix_1_1;
333 this->get_block(1, 1, block_matrix_1_1);
334
335 // Setup the solid preconditioner (inexact solver)
336 double t_start = TimingHelpers::timer();
337 Solid_preconditioner_pt->setup(&block_matrix_1_1);
338 double t_end = TimingHelpers::timer();
339 block_matrix_1_1.clear();
340 double setup_time = t_end - t_start;
341
342 // Solid on fluid terms (if needed)
344 {
345 CRDoubleMatrix block_matrix_0_1 = get_block(0, 1);
346 this->setup_matrix_vector_product(
347 Matrix_vector_product_0_1_pt, &block_matrix_0_1, 1);
348 }
349
350 // Fluid on solid terms (if needed)
352 {
353 CRDoubleMatrix block_matrix_1_0 = get_block(1, 0);
354 this->setup_matrix_vector_product(
355 Matrix_vector_product_1_0_pt, &block_matrix_1_0, 0);
356 }
357
358 // Output times
359 if (Doc_time)
360 {
361 oomph_info << "Solid sub-preconditioner setup time [sec]: " << setup_time
362 << "\n";
363 }
364
365 // We're done (and we stored some data)
367 }
368
369
370 //======================================================================
371 /// Apply preconditioner to Vector r
372 //======================================================================
373 void FSIPreconditioner::preconditioner_solve(const DoubleVector& r,
374 DoubleVector& z)
375 {
376 // if z is not setup then give it the same distribution
377 if (!z.built())
378 {
379 z.build(r.distribution_pt(), 0.0);
380 }
381
382 // Make copy of residual vector (to overcome const-ness
383 DoubleVector res(r);
384
385
386 // Retain off-diagonals that represent effect of solid on fluid
387 //-------------------------------------------------------------
389 {
390 // Working vectors
391 DoubleVector temp_solid_vec;
392 DoubleVector temp_fluid_vec;
393
394 // Copy solid values from residual to temp_vec:
395 // Loop over all entries in the global vector (this one
396 // includes solid, velocity and pressure dofs in some random fashion)
397 get_block_vector(1, res, temp_solid_vec);
398
399 // Solve solid system by back-substitution
400 // with LU-decomposed stiffness matrix
401 DoubleVector temp_solid_vec2;
402 Solid_preconditioner_pt->preconditioner_solve(temp_solid_vec,
403 temp_solid_vec2);
404 this->return_block_vector(1, temp_solid_vec2, z);
405
406 // NOTE: temp_solid_vec now contains z_s = S^{-1} r_s
407
408 // Multiply C_{us} by z_s
409 Matrix_vector_product_0_1_pt->multiply(temp_solid_vec2, temp_fluid_vec);
410 temp_solid_vec.clear();
411
412 // Subtract from fluid residual vector for fluid solve
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);
417
418 // now apply the navier stokes lsc preconditioner
419 Navier_stokes_preconditioner_pt->preconditioner_solve(res, z);
420 }
421
422
423 // Retain off-diagonals that represent effect of fluid on solid
424 //-------------------------------------------------------------
425 // (or diagonal preconditioner)
426 //-----------------------------
427 else
428 {
429 // Call fluid preconditioner for fluid block
430 Navier_stokes_preconditioner_pt->preconditioner_solve(res, z);
431
432 // Working vectors
433 DoubleVector temp_solid_vec;
434
435 // get the solid vector
436 get_block_vector(1, res, temp_solid_vec);
437
438 // Do matrix vector products with fluid onto solid coupling matrices:
440 {
441 DoubleVector temp_fluid_vec;
442 get_block_vector(0, z, temp_fluid_vec);
443
444 // Auxiliary vector to hold the matrix vector product of the
445 // fluid-onto-solid coupling matrices with the fluid solutions:
446 DoubleVector aux_vec;
447
448 // Multiply C_{su} by z_u
449 Matrix_vector_product_1_0_pt->multiply(temp_fluid_vec, aux_vec);
450
451 // ...and subtract from r_s:
452 temp_solid_vec -= aux_vec;
453 }
454
455 // Solve solid system by back-substitution
456 // with LU-decomposed stiffness matrix
457 DoubleVector temp_solid_vec2;
458 Solid_preconditioner_pt->preconditioner_solve(temp_solid_vec,
459 temp_solid_vec2);
460
461 // Now copy result_vec (i.e. z_s) back into the global vector z.
462 // Loop over all entries in the global results vector z:
463 return_block_vector(1, temp_solid_vec2, z);
464 }
465 }
466
467
468 /// ////////////////////////////////////////////////////////////////////////
469 /// ////////////////////////////////////////////////////////////////////////
470 /// ////////////////////////////////////////////////////////////////////////
471
472
473 //============================================================================
474 /// FSI preconditioner. This extracts upper/lower triangular
475 /// blocks in the 3x3 overall block matrix structure arising from
476 /// the monolithic discretisation of FSI problems with algebraic
477 /// node updates. Dofs are decomposed into fluid velocity, pressure
478 /// and solid unknowns. Blocks are then re-assembled into one global
479 /// matrix and solved with a direct solver (SuperLU in its incarnation
480 /// as an exact preconditioner). By default we retain the fluid on solid off
481 /// diagonal blocks.
482 //=============================================================================
483 template<typename MATRIX>
484 class SimpleFSIPreconditioner : public BlockPreconditioner<MATRIX>
485 {
486 public:
487 /// Constructor.
488 SimpleFSIPreconditioner() : BlockPreconditioner<MATRIX>()
489 {
490 // set the mesh pointers
492 Wall_mesh_pt = 0;
493 this->set_nmesh(2);
494
495 // Default setting: Retain fluid on solid
498
499 // Null the preconditioner pointer (inexact solver)
501
502 // Initially assume that there are no multiple element types in
503 // the same mesh.
506 }
507
508
509 /// Destructor: Clean up
511 {
512 // Wiping preconditioner (inexact solver) wipes the stored
513 // LU decompositon
514 if (Preconditioner_pt != 0)
515 {
516 delete Preconditioner_pt;
518 }
519 }
520
521
522 /// Broken copy constructor
524
525
526 /// Broken assignment operator
527 /*void operator=(const SimpleFSIPreconditioner&) = delete;*/
528
529 /// Setter function for the mesh containing the
530 /// block-preconditionable Navier-Stokes elements.
532 Mesh* mesh_pt,
533 const bool& allow_multiple_element_type_in_navier_stokes_mesh = false)
534 {
535 // Store the mesh pointer.
536 Navier_stokes_mesh_pt = mesh_pt;
537
538 // Are there multiple elements in this mesh?
540 allow_multiple_element_type_in_navier_stokes_mesh;
541 }
542
543 /// Setter function for the mesh containing the
544 /// block-preconditionable FSI solid elements.
546 Mesh* mesh_pt,
547 const bool& allow_multiple_element_type_in_wall_mesh = false)
548 {
549 // Store the mesh pointer
550 Wall_mesh_pt = mesh_pt;
551
552 // Are the multiple elements in this mesh?
554 allow_multiple_element_type_in_wall_mesh;
555 }
556
557 /// Setup the preconditioner
558 void setup();
559
560 /// Apply preconditioner to r
561 void preconditioner_solve(const DoubleVector& r, DoubleVector& z);
562
563 /// Switch to block-diagonal preconditioner
569
570 /// Switch to block-triangular preconditioner in which
571 /// action of fluid dofs onto solid equations is retained
577
578 /// Switch to block-triangular preconditioner in which
579 /// action of solid dofs onto fluid equations is retained
585
586 private:
587 /// Preconditioner (inexact solver)
588 Preconditioner* Preconditioner_pt;
589
590 /// Boolean flag used to indicate that the solid onto fluid
591 /// interaction terms are to be retained
593
594 /// Boolean flag used to indicate that the fluid onto solid
595 /// interaction terms are to be retained
597
598 /// Identify the required blocks: Here we only need
599 /// the momentum, gradient and divergence blocks of the
600 /// 2x2 block-structured fluid matrix, the 1x1 solid block
601 /// and the selected FSI-off diagonals.
602 virtual void identify_required_blocks(DenseMatrix<bool>& required_blocks);
603
604 /// Pointer to the navier stokes mesh
606
607 /// pointer to the solid mesh
609
610 /// Flag for multiple element types in the Navier-Stokes mesh.
612
613 /// Flag for multiple element types in the Wall mesh
615 };
616
617
618 /// /////////////////////////////////////////////////////////////////////
619 /// /////////////////////////////////////////////////////////////////////
620 // FSI preconditioner member functions
621 /// /////////////////////////////////////////////////////////////////////
622 /// /////////////////////////////////////////////////////////////////////
623
624
625 //===========================================================================
626 /// Identify the required blocks: Here we only need
627 /// the momentum, gradient and divergence blocks of the
628 /// 2x2 block-structured fluid matrix, the 1x1 solid block
629 /// and the selected FSI-off diagonals.
630 //===========================================================================
631 template<typename MATRIX>
633 DenseMatrix<bool>& required_blocks)
634 {
635 // find number of block types
636 unsigned n_dof = this->nblock_types();
637
638 // Initialise all blocks to false
639 for (unsigned i = 0; i < n_dof; i++)
640 {
641 for (unsigned j = 0; j < n_dof; j++)
642 {
643 required_blocks(i, j) = false;
644 }
645 }
646
647 // Fluid: Only need momentum, gradient and divergence blocks
648 required_blocks(0, 0) = true;
649 required_blocks(1, 0) = true;
650 required_blocks(0, 1) = true;
651
652 // Always retain the solid block
653 required_blocks(2, 2) = true;
654
655 // Switch on the required off-diagonals
656 if (Retain_solid_onto_fluid_terms)
657 {
658 required_blocks(0, 2) = true;
659 required_blocks(1, 2) = true;
660 }
661 if (Retain_fluid_onto_solid_terms)
662 {
663 required_blocks(2, 0) = true;
664 required_blocks(2, 1) = true;
665 if (Retain_solid_onto_fluid_terms)
666 {
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);
672 }
673 }
674 }
675
676
677 //=============================================================================
678 /// Setup the preconditioner: Copy the upper/lower triangular
679 /// block matrices back into a big matrix (with the entries
680 /// re-ordered relative to the original Jacobian matrix).
681 //=============================================================================
682 template<typename MATRIX>
684 {
685 // Clean up memory
686 if (Preconditioner_pt != 0)
687 {
688 delete Preconditioner_pt;
689 Preconditioner_pt = 0;
690 }
691#ifdef PARANOID
692 if (Navier_stokes_mesh_pt == 0)
693 {
694 std::ostringstream error_message;
695 error_message << "Pointer to fluid mesh hasn't been set!\n";
696 throw OomphLibError(
697 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
698 }
699 if (Wall_mesh_pt == 0)
700 {
701 std::ostringstream error_message;
702 error_message << "Pointer to solid mesh hasn't been set!\n";
703 throw OomphLibError(
704 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
705 }
706#endif
707
708 // setup the meshes
709 this->set_mesh(0,
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);
713
714 // get the number of fluid dofs from the first element in the 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);
717
718 // this fsi preconditioner has two types of DOF fluid dofs and solid dofs
719 Vector<unsigned> dof_to_block_map(n_dof, 0);
720 dof_to_block_map[n_fluid_dof - 1] = 1; // pressure
721 for (unsigned i = n_fluid_dof; i < n_dof; i++) // solid
722 {
723 dof_to_block_map[i] = 2;
724 }
725
726 // Set up the blocks look up schemes
727 this->block_setup(dof_to_block_map);
728
729 // find number of block types
730 n_dof = this->nblock_types();
731
732 // Create matrix that indicates which blocks are required
733 DenseMatrix<bool> required_blocks(n_dof, n_dof);
734
735 // Identify required blocks
736 identify_required_blocks(required_blocks);
737
738 VectorMatrix<BlockSelector> selected_blocks(n_dof, n_dof);
739
740 for (unsigned dof_i = 0; dof_i < n_dof; dof_i++)
741 {
742 for (unsigned dof_j = 0; dof_j < n_dof; dof_j++)
743 {
744 selected_blocks[dof_i][dof_j].select_block(dof_i, dof_j, false, 0);
745
746 if (required_blocks(dof_i, dof_j))
747 {
748 selected_blocks[dof_i][dof_j].want_block();
749 }
750 }
751 }
752
753 CRDoubleMatrix P_matrix = this->get_concatenated_block(selected_blocks);
754
755 // Setup preconditioner (i.e. inexact solver) -- does the LU decomposition
756 Preconditioner_pt = new SuperLUPreconditioner;
757 Preconditioner_pt->setup(&P_matrix);
758 }
759
760
761 //======================================================================
762 /// Apply preconditioner to Vector r
763 //======================================================================
764 template<typename MATRIX>
766 const DoubleVector& r, DoubleVector& z)
767 {
768 // create a temporary vector to hold the result of preconditioning
769 DoubleVector temp_vec;
770
771 // get the reordered vector
772 this->get_block_ordered_preconditioner_vector(r, temp_vec);
773
774 // apply preconditioner to z and store in r
775 Preconditioner_pt->preconditioner_solve(temp_vec, temp_vec);
776
777 // copy the solution back
778 this->return_block_ordered_preconditioner_vector(temp_vec, z);
779 }
780
781
782 /// ////////////////////////////////////////////////////////////////////////
783 /// ////////////////////////////////////////////////////////////////////////
784 /// ////////////////////////////////////////////////////////////////////////
785
786
787} // namespace oomph
788
789#endif
//////////////////////////////////////////////////////////////////////////// ////////////////////////...
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.
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....
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
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
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...