general_purpose_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// Version 1.0; svn revision $LastChangedRevision: 1099 $
7 //LIC//
8 //LIC// $LastChangedDate: 2016-01-07 09:05:59 +0000 (Thu, 07 Jan 2016) $
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 
31 //Include guards
32 #ifndef OOMPH_GENERAL_BLOCK_PRECONDITIONERS
33 #define OOMPH_GENERAL_BLOCK_PRECONDITIONERS
34 
35 
36 // Config header generated by autoconfig
37 #ifdef HAVE_CONFIG_H
38 #include <oomph-lib-config.h>
39 #endif
40 
41 // c++ include
42 // #include<list>
43 
44 // oomph-lib includes
45 #include "matrices.h"
46 // #include "mesh.h"
47 // #include "problem.h"
48 #include "block_preconditioner.h"
49 #include "SuperLU_preconditioner.h"
50 #include "preconditioner_array.h"
51 #include "matrix_vector_product.h"
52 
53 
54 namespace oomph
55 {
56 
57  namespace PreconditionerCreationFunctions
58  {
59  /// \short Helper function to create a SuperLu preconditioner (for use as
60  /// the default subsididary preconditioner creator in
61  /// GeneralPurposeBlockPreconditioners).
63  { return new SuperLUPreconditioner; }
64  }
65 
66 
67  //============================================================================
68  /// Base class for general purpose block preconditioners. Deals with
69  /// setting subsidiary preconditioners and dof to block maps.
70  /// Subsidiary preconditioners can be set in two ways:
71  /// 1) A pointer to a subsidiary preconditioner for block i can be passed
72  /// to set_subsidiary_preconditioner_pt(prec, i).
73  /// 2) A default subsidiary preconditioner can be set up by providing a
74  /// function pointer to a function which creates a preconditioner. During
75  /// setup() all unset subsidiary preconditioner pointers will be filled in
76  /// using this function. By default this uses SuperLU.
77  //============================================================================
78  template<typename MATRIX>
80  {
81 
82  public:
83 
84  /// \short typedef for a function that allows other preconditioners to be
85  /// employed to solve the subsidiary linear systems.
86  /// The function should return a pointer to the required subsidiary
87  /// preconditioner generated using new. This preconditioner is responsible
88  /// for the destruction of the subsidiary preconditioners.
89  typedef Preconditioner* (*SubsidiaryPreconditionerFctPt)();
90 
91  /// constructor
93  : BlockPreconditioner<MATRIX>(),
95  (&PreconditionerCreationFunctions::create_super_lu_preconditioner)
96  {
97  // Make sure that the Gp_mesh_pt container is size zero.
98  Gp_mesh_pt.resize(0);
99  }
100 
101  /// Destructor: clean up memory then delete all subsidiary
102  /// preconditioners.
104  {
105  this->clean_up_memory();
106 
107  for(unsigned j=0, nj=Subsidiary_preconditioner_pt.size(); j<nj; j++)
108  {
110  }
111  }
112 
113  /// \short ??ds I think clean_up_memory is supposed to clear out any stuff that
114  /// doesn't need to be stored between solves.
115  /// Call clean up on any non-null subsidiary preconditioners.
116  virtual void clean_up_memory()
117  {
118  // Call clean up in any subsidiary precondtioners that are set.
119  for(unsigned j=0, nj=Subsidiary_preconditioner_pt.size(); j<nj; j++)
120  {
121  if(Subsidiary_preconditioner_pt[j] != 0)
122  {
123  Subsidiary_preconditioner_pt[j]->clean_up_memory();
124  }
125  }
126 
127  // Clean up the block preconditioner base class stuff
129  }
130 
131  /// Broken copy constructor
133  {
134  BrokenCopy::broken_copy("GeneralPurposeBlockPreconditioner");
135  }
136 
137  /// Broken assignment operator
139  {
140  BrokenCopy::broken_assign("GeneralPurposeBlockPreconditioner");
141  }
142 
143  /// access function to set the subsidiary preconditioner function.
146  {
148  }
149 
150  /// Reset the subsidiary preconditioner function to its default
152  {
155  }
156  /// \short Set the subsidiary preconditioner to use for block i. The
157  /// subsidiary preconditioner should have been created using new (the
158  /// general purpose block preconditioner will delete it later). If null
159  /// the general purpose block preconditioner will use the
160  /// Subsidiary_preconditioner_creation_function_pt to create the
161  /// preconditioner during setup().
162  void set_subsidiary_preconditioner_pt(Preconditioner* prec, const unsigned &i)
163  {
164  // If the vector is currently too small to hold that many
165  // preconditioners then expand it and fill with nulls.
166  if(Subsidiary_preconditioner_pt.size() < i +1)
167  {
168  Subsidiary_preconditioner_pt.resize(i+1, 0);
169  }
170  // Note: the size of the vector is checked by
171  // fill_in_subsidiary_preconditioners(..) when we know what size it
172  // should be.
173 
174  // I'm assuming that the number of preconditioners is always "small"
175  // compared to Jacobian size, so a resize doesn't waste much time.
176 
177  // Put the pointer in the vector
179  }
180 
181  /// \short Get the subsidiary precondtioner pointer in block i (is
182  /// allowed to be null if not yet set).
184  { return Subsidiary_preconditioner_pt[i]; }
185 
186  /// \short Specify a DOF to block map
187  void set_dof_to_block_map(Vector<unsigned>& dof_to_block_map)
188  {
189  Dof_to_block_map = dof_to_block_map;
190  }
191 
192  /// \short Adds a mesh to be used by the
193  /// block preconditioning framework for classifying DOF types. Optional boolean
194  /// argument (default: false) allows the mesh to contain multiple element types.
195  void add_mesh(const Mesh* mesh_pt,
196  const bool &allow_multiple_element_type_in_mesh = false)
197  {
198 #ifdef PARANOID
199  // Check that the mesh pointer is not null.
200  if(mesh_pt == 0)
201  {
202  std::ostringstream err_msg;
203  err_msg << "The mesh_pt is null, please point it to a mesh.\n";
204  throw OomphLibError(err_msg.str(),
205  OOMPH_CURRENT_FUNCTION,
206  OOMPH_EXCEPTION_LOCATION);
207  }
208 #endif
209  // Push back the mesh pointer and the boolean in a pair.
210  Gp_mesh_pt.push_back(std::make_pair(mesh_pt,
211  allow_multiple_element_type_in_mesh));
212  }
213 
214  /// \short Returns the number of meshes currently set in the
215  /// GeneralPurposeBlockPreconditioner base class.
216  unsigned gp_nmesh()
217  {
218  return Gp_mesh_pt.size();
219  }
220 
221  protected:
222 
223  /// \short Set the mesh in the block preconditioning framework.
225  {
226  const unsigned nmesh = gp_nmesh();
227 #ifdef PARANOID
228  if(nmesh == 0)
229  {
230  std::ostringstream err_msg;
231  err_msg << "There are no meshes set.\n"
232  << "Have you remembered to call add_mesh(...)?\n";
233  throw OomphLibError(err_msg.str(),
234  OOMPH_CURRENT_FUNCTION,
235  OOMPH_EXCEPTION_LOCATION);
236  }
237 #endif
238 
239  this->set_nmesh(nmesh);
240  for (unsigned mesh_i = 0; mesh_i < nmesh; mesh_i++)
241  {
242  this->set_mesh(mesh_i,
243  Gp_mesh_pt[mesh_i].first,
244  Gp_mesh_pt[mesh_i].second);
245  }
246  }
247 
248  /// Modified block setup for general purpose block preconditioners
250  {
251  if (Dof_to_block_map.size() > 0)
252  {
254  }
255  else
256  {
258  }
259  }
260 
261  /// \short Create any subsidiary preconditioners needed. Usually
262  /// nprec_needed = nblock_types, except for the ExactBlockPreconditioner
263  /// which only requires one preconditioner.
264  void fill_in_subsidiary_preconditioners(const unsigned &nprec_needed)
265  {
266 
267  // If it's empty then fill it in with null pointers.
268  if(Subsidiary_preconditioner_pt.empty())
269  {
270  Subsidiary_preconditioner_pt.assign(nprec_needed, 0);
271  }
272  else
273  {
274  // Otherwise check we have the right number of them
275 #ifdef PARANOID
276  if(Subsidiary_preconditioner_pt.size() != nprec_needed)
277  {
278  using namespace StringConversion;
279  std::string error_msg = "Wrong number of precondtioners in";
280  error_msg += "Subsidiary_preconditioner_pt, should have ";
281  error_msg += to_string(nprec_needed) + " but we actually have ";
282  error_msg += to_string(Subsidiary_preconditioner_pt.size());
283  throw OomphLibError(error_msg, OOMPH_CURRENT_FUNCTION,
284  OOMPH_EXCEPTION_LOCATION);
285  }
286 #endif
287  }
288 
289 
290  // Now replace any null pointers with new preconditioners
291  for(unsigned j=0, nj=Subsidiary_preconditioner_pt.size(); j<nj; j++)
292  {
293  if(Subsidiary_preconditioner_pt[j] == 0)
294  {
296  (*Subsidiary_preconditioner_creation_function_pt)();
297  }
298  }
299 
300  }
301 
302  /// List of preconditioners to use for the blocks to be solved.
304 
305  /// Function to create any subsidiary preconditioners not set in
306  /// Subsidiary_preconditioner_pt.
308 
309  private:
310 
311  /// the set of dof to block maps for this preconditioner
313 
314  /// Vector of mesh pointers and a boolean indicating if we allow multiple
315  /// element types in the same mesh.
317  };
318 
319 
320 
321  //=============================================================================
322  /// \short Block diagonal preconditioner. By default SuperLU is used to solve
323  /// the subsidiary systems, but other preconditioners can be used by setting
324  /// them using passing a pointer to a function of type
325  /// SubsidiaryPreconditionerFctPt to the method
326  /// subsidiary_preconditioner_function_pt().
327  //=============================================================================
328  template<typename MATRIX>
330  : public GeneralPurposeBlockPreconditioner<MATRIX>
331  {
332 
333  public :
334 
335  /// constructor - when the preconditioner is used as a master preconditioner
337  {
338  // by default we do not use two level parallelism
339  Use_two_level_parallelisation = false;
340 
341  // null the Preconditioner array pt
342  Preconditioner_array_pt = 0;
343 
344  // Don't doc by default
345  Doc_time_during_preconditioner_solve=false;
346  }
347 
348  /// Destructor - delete the preconditioner matrices
350  {
351  this->clean_up_memory();
352  }
353 
354  /// clean up the memory
355  virtual void clean_up_memory()
356  {
357  if (Use_two_level_parallelisation)
358  {
359  delete Preconditioner_array_pt;
360  Preconditioner_array_pt = 0;
361  }
362 
363  // Clean up the base class too
365  }
366 
367  /// Broken copy constructor
369  {
370  BrokenCopy::broken_copy("BlockDiagonalPreconditioner");
371  }
372 
373  /// Broken assignment operator
375  {
376  BrokenCopy::broken_assign("BlockDiagonalPreconditioner");
377  }
378 
379  /// Apply preconditioner to r
381 
382  /// \short Setup the preconditioner
383  virtual void setup();
384 
385  /// \short Use two level parallelisation
387  {
388 #ifndef OOMPH_HAS_MPI
389  throw OomphLibError("Cannot do any parallelism since we don't have MPI.",
390  OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
391 #endif
392  Use_two_level_parallelisation = true;
393  }
394 
395  /// \short Don't use two-level parallelisation
397  { Use_two_level_parallelisation = false;}
398 
399  /// Enable Doc timings in application of block sub-preconditioners
401  {Doc_time_during_preconditioner_solve=true;}
402 
403  /// Disable Doc timings in application of block sub-preconditioners
405  {Doc_time_during_preconditioner_solve=false;}
406 
407  void fill_in_subsidiary_preconditioners(const unsigned &nprec_needed)
408  {
409 #ifdef PARANOID
410  if((Use_two_level_parallelisation) &&
411  !this->Subsidiary_preconditioner_pt.empty())
412  {
413  std::string err_msg =
414  "Two level parallelism diagonal block preconditioners cannot have";
415  err_msg += " any preset preconditioners (due to weird memory management";
416  err_msg += " in the PreconditionerArray, you could try fixing it).";
417  throw OomphLibError(err_msg, OOMPH_CURRENT_FUNCTION,
418  OOMPH_EXCEPTION_LOCATION);
419  }
420 #endif
421 
422  // Now call the real function
425  }
426 
427 protected:
428 
429  /// This is a helper function to allow us to implement AntiDiagonal
430  /// preconditioner by only changing this function. Get the second index
431  /// for block number i. Obviously for a diagonal preconditioner we want
432  /// the blocks (i,i), (for anti diagonal we will want blocks (i, nblock -
433  /// i), see that class).
434  virtual unsigned get_other_diag_ds(const unsigned &i,
435  const unsigned &nblock) const
436  { return i; }
437 
438 
439  private :
440 
441  /// pointer for the PreconditionerArray
443 
444  /// Use two level parallelism using the PreconditionerArray
446 
447  /// Doc timings in application of block sub-preconditioners?
449  };
450 
451 
452 
453 
454  ///////////////////////////////////////////////////////////////////////////////
455  ///////////////////////////////////////////////////////////////////////////////
456  ///////////////////////////////////////////////////////////////////////////////
457 
458 
459 
460 
461  //=============================================================================
462  /// \short General purpose block triangular preconditioner
463  /// By default this is Upper triangular.
464  /// By default SuperLUPreconditioner (or SuperLUDistPreconditioner) is used to
465  /// solve the subsidiary systems, but other preconditioners can be used by
466  /// setting them using passing a pointer to a function of type
467  /// SubsidiaryPreconditionerFctPt to the method
468  /// subsidiary_preconditioner_function_pt().
469  //=============================================================================
470  template<typename MATRIX>
472  : public GeneralPurposeBlockPreconditioner<MATRIX>
473  {
474 
475  public :
476 
477  /// Constructor. (By default this preconditioner is upper triangular).
480  {
481  // default to upper triangular
482  Upper_triangular = true;
483  }
484 
485  /// Destructor - delete the preconditioner matrices
487  {
488  this->clean_up_memory();
489  }
490 
491  /// clean up the memory
492  virtual void clean_up_memory()
493  {
494  // Delete anything in Off_diagonal_matrix_vector_products
495  for(unsigned i=0, ni=Off_diagonal_matrix_vector_products.nrow(); i < ni; i++)
496  {
497  for(unsigned j=0, nj=Off_diagonal_matrix_vector_products.ncol(); j < nj; j++)
498  {
499  delete Off_diagonal_matrix_vector_products(i,j);
500  Off_diagonal_matrix_vector_products(i,j) = 0;
501  }
502  }
503 
504  // Clean up the base class too
506  }
507 
508  /// Broken copy constructor
510  {
511  BrokenCopy::broken_copy("BlockTriangularPreconditioner");
512  }
513 
514  /// Broken assignment operator
516  {
517  BrokenCopy::broken_assign("BlockTriangularPreconditioner");
518  }
519 
520  /// Apply preconditioner to r
522 
523  /// \short Setup the preconditioner
524  void setup();
525 
526  /// Use as an upper triangular preconditioner
528  {
529  Upper_triangular = true;
530  }
531 
532  /// Use as a lower triangular preconditioner
534  {
535  Upper_triangular = false;
536  }
537 
538  private:
539 
540  /// Matrix of matrix vector product operators for the off diagonals
542 
543  /// Boolean indicating upper or lower triangular
545  };
546 
547 
548 
549  ///////////////////////////////////////////////////////////////////////////////
550  ///////////////////////////////////////////////////////////////////////////////
551  ///////////////////////////////////////////////////////////////////////////////
552 
553 
554 
555  //=============================================================================
556  /// Exact block preconditioner - block preconditioner assembled from all blocks
557  /// associated with the preconditioner and solved by SuperLU.
558  //=============================================================================
559  template<typename MATRIX>
561  : public GeneralPurposeBlockPreconditioner<MATRIX>
562  {
563 
564  public :
565 
566  /// constructor
568  : GeneralPurposeBlockPreconditioner<MATRIX>() {}
569 
570  /// Destructor
572 
573  /// Broken copy constructor
575  {
576  BrokenCopy::broken_copy("ExactBlockPreconditioner");
577  }
578 
579  /// Broken assignment operator
581  {
582  BrokenCopy::broken_assign("ExactBlockPreconditioner");
583  }
584 
585  /// Apply preconditioner to r
587 
588  /// \short Setup the preconditioner
589  void setup();
590 
591  /// \short Access for the preconditioner pointer used to solve the
592  /// system (stored in the vector of pointers in the base class);
594  {
595  return this->Subsidiary_preconditioner_pt[0];
596  }
597  };
598 
599 
600  // =================================================================
601  /// \short Block "anti-diagonal" preconditioner, i.e. same as block
602  /// diagonal but along the other diagonal of the matrix (top-right to
603  /// bottom-left).
604  // =================================================================
605  template<typename MATRIX>
607  : public BlockDiagonalPreconditioner<MATRIX>
608  {
609  protected:
610 
611  /// This is a helper function to allow us to implement BlockAntiDiagonal
612  /// using BlockDiagonal preconditioner and only changing this
613  /// function. Get the second index for block number i. Obviously for a
614  /// diagonal preconditioner we want the blocks (i,i). For anti diagonal
615  /// we will want blocks (i, nblock - i - 1).
616  unsigned get_other_diag_ds(const unsigned &i,
617  const unsigned &nblock) const
618  { return nblock - i -1; }
619 
620  };
621 
622 
623 
624  // =================================================================
625  /// Preconditioner that doesn't actually do any preconditioning, it just
626  /// allows access to the Jacobian blocks. This is pretty hacky but oh well..
627  // =================================================================
628  template<typename MATRIX>
630  : public GeneralPurposeBlockPreconditioner<MATRIX>
631  {
632 
633  public :
634 
635  /// Constructor
637  : GeneralPurposeBlockPreconditioner<MATRIX>() {}
638 
639  /// Destructor
641 
642  /// Broken copy constructor
644  {
645  BrokenCopy::broken_copy("DummyBlockPreconditioner");
646  }
647 
648  /// Broken assignment operator
650  {
651  BrokenCopy::broken_assign("DummyBlockPreconditioner");
652  }
653 
654  /// Apply preconditioner to r (just copy r to z).
656  {z.build(r);}
657 
658  /// \short Setup the preconditioner
659  void setup()
660  {
661  // Set up the block look up schemes
662  this->block_setup();
663  }
664 
665  };
666 
667 }
668 #endif
void clear_block_preconditioner_base()
Clears all BlockPreconditioner data. Called by the destructor and the block_setup(...) methods.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void set_subsidiary_preconditioner_pt(Preconditioner *prec, const unsigned &i)
Set the subsidiary preconditioner to use for block i. The subsidiary preconditioner should have been ...
virtual void preconditioner_solve(const DoubleVector &r, DoubleVector &z)=0
Apply the preconditioner. Pure virtual generic interface function. This method should apply the preco...
GeneralPurposeBlockPreconditioner(const GeneralPurposeBlockPreconditioner &)
Broken copy constructor.
bool Doc_time_during_preconditioner_solve
Doc timings in application of block sub-preconditioners?
unsigned gp_nmesh()
Returns the number of meshes currently set in the GeneralPurposeBlockPreconditioner base class...
DummyBlockPreconditioner(const DummyBlockPreconditioner &)
Broken copy constructor.
void set_subsidiary_preconditioner_function(SubsidiaryPreconditionerFctPt sub_prec_fn)
access function to set the subsidiary preconditioner function.
cstr elem_len * i
Definition: cfortran.h:607
PreconditionerArray * Preconditioner_array_pt
pointer for the PreconditionerArray
void operator=(const DummyBlockPreconditioner &)
Broken assignment operator.
void reset_subsidiary_preconditioner_function_to_default()
Reset the subsidiary preconditioner function to its default.
void preconditioner_solve(const DoubleVector &r, DoubleVector &z)
Apply preconditioner to r (just copy r to z).
ExactBlockPreconditioner(const ExactBlockPreconditioner &)
Broken copy constructor.
void enable_doc_time_during_preconditioner_solve()
Enable Doc timings in application of block sub-preconditioners.
bool Upper_triangular
Boolean indicating upper or lower triangular.
void gp_preconditioner_set_all_meshes()
Set the mesh in the block preconditioning framework.
void lower_triangular()
Use as a lower triangular preconditioner.
PreconditionerArray - NOTE - first implementation, a number of assumptions / simplifications were mad...
virtual void clean_up_memory()
??ds I think clean_up_memory is supposed to clear out any stuff that doesn't need to be stored betwee...
Block "anti-diagonal" preconditioner, i.e. same as block diagonal but along the other diagonal of the...
void fill_in_subsidiary_preconditioners(const unsigned &nprec_needed)
Create any subsidiary preconditioners needed. Usually nprec_needed = nblock_types, except for the ExactBlockPreconditioner which only requires one preconditioner.
bool Use_two_level_parallelisation
Use two level parallelism using the PreconditionerArray.
void operator=(const GeneralPurposeBlockPreconditioner &)
Broken assignment operator.
virtual ~BlockTriangularPreconditioner()
Destructor - delete the preconditioner matrices.
Preconditioner * subsidiary_preconditioner_pt(const unsigned &i) const
Get the subsidiary precondtioner pointer in block i (is allowed to be null if not yet set)...
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
BlockTriangularPreconditioner()
Constructor. (By default this preconditioner is upper triangular).
Vector< unsigned > Dof_to_block_map
the set of dof to block maps for this preconditioner
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...
void operator=(const BlockDiagonalPreconditioner &)
Broken assignment operator.
unsigned nmesh() const
Return the number of meshes in Mesh_pt.
virtual void block_setup()
Determine the size of the matrix blocks and setup the lookup schemes relating the global degrees of f...
void disable_doc_time_during_preconditioner_solve()
Disable Doc timings in application of block sub-preconditioners.
void set_nmesh(const unsigned &n)
Specify the number of meshes required by this block preconditioner. Note: elements in different meshe...
void disable_two_level_parallelisation()
Don't use two-level parallelisation.
virtual unsigned get_other_diag_ds(const unsigned &i, const unsigned &nblock) const
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...
void operator=(const BlockTriangularPreconditioner &)
Broken assignment operator.
void enable_two_level_parallelisation()
Use two level parallelisation.
void operator=(const ExactBlockPreconditioner &)
Broken assignment operator.
Preconditioner *(* SubsidiaryPreconditionerFctPt)()
typedef for a function that allows other preconditioners to be employed to solve the subsidiary linea...
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...
BlockDiagonalPreconditioner(const BlockDiagonalPreconditioner &)
Broken copy constructor.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Block diagonal preconditioner. By default SuperLU is used to solve the subsidiary systems...
void upper_triangular()
Use as an upper triangular preconditioner.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
BlockTriangularPreconditioner(const BlockTriangularPreconditioner &)
Broken copy constructor.
unsigned get_other_diag_ds(const unsigned &i, const unsigned &nblock) const
virtual void setup()=0
Setup the preconditioner. Pure virtual generic interface function.
void gp_preconditioner_block_setup()
Modified block setup for general purpose block preconditioners.
Class for dense matrices, storing all the values of the matrix as a pointer to a pointer with assorte...
Definition: communicator.h:50
void fill_in_subsidiary_preconditioners(const unsigned &nprec_needed)
Vector< Preconditioner * > Subsidiary_preconditioner_pt
List of preconditioners to use for the blocks to be solved.
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
void set_dof_to_block_map(Vector< unsigned > &dof_to_block_map)
Specify a DOF to block map.
General purpose block triangular preconditioner By default this is Upper triangular. By default SuperLUPreconditioner (or SuperLUDistPreconditioner) is used to solve the subsidiary systems, but other preconditioners can be used by setting them using passing a pointer to a function of type SubsidiaryPreconditionerFctPt to the method subsidiary_preconditioner_function_pt().
Vector< std::pair< const Mesh *, bool > > Gp_mesh_pt
void add_mesh(const Mesh *mesh_pt, const bool &allow_multiple_element_type_in_mesh=false)
Adds a mesh to be used by the block preconditioning framework for classifying DOF types...
DenseMatrix< MatrixVectorProduct * > Off_diagonal_matrix_vector_products
Matrix of matrix vector product operators for the off diagonals.
virtual ~BlockDiagonalPreconditioner()
Destructor - delete the preconditioner matrices.
BlockDiagonalPreconditioner()
constructor - when the preconditioner is used as a master preconditioner
Preconditioner *& preconditioner_pt()
Access for the preconditioner pointer used to solve the system (stored in the vector of pointers in t...
A general mesh class.
Definition: mesh.h:74
SubsidiaryPreconditionerFctPt Subsidiary_preconditioner_creation_function_pt
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types)...
Preconditioner * create_super_lu_preconditioner()
Helper function to create a SuperLu preconditioner (for use as the default subsididary preconditioner...