solid_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// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 #ifndef OOMPH_SOLID_PRECONDITIONERS_HEADER
31 #define OOMPH_SOLID_PRECONDITIONERS_HEADER
32 
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36  #include <oomph-lib-config.h>
37 #endif
38 
39 
40 // oomphlib headers
41 #include "../generic/matrices.h"
42 #include "../generic/assembly_handler.h"
43 #include "../generic/problem.h"
44 #include "../generic/block_preconditioner.h"
45 #include "../generic/preconditioner.h"
46 #include "../generic/SuperLU_preconditioner.h"
47 #include "../generic/matrix_vector_product.h"
48 
49 
50 namespace oomph
51 {
52 
53 
54 
55 //===========================================================================
56 /// \short The least-squares commutator (LSC; formerly BFBT)
57 /// preconditioner. It uses blocks corresponding to the displacement/position
58 /// and pressure unknowns, i.e. there are a total of 2x2 blocks,
59 /// and all displacement/position components are treated as a
60 /// single block of unknowns.
61 ///
62 /// Here are the details: An "ideal" preconditioner
63 /// would solve the saddle point system
64 /// \f[
65 /// \left(
66 /// \begin{array}{cc}
67 /// {\bf F} & {\bf G} \\ {\bf D} & {\bf 0}
68 /// \end{array}
69 /// \right)
70 /// \left(
71 /// \begin{array}{c}
72 /// {\bf z}_u \\ {\bf z}_p
73 /// \end{array}
74 /// \right) =
75 /// \left(
76 /// \begin{array}{c}
77 /// {\bf r}_u \\ {\bf r}_p
78 /// \end{array}
79 /// \right)
80 /// \f]
81 /// where \f$ {\bf F}\f$, \f$ {\bf G} \f$, and \f$ {\bf D}\f$ are
82 /// the blocks that arise in the Jacobian of the pressure-based
83 /// equations of linear and nonlinear elasticity (with dofs in order
84 /// of displacement/position and pressure).
85 /// The use of this preconditioner would ensure the convergence
86 /// of any iterative linear solver in a single iteration but its
87 /// application is, of course, exactly as expensive as a direct solve.
88 /// The LSC/BFBT preconditioner replaces the exact Jacobian by
89 /// a block-triangular approximation
90 /// \f[
91 /// \left(
92 /// \begin{array}{cc}
93 /// {\bf F} & {\bf G} \\ {\bf 0} & -{\bf M}_s
94 /// \end{array}
95 /// \right)
96 /// \left(
97 /// \begin{array}{c}
98 /// {\bf z}_u \\ {\bf z}_p
99 /// \end{array}
100 /// \right) =
101 /// \left(
102 /// \begin{array}{c}
103 /// {\bf r}_u \\ {\bf r}_p
104 /// \end{array}
105 /// \right),
106 /// \f]
107 /// where \f${\bf M}_s\f$ is an approximation to the pressure
108 /// Schur-complement \f$ {\bf S} = {\bf D} {\bf F}^{-1}{\bf G}. \f$
109 /// This system can be solved in two steps:
110 /// -# Solve the second row for \f$ {\bf z}_p\f$ via
111 /// \f[
112 /// {\bf z}_p = - {\bf M}_s^{-1} {\bf r}_p
113 /// \f]
114 /// -# Given \f$ {\bf z}_p \f$ , solve the first row for \f$ {\bf z}_u\f$ via
115 /// \f[
116 /// {\bf z}_u = {\bf F}^{-1} \big( {\bf r}_u - {\bf G} {\bf z}_p \big)
117 /// \f]
118 /// .
119 /// In the LSC/BFBT preconditioner, the action of the inverse pressure
120 /// Schur complement
121 /// \f[
122 /// {\bf z}_p = - {\bf M}_s^{-1} {\bf r}_p
123 /// \f]
124 /// is approximated by
125 /// \f[
126 /// {\bf z}_p = -
127 /// \big({\bf D} \widehat{\bf Q}^{-1}{\bf G} \big)^{-1}
128 /// \big({\bf D} \widehat{\bf Q}^{-1}{\bf F} \widehat{\bf Q}^{-1}{\bf G}\big)
129 /// \big({\bf D} \widehat{\bf Q}^{-1}{\bf G} \big)^{-1}
130 /// {\bf r}_p,
131 /// \f]
132 /// where \f$ \widehat{\bf Q} \f$ is the diagonal of the displacement/position
133 /// mass matrix. The evaluation of this expression involves
134 /// two linear solves involving the matrix
135 /// \f[
136 /// {\bf P} = \big({\bf D} \widehat{\bf Q}^{-1}{\bf G} \big)
137 /// \f]
138 /// which has the character of a matrix arising from the discretisation
139 /// of a Poisson problem on the pressure space. We also have
140 /// to evaluate matrix-vector products with the matrix
141 /// \f[
142 /// {\bf E}={\bf D}\widehat{\bf Q}^{-1}{\bf F}\widehat{\bf Q}^{-1}{\bf G}
143 /// \f]
144 /// Details of the theory can be found in "Finite Elements and
145 /// Fast Iterative Solvers with Applications in Incompressible Fluid
146 /// Dynamics" by Howard C. Elman, David J. Silvester, and Andrew J. Wathen,
147 /// published by Oxford University Press, 2006.
148 ///
149 /// In our implementation of the preconditioner, the linear systems
150 /// can either be solved "exactly", using SuperLU (in its incarnation
151 /// as an exact preconditioner; this is the default) or by any
152 /// other Preconditioner (inexact solver) specified via the access functions
153 /// \code
154 /// PressureBasedSolidLSCPreconditioner::set_f_preconditioner(...)
155 /// \endcode
156 /// or
157 /// \code
158 /// PressureBasedSolidLSCPreconditioner::set_p_preconditioner(...)
159 /// \endcode
160 //===========================================================================
162  public BlockPreconditioner<CRDoubleMatrix>
163  {
164 
165  public :
166 
167  /// Constructor - sets defaults for control flags
169  {
170  // Flag to indicate that the preconditioner has been setup
171  // previously -- if setup() is called again, data can
172  // be wiped.
174 
175  // By default we use SuperLU for both p and f blocks
178 
179  // resize the mesh pt
180  // note: meaningless if subsidiary preconditioner
181  this->set_nmesh(1);
182  Solid_mesh_pt = 0;
183 
184  // Set default preconditioners (inexact solvers) -- they are
185  // members of this class!
188 
189  // Flag to determine if mass matrix diagonal Q^{-1}
190  // is used for scaling.
191  P_matrix_using_scaling = true;
192 
193  // set Doc_time to false
194  Doc_time = false;
195 
196  // null the off diagonal Block matrix pt
197  Bt_mat_vec_pt = 0;
198 
199  // null the F matrix vector product helper
200  F_mat_vec_pt = 0;
201 
202  // null the QBt matrix vector product pt
203  QBt_mat_vec_pt = 0;
204 
205  // null the E matrix vector product helper
206  E_mat_vec_pt = 0;
207 
208  // by default we do not form the E matrix (BQFQBt)
209  Form_BFBt_product = false;
210  }
211 
212  /// Destructor
214  {
215  clean_up_memory();
216  }
217 
218  /// Broken copy constructor
220  {
221  BrokenCopy::broken_copy("PressureBasedSolidLSCPreconditioner");
222  }
223 
224  /// Broken assignment operator
225 //Commented out broken assignment operator because this can lead to a conflict warning
226 //when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
227 //realise that two separate implementations of the broken function are the same and so,
228 //quite rightly, it shouts.
229  /*void operator=(const PressureBasedSolidLSCPreconditioner&)
230  {
231  BrokenCopy::broken_assign("PressureBasedSolidLSCPreconditioner");
232  }*/
233 
234  /// Setup the preconditioner
235  void setup();
236 
237  /// Apply preconditioner to Vector r
239 
240  /// specify the mesh containing the mesh containing the
241  /// block-preconditionable solid elements. The dimension of the
242  /// problem must also be specified.
244  {
246  }
247 
248  /// \short Enable mass matrix diagonal scaling in the
249  /// Schur complement approximation
251 
252  /// \short Enable mass matrix diagonal scaling in the
253  /// Schur complement approximation
255 
256  /// \short Return whether the mass matrix is using diagonal
257  /// scaling or not
259 
260  /// Function to set a new pressure matrix preconditioner (inexact solver)
261  void set_p_preconditioner(Preconditioner* new_p_preconditioner_pt)
262  {
263  // If the default preconditioner has been used
264  // clean it up now...
266  {
267  delete P_preconditioner_pt;
268  }
269  P_preconditioner_pt = new_p_preconditioner_pt;
271  }
272 
273  /// \short Function to (re-)set pressure matrix preconditioner (inexact
274  /// solver) to SuperLU
276  {
278  {
281  }
282  }
283 
284  /// Function to set a new momentum matrix preconditioner (inexact solver)
285  void set_f_preconditioner(Preconditioner* new_f_preconditioner_pt)
286  {
287  // If the default preconditioner has been used
288  // clean it up now...
290  {
291  delete F_preconditioner_pt;
292  }
293  F_preconditioner_pt = new_f_preconditioner_pt;
295  }
296 
297  ///\short Function to (re-)set momentum matrix preconditioner (inexact
298  /// solver) to SuperLU
300  {
302  {
305  }
306  }
307 
308 
309  ///Enable documentation of time
310  void enable_doc_time() {Doc_time = true;}
311 
312  ///Disable documentation of time
313  void disable_doc_time() {Doc_time = false;}
314 
315  /// \short If this function is called then:
316  /// in setup(...) : BFBt is computed.
317  /// in preconditioner_solve(...) : a single matrix vector product with
318  /// BFBt is performed.
320 
321  /// \short if this function is called then:
322  /// in setup(...) : the matrices B, F are assembled and stored
323  /// (the default behaviour) .
324  /// in preconditioner_solve(...) : a sequence of matrix vector products
325  /// with B, F, and Bt is performed.
326  /// (Note: in this discussion no scaling was considered but B and Bt
327  /// are replaced with BQ and QBt with scaling)
329 
330  /// \short Helper function to delete preconditioner data.
331  void clean_up_memory();
332 
333  private:
334 
335  // oomph-lib objects
336  // -----------------
337 
338  // Pointers to preconditioner (=inexact solver) objects
339  // -----------------------------------------------------
340  /// Pointer to the 'preconditioner' for the pressure matrix
342 
343  /// Pointer to the 'preconditioner' for the F matrix
345 
346  /// flag indicating whether the default F preconditioner is used
348 
349  /// flag indicating whether the default P preconditioner is used
351 
352  /// \short Control flag is true if the preconditioner has been setup
353  /// (used so we can wipe the data when the preconditioner is
354  /// called again)
356 
357  /// \short Control flag is true if mass matrix diagonal scaling
358  /// is used in the Schur complement approximation
360 
361  /// Helper function to assemble the diagonal of the
362  /// mass matrix from the elemental contributions defined in
363  /// PressureBasedSolidEquations<DIM>::get_mass_matrix_diagonal(...).
365 
366  /// \short Boolean indicating whether the momentum system preconditioner
367  /// is a block preconditioner
369 
370  /// Set Doc_time to true for outputting results of timings
371  bool Doc_time;
372 
373  /// MatrixVectorProduct operator for F if BFBt is not to be formed.
375 
376  /// MatrixVectorProduct operator for QBt if BFBt is not to be formed.
378 
379  /// MatrixVectorProduct operator for Bt;
381 
382  /// MatrixVectorProduct operator for E (BFBt) if BFBt is to be formed.
384 
385  /// \short indicates whether BFBt should be formed or the component matrices
386  /// should be retained.
387  /// If true then:
388  /// in setup(...) : BFBt is computed.
389  /// in preconditioner_solve(...) : a single matrix vector product with
390  /// BFBt is performed.
391  /// if false then:
392  /// in setup(...) : the matrices B, F are assembled and stored.
393  /// in preconditioner_solve(...) : a sequence of matrix vector products
394  /// with B, F, and Bt is performed.
395  /// (Note: in this discussion no scaling was considered but B and Bt
396  /// are replaced with BQ and QBt with scaling)
398 
399  /// \short the pointer to the mesh of block preconditionable solid
400  /// elements.
402  };
403 
404 
405 
406 ///////////////////////////////////////////////////////////////////////////////
407 ///////////////////////////////////////////////////////////////////////////////
408 ///////////////////////////////////////////////////////////////////////////////
409 
410 
411 
412 //============================================================================
413 /// \short The exact solid preconditioner. This extracts 2x2 blocks
414 /// (corresponding to the displacement/position and pressure unknowns)
415 /// and uses these to
416 /// build a single preconditioner matrix for testing purposes.
417 /// Iterative solvers should converge in a single step if this is used.
418 /// If it doesn't something is wrong in the setup of the block matrices.
419 //=============================================================================
420  template<typename MATRIX>
422  {
423 
424  public :
425 
426  /// Constructor - do nothing
428 
429 
430  /// Destructor - do nothing
432 
433 
434  /// Broken copy constructor
436  {
437  BrokenCopy::broken_copy("PressureBasedSolidExactPreconditioner");
438  }
439 
440 
441  /// Broken assignment operator
442  /*void operator=(const PressureBasedSolidExactPreconditioner&)
443  {
444  BrokenCopy::broken_assign("PressureBasedSolidExactPreconditioner");
445  }*/
446 
447 
448  /// Setup the preconditioner
449  void setup();
450 
451  /// Apply preconditioner to r
453  Vector<double> &z);
454 
455  protected :
456 
457  /// Preconditioner matrix
458  MATRIX P_matrix;
459 
460  };
461 
462 }
463 #endif
bool Form_BFBt_product
indicates whether BFBt should be formed or the component matrices should be retained. If true then: in setup(...) : BFBt is computed. in preconditioner_solve(...) : a single matrix vector product with BFBt is performed. if false then: in setup(...) : the matrices B, F are assembled and stored. in preconditioner_solve(...) : a sequence of matrix vector products with B, F, and Bt is performed. (Note: in this discussion no scaling was considered but B and Bt are replaced with BQ and QBt with scaling)
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Preconditioner * P_preconditioner_pt
Pointer to the &#39;preconditioner&#39; for the pressure matrix.
void clean_up_memory()
Helper function to delete preconditioner data.
MatrixVectorProduct * Bt_mat_vec_pt
MatrixVectorProduct operator for Bt;.
PressureBasedSolidExactPreconditioner()
Constructor - do nothing.
void enable_doc_time()
Enable documentation of time.
bool P_matrix_using_scaling
Control flag is true if mass matrix diagonal scaling is used in the Schur complement approximation...
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...
The exact solid preconditioner. This extracts 2x2 blocks (corresponding to the displacement/position ...
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to Vector r.
PressureBasedSolidLSCPreconditioner(const PressureBasedSolidLSCPreconditioner &)
Broken copy constructor.
MatrixVectorProduct * F_mat_vec_pt
MatrixVectorProduct operator for F if BFBt is not to be formed.
PressureBasedSolidLSCPreconditioner()
Constructor - sets defaults for control flags.
MatrixVectorProduct * QBt_mat_vec_pt
MatrixVectorProduct operator for QBt if BFBt is not to be formed.
PressureBasedSolidExactPreconditioner(const PressureBasedSolidExactPreconditioner &)
Broken copy constructor.
void disable_doc_time()
Disable documentation of time.
~PressureBasedSolidExactPreconditioner()
Destructor - do nothing.
bool Using_default_f_preconditioner
flag indicating whether the default F preconditioner is used
void disable_form_BFBt_product()
if this function is called then: in setup(...) : the matrices B, F are assembled and stored (the defa...
void enable_form_BFBt_product()
If this function is called then: in setup(...) : BFBt is computed. in preconditioner_solve(...) : a single matrix vector product with BFBt is performed.
The least-squares commutator (LSC; formerly BFBT) preconditioner. It uses blocks corresponding to the...
MatrixVectorProduct * E_mat_vec_pt
MatrixVectorProduct operator for E (BFBt) if BFBt is to be formed.
void set_f_superlu_preconditioner()
Function to (re-)set momentum matrix preconditioner (inexact solver) to SuperLU.
void set_f_preconditioner(Preconditioner *new_f_preconditioner_pt)
Function to set a new momentum matrix preconditioner (inexact solver)
void set_nmesh(const unsigned &n)
Specify the number of meshes required by this block preconditioner. Note: elements in different meshe...
bool F_preconditioner_is_block_preconditioner
Boolean indicating whether the momentum system preconditioner is a block preconditioner.
void set_p_superlu_preconditioner()
Function to (re-)set pressure matrix preconditioner (inexact solver) to SuperLU.
void set_p_preconditioner(Preconditioner *new_p_preconditioner_pt)
Function to set a new pressure matrix preconditioner (inexact solver)
bool Preconditioner_has_been_setup
Control flag is true if the preconditioner has been setup (used so we can wipe the data when the prec...
An interface to allow SuperLU to be used as an (exact) Preconditioner.
Preconditioner base class. Gives an interface to call all other preconditioners through and stores th...
void setup()
Broken assignment operator.
void enable_p_matrix_scaling()
Enable mass matrix diagonal scaling in the Schur complement approximation.
Matrix vector product helper class - primarily a wrapper to Trilinos&#39;s Epetra matrix vector product m...
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
Definition: double_vector.h:61
bool Using_default_p_preconditioner
flag indicating whether the default P preconditioner is used
bool is_p_matrix_using_scaling() const
Return whether the mass matrix is using diagonal scaling or not.
Mesh * Solid_mesh_pt
the pointer to the mesh of block preconditionable solid elements.
A class for compressed row matrices. This is a distributable object.
Definition: matrices.h:872
void disable_p_matrix_scaling()
Enable mass matrix diagonal scaling in the.
A general mesh class.
Definition: mesh.h:74
Preconditioner * F_preconditioner_pt
Pointer to the &#39;preconditioner&#39; for the F matrix.
bool Doc_time
Set Doc_time to true for outputting results of timings.