libMesh
Loading...
Searching...
No Matches
petsc_shell_matrix.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
25namespace libMesh
26{
27template <typename T>
29{
30 this->clear();
31}
32
33template <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
45template <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
56template <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
71template <typename Obj>
72void 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
103template <typename Obj>
104void 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
122template <typename T>
124{
125 init_shell_mat(*this);
126}
127
128template <typename T>
130{
131 return _is_initialized;
132}
133
134template <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
143template class LIBMESH_EXPORT PetscShellMatrix<Number>;
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
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
This class allows to use a PETSc shell matrix as a PetscMatrix.
This class allows to use a PETSc shell matrix.
virtual void init() override
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.
virtual bool initialized() const
Mat mat()
Returns a pointer to the underlying PETSc Mat object.
virtual void clear() override
virtual void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const override
Multiplies the matrix with arg and stores the result in dest.
This class provides a nice interface to PETSc's Vec object.
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.
libmesh_assert(ctx)
dof_id_type numeric_index_type
Definition id_types.h:99
bool initialized()
Checks that library initialization has been done.
Definition libmesh.C:324