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_PETSC_MATRIX_BASE_H 21 : #define LIBMESH_PETSC_MATRIX_BASE_H 22 : 23 : #include "libmesh/libmesh_common.h" 24 : 25 : #ifdef LIBMESH_HAVE_PETSC 26 : 27 : // Local includes 28 : #include "libmesh/sparse_matrix.h" 29 : #include "libmesh/petsc_macro.h" 30 : #include "libmesh/petsc_solver_exception.h" 31 : #include "libmesh/wrapped_petsc.h" 32 : 33 : // Petsc include files. 34 : #ifdef I 35 : # define LIBMESH_SAW_I 36 : #endif 37 : #include <petscmat.h> 38 : #ifndef LIBMESH_SAW_I 39 : # undef I // Avoid complex.h contamination 40 : #endif 41 : 42 : // Macro to identify and debug functions which should be called in 43 : // parallel on parallel matrices but which may be called in serial on 44 : // serial matrices. This macro will only be valid inside non-static 45 : // PetscMatrix methods 46 : #undef semiparallel_only 47 : #undef exceptionless_semiparallel_only 48 : #ifndef NDEBUG 49 : #include <cstring> 50 : 51 : #define semiparallel_only() do { if (this->initialized()) { const char * mytype; \ 52 : LibmeshPetscCall(MatGetType(this->_mat,&mytype)); \ 53 : if (!strcmp(mytype, MATSEQAIJ)) \ 54 : parallel_object_only(); } } while (0) 55 : #define exceptionless_semiparallel_only() do { if (this->initialized()) { const char * mytype; \ 56 : auto semiparallel_only_ierr = MatGetType(this->_mat,&mytype); \ 57 : libmesh_ignore(semiparallel_only_ierr); \ 58 : if (!strcmp(mytype, MATSEQAIJ)) \ 59 : exceptionless_parallel_object_only(); } } while (0) 60 : #else 61 : #define semiparallel_only() 62 : #define exceptionless_semiparallel_only() 63 : #endif 64 : 65 : 66 : namespace libMesh 67 : { 68 : 69 : /** 70 : * This class provides a nice interface to the PETSc C-based data 71 : * structures for parallel, sparse matrices. All overridden virtual 72 : * functions are documented in sparse_matrix.h. 73 : * 74 : * \author Benjamin S. Kirk 75 : * \date 2002 76 : * \brief SparseMatrix interface to PETSc Mat. 77 : */ 78 : template <typename T> 79 : class PetscMatrixBase : public SparseMatrix<T> 80 : { 81 : public: 82 : explicit 83 : PetscMatrixBase (const Parallel::Communicator & comm_in); 84 : 85 : /** 86 : * Constructor. Creates a PetscMatrixBase assuming you already have a 87 : * valid Mat object. In this case, m may not be destroyed by the 88 : * PetscMatrixBase destructor when this object goes out of scope. This 89 : * allows ownership of m to remain with the original creator, and to 90 : * simply provide additional functionality with the PetscMatrixBase. 91 : */ 92 : explicit 93 : PetscMatrixBase (Mat m, 94 : const Parallel::Communicator & comm_in, 95 : bool destroy_on_exit = false); 96 : 97 : /** 98 : * This class manages a C-style struct (Mat) manually, so we 99 : * don't want to allow any automatic copy/move functions to be 100 : * generated, and we can't default the destructor. 101 : */ 102 : PetscMatrixBase (PetscMatrixBase &&) = delete; 103 : PetscMatrixBase (const PetscMatrixBase &) = delete; 104 : PetscMatrixBase & operator= (PetscMatrixBase &&) = delete; 105 : virtual ~PetscMatrixBase (); 106 : 107 6 : virtual SolverPackage solver_package() override 108 : { 109 6 : return PETSC_SOLVERS; 110 : } 111 : 112 : /** 113 : * \returns The raw PETSc matrix pointer. 114 : * 115 : * \note This is generally not required in user-level code. 116 : * 117 : * \note Don't do anything crazy like calling MatDestroy() on 118 : * it, or very bad things will likely happen! 119 : */ 120 3758008 : Mat mat () { libmesh_assert (_mat); return _mat; } 121 0 : Mat mat() const { libmesh_assert(_mat); return _mat; } 122 : 123 : /** 124 : * clear() is called from the destructor, so it should not throw. 125 : */ 126 : virtual void clear() noexcept override; 127 : 128 : /** 129 : * If set to false, we don't delete the Mat on destruction and allow 130 : * instead for \p PETSc to manage it. 131 : */ 132 : void set_destroy_mat_on_exit(bool destroy = true); 133 : 134 : /** 135 : * Swaps the internal data pointers of two PetscMatrices, no actual 136 : * values are swapped. 137 : */ 138 : void swap (PetscMatrixBase<T> &); 139 : 140 : using SparseMatrix<T>::operator=; 141 : 142 : /** 143 : * Set the context (ourself) for \p _mat 144 : */ 145 : void set_context(); 146 : 147 : /** 148 : * @returns The context for \p mat if it exists, else a \p nullptr 149 : */ 150 : static PetscMatrixBase<T> * get_context(Mat mat, const TIMPI::Communicator & comm); 151 : 152 : virtual numeric_index_type m () const override; 153 : 154 : virtual numeric_index_type local_m () const final; 155 : 156 : virtual numeric_index_type n () const override; 157 : 158 : /** 159 : * Get the number of columns owned by this process 160 : */ 161 : virtual numeric_index_type local_n () const final; 162 : 163 : virtual numeric_index_type row_start () const override; 164 : 165 : virtual numeric_index_type row_stop () const override; 166 : 167 : virtual numeric_index_type col_start () const override; 168 : 169 : virtual numeric_index_type col_stop () const override; 170 : 171 : virtual void close () override; 172 : 173 : virtual bool closed() const override; 174 : 175 : protected: 176 : 177 : /** 178 : * PETSc matrix datatype to store values. 179 : */ 180 : Mat _mat; 181 : 182 : /** 183 : * This boolean value should only be set to \p false for the 184 : * constructor which takes a PETSc Mat object. 185 : */ 186 : bool _destroy_mat_on_exit; 187 : }; 188 : 189 : } // namespace libMesh 190 : 191 : #endif // #ifdef LIBMESH_HAVE_PETSC 192 : #endif // LIBMESH_PETSC_MATRIX_BASE_H