libMesh
petsc_macro.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 #ifndef LIBMESH_PETSC_MACRO_H
19 #define LIBMESH_PETSC_MACRO_H
20 
21 // Local includes
22 #include "libmesh/libmesh_config.h"
23 
24 #ifdef LIBMESH_HAVE_PETSC
25 
26 // A convenient macro for comparing PETSc versions. Returns 1 if the
27 // current PETSc version is < major.minor.subminor and zero otherwise.
28 //
29 // This macro does not require petscversion.h to be included for it to work correctly.
30 // It instead relies on the PETSc version numbers detected during configure. Note that if
31 // LIBMESH_HAVE_PETSC is not defined, none of the LIBMESH_DETECTED_PETSC_VERSION_* variables will
32 // be defined either.
33 #define PETSC_VERSION_LESS_THAN(major,minor,subminor) \
34  ((LIBMESH_DETECTED_PETSC_VERSION_MAJOR < (major) || \
35  (LIBMESH_DETECTED_PETSC_VERSION_MAJOR == (major) && (LIBMESH_DETECTED_PETSC_VERSION_MINOR < (minor) || \
36  (LIBMESH_DETECTED_PETSC_VERSION_MINOR == (minor) && \
37  LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR < (subminor))))))
38 #define PETSC_VERSION_EQUALS(major,minor,subminor) \
39  ((LIBMESH_DETECTED_PETSC_VERSION_MAJOR == (major)) && \
40  (LIBMESH_DETECTED_PETSC_VERSION_MINOR == (minor)) && \
41  (LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR == (subminor)))
42 
43 // We used to have workarounds for missing extern "C" in old PETSc
44 // versions. We no longer support PETSc versions so old, but we do
45 // still support libMesh applications old enough to have used these
46 // macros.
47 #define EXTERN_C_FOR_PETSC_BEGIN
48 #define EXTERN_C_FOR_PETSC_END
49 
50 // Petsc include files
51 // Wrapped to avoid triggering our more paranoid warnings
52 #include <libmesh/ignore_warnings.h>
53 #ifdef I
54 # define LIBMESH_SAW_I
55 #endif
56 #include <petsc.h>
57 #ifndef LIBMESH_SAW_I
58 # undef I // Avoid complex.h contamination
59 #endif
60 #include <libmesh/restore_warnings.h>
61 
62 // These macros are still around for backwards compatibility, but we
63 // no longer use them within the library.
64 #define LibMeshVecDestroy(x) VecDestroy(x)
65 #define LibMeshVecScatterDestroy(x) VecScatterDestroy(x)
66 #define LibMeshMatDestroy(x) MatDestroy(x)
67 #define LibMeshISDestroy(x) ISDestroy(x)
68 #define LibMeshKSPDestroy(x) KSPDestroy(x)
69 #define LibMeshSNESDestroy(x) SNESDestroy(x)
70 #define LibMeshPetscViewerDestroy(x) PetscViewerDestroy(x)
71 #define LibMeshPCDestroy(x) PCDestroy(x)
72 
73 // PETSc devs temporarily considered adding VecScatterCreateWithData, but
74 // it was dropped in PETSc-130e142e39 and never made it into any release.
75 // We will keep the ifdef for backwards compatibility in case anyone wrote
76 // code directly using it, but that should be pretty unlikely.
77 #define LibMeshVecScatterCreate(xin,ix,yin,iy,newctx) VecScatterCreate(xin,ix,yin,iy,newctx)
78 #define ISCreateLibMesh(comm,n,idx,mode,is) ISCreateGeneral((comm),(n),(idx),(mode),(is))
79 
80 // As of release 3.8.0, MatGetSubMatrix was renamed to MatCreateSubMatrix.
81 #if PETSC_VERSION_LESS_THAN(3,8,0)
82 # define LibMeshCreateSubMatrix MatGetSubMatrix
83 #else
84 # define LibMeshCreateSubMatrix MatCreateSubMatrix
85 #endif
86 
87 // As of release 3.17.0, SETERRQ was made to use __VA_ARGS__ and
88 // SETERRQ1, SETERRQ2, etc. were deprecated
89 #if PETSC_VERSION_LESS_THAN(3,17,0)
90 # define LIBMESH_SETERRQ1 SETERRQ1
91 # define LIBMESH_SETERRQ2 SETERRQ2
92 # define LIBMESH_SETERRQ3 SETERRQ3
93 #else
94 # define LIBMESH_SETERRQ1 SETERRQ
95 # define LIBMESH_SETERRQ2 SETERRQ
96 # define LIBMESH_SETERRQ3 SETERRQ
97 #endif
98 
99 // As of 3.18, %D is no longer supported in format strings, but the
100 // replacement PetscInt_FMT didn't get added until 3.7.2
101 #if PETSC_VERSION_LESS_THAN(3,8,0)
102 # define LIBMESH_PETSCINT_FMT "D"
103 #else
104 # define LIBMESH_PETSCINT_FMT PetscInt_FMT
105 #endif
106 
107 // As of 3.19, PETSC_NULL is deprecated
108 #if PETSC_VERSION_LESS_THAN(3,19,0)
109 # define LIBMESH_PETSC_NULLPTR PETSC_NULL
110 #else
111 # define LIBMESH_PETSC_NULLPTR PETSC_NULLPTR
112 #endif
113 
114 // If we're using quad precision, we need to disambiguate std
115 // operations on PetscScalar
116 
117 #if LIBMESH_DEFAULT_QUADRUPLE_PRECISION
118 # include <boost/multiprecision/float128.hpp>
119 
120 namespace std
121 {
122 inline
123 std::ostream & operator<< (std::ostream & os, const PetscScalar in)
124 {
125  os << (boost::multiprecision::float128(in));
126  return os;
127 }
128 
129 /*
130 
131 // Whether these are necessary or not depends on gcc version!?
132 
133 #define LIBMESH_PETSCSCALAR_UNARY(funcname) \
134 inline PetscScalar funcname \
135  (const PetscScalar in) \
136 { \
137  return boost::multiprecision::funcname \
138  (boost::multiprecision::float128(in)).backend().value(); \
139 }
140 
141 LIBMESH_PETSCSCALAR_UNARY(sqrt)
142 LIBMESH_PETSCSCALAR_UNARY(exp)
143 LIBMESH_PETSCSCALAR_UNARY(log)
144 LIBMESH_PETSCSCALAR_UNARY(log10)
145 LIBMESH_PETSCSCALAR_UNARY(sin)
146 LIBMESH_PETSCSCALAR_UNARY(cos)
147 LIBMESH_PETSCSCALAR_UNARY(tan)
148 LIBMESH_PETSCSCALAR_UNARY(asin)
149 LIBMESH_PETSCSCALAR_UNARY(acos)
150 LIBMESH_PETSCSCALAR_UNARY(atan)
151 LIBMESH_PETSCSCALAR_UNARY(sinh)
152 LIBMESH_PETSCSCALAR_UNARY(cosh)
153 LIBMESH_PETSCSCALAR_UNARY(tanh)
154 LIBMESH_PETSCSCALAR_UNARY(abs)
155 LIBMESH_PETSCSCALAR_UNARY(fabs)
156 LIBMESH_PETSCSCALAR_UNARY(ceil)
157 LIBMESH_PETSCSCALAR_UNARY(floor)
158 */
159 
160 } // namespace std
161 
162 // Helper functions for boost float128 compatibility
163 namespace libMesh
164 {
165 template <typename T>
166 PetscScalar PS(T val)
167 {
168  return val.backend().value();
169 }
170 
171 template <typename T>
172 PetscScalar * pPS(T * ptr)
173 {
174  return &(ptr->backend().value());
175 }
176 
177 template <typename T>
178 const PetscScalar * pPS(const T * ptr)
179 {
180  return &(ptr->backend().value());
181 }
182 
183 template <typename T>
184 PetscReal * pPR(T * ptr)
185 {
186  return &(ptr->backend().value());
187 }
188 
189 template <typename T>
190 const PetscReal * pPR(const T * ptr)
191 {
192  return &(ptr->backend().value());
193 }
194 } // namespace libMesh
195 
196 #else
197 
198 namespace libMesh
199 {
200 template <typename T>
201 PetscScalar PS(T val)
202 {
203  return val;
204 }
205 
206 template <typename T>
207 PetscScalar * pPS(T * ptr)
208 {
209  return ptr;
210 }
211 
212 template <typename T>
213 const PetscScalar * pPS(const T * ptr)
214 {
215  return ptr;
216 }
217 
218 template <typename T>
219 PetscReal * pPR(T * ptr)
220 {
221  return ptr;
222 }
223 
224 template <typename T>
225 const PetscReal * pPR(const T * ptr)
226 {
227  return ptr;
228 }
229 } // namespace libMesh
230 
231 #endif // LIBMESH_ENABLE_QUADRUPLE_PRECISION
232 
233 #else // LIBMESH_HAVE_PETSC
234 
235 #define PETSC_VERSION_LESS_THAN(major,minor,subminor) 1
236 #define PETSC_VERSION_EQUALS(major,minor,revision) 0
237 
238 #endif // LIBMESH_HAVE_PETSC
239 
240 // The PETSC_VERSION_RELEASE constant was introduced just prior to 2.3.0 (ca. Apr 22 2005),
241 // so fall back to using PETSC_VERSION_LESS_THAN in case it doesn't exist.
242 #ifdef LIBMESH_DETECTED_PETSC_VERSION_RELEASE
243 
244 #define PETSC_RELEASE_LESS_THAN(major, minor, subminor) \
245  (PETSC_VERSION_LESS_THAN(major, minor, subminor) && LIBMESH_DETECTED_PETSC_VERSION_RELEASE)
246 #define PETSC_RELEASE_EQUALS(major, minor, subminor) \
247  (PETSC_VERSION_EQUALS(major, minor, subminor) && LIBMESH_DETECTED_PETSC_VERSION_RELEASE)
248 
249 #else
250 
251 #define PETSC_RELEASE_LESS_THAN(major, minor, subminor) \
252  (PETSC_VERSION_LESS_THAN(major, minor, subminor))
253 #define PETSC_RELEASE_EQUALS(major, minor, subminor) (PETSC_VERSION_EQUALS(major, minor, subminor))
254 
255 #endif
256 
257 #define PETSC_RELEASE_LESS_EQUALS(major, minor, subminor) \
258  (PETSC_RELEASE_LESS_THAN(major, minor, subminor) || PETSC_RELEASE_EQUALS(major, minor, subminor))
259 
260 #define PETSC_RELEASE_GREATER_EQUALS(major, minor, subminor) \
261  (0 == PETSC_RELEASE_LESS_THAN(major, minor, subminor))
262 
263 #define PETSC_RELEASE_GREATER_THAN(major, minor, subminor) \
264  (0 == PETSC_RELEASE_LESS_EQUALS(major, minor, subminor))
265 
266 #endif // LIBMESH_PETSC_MACRO_H
PetscReal * pPR(T *ptr)
Definition: petsc_macro.h:184
std::ostream & operator<<(std::ostream &os, const PetscScalar in)
Definition: petsc_macro.h:123
PetscScalar * pPS(T *ptr)
Definition: petsc_macro.h:172
The libMesh namespace provides an interface to certain functionality in the library.
PetscScalar PS(T val)
Definition: petsc_macro.h:166