20#include "../private/private.h"
31 : bc(_bc), modifier(bc->dim){};
35typedef std::function<MatStencil(
const PetscInt &,
const PetscInt &,
40typedef std::function<PetscReal(
const PetscInt &,
const PetscInt &,
45PetscErrorCode DCorrectionMult(Mat mat, Vec
x, Vec
y)
47 PetscFunctionBeginUser;
54 ierr = MatShellGetContext(mat, (
void *)&ctx); CHKERRQ(ierr);
57 ierr = VecSet(
y, 0.0); CHKERRQ(ierr);
60 for (PetscInt f = 0; f < ctx->bc->dim; ++f)
61 for (
auto &bd : ctx->bc->bds[f])
63 for (
auto &pt : bd->points)
66 y, ctx->modifier[f][pt.first].row,
67 ctx->modifier[f][pt.first].coeff * pt.second.a1,
68 ADD_VALUES); CHKERRQ(ierr);
74 ierr = VecAssemblyBegin(
y); CHKERRQ(ierr);
75 ierr = VecAssemblyEnd(
y); CHKERRQ(ierr);
77 PetscFunctionReturn(0);
81PetscErrorCode DCorrectionDestroy(Mat mat)
83 PetscFunctionBeginUser;
89 ierr = MatShellGetContext(mat, (
void *)&ctx); CHKERRQ(ierr);
94 PetscFunctionReturn(0);
105 Mat &DCorrection,
const PetscBool &normalize)
107 PetscFunctionBeginUser;
111 std::vector<GetNeighborFunc> getNeighbor(3);
113 std::vector<Kernel> kernel(3);
118 ctx =
new DivergenceCtx(bc);
121 getNeighbor[0] = [](
const PetscInt &i,
const PetscInt &j,
122 const PetscInt &k) -> MatStencil {
123 return {k, j, i - 1};
125 getNeighbor[1] = [](
const PetscInt &i,
const PetscInt &j,
126 const PetscInt &k) -> MatStencil {
127 return {k, j - 1, i};
129 getNeighbor[2] = [](
const PetscInt &i,
const PetscInt &j,
130 const PetscInt &k) -> MatStencil {
131 return {k - 1, j, i};
136 kernel[0] = kernel[1] = kernel[2] =
137 std::bind([]() -> PetscReal {
return 1.0; });
140 kernel[0] = [&mesh](
const PetscInt &i,
const PetscInt &j,
141 const PetscInt &k) -> PetscReal {
142 return mesh->dL[0][1][j] * mesh->dL[0][2][k];
144 kernel[1] = [&mesh](
const PetscInt &i,
const PetscInt &j,
145 const PetscInt &k) -> PetscReal {
146 return mesh->dL[1][0][i] * mesh->dL[1][2][k];
148 kernel[2] = [&mesh](
const PetscInt &i,
const PetscInt &j,
149 const PetscInt &k) -> PetscReal {
150 return mesh->dL[2][0][i] * mesh->dL[2][1][j];
155 ierr = MatCreate(mesh->comm, &D); CHKERRQ(ierr);
156 ierr = MatSetSizes(D, mesh->pNLocal, mesh->UNLocal, PETSC_DETERMINE,
157 PETSC_DETERMINE); CHKERRQ(ierr);
158 ierr = MatSetFromOptions(D); CHKERRQ(ierr);
159 ierr = MatSeqAIJSetPreallocation(D, mesh->dim * 2,
nullptr); CHKERRQ(ierr);
162 ierr = MatMPIAIJSetPreallocation(D, mesh->dim * 2,
nullptr, 3,
nullptr);
165 ierr = MatSetUp(D); CHKERRQ(ierr);
166 ierr = MatSetOption(D, MAT_KEEP_NONZERO_PATTERN, PETSC_FALSE);
168 ierr = MatSetOption(D, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE); CHKERRQ(ierr);
171 for (PetscInt k = mesh->bg[3][2]; k < mesh->ed[3][2]; ++k)
172 for (PetscInt j = mesh->bg[3][1]; j < mesh->ed[3][1]; ++j)
173 for (PetscInt i = mesh->bg[3][0]; i < mesh->ed[3][0]; ++i)
178 ierr = mesh->getGlobalIndex(3, {k, j, i, 0}, self);
183 for (PetscInt field = 0; field < mesh->dim; ++field)
192 PetscReal value = kernel[field](i, j, k);
195 target = {k, j, i, 0};
197 ierr = mesh->getPackedGlobalIndex(field, target, targetIdx);
201 MatSetValue(D, self, targetIdx, value, INSERT_VALUES);
206 ctx->modifier[field][target] = {self, value};
209 target = getNeighbor[field](i, j, k);
211 ierr = mesh->getPackedGlobalIndex(field, target, targetIdx);
216 MatSetValue(D, self, targetIdx, -value, INSERT_VALUES);
221 ctx->modifier[field][target] = {self, -value};
226 ierr = MatAssemblyBegin(D, MAT_FLUSH_ASSEMBLY); CHKERRQ(ierr);
227 ierr = MatAssemblyEnd(D, MAT_FLUSH_ASSEMBLY); CHKERRQ(ierr);
231 for (PetscInt f = 0; f < mesh->dim; ++f)
232 for (
auto &bd : bc->bds[f])
234 for (
auto &pt : bd->points)
236 PetscInt col = pt.second.targetPackedId;
238 ctx->modifier[f][pt.first].coeff * pt.second.a0;
240 ierr = MatSetValue(D, ctx->modifier[f][pt.first].row, col,
241 value, ADD_VALUES); CHKERRQ(ierr);
245 ierr = MatAssemblyBegin(D, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
246 ierr = MatAssemblyEnd(D, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
249 ierr = MatCreateShell(mesh->comm, mesh->pNLocal, mesh->UNLocal,
250 PETSC_DETERMINE, PETSC_DETERMINE, (
void *)ctx,
251 &DCorrection); CHKERRQ(ierr);
253 ierr = MatShellSetOperation(DCorrection, MATOP_MULT,
254 (
void (*)(
void))DCorrectionMult);
257 ierr = MatShellSetOperation(DCorrection, MATOP_DESTROY,
258 (
void (*)(
void))DCorrectionDestroy);
261 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 createDivergence(const type::Mesh &mesh, const type::Boundary &bc, Mat &D, Mat &DCorrection, const PetscBool &normalize=PETSC_TRUE)
Create a divergence operator, , and corresponding boundary correction, , for velocity fields.
std::vector< std::map< MatStencil, RowModifier > > MatrixModifier
A type that holds necessary info for a matrix modifier that modifies matrix coefficient based on BCs.
Prototype of mesh::MeshBase, type::Mesh, and factory function.
std::function< StencilVec(const PetscInt &, const PetscInt &, const PetscInt &)> GetNeighborFunc
a function type for functions returning neighbors' stencils.
std::function< type::RealVec1D(const PetscInt &, const PetscInt &, const PetscInt &)> Kernel
a function type for functions computing matrix entries' values.
A toolbox for building flow solvers.
Definition of user-defined types for convenience.