Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : #ifndef LIBMESH_PRECONDITIONER_H 21 : #define LIBMESH_PRECONDITIONER_H 22 : 23 : 24 : // Local includes 25 : #include "libmesh/libmesh_common.h" 26 : #include "libmesh/reference_counted_object.h" 27 : #include "libmesh/libmesh.h" 28 : #include "libmesh/parallel_object.h" 29 : 30 : // C++ includes 31 : #include <cstddef> 32 : 33 : namespace libMesh 34 : { 35 : 36 : // forward declarations 37 : template <typename T> class SparseMatrix; 38 : template <typename T> class NumericVector; 39 : template <typename T> class ShellMatrix; 40 : enum SolverPackage : int; 41 : enum PreconditionerType : int; 42 : 43 : /** 44 : * This class provides a uniform interface for preconditioners. This base 45 : * class can be inherited from to wrap preconditioners from different packages 46 : * like PETSc or Trilinos. 47 : * 48 : * In the below comments P is the matrix to be preconditioned with Apply() 49 : * performing the equivalent of the matrix vector product P^-1 x. This 50 : * can also be thought of as (usually approximately) solving for Py=x. 51 : * 52 : * \author Derek Gaston 53 : * \date 2009 54 : */ 55 : template <typename T> 56 : class Preconditioner : public ReferenceCountedObject<Preconditioner<T>>, 57 : public ParallelObject 58 : { 59 : public: 60 : 61 : /** 62 : * Constructor. Initializes Preconditioner data structures. 63 : */ 64 : Preconditioner (const libMesh::Parallel::Communicator & comm); 65 : 66 : /** 67 : * Destructor. 68 : */ 69 : virtual ~Preconditioner (); 70 : 71 : /** 72 : * Builds a \p Preconditioner using the linear solver package 73 : * specified by \p solver_package, returning the result wrapped in a 74 : * std::unique_ptr for safety. 75 : */ 76 : static std::unique_ptr<Preconditioner<T>> 77 : build_preconditioner(const libMesh::Parallel::Communicator & comm, 78 : const SolverPackage solver_package = libMesh::default_solver_package()); 79 : 80 : /** 81 : * \returns \p true if the data structures are initialized, \p false 82 : * otherwise. 83 : */ 84 0 : virtual bool initialized () const { return _is_initialized; } 85 : 86 : /** 87 : * Computes the preconditioned vector \p y based on input vector \p 88 : * x. This is usually done by solving \f$ Py=x \f$ to get the 89 : * action of \f$ P^-1 x \f$. 90 : */ 91 : virtual void apply(const NumericVector<T> & x, NumericVector<T> & y) = 0; 92 : 93 : /** 94 : * Release all memory and clear data structures. 95 : */ 96 10 : virtual void clear () {} 97 : 98 : /** 99 : * Initialize data structures if not done so already. 100 : * 101 : * \note This MUST be called before the preconditioning object is used. 102 : */ 103 0 : virtual void init () {} 104 : 105 : /** 106 : * This is called every time the "operator might have changed". 107 : * 108 : * This is where you need to fill in your preconditioning matrix. 109 : */ 110 0 : virtual void setup () {} 111 : 112 : /** 113 : * Can be used to zero items relevant to the preconditioner 114 : */ 115 0 : virtual void zero() {} 116 : 117 : /** 118 : * Sets the matrix to be preconditioned. 119 : */ 120 : void set_matrix(SparseMatrix<Number> & mat); 121 : 122 : /** 123 : * \returns The type of preconditioner to use. 124 : */ 125 0 : PreconditionerType type () const { return _preconditioner_type; } 126 : 127 : /** 128 : * Sets the type of preconditioner to use. 129 : */ 130 : void set_type (const PreconditionerType pct); 131 : 132 : protected: 133 : 134 : /** 135 : * The matrix P... ie the matrix to be preconditioned. 136 : * This is often the actual system matrix of a linear system. 137 : */ 138 : SparseMatrix<T> * _matrix; 139 : 140 : /** 141 : * Enum stating with type of preconditioner to use. 142 : */ 143 : PreconditionerType _preconditioner_type; 144 : 145 : /** 146 : * Flag indicating if the data structures have been initialized. 147 : */ 148 : bool _is_initialized; 149 : }; 150 : 151 : 152 : 153 : 154 : /*----------------------- inline functions ----------------------------------*/ 155 : template <typename T> 156 : inline 157 10 : Preconditioner<T>::~Preconditioner () 158 : { 159 10 : this->clear (); 160 10 : } 161 : 162 : template <typename T> 163 : void 164 14 : Preconditioner<T>::set_matrix(SparseMatrix<Number> & mat) 165 : { 166 : //If the matrix is changing then we (probably) need to reinitialize. 167 490 : _is_initialized = false; 168 292 : _matrix = &mat; 169 212 : } 170 : 171 : template <typename T> 172 : void 173 0 : Preconditioner<T>::set_type (const PreconditionerType pct) 174 : { 175 : //If the preconditioner type changes we (probably) need to reinitialize. 176 0 : _is_initialized = false; 177 0 : _preconditioner_type = pct; 178 0 : } 179 : 180 : } // namespace libMesh 181 : 182 : 183 : #endif // LIBMESH_PRECONDITIONER_H