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-2024 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 
32 namespace 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.
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
76 
77  // Create the Solid preconditioner
79 
80  // Preconditioner hasn't been set up yet.
82 
83  // Create the matrix vector product operators
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
124  if (Solid_preconditioner_pt != 0)
125  {
127  }
129  }
130 
131  /// Read-only access to solid preconditoner (use set_... to set it)
133  {
135  }
136 
137 
138  /// Switch to block-diagonal preconditioner
140  {
143  }
144 
145  /// Switch to block-triangular preconditioner in which
146  /// action of fluid dofs onto solid equations is retained
148  {
151  }
152 
153  /// Switch to block-triangular preconditioner in which
154  /// action of solid dofs onto fluid equations is retained
156  {
159  }
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.
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
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
196 
197  /// Access function to the Navier Stokes preconditioner (inexact solver)
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)
220 
221  /// Pointer to the solid preconditioner (inexact solver)
223 
224  /// Pointer to fluid/solid interaction matrix
226 
227  /// Pointer to solid/fluid solid interaction matrix
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
242  bool Doc_time;
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
321  this, ns_dof_lookup);
322 
323  // Setup the navier stokes preconditioner: Tell it about the
324  // Navier Stokes mesh and set it up.
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);
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);
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  //======================================================================
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;
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
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
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;
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>
485  {
486  public:
487  /// Constructor.
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)
500  Preconditioner_pt = 0;
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;
517  Preconditioner_pt = 0;
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.
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
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
562 
563  /// Switch to block-diagonal preconditioner
565  {
568  }
569 
570  /// Switch to block-triangular preconditioner in which
571  /// action of fluid dofs onto solid equations is retained
573  {
576  }
577 
578  /// Switch to block-triangular preconditioner in which
579  /// action of solid dofs onto fluid equations is retained
581  {
584  }
585 
586  private:
587  /// Preconditioner (inexact solver)
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
cstr elem_len * i
Definition: cfortran.h:603
Block Preconditioner base class. The block structure of the overall problem is determined from the Me...
void return_block_vector(const unsigned &n, const DoubleVector &b, DoubleVector &v) const
Takes the n-th block ordered vector, b, and copies its entries to the appropriate entries in the natu...
const Mesh * mesh_pt(const unsigned &i) const
Access to i-th mesh (of the various meshes that contain block preconditionable elements of the same n...
unsigned ndof_types_in_mesh(const unsigned &i) const
Return the number of DOF types in mesh i. WARNING: This should only be used by the upper-most master ...
void get_block(const unsigned &i, const unsigned &j, CRDoubleMatrix &output_matrix, const bool &ignore_replacement_block=false) const
Put block (i,j) into output_matrix. This block accounts for any coarsening of dof types and any repla...
void get_block_vector(const unsigned &n, const DoubleVector &v, DoubleVector &b) const
Takes the naturally ordered vector, v and returns the n-th block vector, b. Here n is the block numbe...
CRDoubleMatrix * matrix_pt() const
Access function to matrix_pt. If this is the master then cast the matrix pointer to MATRIX*,...
void turn_into_subsidiary_block_preconditioner(BlockPreconditioner< MATRIX > *master_block_prec_pt, const Vector< unsigned > &doftype_in_master_preconditioner_coarse)
Function to turn this preconditioner into a subsidiary preconditioner that operates within a bigger "...
void setup_matrix_vector_product(MatrixVectorProduct *matvec_prod_pt, CRDoubleMatrix *block_pt, const Vector< unsigned > &block_col_indices)
Setup a matrix vector product. matvec_prod_pt is a pointer to the MatrixVectorProduct,...
void set_nmesh(const unsigned &n)
Specify the number of meshes required by this block preconditioner. Note: elements in different meshe...
virtual void block_setup()
Determine the size of the matrix blocks and setup the lookup schemes relating the global degrees of f...
void set_mesh(const unsigned &i, const Mesh *const mesh_pt, const bool &allow_multiple_element_type_in_mesh=false)
Set the i-th mesh for this block preconditioner. Note: The method set_nmesh(...) must be called befor...
A class for compressed row matrices. This is a distributable object.
Definition: matrices.h:888
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
A vector in the mathematical sense, initially developed for linear algebra type applications....
Definition: double_vector.h:58
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
bool built() const
void clear()
wipes the DoubleVector
//////////////////////////////////////////////////////////////////////////// ////////////////////////...
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.
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....
Matrix vector product helper class - primarily a wrapper to Trilinos's Epetra matrix vector product m...
void multiply(const DoubleVector &x, DoubleVector &y) const
Apply the operator to the vector x and return the result in the vector y.
A general mesh class.
Definition: mesh.h:67
///////////////////////////////////////////////////////////////////////// ///////////////////////////...
void set_navier_stokes_mesh(Mesh *mesh_pt, const bool &allow_multiple_element_type_in_navier_stokes_mesh=false)
Specify the mesh containing the block-preconditionable Navier-Stokes elements. The optional argument ...
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to Vector r.
An OomphLibError object which should be thrown when an run-time error is encountered....
Preconditioner base class. Gives an interface to call all other preconditioners through and stores th...
void setup(DoubleMatrixBase *matrix_pt)
Setup the preconditioner: store the matrix pointer and the communicator pointer then call preconditio...
double setup_time() const
Returns the time to setup the preconditioner.
virtual void preconditioner_solve(const DoubleVector &r, DoubleVector &z)=0
Apply the preconditioner. Pure virtual generic interface function. This method should apply the preco...
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition: problem.h:154
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
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...
An interface to allow SuperLU to be used as an (exact) Preconditioner.
void setup()
Function to set up a preconditioner for the linear system defined by matrix_pt. This function must be...
VectorMatrix is a generalised, STL-map-based, matrix based on a Vector of Vectors.
Definition: vector_matrix.h:79
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...