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