27 std::vector<Vec> qLocal;
31 : mesh(_mesh), bc(_bc), qLocal(_mesh->dim)
34 for (PetscInt f = 0; f < mesh->dim; ++f)
35 DMCreateLocalVector(mesh->da[f], &qLocal[f]);
40inline PetscReal kernelU(NonLinearCtx
const *
const &ctx,
41 const std::vector<PetscReal **> &flux,
42 const PetscInt &i,
const PetscInt &j)
45 PetscReal uS, uN, uW, uE;
49 uSelf = flux[0][j][i];
52 uW = (uSelf + flux[0][j][i - 1]) / 2.0;
53 uE = (uSelf + flux[0][j][i + 1]) / 2.0;
54 uS = (uSelf + flux[0][j - 1][i]) / 2.0;
55 uN = (uSelf + flux[0][j + 1][i]) / 2.0;
58 vS = (flux[1][j - 1][i] + flux[1][j - 1][i + 1]) / 2.0;
59 vN = (flux[1][j][i] + flux[1][j][i + 1]) / 2.0;
61 return (uE * uE - uW * uW) / ctx->mesh->dL[0][0][i] +
62 (vN * uN - vS * uS) / ctx->mesh->dL[0][1][j];
66inline PetscReal kernelV(NonLinearCtx
const *
const &ctx,
67 const std::vector<PetscReal **> &flux,
68 const PetscInt &i,
const PetscInt &j)
72 PetscReal vS, vN, vW, vE;
75 vSelf = flux[1][j][i];
78 uW = (flux[0][j][i - 1] + flux[0][j + 1][i - 1]) / 2.0;
79 uE = (flux[0][j][i] + flux[0][j + 1][i]) / 2.0;
82 vW = (vSelf + flux[1][j][i - 1]) / 2.0;
83 vE = (vSelf + flux[1][j][i + 1]) / 2.0;
84 vS = (vSelf + flux[1][j - 1][i]) / 2.0;
85 vN = (vSelf + flux[1][j + 1][i]) / 2.0;
87 return (uE * vE - uW * vW) / ctx->mesh->dL[1][0][i] +
88 (vN * vN - vS * vS) / ctx->mesh->dL[1][1][j];
92inline PetscReal kernelU(NonLinearCtx
const *
const &ctx,
93 const std::vector<PetscReal ***> &flux,
94 const PetscInt &i,
const PetscInt &j,
98 PetscReal uS, uN, uW, uE, uB, uF;
103 uSelf = flux[0][k][j][i];
106 uW = (uSelf + flux[0][k][j][i - 1]) / 2.0;
107 uE = (uSelf + flux[0][k][j][i + 1]) / 2.0;
108 uS = (uSelf + flux[0][k][j - 1][i]) / 2.0;
109 uN = (uSelf + flux[0][k][j + 1][i]) / 2.0;
110 uB = (uSelf + flux[0][k - 1][j][i]) / 2.0;
111 uF = (uSelf + flux[0][k + 1][j][i]) / 2.0;
114 vS = (flux[1][k][j - 1][i] + flux[1][k][j - 1][i + 1]) / 2.0;
115 vN = (flux[1][k][j][i] + flux[1][k][j][i + 1]) / 2.0;
118 wB = (flux[2][k - 1][j][i] + flux[2][k - 1][j][i + 1]) / 2.0;
119 wF = (flux[2][k][j][i] + flux[2][k][j][i + 1]) / 2.0;
121 return (uE * uE - uW * uW) / ctx->mesh->dL[0][0][i] +
122 (vN * uN - vS * uS) / ctx->mesh->dL[0][1][j] +
123 (wF * uF - wB * uB) / ctx->mesh->dL[0][2][k];
127inline PetscReal kernelV(NonLinearCtx
const *
const &ctx,
128 const std::vector<PetscReal ***> &flux,
129 const PetscInt &i,
const PetscInt &j,
134 PetscReal vS, vN, vW, vE, vB, vF;
138 vSelf = flux[1][k][j][i];
141 uW = (flux[0][k][j][i - 1] + flux[0][k][j + 1][i - 1]) / 2.0;
142 uE = (flux[0][k][j][i] + flux[0][k][j + 1][i]) / 2.0;
145 vW = (vSelf + flux[1][k][j][i - 1]) / 2.0;
146 vE = (vSelf + flux[1][k][j][i + 1]) / 2.0;
147 vS = (vSelf + flux[1][k][j - 1][i]) / 2.0;
148 vN = (vSelf + flux[1][k][j + 1][i]) / 2.0;
149 vB = (vSelf + flux[1][k - 1][j][i]) / 2.0;
150 vF = (vSelf + flux[1][k + 1][j][i]) / 2.0;
153 wB = (flux[2][k - 1][j][i] + flux[2][k - 1][j + 1][i]) / 2.0;
154 wF = (flux[2][k][j][i] + flux[2][k][j + 1][i]) / 2.0;
156 return (uE * vE - uW * vW) / ctx->mesh->dL[1][0][i] +
157 (vN * vN - vS * vS) / ctx->mesh->dL[1][1][j] +
158 (wF * vF - wB * vB) / ctx->mesh->dL[1][2][k];
163inline PetscReal kernelW(NonLinearCtx
const *
const &ctx,
164 const std::vector<PetscReal ***> &flux,
165 const PetscInt &i,
const PetscInt &j,
171 PetscReal wS, wN, wW, wE, wB, wF;
174 wSelf = flux[2][k][j][i];
177 uW = (flux[0][k][j][i - 1] + flux[0][k + 1][j][i - 1]) / 2.0;
178 uE = (flux[0][k][j][i] + flux[0][k + 1][j][i]) / 2.0;
181 vS = (flux[1][k][j - 1][i] + flux[1][k + 1][j - 1][i]) / 2.0;
182 vN = (flux[1][k][j][i] + flux[1][k + 1][j][i]) / 2.0;
185 wW = (wSelf + flux[2][k][j][i - 1]) / 2.0;
186 wE = (wSelf + flux[2][k][j][i + 1]) / 2.0;
187 wS = (wSelf + flux[2][k][j - 1][i]) / 2.0;
188 wN = (wSelf + flux[2][k][j + 1][i]) / 2.0;
189 wB = (wSelf + flux[2][k - 1][j][i]) / 2.0;
190 wF = (wSelf + flux[2][k + 1][j][i]) / 2.0;
192 return (uE * wE - uW * wW) / ctx->mesh->dL[2][0][i] +
193 (vN * wN - vS * wS) / ctx->mesh->dL[2][1][j] +
194 (wF * wF - wB * wB) / ctx->mesh->dL[2][2][k];
199PetscErrorCode ConvectionMult2D(Mat mat, Vec
x, Vec
y)
201 PetscFunctionBeginUser;
207 std::vector<Vec> unPacked(2);
209 std::vector<PetscReal **> xArry(2);
211 std::vector<PetscReal **> yArry(2);
214 ierr = MatShellGetContext(mat, (
void *)&ctx); CHKERRQ(ierr);
217 ierr = DMCompositeScatterArray(ctx->mesh->UPack,
x, ctx->qLocal.data());
221 ierr = ctx->bc->copyValues2LocalVecs(ctx->qLocal); CHKERRQ(ierr);
224 ierr = DMCompositeGetAccessArray(ctx->mesh->UPack,
y, ctx->mesh->dim,
225 nullptr, unPacked.data()); CHKERRQ(ierr);
228 for (PetscInt f = 0; f < ctx->mesh->dim; ++f)
230 ierr = DMDAVecGetArrayRead(ctx->mesh->da[f], ctx->qLocal[f], &xArry[f]);
233 ierr = DMDAVecGetArray(ctx->mesh->da[f], unPacked[f], &yArry[f]);
238 for (PetscInt j = ctx->mesh->bg[0][1]; j < ctx->mesh->ed[0][1]; ++j)
239 for (PetscInt i = ctx->mesh->bg[0][0]; i < ctx->mesh->ed[0][0]; ++i)
240 yArry[0][j][i] = kernelU(ctx, xArry, i, j);
243 for (PetscInt j = ctx->mesh->bg[1][1]; j < ctx->mesh->ed[1][1]; ++j)
244 for (PetscInt i = ctx->mesh->bg[1][0]; i < ctx->mesh->ed[1][0]; ++i)
245 yArry[1][j][i] = kernelV(ctx, xArry, i, j);
248 for (PetscInt f = 0; f < ctx->mesh->dim; ++f)
250 ierr = DMDAVecRestoreArrayRead(ctx->mesh->da[f], ctx->qLocal[f],
251 &xArry[f]); CHKERRQ(ierr);
253 ierr = DMDAVecRestoreArray(ctx->mesh->da[f], unPacked[f], &yArry[f]);
258 ierr = DMCompositeRestoreAccessArray(ctx->mesh->UPack,
y, ctx->mesh->dim,
259 nullptr, unPacked.data());
262 PetscFunctionReturn(0);
267PetscErrorCode ConvectionMult3D(Mat mat, Vec
x, Vec
y)
269 PetscFunctionBeginUser;
275 std::vector<Vec> unPacked(3);
277 std::vector<PetscReal ***> xArry(3);
279 std::vector<PetscReal ***> yArry(3);
282 ierr = MatShellGetContext(mat, (
void *)&ctx); CHKERRQ(ierr);
285 ierr = DMCompositeScatterArray(ctx->mesh->UPack,
x, ctx->qLocal.data());
289 ierr = ctx->bc->copyValues2LocalVecs(ctx->qLocal); CHKERRQ(ierr);
292 ierr = DMCompositeGetAccessArray(ctx->mesh->UPack,
y, ctx->mesh->dim,
293 nullptr, unPacked.data()); CHKERRQ(ierr);
296 for (PetscInt f = 0; f < ctx->mesh->dim; ++f)
298 ierr = DMDAVecGetArrayRead(ctx->mesh->da[f], ctx->qLocal[f], &xArry[f]);
301 ierr = DMDAVecGetArray(ctx->mesh->da[f], unPacked[f], &yArry[f]);
306 for (PetscInt k = ctx->mesh->bg[0][2]; k < ctx->mesh->ed[0][2]; ++k)
307 for (PetscInt j = ctx->mesh->bg[0][1]; j < ctx->mesh->ed[0][1]; ++j)
308 for (PetscInt i = ctx->mesh->bg[0][0]; i < ctx->mesh->ed[0][0]; ++i)
309 yArry[0][k][j][i] = kernelU(ctx, xArry, i, j, k);
312 for (PetscInt k = ctx->mesh->bg[1][2]; k < ctx->mesh->ed[1][2]; ++k)
313 for (PetscInt j = ctx->mesh->bg[1][1]; j < ctx->mesh->ed[1][1]; ++j)
314 for (PetscInt i = ctx->mesh->bg[1][0]; i < ctx->mesh->ed[1][0]; ++i)
315 yArry[1][k][j][i] = kernelV(ctx, xArry, i, j, k);
318 for (PetscInt k = ctx->mesh->bg[2][2]; k < ctx->mesh->ed[2][2]; ++k)
319 for (PetscInt j = ctx->mesh->bg[2][1]; j < ctx->mesh->ed[2][1]; ++j)
320 for (PetscInt i = ctx->mesh->bg[2][0]; i < ctx->mesh->ed[2][0]; ++i)
321 yArry[2][k][j][i] = kernelW(ctx, xArry, i, j, k);
324 for (PetscInt f = 0; f < ctx->mesh->dim; ++f)
326 ierr = DMDAVecRestoreArrayRead(ctx->mesh->da[f], ctx->qLocal[f],
327 &xArry[f]); CHKERRQ(ierr);
329 ierr = DMDAVecRestoreArray(ctx->mesh->da[f], unPacked[f], &yArry[f]);
334 ierr = DMCompositeRestoreAccessArray(ctx->mesh->UPack,
y, ctx->mesh->dim,
335 nullptr, unPacked.data());
338 PetscFunctionReturn(0);
343PetscErrorCode ConvectionDestroy(Mat mat)
345 PetscFunctionBeginUser;
352 ierr = MatShellGetContext(mat, (
void *)&ctx); CHKERRQ(ierr);
355 for (PetscInt f = 0; f < ctx->mesh->dim; f++)
357 ierr = VecDestroy(&ctx->qLocal[f]); CHKERRQ(ierr);
363 PetscFunctionReturn(0);
375 PetscFunctionBeginUser;
383 mesh->n[0][0] * mesh->n[0][1] * mesh->n[0][2] +
384 mesh->n[1][0] * mesh->n[1][1] * mesh->n[1][2] +
385 ((mesh->dim == 3) ? mesh->n[2][0] * mesh->n[2][1] * mesh->n[2][2] : 0);
388 ctx =
new NonLinearCtx(mesh, bd);
391 ierr = MatCreateShell(mesh->comm, mesh->UNLocal, mesh->UNLocal, N, N,
392 (
void *)ctx, &H); CHKERRQ(ierr);
397 ierr = MatShellSetOperation(H, MATOP_MULT,
398 (
void (*)(
void))ConvectionMult2D);
403 ierr = MatShellSetOperation(H, MATOP_MULT,
404 (
void (*)(
void))ConvectionMult3D);
409 ierr = MatShellSetOperation(H, MATOP_DESTROY,
410 (
void (*)(
void))ConvectionDestroy);
413 PetscFunctionReturn(0);
boundary::BoundaryBase, type::Boundary, and factory function.
std::shared_ptr< boundary::BoundaryBase > Boundary
Type definition of petibm::type::Boundary.
std::shared_ptr< mesh::MeshBase > Mesh
Type definition of Mesh.
PetscErrorCode createConvection(const type::Mesh &mesh, const type::Boundary &bc, Mat &H)
Create a matrix-free Mat for convection operator, .
Prototype of mesh::MeshBase, type::Mesh, and factory function.
A toolbox for building flow solvers.