lagrange_enforced_flow_preconditioner.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-2025 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_LAGRANGE_ENFORCED_FLOW_PRECONDITIONERS_HEADER
27#define OOMPH_LAGRANGE_ENFORCED_FLOW_PRECONDITIONERS_HEADER
28
29
30// Config header
31#ifdef HAVE_CONFIG_H
32#include <oomph-lib-config.h>
33#endif
34
35// oomphlib headers
36#include "generic/matrices.h"
38#include "generic/problem.h"
45#ifdef OOMPH_HAS_HYPRE
47#endif
48#ifdef OOMPH_HAS_TRILINOS
50#endif
51
52namespace oomph
53{
54 //==========================================================================
55 /// Namespace for subsidiary preconditioner creation helper functions
56 //==========================================================================
57 namespace Lagrange_Enforced_Flow_Preconditioner_Subsidiary_Operator_Helper
58 {
59 /// CG with diagonal preconditioner for W-block subsidiary linear
60 /// systems.
61 extern Preconditioner* get_w_cg_preconditioner();
62
63 /// Hypre Boomer AMG setting for the augmented momentum block
64 /// of a 2D Navier-Stokes problem using the simple form of the viscous
65 /// term (for serial code).
66 extern Preconditioner* boomer_amg_for_2D_momentum_simple_visc();
67
68 /// Hypre Boomer AMG setting for the augmented momentum block
69 /// of a 2D Navier-Stokes problem using the stress divergence form of the
70 /// viscous term (for serial code).
71 extern Preconditioner* boomer_amg_for_2D_momentum_stressdiv_visc();
72
73 /// Hypre Boomer AMG setting for the augmented momentum block
74 /// of a 3D Navier-Stokes problem (for serial code).
75 extern Preconditioner* boomer_amg_for_3D_momentum();
76
77 /// Hypre Boomer AMG setting for the augmented momentum block
78 /// of a 3D Navier-Stokes problem (for serial code).
79 extern Preconditioner* boomer_amg2v22_for_3D_momentum();
80
81 /// Hypre Boomer AMG setting for the 2D Poisson problem
82 /// (for serial code).
83 extern Preconditioner* boomer_amg_for_2D_poisson_problem();
84
85 /// Hypre Boomer AMG setting for the 3D Poisson problem
86 /// (for serial code).
87 extern Preconditioner* boomer_amg_for_3D_poisson_problem();
88
89 } // namespace
90 // Lagrange_Enforced_Flow_Preconditioner_Subsidiary_Operator_Helper
91
92
93 //==========================================================================
94 /// The preconditioner for the Lagrange multiplier constrained
95 /// Navier-Stokes equations. The velocity components are constrained by
96 /// Lagrange multiplier, which are applied via OOMPH-LIB's FACE elements.
97 ///
98 ///
99 /// The linearised Jacobian takes the block form:
100 ///
101 /// | F_ns | L^T |
102 /// |------------|
103 /// | L | 0 |
104 ///
105 /// where L correspond to the constrained block,
106 /// F_ns is the Navier-Stokes block with the following block structure
107 ///
108 /// | F | G^T |
109 /// |----------|
110 /// | D | 0 |
111 ///
112 /// Here F is the momentum block, G the discrete gradient operator,
113 /// and D the discrete divergence operator. For unstabilised elements,
114 /// we have D = G^T and in much of the literature the divergence matrix is
115 /// denoted by B.
116 ///
117 /// The Lagrange enforced flow preconditioner takes the form:
118 /// | F_aug | |
119 /// |-------|----|
120 /// | | Wd |
121 ///
122 /// where F_aug = F_ns + L^T*inv(Wd)*L is an augmented Navier-Stokes block
123 /// and Wd=(1/Scaling_sigma)*diag(LL^T).
124 ///
125 /// In our implementation of the preconditioner, the linear systems
126 /// associated with the (1,1) block can either be solved "exactly",
127 /// using SuperLU (in its incarnation as an exact preconditioner;
128 /// this is the default) or by any other Preconditioner (inexact solver)
129 /// specified via the access functions
130 ///
131 /// LagrangeEnforcedFlowPreconditioner::set_navier_stokes_preconditioner(...)
132 ///
133 /// Access to the elements is provided via meshes. However, a Vector of
134 /// meshes is taken, each mesh contains a different type of block
135 /// preconditionable element. This allows the (re-)classification of the
136 /// constrained velocity DOF types.
137 ///
138 /// The first mesh in the Vector Mesh_pt must be the 'bulk' mesh.
139 /// The rest are assumed to contain FACEELMENTS.
140 ///
141 /// Thus, the most general block structure (in 3D) is:
142 ///
143 /// 0 1 2 3 4 5 6 7 8 ..x x+0 x+1 x+2 x+3 x+4
144 /// [u v w p] [u v w l1 l2 ...] [u v w l1 l2 ...] ...
145 /// Bulk Surface 1 Surface 2 ...
146 ///
147 /// where the DOF types in [] are the DOF types associated with each mesh.
148 ///
149 /// For example, consider a unit cube domain [0,1]^3 with parallel outflow
150 /// imposed (in mesh 0) and tangential flow imposed (in mesh 1), then there
151 /// are 13 DOF types and our implementation respects the following
152 /// (natural) DOF type order:
153 ///
154 /// bulk mesh 0 mesh 1
155 /// [0 1 2 3] [4 5 6 7 8 ] [9 10 11 12 ]
156 /// [u v w p] [up vp wp Lp1 Lp2] [ut vt wt Lt1]
157 ///
158 /// Via the appropriate mapping, the block_setup(...) function will
159 /// re-order the DOF types into the following block types:
160 ///
161 /// 0 1 2 3 4 5 6 7 8 9 10 11 12 <- Block type
162 /// 0 4 9 1 5 10 2 6 11 3 7 8 12 <- DOF type
163 /// [u up ut v vp vt w wp wt ] [p] [Lp1 Lp2 Lt1]
164 ///
165 //==========================================================================
167 : public BlockPreconditioner<CRDoubleMatrix>
168 {
169 public:
170 /// This preconditioner includes the option to use subsidiary
171 /// operators other than ExactPreconditioner for this problem.
172 /// This is the typedef of a function that should return an instance
173 /// of a subsidiary preconditioning operator. This preconditioner is
174 /// responsible for the destruction of the subsidiary preconditioners.
175 typedef Preconditioner* (*SubsidiaryPreconditionerFctPt)();
176
177 /// Constructor - initialise variables.
179 {
180 // The null pointer.
182
183 // By default, the linear systems associated with the diagonal blocks
184 // are solved "exactly" using SuperLU (in its incarnation as an exact
185 // preconditioner. This is not a block preconditioner.
187
188 // Flag to indicate to use SuperLU or not.
190
191 // Empty vector of meshes and set the number of meshes to zero.
192 My_mesh_pt.resize(0, 0);
193 My_nmesh = 0;
194
195 // The number of DOF types within the meshes.
196 My_ndof_types_in_mesh.resize(0, 0);
197
198 // Initialise other variables.
200 Scaling_sigma = 0.0;
205 } // constructor
206
207 /// Destructor
209 {
210 this->clean_up_memory();
211 }
212
213 /// Broken copy constructor
215 const LagrangeEnforcedFlowPreconditioner&) = delete;
216
217 /// Broken assignment operator
219
220 /// Setup method for the LagrangeEnforcedFlowPreconditioner.
221 void setup();
222
223 /// Apply the preconditioner.
224 /// r is the residual (rhs), z will contain the solution.
226
227 /// Set the meshes,
228 /// the first mesh in the vector must be the bulk mesh.
229 void set_meshes(const Vector<Mesh*>& mesh_pt);
230
231 /// Set flag to use the infinite norm of the Navier-Stokes F matrix
232 /// as the scaling sigma. This is the default behaviour. Note: the norm of
233 /// the NS F matrix positive, however, we actually use the negative of
234 /// the norm. This is because the underlying Navier-Stokes Jacobian is
235 /// multiplied by -1. Ask Andrew/Matthias for more detail.
240
241 /// Access function to set the scaling sigma.
242 /// Note: this also sets the flag to use the infinite norm of
243 /// the Navier-Stokes F matrix as the scaling sigma to false.
244 /// Warning is given if trying to set scaling sigma to be equal to
245 /// or greater than zero.
247 {
248 // Check if scaling sigma is zero or positive.
249#ifdef PARANOID
250 if (scaling_sigma == 0.0)
251 {
252 std::ostringstream warning_stream;
253 warning_stream << "WARNING: \n"
254 << "Setting scaling_sigma = 0.0 may cause values.\n";
258 }
259 if (scaling_sigma > 0.0)
260 {
261 std::ostringstream warning_stream;
262 warning_stream << "WARNING: " << std::endl
263 << "The scaling (scaling_sigma) is positive: "
264 << Scaling_sigma << "\n"
265 << "Performance may be degraded.\n";
269 }
270#endif
271
274 }
275
276 /// Read (const) function to get the scaling sigma.
277 double scaling_sigma() const
278 {
279 return Scaling_sigma;
280 }
281
282 /// Set a new Navier-Stokes matrix preconditioner
283 /// (inexact solver)
286
287 /// Set Navier-Stokes matrix preconditioner (inexact
288 /// solver) to SuperLU
299
300 /// Clears the memory.
301 void clean_up_memory();
302
303 private:
304 /// Control flag is true if the preconditioner has been setup
305 /// (used so we can wipe the data when the preconditioner is
306 /// called again)
308
309 /// Scaling for the augmentation: Scaling_sigma*(LL^T)
311
312 /// Flag to indicate if we want to use the infinite norm of the
313 /// Navier-Stokes momentum block for the scaling sigma.
315
316 /// Inverse W values
318
319 /// Pointer to the 'preconditioner' for the Navier-Stokes block
321
322 /// Flag to indicate if the preconditioner for the Navier-Stokes
323 /// block is a block preconditioner or not.
325
326 /// Flag to indicate whether the default NS preconditioner is used
328
329 /// Storage for the meshes. In our implementation, the first mesh
330 /// must always be the Navier-Stokes (bulk) mesh, followed by surface
331 /// meshes.
333
334 /// The number of DOF types in each mesh. This is used create
335 /// various lookup lists.
337
338 /// The number of meshes. This is used to create various lookup
339 /// lists.
340 unsigned My_nmesh;
341
342 /// The number of Lagrange multiplier DOF types.
344
345 /// The number of fluid DOF types (including pressure).
347
348 /// The number of velocity DOF types.
350
351 }; // end of LagrangeEnforcedFlowPreconditioner class
352
353} // namespace oomph
354#endif
Block Preconditioner base class. The block structure of the overall problem is determined from the Me...
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...
A class for compressed row matrices. This is a distributable object.
Definition matrices.h:888
A vector in the mathematical sense, initially developed for linear algebra type applications....
The preconditioner for the Lagrange multiplier constrained Navier-Stokes equations....
Preconditioner * Navier_stokes_preconditioner_pt
Pointer to the 'preconditioner' for the Navier-Stokes block.
unsigned N_lagrange_doftypes
The number of Lagrange multiplier DOF types.
void set_scaling_sigma(const double &scaling_sigma)
Access function to set the scaling sigma. Note: this also sets the flag to use the infinite norm of t...
unsigned N_fluid_doftypes
The number of fluid DOF types (including pressure).
void set_navier_stokes_preconditioner(Preconditioner *new_ns_preconditioner_pt=0)
Set a new Navier-Stokes matrix preconditioner (inexact solver)
LagrangeEnforcedFlowPreconditioner(const LagrangeEnforcedFlowPreconditioner &)=delete
Broken copy constructor.
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...
bool Use_norm_f_for_scaling_sigma
Flag to indicate if we want to use the infinite norm of the Navier-Stokes momentum block for the scal...
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply the preconditioner. r is the residual (rhs), z will contain the solution.
double scaling_sigma() const
Read (const) function to get the scaling sigma.
Vector< unsigned > My_ndof_types_in_mesh
The number of DOF types in each mesh. This is used create various lookup lists.
LagrangeEnforcedFlowPreconditioner()
Constructor - initialise variables.
Vector< Vector< double > > Inv_w_diag_values
Inverse W values.
void set_meshes(const Vector< Mesh * > &mesh_pt)
Set the meshes, the first mesh in the vector must be the bulk mesh.
unsigned My_nmesh
The number of meshes. This is used to create various lookup lists.
void use_norm_f_for_scaling_sigma()
Set flag to use the infinite norm of the Navier-Stokes F matrix as the scaling sigma....
void operator=(const LagrangeEnforcedFlowPreconditioner &)=delete
Broken assignment operator.
double Scaling_sigma
Scaling for the augmentation: Scaling_sigma*(LL^T)
void setup()
Setup method for the LagrangeEnforcedFlowPreconditioner.
bool Using_superlu_ns_preconditioner
Flag to indicate whether the default NS preconditioner is used.
bool Navier_stokes_preconditioner_is_block_preconditioner
Flag to indicate if the preconditioner for the Navier-Stokes block is a block preconditioner or not.
void set_superlu_for_navier_stokes_preconditioner()
Set Navier-Stokes matrix preconditioner (inexact solver) to SuperLU.
Vector< Mesh * > My_mesh_pt
Storage for the meshes. In our implementation, the first mesh must always be the Navier-Stokes (bulk)...
unsigned N_velocity_doftypes
The number of velocity DOF types.
An OomphLibWarning object which should be created as a temporary object to issue a warning....
Preconditioner base class. Gives an interface to call all other preconditioners through and stores th...
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Preconditioner * create_exact_preconditioner()
Factory function to create suitable exact preconditioner.
Preconditioner * boomer_amg_for_2D_momentum_stressdiv_visc()
Hypre Boomer AMG setting for the augmented momentum block of a 2D Navier-Stokes problem using the str...
Preconditioner * boomer_amg_for_3D_momentum()
Hypre Boomer AMG setting for the augmented momentum block of a 3D Navier-Stokes problem (for serial c...
Preconditioner * get_w_cg_preconditioner()
CG with diagonal preconditioner for W-block subsidiary linear systems.
Preconditioner * boomer_amg_for_3D_poisson_problem()
Hypre Boomer AMG setting for the 3D Poisson problem (for serial code).
Preconditioner * boomer_amg_for_2D_poisson_problem()
Hypre Boomer AMG setting for the 2D Poisson problem (for serial code).
Preconditioner * boomer_amg_for_2D_momentum_simple_visc()
Hypre Boomer AMG setting for the augmented momentum block of a 2D Navier-Stokes problem using the sim...
Preconditioner * boomer_amg2v22_for_3D_momentum()
Hypre Boomer AMG setting for the augmented momentum block of a 3D Navier-Stokes problem (for serial c...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).