PetIBM 0.5.4
Toolbox and applications of the immersed-boundary method for distributed-memory architectures
bodypack.cpp
Go to the documentation of this file.
1
8#include <petibm/bodypack.h>
9#include <petibm/io.h>
10
11namespace petibm
12{
13namespace body
14{
15BodyPackBase::BodyPackBase(const MPI_Comm &comm, const PetscInt &dim,
16 const YAML::Node &node)
17{
18 init(comm, dim, node);
19} // BodyPackBase
20
22{
23 PetscErrorCode ierr;
24 PetscBool finalized;
25
26 PetscFunctionBeginUser;
27
28 ierr = PetscFinalized(&finalized); CHKERRV(ierr);
29 if (finalized) return;
30
31 ierr = DMDestroy(&dmPack); CHKERRV(ierr);
32 comm = MPI_COMM_NULL;
33} // ~BodyPackBase
34
35PetscErrorCode BodyPackBase::destroy()
36{
37 PetscErrorCode ierr;
38
39 PetscFunctionBeginUser;
40
41 dim = -1;
42 nBodies = nPts = nLclPts = 0;
43 std::vector<type::SingleBody>().swap(bodies);
44 ierr = DMDestroy(&dmPack); CHKERRQ(ierr);
45 info = "";
46
47 comm = MPI_COMM_NULL;
48 mpiSize = mpiRank = 0;
51
52 PetscFunctionReturn(0);
53} // destroy
54
55PetscErrorCode BodyPackBase::init(const MPI_Comm &inComm, const PetscInt &inDim,
56 const YAML::Node &node)
57{
58 PetscErrorCode ierr;
59
60 PetscFunctionBeginUser;
61
62 // get info from MPI communicator
63 comm = inComm;
64 ierr = MPI_Comm_size(comm, &mpiSize); CHKERRQ(ierr);
65 ierr = MPI_Comm_rank(comm, &mpiRank); CHKERRQ(ierr);
66
67 // set the dimension
68 dim = inDim;
69
70 // get the number of bodies
71 if (!node["bodies"].IsDefined())
72 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
73 "No key \"bodies\" found in the YAML node provided for "
74 "initializing a BodyPack instance.\n");
75
76 nBodies = node["bodies"].size();
77
78 // re-size the vector holding all SingleBody instances
79 bodies.resize(nBodies);
80
81 // allocate other vectors
84
85 // initialize variables
86 nPts = 0;
87 nLclPts = 0;
88
89 // loop through all bodies in the YAML node
90 for (PetscInt i = 0; i < nBodies; ++i)
91 {
92 std::string name, filePath, type;
93
94 // if user didn't set the name of body, use the index in vector `bodies`
95 name = node["bodies"][i]["name"].as<std::string>("body" +
96 std::to_string(i));
97
98 // so far, we only have one type: points. So this is also the default
99 // value
100 type = node["bodies"][i]["type"].as<std::string>("points");
101
102 // check if the key "file" exists
103 if (!node["bodies"][i]["file"].IsDefined())
104 SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
105 "No key \"file\" found in the YAML node of the body "
106 "\"%s\".\n",
107 name.c_str());
108
109 filePath = node["bodies"][i]["file"].as<std::string>();
110
111 // check if file path is absolute; if not, prepend directory path
112 // note: this only works on Unix-like OS
113 if (filePath[0] != '/')
114 filePath = node["directory"].as<std::string>() + "/" + filePath;
115
116 ierr = createSingleBody(comm, dim, type, name, filePath, bodies[i]);
117 CHKERRQ(ierr);
118
119 for (PetscMPIInt r = 0; r < mpiSize; ++r)
120 nLclAllProcs[r] += bodies[i]->nLclAllProcs[r];
121
122 // add to total number of points
123 nPts += bodies[i]->nPts;
124
125 // add to total number of local points
126 nLclPts += bodies[i]->nLclPts;
127 }
128
129 // calculate offsets
130 for (PetscMPIInt r = mpiSize - 1; r > 0; r--)
131 offsetsAllProcs[r] = nLclAllProcs[r - 1];
132 for (PetscMPIInt r = 1; r < mpiSize; r++)
133 offsetsAllProcs[r] += offsetsAllProcs[r - 1];
134
135 // create the DMComposite object (of 1D DMDA objects)
136 ierr = createDmPack(); CHKERRQ(ierr);
137
138 // create info
139 ierr = createInfoString(); CHKERRQ(ierr);
140
141 PetscFunctionReturn(0);
142} // init
143
145{
146 PetscErrorCode ierr;
147
148 PetscFunctionBeginUser;
149
150 ierr = DMCompositeCreate(comm, &dmPack); CHKERRQ(ierr);
151
152 for (PetscInt i = 0; i < nBodies; ++i)
153 {
154 ierr = DMCompositeAddDM(dmPack, bodies[i]->da); CHKERRQ(ierr);
155 }
156
157 PetscFunctionReturn(0);
158} // createDmPack
159
160PetscErrorCode BodyPackBase::updateMeshIdx(const type::Mesh &mesh)
161{
162 PetscErrorCode ierr;
163
164 PetscFunctionBeginUser;
165
166 for (auto body : bodies)
167 {
168 ierr = body->updateMeshIdx(mesh); CHKERRQ(ierr);
169 }
170
171 PetscFunctionReturn(0);
172} // updateMeshIdx
173
175{
176 PetscFunctionBeginUser;
177
178 if (mpiRank == 0)
179 {
180 std::stringstream ss;
181 ss << std::string(80, '=') << std::endl;
182 ss << "Body Pack:" << std::endl;
183 ss << std::string(80, '=') << std::endl;
184 ss << "\tDimension: " << dim << std::endl << std::endl;
185 ss << "\tNumber of bodies: " << nBodies << std::endl << std::endl;
186 ss << "\tName of bodies: [";
187 for (PetscInt i = 0; i < nBodies; ++i) ss << bodies[i]->name << ", ";
188 ss << "]" << std::endl;
189 info = ss.str();
190 }
191
192 PetscFunctionReturn(0);
193} // createInfoString
194
195PetscErrorCode BodyPackBase::printInfo() const
196{
197 PetscErrorCode ierr;
198
199 PetscFunctionBeginUser;
200
201 ierr = io::print(info); CHKERRQ(ierr);
202
203 for (PetscInt i = 0; i < nBodies; ++i)
204 {
205 ierr = bodies[i]->printInfo(); CHKERRQ(ierr);
206 }
207
208 PetscFunctionReturn(0);
209} // printInfo
210
211PetscErrorCode BodyPackBase::findProc(const PetscInt &bIdx,
212 const PetscInt &ptIdx,
213 PetscMPIInt &proc) const
214{
215 PetscErrorCode ierr;
216
217 PetscFunctionBeginUser;
218
219 if ((bIdx < 0) || (bIdx >= nBodies))
220 SETERRQ2(comm, PETSC_ERR_ARG_SIZ,
221 "Body index %d is out of range. Total number of bodies is %d.",
222 bIdx, nBodies);
223
224 ierr = bodies[bIdx]->findProc(ptIdx, proc); CHKERRQ(ierr);
225
226 PetscFunctionReturn(0);
227} // findProc
228
229PetscErrorCode BodyPackBase::getGlobalIndex(const PetscInt &bIdx,
230 const PetscInt &ptIdx,
231 const PetscInt &dof,
232 PetscInt &idx) const
233{
234 PetscErrorCode ierr;
235
236 PetscFunctionBeginUser;
237
238 if ((bIdx < 0) || (bIdx >= nBodies))
239 SETERRQ2(comm, PETSC_ERR_ARG_SIZ,
240 "Body index %d is out of range. Total number of bodies is %d.",
241 bIdx, nBodies);
242
243 ierr = bodies[bIdx]->getGlobalIndex(ptIdx, dof, idx); CHKERRQ(ierr);
244
245 PetscFunctionReturn(0);
246} // getGlobalIndex
247
248PetscErrorCode BodyPackBase::getGlobalIndex(const PetscInt &bIdx,
249 const MatStencil &s,
250 PetscInt &idx) const
251{
252 PetscErrorCode ierr;
253
254 PetscFunctionBeginUser;
255
256 ierr = getGlobalIndex(bIdx, s.i, s.c, idx); CHKERRQ(ierr);
257
258 PetscFunctionReturn(0);
259} // getGlobalIndex
260
261PetscErrorCode BodyPackBase::getPackedGlobalIndex(const PetscInt &bIdx,
262 const PetscInt &ptIdx,
263 const PetscInt &dof,
264 PetscInt &idx) const
265{
266 PetscErrorCode ierr;
267 PetscMPIInt p;
268 PetscInt unPackedIdx;
269
270 PetscFunctionBeginUser;
271
272 ierr = findProc(bIdx, ptIdx, p); CHKERRQ(ierr);
273
274 ierr = getGlobalIndex(bIdx, ptIdx, dof, unPackedIdx); CHKERRQ(ierr);
275
276 idx = offsetsAllProcs[p];
277
278 for (PetscInt b = 0; b < bIdx; ++b) idx += bodies[b]->nLclAllProcs[p];
279
280 idx += (unPackedIdx - bodies[bIdx]->offsetsAllProcs[p]);
281
282 PetscFunctionReturn(0);
283} // getPackedGlobalIndex
284
285PetscErrorCode BodyPackBase::getPackedGlobalIndex(const PetscInt &bIdx,
286 const MatStencil &s,
287 PetscInt &idx) const
288{
289 PetscErrorCode ierr;
290
291 PetscFunctionBeginUser;
292
293 ierr = getPackedGlobalIndex(bIdx, s.i, s.c, idx); CHKERRQ(ierr);
294
295 PetscFunctionReturn(0);
296} // getPackedGlobalIndex
297
298PetscErrorCode BodyPackBase::calculateAvgForces(const Vec &f,
299 type::RealVec2D &fAvg)
300{
301 PetscErrorCode ierr;
302
303 PetscFunctionBeginUser;
304
305 std::vector<Vec> unPacked(nBodies);
306
307 fAvg.resize(nBodies);
308
309 ierr =
310 DMCompositeGetAccessArray(dmPack, f, nBodies, nullptr, unPacked.data());
311 CHKERRQ(ierr);
312
313 for (PetscInt i = 0; i < nBodies; ++i)
314 {
315 fAvg[i].resize(dim);
316 ierr = bodies[i]->calculateAvgForces(unPacked[i], fAvg[i]);
317 CHKERRQ(ierr);
318 }
319
320 ierr = DMCompositeRestoreAccessArray(dmPack, f, nBodies, nullptr,
321 unPacked.data()); CHKERRQ(ierr);
322
323 PetscFunctionReturn(0);
324} // calculateAvgForces
325
326PetscErrorCode createBodyPack(const MPI_Comm &comm, const PetscInt &dim,
327 const YAML::Node &node, type::BodyPack &bodies)
328{
329 PetscFunctionBeginUser;
330
331 bodies = std::make_shared<BodyPackBase>(comm, dim, node);
332
333 PetscFunctionReturn(0);
334} // createBodyPack
335
336} // end of namespace body
337
338} // end of namespace petibm
body::BodyPackBase, type::BodyPack, and factory function.
PetscInt nLclPts
Total number of local Lagrangian points.
Definition: bodypack.h:83
PetscMPIInt mpiSize
Total number of processes.
Definition: bodypack.h:225
std::string info
String used to print information.
Definition: bodypack.h:92
PetscErrorCode printInfo() const
Print information about the bodies.
Definition: bodypack.cpp:195
BodyPackBase()=default
Default constructor.
type::IntVec1D nLclAllProcs
Number of local packed variables of all processes.
Definition: bodypack.h:231
virtual PetscErrorCode destroy()
Manually destroy data.
Definition: bodypack.cpp:35
PetscErrorCode getPackedGlobalIndex(const PetscInt &bIdx, const PetscInt &ptIdx, const PetscInt &dof, PetscInt &idx) const
Find packed global index of a DoF of Lagrangian point of a body.
Definition: bodypack.cpp:261
PetscErrorCode createInfoString()
Create a string used to print information.
Definition: bodypack.cpp:174
MPI_Comm comm
Reference to the MPI communicator.
Definition: bodypack.h:222
PetscInt dim
Dimension.
Definition: bodypack.h:74
PetscErrorCode calculateAvgForces(const Vec &f, type::RealVec2D &fAvg)
Calculate the averaged force of each body.
Definition: bodypack.cpp:298
virtual ~BodyPackBase()
Default destructor.
Definition: bodypack.cpp:21
PetscErrorCode createDmPack()
Create DMComposite object for all bodies.
Definition: bodypack.cpp:144
PetscMPIInt mpiRank
Rank of the local process.
Definition: bodypack.h:228
std::vector< type::SingleBody > bodies
Vector of SingleBody objects.
Definition: bodypack.h:86
type::IntVec1D offsetsAllProcs
Offsets of packed variables of all processes.
Definition: bodypack.h:234
PetscErrorCode updateMeshIdx(const type::Mesh &mesh)
Get the index of closest Eulerian mesh cell for each local Lagrangian point.
Definition: bodypack.cpp:160
PetscErrorCode getGlobalIndex(const PetscInt &bIdx, const PetscInt &ptIdx, const PetscInt &dof, PetscInt &idx) const
Find unpacked global index of a DoF of Lagrangian point of a body.
Definition: bodypack.cpp:229
DM dmPack
DMComposite of DMDA objects of all SingleBody objects.
Definition: bodypack.h:89
PetscErrorCode findProc(const PetscInt &bIdx, const PetscInt &ptIdx, PetscMPIInt &proc) const
Find which process owns the target Lagrangian point of target body.
Definition: bodypack.cpp:211
PetscInt nPts
Total number of Lagrangian points.
Definition: bodypack.h:80
PetscErrorCode init(const MPI_Comm &comm, const PetscInt &dim, const YAML::Node &node)
Initialize the pack of bodies.
Definition: bodypack.cpp:55
PetscInt nBodies
Number of bodies in this pack.
Definition: bodypack.h:77
PetscErrorCode createBodyPack(const MPI_Comm &comm, const PetscInt &dim, const YAML::Node &node, type::BodyPack &bodies)
Factory function to create a pack of bodies.
Definition: bodypack.cpp:326
std::shared_ptr< body::BodyPackBase > BodyPack
Definition of type::BodyPack.
Definition: bodypack.h:262
PetscErrorCode createSingleBody(const MPI_Comm &comm, const PetscInt &dim, const std::string &type, const std::string &name, const std::string &filePath, type::SingleBody &body)
Factory function to create a single body.
Definition: singlebody.cpp:83
std::shared_ptr< mesh::MeshBase > Mesh
Type definition of Mesh.
Definition: mesh.h:348
PetscErrorCode print(const std::string &info)
Print information of a parallel object to standard output.
Definition: io.cpp:120
std::vector< RealVec1D > RealVec2D
2D std::vector holding PetscReal.
Definition: type.h:142
std::vector< PetscInt > IntVec1D
1D std::vector holding PetscInt.
Definition: type.h:133
Prototypes of I/O functions.
A toolbox for building flow solvers.
Definition: bodypack.h:52