libMesh
petsc_matrix_base.C
Go to the documentation of this file.
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 #include "libmesh/libmesh_config.h"
21 
22 #ifdef LIBMESH_HAVE_PETSC
23 
24 // Local includes
25 #include "libmesh/petsc_matrix_base.h"
26 #include "libmesh/petsc_matrix_shell_matrix.h"
27 #include "libmesh/petsc_matrix.h"
28 
29 namespace libMesh
30 {
31 
32 
33 //-----------------------------------------------------------------------
34 // PetscMatrixBase members
35 
36 
37 // Constructor
38 template <typename T>
40  SparseMatrix<T>(comm_in),
41  _mat(nullptr),
42  _destroy_mat_on_exit(true)
43 {}
44 
45 
46 
47 // Constructor taking an existing Mat but not the responsibility
48 // for destroying it
49 template <typename T>
51  const Parallel::Communicator & comm_in,
52  const bool destroy_on_exit) :
53  SparseMatrix<T>(comm_in),
54  _destroy_mat_on_exit(destroy_on_exit)
55 {
56  this->_mat = mat_in;
57  this->_is_initialized = true;
58 
59  this->set_context();
60 }
61 
62 
63 
64 // Destructor
65 template <typename T>
67 {
68  this->clear();
69 }
70 
71 
72 
73 template <typename T>
74 void PetscMatrixBase<T>::clear () noexcept
75 {
76  if ((this->initialized()) && (this->_destroy_mat_on_exit))
77  {
78  exceptionless_semiparallel_only();
79 
80  // If we encounter an error here, print a warning but otherwise
81  // keep going since we may be recovering from an exception.
82  PetscErrorCode ierr = MatDestroy (&_mat);
83  if (ierr)
84  libmesh_warning("Warning: MatDestroy returned a non-zero error code which we ignored.");
85 
86  this->_is_initialized = false;
87  }
88 }
89 
90 template <typename T>
92 {
93  this->_destroy_mat_on_exit = destroy;
94 }
95 
96 
97 template <typename T>
99 {
100  std::swap(_mat, m_in._mat);
101  std::swap(_destroy_mat_on_exit, m_in._destroy_mat_on_exit);
102 }
103 
104 template <typename T>
106 {
107  libmesh_assert(this->_mat);
108  PetscContainer container;
109  LibmeshPetscCall(PetscContainerCreate(this->comm().get(), &container));
110  LibmeshPetscCall(PetscContainerSetPointer(container, this));
111  LibmeshPetscCall(PetscObjectCompose((PetscObject)(Mat)this->_mat, "PetscMatrixCtx", (PetscObject)container));
112  LibmeshPetscCall(PetscContainerDestroy(&container));
113 }
114 
115 template <typename T>
117 {
118  void * ctx;
119  PetscContainer container;
120  LibmeshPetscCall2(comm, PetscObjectQuery((PetscObject)mat, "PetscMatrixCtx", (PetscObject *)&container));
121  if (!container)
122  return nullptr;
123 
124  LibmeshPetscCall2(comm, PetscContainerGetPointer(container, &ctx));
126  return static_cast<PetscMatrixBase<T> *>(ctx);
127 }
128 
129 template <typename T>
131 {
132  libmesh_assert (this->initialized());
133 
134  PetscInt petsc_m=0, petsc_n=0;
135 
136  LibmeshPetscCall(MatGetSize (this->_mat, &petsc_m, &petsc_n));
137 
138  return static_cast<numeric_index_type>(petsc_m);
139 }
140 
141 template <typename T>
143 {
144  libmesh_assert (this->initialized());
145 
146  PetscInt m = 0;
147 
148  LibmeshPetscCall(MatGetLocalSize (this->_mat, &m, NULL));
149 
150  return static_cast<numeric_index_type>(m);
151 }
152 
153 template <typename T>
155 {
156  libmesh_assert (this->initialized());
157 
158  PetscInt petsc_m=0, petsc_n=0;
159 
160  LibmeshPetscCall(MatGetSize (this->_mat, &petsc_m, &petsc_n));
161 
162  return static_cast<numeric_index_type>(petsc_n);
163 }
164 
165 template <typename T>
167 {
168  libmesh_assert (this->initialized());
169 
170  PetscInt n = 0;
171 
172  LibmeshPetscCall(MatGetLocalSize (this->_mat, NULL, &n));
173 
174  return static_cast<numeric_index_type>(n);
175 }
176 
177 template <typename T>
179 {
180  libmesh_assert (this->initialized());
181 
182  PetscInt start=0, stop=0;
183 
184  LibmeshPetscCall(MatGetOwnershipRange(this->_mat, &start, &stop));
185 
186  return static_cast<numeric_index_type>(start);
187 }
188 
189 template <typename T>
191 {
192  libmesh_assert (this->initialized());
193 
194  PetscInt start=0, stop=0;
195 
196  LibmeshPetscCall(MatGetOwnershipRange(this->_mat, &start, &stop));
197 
198  return static_cast<numeric_index_type>(stop);
199 }
200 
201 template <typename T>
203 {
204  libmesh_assert (this->initialized());
205 
206  PetscInt start=0, stop=0;
207 
208  LibmeshPetscCall(MatGetOwnershipRangeColumn(this->_mat, &start, &stop));
209 
210  return static_cast<numeric_index_type>(start);
211 }
212 
213 template <typename T>
215 {
216  libmesh_assert (this->initialized());
217 
218  PetscInt start=0, stop=0;
219 
220  LibmeshPetscCall(MatGetOwnershipRangeColumn(this->_mat, &start, &stop));
221 
222  return static_cast<numeric_index_type>(stop);
223 }
224 
225 template <typename T>
227 {
228  semiparallel_only();
229 
230  // BSK - 1/19/2004
231  // strictly this check should be OK, but it seems to
232  // fail on matrix-free matrices. Do they falsely
233  // state they are assembled? Check with the developers...
234  // if (this->closed())
235  // return;
236 
237  MatAssemblyBeginEnd(this->comm(), this->_mat, MAT_FINAL_ASSEMBLY);
238 }
239 
240 template <typename T>
242 {
243  libmesh_assert (this->initialized());
244 
245  PetscBool assembled;
246 
247  LibmeshPetscCall(MatAssembled(this->_mat, &assembled));
248 
249  return (assembled == PETSC_TRUE);
250 }
251 
252 //------------------------------------------------------------------
253 // Explicit instantiations
254 template class LIBMESH_EXPORT PetscMatrixBase<Number>;
255 
256 } // namespace libMesh
257 
258 
259 #endif // #ifdef LIBMESH_HAVE_PETSC
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:283
bool _destroy_mat_on_exit
This boolean value should only be set to false for the constructor which takes a PETSc Mat object...
This class provides a nice interface to the PETSc C-based data structures for parallel, sparse matrices.
The libMesh namespace provides an interface to certain functionality in the library.
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
dof_id_type numeric_index_type
Definition: id_types.h:99
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:257
libmesh_assert(ctx)
void stop(const char *file, int line, const char *date, const char *time)
Mat _mat
PETSc matrix datatype to store values.
PetscMatrixBase(const Parallel::Communicator &comm_in)
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:276
void * ctx
void destroy(triangulateio &t, IO_Type)
Frees any memory which has been dynamically allocated by Triangle.