v0.14.0
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 
8 namespace MoFEM {
9 template <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  */
23 template <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  */
39 template <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 
58 template <> void intrusive_ptr_release<Vec>(Vec obj);
59 template <> void intrusive_ptr_release<Mat>(Mat obj);
60 template <> void intrusive_ptr_release<DM>(DM obj);
61 template <> void intrusive_ptr_release<IS>(IS obj);
62 template <> void intrusive_ptr_release<AO>(AO obj);
63 template <> void intrusive_ptr_release<KSP>(KSP obj);
64 template <> void intrusive_ptr_release<SNES>(SNES obj);
65 template <> void intrusive_ptr_release<TS>(TS obj);
66 
67 namespace 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  */
81 template <typename OBJ>
83  : public boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type> {
84 
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  */
141 inline 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 */
149 DEPRECATED 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  */
160 inline 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  */
179 inline 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 */
188 DEPRECATED 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  */
202 inline 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 */
209 DEPRECATED 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  */
231  return vectorDuplicate(vec);
232 }
233 
234 inline 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 
249 inline 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 
255 inline 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 
261 inline 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 
267 inline 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  */
287 inline 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  */
300 inline 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  */
318 inline 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  */
338 inline 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  */
361 inline 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");
364  return SmartPetscObj<VecScatter>(s);
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  */
377 inline 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 
383 inline auto createISLocalToGlobalMapping(IS is) {
384  ISLocalToGlobalMapping map_raw;
385  CHK_THROW_MESSAGE(ISLocalToGlobalMappingCreateIS(is, &map_raw),
386  "create local to global mapping");
388 }
389 
390 inline 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 
396 inline 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
MoFEM::createAOMappingIS
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Definition: PetscSmartObj.hpp:318
DEPRECATED
#define DEPRECATED
Definition: definitions.h:17
intrusive_ptr_release< KSP >
void intrusive_ptr_release< KSP >(KSP obj)
Definition: PetscSmartObj.cpp:68
MoFEM::createISGeneral
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.
Definition: PetscSmartObj.hpp:287
MoFEM::createTS
auto createTS(MPI_Comm comm)
Definition: PetscSmartObj.hpp:249
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
MoFEM::createSNES
auto createSNES(MPI_Comm comm)
Definition: PetscSmartObj.hpp:255
MoFEM::createSmartDM
DEPRECATED auto createSmartDM(MPI_Comm comm, const std::string dm_type_name)
Definition: PetscSmartObj.hpp:149
MoFEM::createSmartVectorMPI
DEPRECATED auto createSmartVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Definition: PetscSmartObj.hpp:209
intrusive_ptr_release< TS >
void intrusive_ptr_release< TS >(TS obj)
Definition: PetscSmartObj.cpp:94
MoFEM::getPetscObject
PetscObject getPetscObject(T obj)
Definition: PetscSmartObj.hpp:9
MoFEM::createKSP
auto createKSP(MPI_Comm comm)
Definition: PetscSmartObj.hpp:261
intrusive_ptr_release< SNES >
void intrusive_ptr_release< SNES >(SNES obj)
Definition: PetscSmartObj.cpp:81
MoFEM::smartMatDuplicate
DEPRECATED SmartPetscObj< Mat > smartMatDuplicate(Mat mat, MatDuplicateOption op)
Definition: PetscSmartObj.hpp:244
intrusive_ptr_release< IS >
void intrusive_ptr_release< IS >(IS obj)
Definition: PetscSmartObj.cpp:42
MoFEM::createISLocalToGlobalMapping
auto createISLocalToGlobalMapping(IS is)
Definition: PetscSmartObj.hpp:383
MoFEM::createAOMapping
auto createAOMapping(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[])
Creates an application mapping using two integer arrays.
Definition: PetscSmartObj.hpp:338
MoFEM::matCreateVecs
auto matCreateVecs(Mat mat)
Definition: PetscSmartObj.hpp:390
MoFEM::isDifference
auto isDifference(IS is1, IS is2)
Get ISDifference.
Definition: PetscSmartObj.hpp:377
MoFEM::createGhostVector
auto createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Create smart ghost vector.
Definition: PetscSmartObj.hpp:179
intrusive_ptr_release< Vec >
void intrusive_ptr_release< Vec >(Vec obj)
Definition: PetscSmartObj.cpp:3
MoFEM::SmartPetscObj::use_count
int use_count() const
Definition: PetscSmartObj.hpp:109
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::createDM
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
Definition: PetscSmartObj.hpp:141
convert.type
type
Definition: convert.py:64
MoFEM::createPC
auto createPC(MPI_Comm comm)
Definition: PetscSmartObj.hpp:267
MoFEM::smartVectorDuplicate
DEPRECATED SmartPetscObj< Vec > smartVectorDuplicate(Vec vec)
Definition: PetscSmartObj.hpp:230
intrusive_ptr_release< DM >
void intrusive_ptr_release< DM >(DM obj)
Definition: PetscSmartObj.cpp:29
MoFEM::matDuplicate
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
Definition: PetscSmartObj.hpp:234
MoFEM::isDuplicate
auto isDuplicate(IS is)
Definition: PetscSmartObj.hpp:396
MoFEM::createSmartGhostVector
DEPRECATED auto createSmartGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Definition: PetscSmartObj.hpp:188
intrusive_ptr_add_ref
void intrusive_ptr_add_ref(OBJ obj)
It is used by intrusive_ptr to bump reference.
Definition: PetscSmartObj.hpp:23
convert.n
n
Definition: convert.py:82
N
const int N
Definition: speed_test.cpp:3
MoFEM::vectorDuplicate
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
Definition: PetscSmartObj.hpp:221
intrusive_ptr_release< Mat >
void intrusive_ptr_release< Mat >(Mat obj)
Definition: PetscSmartObj.cpp:16
MoFEM::SmartPetscObj::SmartPetscObj
SmartPetscObj(OBJ o, bool add_ref=false)
Construct a new Smart Petsc Obj object.
Definition: PetscSmartObj.hpp:99
std
Definition: enable_if.hpp:5
intrusive_ptr_release
void intrusive_ptr_release(OBJ obj)
It is used by intrusive_ptr to dereference and destroy petsc object.
Definition: PetscSmartObj.hpp:39
MoFEM::createVecScatter
auto createVecScatter(Vec x, IS ix, Vec y, IS iy)
Create a Vec Scatter object.
Definition: PetscSmartObj.hpp:361
MoFEM::Exceptions::ierr
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:66
MoFEM::getCommFromPetscObject
MPI_Comm getCommFromPetscObject(PetscObject obj)
Get the Comm From Petsc Object object.
Definition: PetscSmartObj.hpp:160
MoFEM::SmartPetscObj::SmartPetscObj
SmartPetscObj(std::nullptr_t ptr)
Definition: PetscSmartObj.hpp:89
MoFEM::createVectorMPI
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
Definition: PetscSmartObj.hpp:202
MoFEM::SmartPetscObj
intrusive_ptr for managing petsc objects
Definition: PetscSmartObj.hpp:82
intrusive_ptr_release< AO >
void intrusive_ptr_release< AO >(AO obj)
Definition: PetscSmartObj.cpp:55
MoFEM::SmartPetscObj< AO >::Derived
boost::intrusive_ptr< typename std::remove_pointer< AO >::type > Derived
Definition: PetscSmartObj.hpp:85
MoFEM::isAllGather
auto isAllGather(IS is)
IS All gather.
Definition: PetscSmartObj.hpp:300