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  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  */
37 template <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 
54 template <> void intrusive_ptr_release<Vec>(Vec obj);
55 template <> void intrusive_ptr_release<Mat>(Mat obj);
56 template <> void intrusive_ptr_release<DM>(DM obj);
57 template <> void intrusive_ptr_release<IS>(IS obj);
58 template <> void intrusive_ptr_release<AO>(AO obj);
59 template <> void intrusive_ptr_release<KSP>(KSP obj);
60 template <> void intrusive_ptr_release<SNES>(SNES obj);
61 template <> void intrusive_ptr_release<TS>(TS obj);
62 
63 namespace 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  */
77 template <typename OBJ>
79  : public boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type> {
80 
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  */
137 inline 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 */
145 DEPRECATED 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  */
156 inline 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  */
175 inline 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 */
184 DEPRECATED 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  */
198 inline 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 */
205 DEPRECATED 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 
230 inline 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 
245 inline 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 
251 inline 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 
257 inline 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 
263 inline 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  */
283 inline 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  */
302 inline 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  */
322 inline 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  */
345 inline 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");
348  return SmartPetscObj<VecScatter>(s);
349 }
350 
351 } // namespace MoFEM
352 
353 #endif
MoFEM::createAOMappingIS
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Definition: PetscSmartObj.hpp:302
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:283
MoFEM::createTS
auto createTS(MPI_Comm comm)
Definition: PetscSmartObj.hpp:245
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:596
MoFEM::createSNES
auto createSNES(MPI_Comm comm)
Definition: PetscSmartObj.hpp:251
MoFEM::createSmartDM
DEPRECATED auto createSmartDM(MPI_Comm comm, const std::string dm_type_name)
Definition: PetscSmartObj.hpp:145
MoFEM::createSmartVectorMPI
DEPRECATED auto createSmartVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Definition: PetscSmartObj.hpp:205
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:257
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:240
intrusive_ptr_release< IS >
void intrusive_ptr_release< IS >(IS obj)
Definition: PetscSmartObj.cpp:42
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:322
MoFEM::createGhostVector
auto createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Create smart ghost vector.
Definition: PetscSmartObj.hpp:175
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:105
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:137
convert.type
type
Definition: convert.py:64
MoFEM::createPC
auto createPC(MPI_Comm comm)
Definition: PetscSmartObj.hpp:263
MoFEM::smartVectorDuplicate
DEPRECATED SmartPetscObj< Vec > smartVectorDuplicate(Vec vec)
Definition: PetscSmartObj.hpp:226
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:230
MoFEM::createSmartGhostVector
DEPRECATED auto createSmartGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Definition: PetscSmartObj.hpp:184
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:217
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:95
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:37
MoFEM::createVecScatter
auto createVecScatter(Vec x, IS ix, Vec y, IS iy)
Create a Vec Scatter object.
Definition: PetscSmartObj.hpp:345
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:156
MoFEM::SmartPetscObj::SmartPetscObj
SmartPetscObj(std::nullptr_t ptr)
Definition: PetscSmartObj.hpp:85
MoFEM::createVectorMPI
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
Definition: PetscSmartObj.hpp:198
MoFEM::SmartPetscObj
intrusive_ptr for managing petsc objects
Definition: PetscSmartObj.hpp:78
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:81