libMesh
petsc_shell_matrix.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 #include "libmesh/libmesh_config.h"
19 #ifdef LIBMESH_HAVE_PETSC
20 
21 // Local includes
22 #include "libmesh/petsc_shell_matrix.h"
23 #include "libmesh/petsc_matrix_shell_matrix.h"
24 
25 namespace libMesh
26 {
27 template <typename T>
29 {
30  this->clear();
31 }
32 
33 template <typename T>
35  const NumericVector<T> & arg) const
36 {
37  PetscVector<T> & petsc_dest = cast_ref<PetscVector<T> &>(dest);
38  const PetscVector<T> & petsc_arg = cast_ref<const PetscVector<T> &>(arg);
39 
40  LibmeshPetscCall(MatMult(_mat, petsc_arg.vec(), petsc_dest.vec()));
41 }
42 
43 
44 
45 template <typename T>
47  const NumericVector<T> & arg) const
48 {
49  PetscVector<T> & petsc_dest = cast_ref<PetscVector<T> &>(dest);
50  const PetscVector<T> & petsc_arg = cast_ref<const PetscVector<T> &>(arg);
51 
52  LibmeshPetscCall(MatMultAdd(_mat, petsc_arg.vec(), petsc_dest.vec(), petsc_dest.vec()));
53 }
54 
55 
56 template <typename T>
58 {
59  if (this->initialized())
60  {
61  // If we encounter an error here, print a warning but otherwise
62  // keep going since we may be recovering from an exception.
63  PetscErrorCode ierr = MatDestroy (&_mat);
64  if (ierr)
65  libmesh_warning("Warning: MatDestroy returned a non-zero error code which we ignored.");
66 
67  this->_is_initialized = false;
68  }
69 }
70 
71 template <typename Obj>
72 void init_shell_mat(Obj & obj,
73  const numeric_index_type m,
74  const numeric_index_type n,
75  const numeric_index_type m_l,
76  const numeric_index_type n_l,
77  const numeric_index_type blocksize_in)
78 {
79  // Clear initialized matrices
80  if (obj.initialized())
81  obj.clear();
82 
83  PetscInt m_global = static_cast<PetscInt>(m);
84  PetscInt n_global = static_cast<PetscInt>(n);
85  PetscInt m_local = static_cast<PetscInt>(m_l);
86  PetscInt n_local = static_cast<PetscInt>(n_l);
87  PetscInt blocksize = static_cast<PetscInt>(blocksize_in);
88 
89  LibmeshPetscCall2(obj.comm(), MatCreate(obj.comm().get(), &obj._mat));
90  LibmeshPetscCall2(obj.comm(), MatSetSizes(obj._mat, m_local, n_local, m_global, n_global));
91  LibmeshPetscCall2(obj.comm(), MatSetBlockSize(obj._mat, blocksize));
92  LibmeshPetscCall2(obj.comm(), MatSetType(obj._mat, MATSHELL));
93 
94  // Is prefix information available somewhere? Perhaps pass in the system name?
95  LibmeshPetscCall2(obj.comm(), MatSetOptionsPrefix(obj._mat, ""));
96  LibmeshPetscCall2(obj.comm(), MatSetFromOptions(obj._mat));
97  LibmeshPetscCall2(obj.comm(), MatSetUp(obj._mat));
98  LibmeshPetscCall2(obj.comm(), MatShellSetContext(obj._mat, &obj));
99 
100  obj._is_initialized = true;
101 }
102 
103 template <typename Obj>
104 void init_shell_mat(Obj & obj)
105 {
106  libmesh_assert(obj._dof_map);
107 
108  numeric_index_type my_m = obj._dof_map->n_dofs();
109  numeric_index_type m_l = obj._dof_map->n_local_dofs();
110  if (obj._omit_constrained_dofs)
111  {
112  my_m -= obj._dof_map->n_constrained_dofs();
113  m_l -= obj._dof_map->n_local_constrained_dofs();
114  }
115 
116  const numeric_index_type my_n = my_m;
117  const numeric_index_type n_l = m_l;
118 
119  init_shell_mat(obj, my_m, my_n, m_l, n_l, obj._dof_map->block_size());
120 }
121 
122 template <typename T>
124 {
125  init_shell_mat(*this);
126 }
127 
128 template <typename T>
130 {
131  return _is_initialized;
132 }
133 
134 template <typename T>
136 {
137  libmesh_error_msg_if(!_mat, "A petsc shell matrix is not created yet. Please call init() first.");
138  return _mat;
139 }
140 
141 //------------------------------------------------------------------
142 // Explicit instantiations
143 template class LIBMESH_EXPORT PetscShellMatrix<Number>;
144 template void init_shell_mat(PetscShellMatrix<Number> & obj);
146 template void init_shell_mat(PetscShellMatrix<Number> & obj,
147  const numeric_index_type m,
148  const numeric_index_type n,
149  const numeric_index_type m_l,
150  const numeric_index_type n_l,
151  const numeric_index_type blocksize_in);
153  const numeric_index_type m,
154  const numeric_index_type n,
155  const numeric_index_type m_l,
156  const numeric_index_type n_l,
157  const numeric_index_type blocksize_in);
158 
159 } // namespace libMesh
160 
161 #endif
virtual void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const override
Multiplies the matrix with arg and adds the result to dest.
This class provides a nice interface to PETSc&#39;s Vec object.
Definition: petsc_vector.h:73
Mat mat()
Returns a pointer to the underlying PETSc Mat object.
This class allows to use a PETSc shell matrix.
virtual void clear() override
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
The libMesh namespace provides an interface to certain functionality in the library.
void init_shell_mat(Obj &obj, const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type blocksize_in)
Initialize a shell matrix object.
virtual void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const override
Multiplies the matrix with arg and stores the result in dest.
virtual bool initialized() const
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)
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:276
virtual void init() override