PetIBM 0.5.4
Toolbox and applications of the immersed-boundary method for distributed-memory architectures
createdelta.cpp
Go to the documentation of this file.
1
8#include <cmath>
9
10#include <petscmat.h>
11
12#include <petibm/bodypack.h>
13#include <petibm/boundary.h>
14#include <petibm/delta.h>
15#include <petibm/mesh.h>
16#include <petibm/singlebody.h>
17#include <petibm/type.h>
18
19namespace petibm
20{
21namespace operators
22{
23// TODO: it's anti-readable that we mix the use of local and global Lagrangian
24// index
25// TODO: no pre-allocation for D matrix, this may be inefficient, though it
26// works
27
28PetscErrorCode getEulerianNeighbors(
29 const type::Mesh &mesh, const PetscInt &dof, const type::IntVec1D &IJK,
30 const std::vector<bool> &periodic, const PetscInt &window,
32
33// implementation of petibm::operators::createDelta
34PetscErrorCode createDelta(const type::Mesh &mesh, const type::Boundary &bc,
35 const type::BodyPack &bodies,
36 const delta::DeltaKernel &kernel,
37 const PetscInt &kernelSize,
38 Mat &Op)
39{
40 PetscFunctionBeginUser;
41
42 PetscErrorCode ierr;
43
44 // get periodic flags and domain sizes
45 std::vector<bool> periodic(mesh->dim); // flags to check periodicity
46 for (PetscInt d = 0; d < mesh->dim; ++d)
47 {
48 // the the x-component of the velocity is periodic in a direction,
49 // so are the other components of the velocity
50 periodic[d] = (bc->bds[0][d]->type == type::BCType::PERIODIC);
51 }
52
53 ierr = MatCreate(mesh->comm, &Op); CHKERRQ(ierr);
54 ierr = MatSetSizes(Op, bodies->nLclPts * bodies->dim, mesh->UNLocal,
55 bodies->nPts * bodies->dim, mesh->UN); CHKERRQ(ierr);
56 ierr = MatSetFromOptions(Op); CHKERRQ(ierr);
57 ierr = MatSetUp(Op); CHKERRQ(ierr);
58 ierr = MatSetOption(
59 Op, MAT_KEEP_NONZERO_PATTERN, PETSC_FALSE); CHKERRQ(ierr);
60 ierr = MatSetOption(
61 Op, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE); CHKERRQ(ierr);
62
63 // loop through all bodies
64 for (PetscInt bIdx = 0; bIdx < bodies->nBodies; ++bIdx)
65 {
66 // get an alias of the current body (for code readability)
67 const type::SingleBody &body = bodies->bodies[bIdx];
68
69 // get the cell widths of the background mesh
70 // (the regularized delta functions work for uniform meshes)
71 std::vector<PetscReal> widths(mesh->dim);
72 for (PetscInt d = 0; d < mesh->dim; ++d)
73 {
74 // get the directional width of the Eulerian cell
75 // closest to the first Lagrangian point
76 widths[d] = mesh->dL[0][d][body->meshIdx[0][d]];
77 }
78
79 // loop through all local points of this body
80 for (PetscInt iLcl = 0, iGlb = body->bgPt; iLcl < body->nLclPts;
81 iLcl++, iGlb++)
82 {
83 // get alias of coordinates and background index of current point
84 const type::IntVec1D &IJK = body->meshIdx[iLcl];
85 const type::RealVec1D &XYZ = body->coords[iGlb];
86
87 // loop through all directions
88 for (PetscInt dof = 0; dof < body->dim; ++dof)
89 {
90 type::IntVec1D cols;
91 type::RealVec1D vals;
92
93 // get packed row index
94 PetscInt row;
95 ierr = bodies->getPackedGlobalIndex(
96 bIdx, iGlb, dof, row); CHKERRQ(ierr);
97
99 type::RealVec2D coords;
101 mesh, dof, IJK, periodic, kernelSize, ijk, coords); CHKERRQ(ierr);
102
103 type::RealVec1D xyz(mesh->dim, 0.0);
104 if (mesh->dim == 3)
105 {
106 for (unsigned int k = 0; k < ijk[2].size(); ++k)
107 {
108 xyz[2] = coords[2][k];
109 for (unsigned int j = 0; j < ijk[1].size(); ++j)
110 {
111 xyz[1] = coords[1][j];
112 for (unsigned int i = 0; i < ijk[0].size(); ++i)
113 {
114 xyz[0] = coords[0][i];
115 // get packed column index
116 PetscInt col;
117 ierr = mesh->getPackedGlobalIndex(
118 dof, ijk[0][i], ijk[1][j], ijk[2][k],
119 col); CHKERRQ(ierr);
120
121 PetscReal val;
122 val = delta::delta(
123 XYZ, xyz, widths, kernel); CHKERRQ(ierr);
124
125 cols.push_back(col);
126 vals.push_back(val);
127 }
128 }
129 }
130 }
131 else if (mesh->dim == 2)
132 {
133 for (unsigned int j = 0; j < ijk[1].size(); ++j)
134 {
135 xyz[1] = coords[1][j];
136 for (unsigned int i = 0; i < ijk[0].size(); ++i)
137 {
138 xyz[0] = coords[0][i];
139 // get packed column index
140 PetscInt col;
141 ierr = mesh->getPackedGlobalIndex(
142 dof, ijk[0][i], ijk[1][j], 0,
143 col); CHKERRQ(ierr);
144
145 PetscReal val;
146 val = delta::delta(
147 XYZ, xyz, widths, kernel); CHKERRQ(ierr);
148
149 cols.push_back(col);
150 vals.push_back(val);
151 }
152 }
153 }
154 else
155 SETERRQ(mesh->comm, PETSC_ERR_ARG_WRONG,
156 "Only 2D and 3D configurations are supported.\n");
157
158 ierr = MatSetValues(Op, 1, &row,
159 cols.size(), cols.data(), vals.data(),
160 INSERT_VALUES); CHKERRQ(ierr);
161 }
162 }
163 }
164
165 ierr = MatAssemblyBegin(Op, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
166 ierr = MatAssemblyEnd(Op, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
167
168 PetscFunctionReturn(0);
169} // createDelta
170
171PetscErrorCode getEulerianNeighbors(
172 const type::Mesh &mesh, const PetscInt &dof, const type::IntVec1D &IJK,
173 const std::vector<bool> &periodic, const PetscInt &window,
175{
176 PetscFunctionBeginUser;
177
178 xyz.resize(mesh->dim);
179 ijk.resize(mesh->dim);
180
181 for (PetscInt d = 0; d < mesh->dim; ++d)
182 {
183 for (PetscInt s = IJK[d] - window; s <= IJK[d] + window; ++s)
184 {
185 if (s >= 0 && s < mesh->n[dof][d])
186 {
187 ijk[d].push_back(s);
188 xyz[d].push_back(mesh->coord[dof][d][s]);
189 }
190 else if (periodic[d])
191 {
192 PetscReal L = mesh->max[d] - mesh->min[d];
193 if (s < 0)
194 {
195 ijk[d].push_back(s + mesh->n[dof][d]);
196 xyz[d].push_back(mesh->coord[dof][d][s] - L);
197 }
198 else
199 {
200 ijk[d].push_back(s - mesh->n[dof][d]);
201 xyz[d].push_back(mesh->coord[dof][d][s] + L);
202 }
203 }
204 }
205 }
206
207 PetscFunctionReturn(0);
208} // getEulerianNeighbors
209
210} // end of namespace operators
211} // end of namespace petibm
body::BodyPackBase, type::BodyPack, and factory function.
boundary::BoundaryBase, type::Boundary, and factory function.
Prototype of Delta functions.
std::shared_ptr< body::BodyPackBase > BodyPack
Definition of type::BodyPack.
Definition: bodypack.h:262
std::shared_ptr< body::SingleBodyBase > SingleBody
Definition of type::SingleBody.
Definition: singlebody.h:206
std::shared_ptr< boundary::BoundaryBase > Boundary
Type definition of petibm::type::Boundary.
Definition: boundary.h:175
std::shared_ptr< mesh::MeshBase > Mesh
Type definition of Mesh.
Definition: mesh.h:348
PetscReal delta(const std::vector< PetscReal > &source, const std::vector< PetscReal > &target, const std::vector< PetscReal > &widths, const DeltaKernel &kernel)
Discrete delta function.
Definition: delta.cpp:65
PetscErrorCode createDelta(const type::Mesh &mesh, const type::Boundary &bc, const type::BodyPack &bodies, const delta::DeltaKernel &kernel, const PetscInt &kernelSize, Mat &Op)
Create a Delta operator, .
Definition: createdelta.cpp:34
std::vector< IntVec1D > IntVec2D
2D std::vector holding PetscInt.
Definition: type.h:135
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
std::vector< PetscReal > RealVec1D
1D std::vector holding PetscReal.
Definition: type.h:140
@ PERIODIC
Definition: type.h:96
Prototype of mesh::MeshBase, type::Mesh, and factory function.
std::function< PetscReal(const PetscReal &r, const PetscReal &dr)> DeltaKernel
Typedef to choose the regularized delta kernel to use.
Definition: delta.h:47
PetscErrorCode getEulerianNeighbors(const type::Mesh &mesh, const PetscInt &dof, const type::IntVec1D &IJK, const std::vector< bool > &periodic, const PetscInt &window, type::IntVec2D &ijk, type::RealVec2D &xyz)
A toolbox for building flow solvers.
Definition: bodypack.h:52
body::SingleBodyBase, type::SingleBody factory function.
Definition of user-defined types for convenience.