v0.14.0
Loading...
Searching...
No Matches
PetscSmartObj.hpp
Go to the documentation of this file.
1/** \file PetscSmartObj.hpp
2 * \brief Petsc smart obj declarations
3 */
4
5#ifndef __PETSCSPARTOBJ_HPP__
6#define __PETSCSPARTOBJ_HPP__
7
8namespace MoFEM {
9template <typename T> inline PetscObject getPetscObject(T obj) {
10 return reinterpret_cast<PetscObject>(obj);
11}
12} // namespace MoFEM
13
14/**
15 * @brief It is used by intrusive_ptr to bump reference
16 *
17 * \note It should not be used directly, it is internally called by
18 * intrusive_ptr
19 *
20 * @tparam OBJ
21 * @param obj
22 */
23template <typename OBJ> void intrusive_ptr_add_ref(OBJ obj) {
24 PetscErrorCode ierr = PetscObjectReference(MoFEM::getPetscObject(obj));
25 CHKERRABORT(PetscObjectComm(MoFEM::getPetscObject(obj)), ierr);
26}
27
28/**
29 * @brief It is used by intrusive_ptr to dereference and destroy petsc object
30 *
31 * \note It should not be used directly, it is internally called by
32 * intrusive_ptr
33 *
34 * @tparam OBJ
35 * @param obj
36 */
37template <typename OBJ> void intrusive_ptr_release(OBJ obj) {
38 int cnt = 0;
39 PetscErrorCode ierr =
40 PetscObjectGetReference(MoFEM::getPetscObject(obj), &cnt);
41 if (!ierr) {
42 if (cnt) {
43 if (cnt > 1) {
44 ierr = PetscObjectDereference(MoFEM::getPetscObject(obj));
45 } else {
46 ierr = PetscObjectDestroy(reinterpret_cast<PetscObject *>(&obj));
47 }
48 }
49 auto comm = PetscObjectComm(MoFEM::getPetscObject(obj));
50 CHKERRABORT(comm, ierr);
51 }
52}
53
54template <> void intrusive_ptr_release<Vec>(Vec obj);
55template <> void intrusive_ptr_release<Mat>(Mat obj);
56template <> void intrusive_ptr_release<DM>(DM obj);
57template <> void intrusive_ptr_release<IS>(IS obj);
58template <> void intrusive_ptr_release<AO>(AO obj);
59template <> void intrusive_ptr_release<KSP>(KSP obj);
60template <> void intrusive_ptr_release<SNES>(SNES obj);
61template <> void intrusive_ptr_release<TS>(TS obj);
62
63namespace MoFEM {
64/**
65 * @brief intrusive_ptr for managing petsc objects
66 *
67 * It manages destruction, referencing and dereferencing petsc objects. It is
68 * similar how smart_ptr pointers works, but applied for petsc objects like Vec,
69 * DM, Mat, etc.
70 *
71 * \code
72 * SmartPetscObj<Vec> smart_vec = createSmartGhostVector(...);
73 * \endcode
74 *
75 * @tparam OBJ
76 */
77template <typename OBJ>
79 : public boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type> {
80
81 using Derived = boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type>;
82
83 using Derived::Derived;
84
85 SmartPetscObj(std::nullptr_t ptr) : SmartPetscObj() {}
86
87 /**
88 * @brief Construct a new Smart Petsc Obj object
89 *
90 * \note If add_red is set to true, you have to destroy OBJ.
91 *
92 * @param o
93 * @param add_ref // if false ownership of OBJ is taken by SmartPetscObj
94 */
95 explicit SmartPetscObj(OBJ o, bool add_ref = false)
96 : boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type>(o,
97 add_ref) {
98 }
99
100 operator OBJ() { return this->get(); }
101 explicit operator PetscObject() {
102 return reinterpret_cast<PetscObject>(this->get());
103 }
104
105 int use_count() const {
106 if (this->get()) {
107 int cnt;
108 ierr = PetscObjectGetReference(getPetscObject(this->get()), &cnt);
109 CHKERRABORT(PetscObjectComm(getPetscObject(this->get())), ierr);
110 return cnt;
111 } else
112 return 0;
113 }
114};
115
116/**
117 * @brief Creates smart DM object
118 *
119 * DM object can be used as any other object, but is destroyed as smart pointer
120 * when no longer used.
121 *
122 * \code
123 * CHKERR DMRegister_MoFEM("MOFEM")
124 * {
125 * auto dm = createDM(PETSC_COMM_WORLD, "MOFEM");
126 *
127 * // ...
128 *
129 * // dm is automatically destroyed when program goes out of the scope
130 * }
131 *
132 *
133 *
134 * \endcode
135 *
136 */
137inline auto createDM(MPI_Comm comm, const std::string dm_type_name) {
138 DM dm;
139 CHK_THROW_MESSAGE(DMCreate(comm, &dm), "Failed to create DM");
140 CHK_THROW_MESSAGE(DMSetType(dm, dm_type_name.c_str()), "Failed set DM type");
141 return SmartPetscObj<DM>(dm);
142};
143
144/** @deprecated use createDM */
145DEPRECATED inline auto createSmartDM(MPI_Comm comm,
146 const std::string dm_type_name) {
147 return createDM(comm, dm_type_name);
148}
149
150/**
151 * @brief Get the Comm From Petsc Object object
152 *
153 * @param obj
154 * @return MPI_Comm
155 */
156inline MPI_Comm getCommFromPetscObject(PetscObject obj) {
157 MPI_Comm comm;
158 CHK_THROW_MESSAGE(PetscObjectGetComm(obj, &comm),
159 "Failed to get comm from PETSc object");
160 return comm;
161};
162
163/**
164 * @brief Create smart ghost vector
165 *
166 * For details abut arguments see here:
167 * <a
168 * href=https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecCreateGhost.html>VecCreateGhost</a>.
169 *
170 * \code
171 * auto vec = createGhostVector(...);
172 * \endcode
173 *
174 */
175inline auto createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N,
176 PetscInt nghost, const PetscInt ghosts[]) {
177 Vec vv;
178 CHK_THROW_MESSAGE(VecCreateGhost(comm, n, N, nghost, ghosts, &vv),
179 "Failed to create ghosted Vec");
180 return SmartPetscObj<Vec>(vv);
181};
182
183/** @deprecated use createGhostVector */
184DEPRECATED inline auto createSmartGhostVector(MPI_Comm comm, PetscInt n,
185 PetscInt N, PetscInt nghost,
186 const PetscInt ghosts[]) {
187 return createGhostVector(comm, n, N, nghost, ghosts);
188}
189
190/**
191 * @brief Create MPI Vector
192 *
193 * For details abut arguments see here:
194 * <a
195 * href=https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecCreateMPI.html>VecCreateMPI</a>.
196 *
197 */
198inline auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N) {
199 Vec vv;
200 CHK_THROW_MESSAGE(VecCreateMPI(comm, n, N, &vv), "Failed to create Vec");
201 return SmartPetscObj<Vec>(vv);
202};
203
204/** @deprecated use createVectorMPI */
205DEPRECATED inline auto createSmartVectorMPI(MPI_Comm comm, PetscInt n,
206 PetscInt N) {
207 return createVectorMPI(comm, n, N);
208}
209
210/**
211 * @brief Create duplicate vector of smart vector
212 *
213 * For details abut arguments see here:
214 * <a
215 * href=https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecDuplicate.html>VecDuplicate</a>.
216 */
218 Vec duplicate;
219 CHK_THROW_MESSAGE(VecDuplicate(vec, &duplicate), "Failed to duplicate Vec");
220 return SmartPetscObj<Vec>(duplicate);
221};
222
223/**
224 * @deprecated use vectorDuplicate
225 */
227 return vectorDuplicate(vec);
228}
229
230inline SmartPetscObj<Mat> matDuplicate(Mat mat, MatDuplicateOption op) {
231 Mat duplicate;
232 CHK_THROW_MESSAGE(MatDuplicate(mat, op, &duplicate),
233 "Failed to duplicate Mat");
234 return SmartPetscObj<Mat>(duplicate);
235};
236
237/**
238 * @deprecated use matDuplicate
239 */
241 MatDuplicateOption op) {
242 return matDuplicate(mat, op);
243}
244
245inline auto createTS(MPI_Comm comm) {
246 TS ts;
247 CHK_THROW_MESSAGE(TSCreate(comm, &ts), "Failed to create TS");
248 return SmartPetscObj<TS>(ts);
249};
250
251inline auto createSNES(MPI_Comm comm) {
252 SNES snes;
253 CHK_THROW_MESSAGE(SNESCreate(comm, &snes), "Failed to create SNES");
254 return SmartPetscObj<SNES>(snes);
255};
256
257inline auto createKSP(MPI_Comm comm) {
258 KSP ksp;
259 CHK_THROW_MESSAGE(KSPCreate(comm, &ksp), "Failed to create KSP");
260 return SmartPetscObj<KSP>(ksp);
261};
262
263inline auto createPC(MPI_Comm comm) {
264 PC pc;
265 CHK_THROW_MESSAGE(PCCreate(comm, &pc), "Failed to create PC");
266 return SmartPetscObj<PC>(pc);
267};
268
269/**
270 * @brief Creates a data structure for an index set containing a list of
271 * integers.
272 *
273 * <a
274 * href=https://petsc.org/release/docs/manualpages/IS/ISCreateGeneral/>AOCreateMappingIS</a>.
275 *
276 * @param comm the MPI communicator
277 * @param n the length of the index set
278 * @param idx the list of integers
279 * @param mode PETSC_COPY_VALUES, PETSC_OWN_POINTER, or PETSC_USE_POINTER; see
280 * PetscCopyMode for meaning of this flag.
281 * @return SmartPetscObj<IS>(is)
282 */
283inline auto createISGeneral(MPI_Comm comm, PetscInt n, const PetscInt idx[],
284 PetscCopyMode mode) {
285 IS is;
286 CHK_THROW_MESSAGE(ISCreateGeneral(comm, n, idx, mode, &is), "Create IS");
287 return SmartPetscObj<IS>(is);
288}
289
290/**
291 * @brief Creates an application mapping using two index sets.
292 *
293 * <a
294 * href=https://petsc.org/release/docs/manualpages/AO/AOCreateMappingIS/>AOCreateMappingIS</a>.
295 *
296 * @param isapp index set that defines an ordering
297 * @param ispetsc index set that defines another ordering, maybe NULL for
298 * identity
299 * @param aoout the new application ordering
300 * @return SmartPetscObj<AO>(ao)
301 */
302inline auto createAOMappingIS(IS isapp, IS ispetsc) {
303 AO ao;
304 CHK_THROW_MESSAGE(AOCreateMappingIS(isapp, ispetsc, &ao),
305 "Failed to create AO");
306 return SmartPetscObj<AO>(ao);
307};
308
309/**
310 * @brief Creates an application mapping using two integer arrays.
311 *
312 * <a
313 * href=https://petsc.org/release/docs/manualpages/AO/AOCreateMapping/>AOCreateMappingIS</a>.
314 *
315 * @param comm MPI communicator that is to share the AO
316 * @param napp size of integer arrays
317 * @param myapp integer array that defines an ordering
318 * @param mypetsc integer array that defines another ordering (may be NULL to
319 * indicate the identity ordering)
320 * @return SmartPetscObj<AO>(ao);
321 */
322inline auto createAOMapping(MPI_Comm comm, PetscInt napp,
323 const PetscInt myapp[], const PetscInt mypetsc[]) {
324 AO ao;
325 CHK_THROW_MESSAGE(AOCreateMapping(comm, napp, myapp, mypetsc, &ao),
326 "create ao");
327 return SmartPetscObj<AO>(ao);
328}
329
330/**
331 * @brief Create a Vec Scatter object
332 *
333 * <a
334 * href=https://petsc.org/release/manualpages/PetscSF/VecScatterCreate/>VecScatterCreate</a>.
335 *
336 * @param x a vector that defines the shape (parallel data layout of the vector)
337 * of vectors from which we scatter
338 * @param ix the indices of xin to scatter (if NULL scatters all values)
339 * @param y a vector that defines the shape (parallel data layout of the vector)
340 * of vectors to which we scatter
341 * @param iy the indices of yin to hold results (if NULL fills entire vector yin
342 * in order)
343 * @return
344 */
345inline auto createVecScatter(Vec x, IS ix, Vec y, IS iy) {
346 VecScatter s;
347 CHK_THROW_MESSAGE(VecScatterCreate(x, ix, y, iy, &s), "create scatter");
349}
350
351} // namespace MoFEM
352
353#endif
static Index< 'o', 3 > o
void intrusive_ptr_release< TS >(TS obj)
void intrusive_ptr_release< AO >(AO obj)
void intrusive_ptr_release< KSP >(KSP obj)
void intrusive_ptr_release< Vec >(Vec obj)
void intrusive_ptr_release< DM >(DM obj)
void intrusive_ptr_release< IS >(IS obj)
void intrusive_ptr_add_ref(OBJ obj)
It is used by intrusive_ptr to bump reference.
void intrusive_ptr_release< SNES >(SNES obj)
void intrusive_ptr_release< Mat >(Mat obj)
void intrusive_ptr_release(OBJ obj)
It is used by intrusive_ptr to dereference and destroy petsc object.
static PetscErrorCode ierr
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:595
#define DEPRECATED
Definition: definitions.h:17
FTensor::Index< 'n', SPACE_DIM > n
const double T
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MPI_Comm getCommFromPetscObject(PetscObject obj)
Get the Comm From Petsc Object object.
auto createKSP(MPI_Comm comm)
auto createSNES(MPI_Comm comm)
DEPRECATED SmartPetscObj< Vec > smartVectorDuplicate(Vec vec)
DEPRECATED auto createSmartDM(MPI_Comm comm, const std::string dm_type_name)
auto createISGeneral(MPI_Comm comm, PetscInt n, const PetscInt idx[], PetscCopyMode mode)
Creates a data structure for an index set containing a list of integers.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
auto createVecScatter(Vec x, IS ix, Vec y, IS iy)
Create a Vec Scatter object.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
auto createTS(MPI_Comm comm)
DEPRECATED auto createSmartGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
auto createPC(MPI_Comm comm)
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
auto createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Create smart ghost vector.
PetscObject getPetscObject(T obj)
DEPRECATED SmartPetscObj< Mat > smartMatDuplicate(Mat mat, MatDuplicateOption op)
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
DEPRECATED auto createSmartVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Definition: enable_if.hpp:6
const int N
Definition: speed_test.cpp:3
intrusive_ptr for managing petsc objects
SmartPetscObj(std::nullptr_t ptr)
SmartPetscObj(OBJ o, bool add_ref=false)
Construct a new Smart Petsc Obj object.
boost::intrusive_ptr< typename std::remove_pointer< OBJ >::type > Derived