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