simple_block_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-2022 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 
27 //Include guards
28 #ifndef OOMPH_SIMPLE_BLOCK_PRECONDITIONERS
29 #define OOMPH_SIMPLE_BLOCK_PRECONDITIONERS
30 
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 // c++ include
38 #include<list>
39 
40 // oomph-lib includes
41 #include "generic.h"
42 
43 namespace oomph
44 {
45 
46 
47 //===start_of_simple_block_diagonal_preconditioner_class=======================
50 //=============================================================================
51  template<typename MATRIX>
53  {
54 
55  public :
56 
59  {
60  } // end_of_constructor
61 
62 
65  {
66  // Delete diagonal preconditioners (approximate solvers)
67  unsigned n_block = Diagonal_block_preconditioner_pt.size();
68  for (unsigned i = 0 ; i < n_block; i++)
69  {
72  }
73  }
74 
77  {
78  BrokenCopy::broken_copy("SimpleBlockDiagonalPreconditioner");
79  }
80 
83  {
84  BrokenCopy::broken_assign("SimpleBlockDiagonalPreconditioner");
85  }
86 
89 
91  virtual void setup();
92 
94  void add_mesh(const Mesh* const mesh_pt)
95  {
96 #ifdef PARANOID
97  // Check that the mesh pointer is not null.
98  if(mesh_pt == 0)
99  {
100  std::ostringstream err_msg;
101  err_msg << "The mesh_pt is null, please point it to a mesh.\n";
102  throw OomphLibError(err_msg.str(),
105  }
106 #endif
107 
108  // Push back the mesh.
109  My_mesh_pt.push_back(mesh_pt);
110  }
111 
112  private :
113 
117 
122 
123  };
124 
125 
126  //==start_of_setup_for_SimpleBlockDiagonalPreconditioner======================
128  //============================================================================
129  template<typename MATRIX>
131  {
132 
133  // Only set the mesh if this is a master block preconditioner.
134  // Otherwise, the DOF ordering information is given by the
135  // master block preconditioner.
136  if(this->is_master_block_preconditioner())
137  {
138  const unsigned my_nmesh = My_mesh_pt.size();
139 
140 #ifdef PARANOID
141  if(my_nmesh == 0)
142  {
143  std::ostringstream err_msg;
144  err_msg << "There are no meshes set.\n"
145  << "Please set at least one mesh with push_back_mesh(...)";
146  throw OomphLibError(err_msg.str(),
149  }
150 #endif
151  // Set the nmesh in the BlockPreconditioner base class
152  this->set_nmesh(my_nmesh);
153 
154  // Loop through all the meshes and set them.
155  for (unsigned mesh_i = 0; mesh_i < my_nmesh; mesh_i++)
156  {
157  this->set_mesh(mesh_i,My_mesh_pt[mesh_i]);
158  }
159  }
160 
161  // Set up the block look up scheme
162  this->block_setup();
163 
164  // Number of blocks
165  unsigned nblock_types = this->nblock_types();
166 
167  // Resize the storage for the diagonal blocks
168  Diagonal_block_preconditioner_pt.resize(nblock_types);
169 
170  // Create the subsidiary preconditioners
171  for (unsigned i=0;i<nblock_types;i++)
172  {
173  Diagonal_block_preconditioner_pt[i] = new SuperLUPreconditioner;
174  }
175 
176  // Get the diagonal matrix blocks
177  Vector<CRDoubleMatrix*> block_diagonal_matrices(nblock_types);
178  for (unsigned i=0;i<nblock_types;i++)
179  {
180  // Get block
182  this->get_block(i,i,block);
183 
184  // Set up preconditioner (i.e. lu-decompose the block)
185  Diagonal_block_preconditioner_pt[i]->setup(&block);
186 
187  // Done with this block now, so can go out of scope; LU decomposition
188  // is retained in superlu
189  }
190  }
191 
192 
193  //=============================================================================
195  //=============================================================================
196  template<typename MATRIX>
199  {
200 
201  // Get number of blocks
202  unsigned n_block = this->nblock_types();
203 
204  // Split up rhs vector into sub-vectors, re-arranged to match
205  // the matrix blocks
206  Vector<DoubleVector> block_r;
207  this->get_block_vectors(r,block_r);
208 
209  // Solution of block solves
210  Vector<DoubleVector> block_z(n_block);
211  for (unsigned i = 0; i < n_block; i++)
212  {
213  Diagonal_block_preconditioner_pt[i]->preconditioner_solve(block_r[i],
214  block_z[i]);
215  }
216 
217  // Copy solution in block vectors block_z back to z
218  this->return_block_vectors(block_z,z);
219  }
220 
221 
222 
223 
227 
228 
229 
230 
231 }
232 #endif
233 
int i
Definition: BiCGSTAB_step_by_step.cpp:9
m m block(1, 0, 2, 2)<< 4
Definition: block_preconditioner.h:422
const Mesh * mesh_pt(const unsigned &i) const
Definition: block_preconditioner.h:1782
Definition: matrices.h:888
Definition: double_vector.h:58
Definition: mesh.h:67
Definition: oomph_definitions.h:222
Definition: simple_block_preconditioners.h:53
void operator=(const SimpleBlockDiagonalPreconditioner &)
Broken assignment operator.
Definition: simple_block_preconditioners.h:82
~SimpleBlockDiagonalPreconditioner()
Destructor - delete the diagonal solvers.
Definition: simple_block_preconditioners.h:64
Vector< const Mesh * > My_mesh_pt
Definition: simple_block_preconditioners.h:121
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r.
Definition: simple_block_preconditioners.h:198
SimpleBlockDiagonalPreconditioner()
Constructor for SimpleBlockDiagonalPreconditioner.
Definition: simple_block_preconditioners.h:58
void add_mesh(const Mesh *const mesh_pt)
Add a mesh.
Definition: simple_block_preconditioners.h:94
Vector< Preconditioner * > Diagonal_block_preconditioner_pt
Definition: simple_block_preconditioners.h:116
SimpleBlockDiagonalPreconditioner(const SimpleBlockDiagonalPreconditioner &)
Broken copy constructor.
Definition: simple_block_preconditioners.h:76
virtual void setup()
Setup the preconditioner.
Definition: simple_block_preconditioners.h:130
An interface to allow SuperLU to be used as an (exact) Preconditioner.
Definition: SuperLU_preconditioner.h:40
Definition: oomph-lib/src/generic/Vector.h:58
r
Definition: UniformPSDSelfTest.py:20
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Definition: oomph_utilities.cc:195
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Definition: oomph_utilities.cc:212
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86