PetIBM 0.5.4
Toolbox and applications of the immersed-boundary method for distributed-memory architectures
solutionsimple.cpp
Go to the documentation of this file.
1
9#include <symengine/lambda_double.h>
10#include <petibm/io.h>
11#include <petibm/parser.h>
13
14namespace petibm
15{
16namespace solution
17{
18using namespace type;
19
20// Default destructor.
22
23// Constructor; initialize the solution object.
25{
26 init(inMesh);
27} // SolutionSimple
28
29// Create the flow field solutions.
30PetscErrorCode SolutionSimple::init(const Mesh &inMesh)
31{
32 PetscErrorCode ierr;
33
34 PetscFunctionBeginUser;
35
36 // make a shared pointer pointing to underlying mesh
37 mesh = inMesh;
38
39 // obtain MPI information from CartesianMesh object
40 comm = mesh->comm;
41 mpiSize = mesh->mpiSize;
42 mpiRank = mesh->mpiRank;
43
44 // get a copy of dim
45 dim = mesh->dim;
46
47 // create global composite vector for q
48 ierr = DMCreateGlobalVector(mesh->UPack, &UGlobal); CHKERRQ(ierr);
49
50 // create global composite vector for pressure
51 ierr = DMCreateGlobalVector(mesh->da[3], &pGlobal); CHKERRQ(ierr);
52
53 // create info string
54 ierr = createInfoString(); CHKERRQ(ierr);
55
56 PetscFunctionReturn(0);
57} // init
58
59// Create a string with information about the solution.
61{
62 PetscErrorCode ierr;
63 std::stringstream ss;
64
65 PetscFunctionBeginUser;
66
67 if (mpiRank == 0)
68 {
69 PetscInt size;
70 ss << std::string(80, '=') << std::endl;
71 ss << "Solution Vectors:" << std::endl;
72 ss << std::string(80, '=') << std::endl;
73 ss << "\tDimension: " << dim << std::endl;
74 ss << std::endl;
75 ierr = VecGetSize(UGlobal, &size); CHKERRQ(ierr);
76 ss << "\tLength of Global Packed Velocity Vector: " << size
77 << std::endl;
78 ss << std::endl;
79 ierr = VecGetSize(pGlobal, &size); CHKERRQ(ierr);
80 ss << "\tLength of Global Pressure Vector: " << size << std::endl;
81 ss << std::endl;
82 }
83
84 info = ss.str();
85
86 PetscFunctionReturn(0);
87} // createInfoString
88
89// Convert velocity fluxes to velocity components.
90PetscErrorCode SolutionSimple::convert2Velocity(const Mat &RInv)
91{
92 PetscErrorCode ierr;
93
94 PetscFunctionBeginUser;
95
96 Vec U; // temporary Vec for the velocity components
97 ierr = VecDuplicate(UGlobal, &U); CHKERRQ(ierr);
98 ierr = MatMult(RInv, UGlobal, U); CHKERRQ(ierr);
99 ierr = VecSwap(UGlobal, U); CHKERRQ(ierr);
100 ierr = VecDestroy(&U); CHKERRQ(ierr);
101
102 PetscFunctionReturn(0);
103} // convert2Velocity
104
105// Convert velocity components to velocity fluxes.
106PetscErrorCode SolutionSimple::convert2Flux(const Mat &R)
107{
108 PetscErrorCode ierr;
109
110 PetscFunctionBeginUser;
111
112 Vec F; // temporary Vec for the fluxes
113 ierr = VecDuplicate(UGlobal, &F); CHKERRQ(ierr);
114 ierr = MatMult(R, UGlobal, F); CHKERRQ(ierr);
115 ierr = VecSwap(UGlobal, F); CHKERRQ(ierr);
116 ierr = VecDestroy(&F); CHKERRQ(ierr);
117
118 PetscFunctionReturn(0);
119} // convert2Flux
120
121// Set initial conditions of the flow fields.
122PetscErrorCode SolutionSimple::setInitialConditions(const YAML::Node &node)
123{
124 PetscErrorCode ierr;
125 PetscReal nu;
126 std::vector<SymEngine::LambdaRealDoubleVisitor> ICs;
127 std::vector<Vec> UGlobalUnpacked(dim);
128 void* raw_arry;
129
130 // so no need to use two different array variables
131 struct arry_t {
132 arry_t() = default;
133 arry_t(double** inp): dim(2), twod(inp) {};
134 arry_t(double*** inp): dim(3), threed(inp) {};
135 PetscErrorCode set(double val, int i, int j, int k) {
136 PetscFunctionBeginUser;
137 switch (dim) {
138 case 2:
139 twod[j][i] = val; // petsc uses k-j-i order
140 break;
141 case 3:
142 threed[k][j][i] = val; // petsc uses k-j-i order
143 break;
144 default:
145 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Wrong dim.\n");
146 }
147 PetscFunctionReturn(0);
148 };
149 int dim;
150 double** twod = nullptr;
151 double*** threed = nullptr;
152 } arry;
153
154 PetscFunctionBeginUser;
155
156 if (! node["flow"]["nu"].IsDefined())
157 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
158 "Could not find the key \"nu\" under the key "
159 "\"flow\" in the YAML node passed to parseICs.\n");
160
161 // kinematic viscosity
162 nu = node["flow"]["nu"].as<PetscReal>();
163
164 // parse initial conditions for the velocity vector field
165 ierr = parser::parseICs(node, ICs); CHKERRQ(ierr);
166
167 // get individual velocity components from the packed Vec object
168 ierr = DMCompositeGetAccessArray(
169 mesh->UPack, UGlobal, dim, nullptr, UGlobalUnpacked.data());
170 CHKERRQ(ierr);
171
172 // IC for velocities
173 for (PetscInt field = 0; field < dim; ++field)
174 {
175 ierr = DMDAVecGetArray(mesh->da[field], UGlobalUnpacked[field], &raw_arry);
176 CHKERRQ(ierr);
177
178 switch (dim) {
179 case 2: arry = static_cast<PetscReal**>(raw_arry); break;
180 case 3: arry = static_cast<PetscReal***>(raw_arry); break;
181 }
182
183 // when 2d, properties in z are just trivial
184 for (PetscInt k=mesh->bg[field][2]; k<mesh->ed[field][2]; ++k) {
185 for (PetscInt j=mesh->bg[field][1]; j<mesh->ed[field][1]; ++j) {
186 for (PetscInt i=mesh->bg[field][0]; i<mesh->ed[field][0]; ++i) {
187 double value = ICs[field].call({
188 mesh->coord[field][0][i], mesh->coord[field][1][j],
189 mesh->coord[field][2][k], 0.0, nu
190 });
191 arry.set(value, i, j, k);
192 }
193 }
194 }
195
196 ierr = DMDAVecRestoreArray(mesh->da[field], UGlobalUnpacked[field], &raw_arry);
197 CHKERRQ(ierr);
198 }
199
200 ierr = DMCompositeRestoreAccessArray(
201 mesh->UPack, UGlobal, dim, nullptr, UGlobalUnpacked.data());
202 CHKERRQ(ierr);
203
204 // IC for pressure
205 ierr = DMDAVecGetArray(mesh->da[3], pGlobal, &raw_arry); CHKERRQ(ierr);
206
207 switch (dim) {
208 case 2: arry = static_cast<PetscReal**>(raw_arry); break;
209 case 3: arry = static_cast<PetscReal***>(raw_arry); break;
210 }
211
212 for (PetscInt k=mesh->bg[3][2]; k<mesh->ed[3][2]; ++k) {
213 for (PetscInt j=mesh->bg[3][1]; j<mesh->ed[3][1]; ++j) {
214 for (PetscInt i=mesh->bg[3][0]; i<mesh->ed[3][0]; ++i) {
215 double value = ICs[3].call({
216 mesh->coord[3][0][i], mesh->coord[3][1][j],
217 mesh->coord[3][2][k], 0.0, nu
218 });
219 arry.set(value, i, j, k);
220 }
221 }
222 }
223 ierr = DMDAVecRestoreArray(mesh->da[3], pGlobal, &raw_arry); CHKERRQ(ierr);
224
225 PetscFunctionReturn(0);
226} // setInitialConditions
227
228// Write flow field solutions to a file.
229PetscErrorCode SolutionSimple::write(const std::string &filePath) const
230{
231 PetscErrorCode ierr;
232
233 PetscFunctionBeginUser;
234
235 std::vector<Vec> vecs(dim + 1);
236 std::vector<std::string> names(dim + 1);
237
238 // set names for u, v, and/or w
239 for (int f = 0; f < dim; ++f) names[f] = type::fd2str[type::Field(f)];
240 // set name for pressure
241 names.back() = "p";
242
243 // get individual velocity components from the packed Vec object
244 ierr = DMCompositeGetAccessArray(mesh->UPack, UGlobal, dim, nullptr,
245 vecs.data()); CHKERRQ(ierr);
246 // get a reference to pressure Vec
247 vecs.back() = pGlobal;
248
249 // write to a HDF5 file
250 ierr = io::writeHDF5Vecs(comm, filePath, "/", names, vecs); CHKERRQ(ierr);
251
252 // nullify the reference to pressure Vec
253 vecs.back() = PETSC_NULL;
254 // return individual Vec objects to the packed Vec object
255 ierr = DMCompositeRestoreAccessArray(mesh->UPack, UGlobal, dim, nullptr,
256 vecs.data()); CHKERRQ(ierr);
257
258 PetscFunctionReturn(0);
259} // write
260
261// Read the flow field solutions from a file.
262PetscErrorCode SolutionSimple::read(const std::string &filePath)
263{
264 PetscErrorCode ierr;
265
266 PetscFunctionBeginUser;
267
268 std::vector<Vec> vecs(dim + 1);
269 std::vector<std::string> names(dim + 1);
270
271 // set names for u, v, and/or w
272 for (int f = 0; f < dim; ++f) names[f] = type::fd2str[type::Field(f)];
273 // set name for pressure
274 names.back() = "p";
275
276 // get individual velocity components from the packed Vec object
277 ierr = DMCompositeGetAccessArray(mesh->UPack, UGlobal, dim, nullptr,
278 vecs.data()); CHKERRQ(ierr);
279 // get a reference to pressure Vec
280 vecs.back() = pGlobal;
281
282 // read Vec objects from a HDF5 file
283 ierr = io::readHDF5Vecs(comm, filePath, "/", names, vecs); CHKERRQ(ierr);
284
285 // nullify the reference to pressure Vec
286 vecs.back() = PETSC_NULL;
287 // return individual Vec objects to the packed Vec object
288 ierr = DMCompositeRestoreAccessArray(mesh->UPack, UGlobal, dim, nullptr,
289 vecs.data()); CHKERRQ(ierr);
290
291 PetscFunctionReturn(0);
292} // read
293
294} // end of namespace solution
295} // end of namespace petibm
PetscMPIInt mpiRank
Rank of the local process.
Definition: solution.h:173
MPI_Comm comm
MPI communicator.
Definition: solution.h:167
PetscMPIInt mpiSize
Size of MPI communicator.
Definition: solution.h:170
std::string info
String containing information about the solution.
Definition: solution.h:72
Vec UGlobal
Packed PETSc Vec object for the velocity vector field.
Definition: solution.h:66
type::Mesh mesh
Shared pointer to the underlying Cartesian mesh object.
Definition: solution.h:176
Vec pGlobal
PETSc Vec for the pressure scalar field.
Definition: solution.h:69
PetscInt dim
Number of dimensions.
Definition: solution.h:63
virtual PetscErrorCode convert2Flux(const Mat &R)
Convert velocity components to velocity fluxes.
virtual PetscErrorCode write(const std::string &filePath) const
Write flow field solutions to a file.
virtual PetscErrorCode convert2Velocity(const Mat &Rinv)
Convert velocity fluxes to velocity components.
PetscErrorCode createInfoString()
Create a string with information about the solution.
virtual PetscErrorCode setInitialConditions(const YAML::Node &node)
Set initial conditions of the flow fields.
SolutionSimple(const type::Mesh &mesh)
Constructor using a Cartesian mesh.
virtual PetscErrorCode init(const type::Mesh &mesh)
Initialize the flow field solutions.
virtual ~SolutionSimple()
Default destructor.
virtual PetscErrorCode read(const std::string &filePath)
Read the flow field solutions from a file.
std::shared_ptr< mesh::MeshBase > Mesh
Type definition of Mesh.
Definition: mesh.h:348
PetscErrorCode writeHDF5Vecs(const MPI_Comm comm, const std::string &filePath, const std::string &loc, const std::vector< std::string > &names, const std::vector< Vec > &vecs, const PetscFileMode mode=FILE_MODE_WRITE)
Write a vector of Vec objects to a HDF5 file.
Definition: io.cpp:137
PetscErrorCode readHDF5Vecs(const MPI_Comm comm, const std::string &filePath, const std::string &loc, const std::vector< std::string > &names, std::vector< Vec > &vecs)
Read a vector of Vec objects from a HDF5 file.
Definition: io.cpp:243
PetscErrorCode parseICs(const YAML::Node &node, std::vector< SymEngine::LambdaRealDoubleVisitor > &ics)
Parse initial conditions from a YAML node.
Definition: parser.cpp:396
Field
Legal fields.
Definition: type.h:80
std::map< Field, std::string > fd2str
Mapping between Field and std::string.
Definition: type.cpp:24
Prototypes of I/O functions.
A toolbox for building flow solvers.
Definition: bodypack.h:52
Prototypes of parser functions.
Definition of class petibm::solution::SolutionSimple.