v0.8.23
AuxPETSc.hpp
Go to the documentation of this file.
1 /** \file AuxPETSc.hpp
2  * \brief Auxuliary MoFEM-PETSc structures
3  */
4 
5 /* This file is part of MoFEM.
6  * MoFEM is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>. */
18 
19 #ifndef __AUXPETSC_HPP__
20 #define __AUXPETSC_HPP__
21 
22 namespace MoFEM {
23 template <typename T> inline PetscObject getPetscObject(T obj) {
24  return reinterpret_cast<PetscObject>(obj);
25 }
26 } // namespace MoFEM
27 
28 /**
29  * @brief It is used by intrusive_ptr to bump reference
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_add_ref(OBJ obj) {
38  PetscErrorCode ierr = PetscObjectReference(MoFEM::getPetscObject(obj));
39  CHKERRABORT(PetscObjectComm(MoFEM::getPetscObject(obj)), ierr);
40 }
41 
42 /**
43  * @brief It is used by intrusive_ptr to dereference and destroy petsc object
44  *
45  * \note It should not be used directly, it is internally called by
46  * intrusive_ptr
47  *
48  * @tparam OBJ
49  * @param obj
50  */
51 template <typename OBJ> void intrusive_ptr_release(OBJ obj) {
52  PetscErrorCode ierr;
53  int cnt;
54  ierr = PetscObjectGetReference(reinterpret_cast<PetscObject>(obj), &cnt);
55  CHKERRABORT(PetscObjectComm(MoFEM::getPetscObject(obj)), ierr);
56  if (cnt > 1) {
57  ierr = PetscObjectDereference(MoFEM::getPetscObject(obj));
58  CHKERRABORT(PetscObjectComm(MoFEM::getPetscObject(obj)), ierr);
59  } else {
60  ierr = PetscObjectDestroy(reinterpret_cast<PetscObject *>(&obj));
61  CHKERRABORT(PetscObjectComm(MoFEM::getPetscObject(obj)), ierr);
62  }
63 }
64 
65 namespace MoFEM {
66 
67 struct PairNameFEMethodPtr : public std::pair<std::string, FEMethod *> {
68 
69  PairNameFEMethodPtr(std::string name, FEMethod *ptr)
70  : std::pair<std::string, FEMethod *>(name, ptr) {}
71  template <typename FEMETHOD>
72  PairNameFEMethodPtr(std::string name, boost::shared_ptr<FEMETHOD> ptr)
73  : std::pair<std::string, FEMethod *>(name, ptr.get()), fePtr(ptr) {}
74  virtual ~PairNameFEMethodPtr() {}
75 
76  inline boost::shared_ptr<BasicMethod> getSharedPtr() const {
77  if (!fePtr)
78  THROW_MESSAGE("Shared pointer not set. You have to be using raw "
79  "pointer, that is unsafe.");
80  return fePtr;
81  }
82 
83 private:
84  boost::shared_ptr<FEMethod> fePtr;
85 };
86 
89  template <typename BASICMETHOD>
90  BasicMethodPtr(boost::shared_ptr<BASICMETHOD> ptr)
91  : rawPtr(ptr.get()), bmPtr(ptr) {}
92  inline BasicMethod &operator*() const { return *rawPtr; };
93  inline BasicMethod *operator->() const { return rawPtr; }
94 
95  inline boost::shared_ptr<BasicMethod> getSharedPtr() const {
96  if (!bmPtr)
97  THROW_MESSAGE("Shared pointer not set. You have to be using raw "
98  "pointer, that is unsafe.");
99  return bmPtr;
100  }
101 
102 private:
104  boost::shared_ptr<BasicMethod> bmPtr;
105 };
106 
107 typedef std::vector<PairNameFEMethodPtr> FEMethodsSequence;
108 typedef std::vector<BasicMethodPtr> BasicMethodsSequence;
109 
110 /**
111  * @brief intrusive_ptr for managing petsc objects
112  *
113  * It manages destruction, referencing and dereferencing petsc objects. It is
114  * similar how smart_ptr pointers works, but applied for petsc objects like Vec,
115  * DM, Mat, etc.
116  *
117  * \code
118  * SmartPetscObj<Vec> smart_vec = createSmartGhostVector(...);
119  * \endcode
120  *
121  * @tparam OBJ
122  */
123 template <typename OBJ>
125  : public boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type> {
126 
128  : boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type>() {}
130  : boost::intrusive_ptr<typename std::remove_pointer<OBJ>::type>(o,
131  false) {}
132  operator OBJ() { return this->get(); }
133 
134  int use_count() const {
135  if (this->get()) {
136  int cnt;
137  ierr = PetscObjectGetReference(getPetscObject(this->get()), &cnt);
138  CHKERRABORT(PetscObjectComm(getPetscObject(this->get())), ierr);
139  return cnt;
140  } else
141  return 0;
142  }
143 };
144 
145 /**
146  * @brief Creates smart DM object
147  *
148  * DM object can be used as any other object, but is destroyed as smart pointer
149  * when no loneger used.
150  *
151  * \code
152  * CHKERR DMRegister_MoFEM("MOFEM")
153  * {
154  * auto dm = createSmartDM(PETSC_COMM_WORLD, "MOFEM");
155  *
156  * // ...
157  *
158  * // dm is autmatically destroyed when program goes out of the scope
159  * }
160  *
161  *
162  *
163  * \endcode
164  *
165  */
166 auto createSmartDM = [](MPI_Comm comm, const std::string dm_type_name) {
167  DM dm;
168  ierr = DMCreate(comm, &dm);
169  CHKERRABORT(comm, ierr);
170  ierr = DMSetType(dm, dm_type_name.c_str());
171  CHKERRABORT(comm, ierr);
172  return SmartPetscObj<DM>(dm);
173 };
174 
175 /**
176  * @brief Create smart ghost vector
177  *
178  * For details abut arguments see here:
179  * <a
180  * href=https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecCreateGhost.html>VecCreateGhost</a>.
181  *
182  * \code
183  * auto vec = createSmartGhostVector(...);
184  * \endcode
185  *
186  */
187 auto createSmartGhostVector = [](MPI_Comm comm, PetscInt n, PetscInt N,
188  PetscInt nghost, const PetscInt ghosts[]) {
189  Vec vv;
190  ierr = VecCreateGhost(comm, n, N, nghost, ghosts, &vv);
191  CHKERRABORT(comm, ierr);
192  return SmartPetscObj<Vec>(vv);
193 };
194 
195 /**
196  * @brief Create duplicate vector of smart vector
197  *
198  * For details abut arguments see here:
199  * <a
200  * href=https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecDuplicate.html>VecDuplicate</a>.
201  */
203  if (vec.use_count()) {
204  Vec duplicate;
205  ierr = VecDuplicate(vec, &duplicate);
206  CHKERRABORT(PETSC_COMM_SELF, ierr);
207  return SmartPetscObj<Vec>(duplicate);
208  } else {
209  return SmartPetscObj<Vec>();
210  }
211 };
212 
213 auto createTS = [](MPI_Comm comm) {
214  TS ts;
215  ierr = TSCreate(PETSC_COMM_WORLD, &ts);
216  CHKERRABORT(comm, ierr);
217  return SmartPetscObj<TS>(ts);
218 };
219 
220 auto createSNES = [](MPI_Comm comm) {
221  SNES snes;
222  ierr = SNESCreate(PETSC_COMM_WORLD, &snes);
223  CHKERRABORT(comm, ierr);
224  return SmartPetscObj<SNES>(snes);
225 };
226 
227 auto createKSP = [](MPI_Comm comm) {
228  KSP ksp;
229  ierr = KSPCreate(PETSC_COMM_WORLD, &ksp);
230  CHKERRABORT(comm, ierr);
231  return SmartPetscObj<KSP>(ksp);
232 };
233 
234 } // namespace MoFEM
235 
236 #endif // __AUXPETSC_HPP__
BasicMethodPtr(BasicMethod *ptr)
Definition: AuxPETSc.hpp:88
structure for User Loop Methods on finite elementsIt can be used to calculate stiffness matrices,...
virtual ~PairNameFEMethodPtr()
Definition: AuxPETSc.hpp:74
auto createTS
Definition: AuxPETSc.hpp:213
int use_count() const
Definition: AuxPETSc.hpp:134
auto createSNES
Definition: AuxPETSc.hpp:220
PetscObject getPetscObject(T obj)
Definition: AuxPETSc.hpp:23
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:619
boost::shared_ptr< BasicMethod > getSharedPtr() const
Definition: AuxPETSc.hpp:76
auto smartVectorDuplicate
Create duplicate vector of smart vector.
Definition: AuxPETSc.hpp:202
BasicMethodPtr(boost::shared_ptr< BASICMETHOD > ptr)
Definition: AuxPETSc.hpp:90
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
BasicMethod * rawPtr
Definition: AuxPETSc.hpp:103
std::vector< BasicMethodPtr > BasicMethodsSequence
Definition: AuxPETSc.hpp:108
std::vector< PairNameFEMethodPtr > FEMethodsSequence
Definition: AuxPETSc.hpp:107
BasicMethod & operator *() const
Definition: AuxPETSc.hpp:92
boost::shared_ptr< BasicMethod > getSharedPtr() const
Definition: AuxPETSc.hpp:95
BasicMethod * operator->() const
Definition: AuxPETSc.hpp:93
void intrusive_ptr_release(OBJ obj)
It is used by intrusive_ptr to dereference and destroy petsc object.
Definition: AuxPETSc.hpp:51
auto createKSP
Definition: AuxPETSc.hpp:227
auto createSmartGhostVector
Create smart ghost vector.
Definition: AuxPETSc.hpp:187
void intrusive_ptr_add_ref(OBJ obj)
It is used by intrusive_ptr to bump reference.
Definition: AuxPETSc.hpp:37
boost::shared_ptr< BasicMethod > bmPtr
Definition: AuxPETSc.hpp:104
PairNameFEMethodPtr(std::string name, boost::shared_ptr< FEMETHOD > ptr)
Definition: AuxPETSc.hpp:72
intrusive_ptr for managing petsc objects
Definition: AuxPETSc.hpp:124
const int N
Definition: speed_test.cpp:3
auto createSmartDM
Creates smart DM object.
Definition: AuxPETSc.hpp:166
boost::shared_ptr< FEMethod > fePtr
Definition: AuxPETSc.hpp:84
Data structure to exchange data between mofem and User Loop Methods.It allows to exchange data betwee...
PairNameFEMethodPtr(std::string name, FEMethod *ptr)
Definition: AuxPETSc.hpp:69