26#ifndef PECLET_VORO_FV_COVOLUME_HPP
27#define PECLET_VORO_FV_COVOLUME_HPP
31#include <Kokkos_Core.hpp>
35#include "peclet/core/common/view.hpp"
36#include "peclet/core/solver/graph_amg_device.hpp"
46 using Exec = peclet::core::ExecSpace;
49 "fv.perotT", Kokkos::RangePolicy<Exec>(0, m.
nFaces), KOKKOS_LAMBDA(
const int f) {
56 for (
int c = 0; c < 3; ++c) {
58 s += cf * acell(3 * a + c) - (cf - m.
conn(f, c)) * acell(3 * b + c);
72 const DV<Real>& Uwall = DV<Real>{},
const DV<Real>& wallGrad = DV<Real>{}) {
73 using Exec = peclet::core::ExecSpace;
75 const bool hasF = force.extent(0) > 0, hasW = Uwall.extent(0) > 0, hasWG = wallGrad.extent(0) > 0;
77 "fv.tendency", Kokkos::RangePolicy<Exec>(0, m.
nCells), KOKKOS_LAMBDA(
const int i) {
78 Real acc[3] = {0, 0, 0};
79 const Real Ui[3] = {U(3 * i), U(3 * i + 1), U(3 * i + 2)};
83 const Real F = convScale * s * u(f) * m.
faceArea(f);
87 for (
int c = 0; c < 3; ++c) {
88 const Real Uj = U(3 * j + c);
89 acc[c] += -F * Real(0.5) * (Ui[c] + Uj) + w * (Uj - Ui[c]);
93 for (
int c = 0; c < 3; ++c) {
94 const Real Uw = hasW ? Uwall(3 * (f - nI) + c) : Real(0);
97 hasWG ? -nu * m.
faceArea(f) * wallGrad(3 * (f - nI) + c) : w * (Uw - Ui[c]);
98 acc[c] += -F * Uw + visc;
103 for (
int c = 0; c < 3; ++c)
104 out(3 * i + c) = acc[c] * iv + (hasF ? force(3 * i + c) : Real(0));
112 using Exec = peclet::core::ExecSpace;
125 peclet::core::solver::GraphAMGDevice
amg;
131 std::function<Real(Real)>
sum;
142 Kokkos::View<double*, peclet::core::MemSpace>
rd,
zd;
154 Kokkos::parallel_for(
155 "ps.ediag", Kokkos::RangePolicy<Exec>(0, mesh.
nCells), KOKKOS_LAMBDA(
const int i) {
164 setup(mesh, withAmg);
170 const int NC =
m.nCombined > 0 ?
m.nCombined : N;
177 Kokkos::parallel_reduce(
178 "ps.vtot", Kokkos::RangePolicy<Exec>(0, N),
179 KOKKOS_LAMBDA(
const int i, Real& acc) { acc += mm.
cellVolume(i); },
Vtot);
186 rd = Kokkos::View<double*, peclet::core::MemSpace>(
"ps.rd", N);
187 zd = Kokkos::View<double*, peclet::core::MemSpace>(
"ps.zd", N);
190 auto A = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.faceCellA);
191 auto B = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.faceCellB);
192 auto Af = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.faceArea);
193 auto df = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.faceDist);
194 auto off = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.cellFaceOffset);
195 auto cf = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.cellFace);
196 auto cs = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{},
m.cellFaceSign);
197 peclet::core::solver::HostCsrOp K;
199 K.diag.assign(N, 0.0);
200 K.start.assign(N + 1, 0);
201 std::vector<Real> edh;
204 for (
int i = 0; i < N; ++i) {
207 for (
int qq = off(i); qq < off(i + 1); ++qq) {
208 const int f = cf(qq);
209 if (f >=
m.nInterior)
211 const int j = cs(qq) > 0 ? B(f) : A(f);
212 const double w =
lapScale * Af(f) / df(f);
217 K.coef.push_back(-w);
219 K.start[i + 1] = (peclet::core::Index)K.nbr.size();
221 peclet::core::solver::AmgParams prm;
226 prm.coarseSweeps =
deflate ? 8 : 0;
236 const bool hasEd = ed.extent(0) > 0;
237 Kokkos::parallel_for(
238 "ps.K", Kokkos::RangePolicy<Exec>(0, mm.
nCells), KOKKOS_LAMBDA(
const int i) {
240 const Real zi = zz(i);
248 qq(i) = acc + (hasEd ? ed(i) * zi : Real(0));
254 Kokkos::parallel_reduce(
255 "ps.dot", Kokkos::RangePolicy<Exec>(0,
m.nCells),
256 KOKKOS_LAMBDA(
const int i, Real& acc) { acc += a(i) * bb(i); }, s);
261 Kokkos::deep_copy(Kokkos::subview(zz, std::make_pair(0, (
int)rr.extent(0))), rr);
264 if constexpr (std::is_same_v<Real, double>) {
265 if (zz.extent(0) == rr.extent(0))
268 amg.apply(rr, Kokkos::subview(zz, std::make_pair(0, (
int)rr.extent(0))));
270 Kokkos::deep_copy(
rd, rr);
272 Kokkos::deep_copy(zz,
zd);
277 const int N =
m.nCells;
282 const Real vt =
Vtot;
285 Kokkos::parallel_reduce(
286 "ps.fmean", Kokkos::RangePolicy<Exec>(0, N),
287 KOKKOS_LAMBDA(
const int i, Real& acc) { acc += mm.
cellVolume(i) * f(i); }, fMean);
292 Kokkos::deep_copy(p, Real(0));
294 Kokkos::parallel_for(
295 "ps.b", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int i) {
296 rr(i) = defl ? mm.
cellVolume(i) * (f(i) - fMean) : f(i);
298 const Real r0 = Kokkos::sqrt(
dot(rr, rr));
299 if (!(r0 > Real(0))) {
305 Kokkos::deep_copy(d, zz);
306 Real rz =
dot(rr, zz);
312 const Real dq =
dot(d, qq);
315 const Real alpha = rz / dq;
316 Kokkos::parallel_for(
317 "ps.upd", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int i) {
318 p(i) += alpha * d(i);
319 rr(i) -= alpha * qq(i);
321 lastRes = Kokkos::sqrt(
dot(rr, rr)) / (r0 > Real(0) ? r0 : Real(1));
327 const Real rzn =
dot(rr, zz);
328 const Real beta = rzn / rz;
330 Kokkos::parallel_for(
331 "ps.d", Kokkos::RangePolicy<Exec>(0, N),
332 KOKKOS_LAMBDA(
const int i) { d(i) = zz(i) + beta * d(i); });
336 Kokkos::parallel_reduce(
337 "ps.pmean", Kokkos::RangePolicy<Exec>(0, N),
338 KOKKOS_LAMBDA(
const int i, Real& acc) { acc += mm.
cellVolume(i) * p(i); }, pMean);
342 Kokkos::parallel_for(
343 "ps.pin", Kokkos::RangePolicy<Exec>(0, N), KOKKOS_LAMBDA(
const int i) { p(i) -= pMean; });
354 using Exec = peclet::core::ExecSpace;
378 sum = [&ex](Real v) {
return ex.sum(v); };
379 max = [&ex](Real v) {
return ex.max(v); };
387 const int N =
m.
nCells, F =
m.nFaces;
388 const int NC =
m.nCombined > 0 ?
m.nCombined : N;
404 const int nB =
m.nFaces -
m.nInterior, nI =
m.nInterior;
407 if (Uw.extent(0) == 0)
411 Kokkos::parallel_for(
412 "fv.ub", Kokkos::RangePolicy<Exec>(0, nB), KOKKOS_LAMBDA(
const int b) {
414 for (
int c = 0; c < 3; ++c)
415 un += Uw(3 * b + c) * mm.
normal(nI + b, c);
421 const int nB =
m.nFaces -
m.nInterior, nI =
m.nInterior;
423 Kokkos::parallel_for(
424 "fv.wall", Kokkos::RangePolicy<Exec>(0, nB),
425 KOKKOS_LAMBDA(
const int b) { uf(nI + b) = bb(b); });
429 dec = buildDecEdges<Real>(view,
m);
447 Kokkos::parallel_for(
448 "ns.decvisc", Kokkos::RangePolicy<Exec>(0,
m.nInterior),
449 KOKKOS_LAMBDA(
const int f) { out(f) += nuL * dO(f); });
456 if (
wg.extent(0) == 0) {
458 g9w =
DV<Real>(
"ns.g9w", 9 * (
m.nCombined > 0 ?
m.nCombined :
m.nCells));
474 const Real s = -Real(1) / dt;
475 Kokkos::parallel_for(
476 "ns.rhsP", Kokkos::RangePolicy<Exec>(0,
m.nCells),
477 KOKKOS_LAMBDA(
const int i) { dv(i) *= s; });
480 Kokkos::parallel_for(
481 "ns.corr", Kokkos::RangePolicy<Exec>(0,
m.nFaces),
482 KOKKOS_LAMBDA(
const int f) { uf(f) -= dt * g(f); });
486 const int F =
m.nFaces;
489 Kokkos::parallel_for(
490 "ns.s1", Kokkos::RangePolicy<Exec>(0, F),
491 KOKKOS_LAMBDA(
const int f) { v1(f) = uu(f) + dt * kk(f); });
494 Kokkos::parallel_for(
495 "ns.s2", Kokkos::RangePolicy<Exec>(0, F), KOKKOS_LAMBDA(
const int f) {
496 v2(f) = Real(0.75) * uu(f) + Real(0.25) * (v1(f) + dt * kk(f));
500 Kokkos::parallel_for(
501 "ns.s3", Kokkos::RangePolicy<Exec>(0, F),
502 KOKKOS_LAMBDA(
const int f) { uu(f) = (uu(f) + Real(2) * (v2(f) + dt * kk(f))) / Real(3); });
503 project(uu, Real(2) / Real(3) * dt);
512 Kokkos::parallel_reduce(
513 "ns.ke", Kokkos::RangePolicy<Exec>(0,
m.nInterior),
514 KOKKOS_LAMBDA(
const int f, Real& acc) {
515 const Real w = mm.
faceCellB(f) >= nOwn ? Real(0.5) : Real(1);
521 return Real(0.5) * e;
528 Kokkos::parallel_reduce(
529 "ns.maxdiv", Kokkos::RangePolicy<Exec>(0,
m.nCells),
530 KOKKOS_LAMBDA(
const int i, Real& acc) {
531 const Real v = Kokkos::fabs(dv(i));
535 Kokkos::Max<Real>(mx));
536 return max ?
max(mx) : mx;
Track C, rung C2a′ (Voronoi methods plan): the discrete-exterior-calculus (Nicolaides covolume) vecto...
Track C, rung C1 (Voronoi methods plan): the FACE mesh of a published tessellation — one record per g...
Definition collocated.hpp:38
void vectorGreenGauss(const FaceMesh< Real > &m, const DV< Real > &U, const DV< Real > &out, const DV< Real > &Uwall=DV< Real >{})
Definition operators.hpp:161
void perotTranspose(const FaceMesh< Real > &m, const DV< Real > &acell, const DV< Real > &out)
Transpose of the Perot reconstruction: face-normal tendency from cell tendencies (3N).
Definition covolume.hpp:45
void cellTendency(const FaceMesh< Real > &m, const DV< Real > &u, const DV< Real > &U, Real nu, const DV< Real > &out, const DV< Real > &force=DV< Real >{}, Real convScale=Real(1), const DV< Real > &Uwall=DV< Real >{}, const DV< Real > &wallGrad=DV< Real >{})
Definition covolume.hpp:70
Kokkos::View< Real *, peclet::core::MemSpace > DV
Definition operators.hpp:26
void divergence(const FaceMesh< Real > &m, const DV< Real > &u, const DV< Real > &out)
(div u)_i from face-normal fluxes u (nFaces; boundary faces included, along the outward normal).
Definition operators.hpp:30
void faceGradient(const FaceMesh< Real > &m, const DV< Real > &p, const DV< Real > &out, const DV< Real > &pb=DV< Real >{})
Definition operators.hpp:46
void decLaplacian(const FaceMesh< Real > &m, const DecEdges< Real > &d, const DV< Real > &u, const DV< Real > &divScratch, const DV< Real > &out)
Definition dec.hpp:185
void perotVelocity(const FaceMesh< Real > &m, const DV< Real > &u, const DV< Real > &out)
Perot reconstruction of the cell velocity (3N) from face-normal fluxes.
Definition operators.hpp:103
void wallGradientLS(const FaceMesh< Real > &m, const DV< Real > &U, const DV< Real > &gradU, const DV< Real > &Uwall, const DV< Real > &out)
Definition operators.hpp:359
int poissonCG(const FaceMesh< Real > &m, const DV< Real > &f, const DV< Real > &p, Real tol, int maxIter, Real &resOut)
Definition operators.hpp:429
Track C, rung C1: the discrete operators of the staggered COVOLUME scheme on a face mesh (plan verdic...
Definition tessellation_view.hpp:111
The covolume NS solver state: face fluxes u, cell pressure p (from the last projection).
Definition covolume.hpp:353
DV< Real > gphi
Definition covolume.hpp:368
peclet::core::ExecSpace Exec
Definition covolume.hpp:354
DecEdges< Real > dec
Definition covolume.hpp:366
DV< Real > k
Definition covolume.hpp:368
DV< Real > Uwall
Definition covolume.hpp:359
DV< Real > decDiv
Definition covolume.hpp:367
std::function< Real(Real)> max
Definition covolume.hpp:374
void applyWallFlux(const DV< Real > &uf) const
Impose the boundary fluxes on a face field.
Definition covolume.hpp:420
DV< Real > U
Definition covolume.hpp:368
void setWallVelocity(const DV< Real > &Uw)
Definition covolume.hpp:403
Real convScale
Definition covolume.hpp:357
bool viscousDEC
Definition covolume.hpp:365
void setExchange(Ex &ex)
Definition covolume.hpp:376
void rhs(const DV< Real > &uf, const DV< Real > &out)
k = Rᵀ a(u): the face-normal tendency (no pressure).
Definition covolume.hpp:435
DV< Real > div
Definition covolume.hpp:368
Real maxDivergence()
max_i |div u|_i
Definition covolume.hpp:524
DV< Real > force
Definition covolume.hpp:358
DV< Real > ub
Definition covolume.hpp:359
void step(Real dt)
One SSP-RK3 step with a projection after every stage.
Definition covolume.hpp:485
Real nu
Definition covolume.hpp:356
void setup(const FaceMesh< Real > &mesh, Real viscosity, bool amg=false)
Definition covolume.hpp:384
void project(const DV< Real > &uf, Real dt)
Make uf divergence-free: L φ = div uf / dt, uf −= dt grad φ; p = φ.
Definition covolume.hpp:471
Real lastDiv
Definition covolume.hpp:382
Real kineticEnergy() const
½⟨u,u⟩_F — the energy the scheme conserves.
Definition covolume.hpp:506
DV< Real > decOut
Definition covolume.hpp:367
DV< Real > p
Definition covolume.hpp:358
DV< Real > wg
Definition covolume.hpp:361
DV< Real > u
Definition covolume.hpp:358
bool wallQuadratic
Definition covolume.hpp:360
DV< Real > g9w
Definition covolume.hpp:361
std::function< void(const DV< Real > &, int)> exchange
Definition covolume.hpp:373
PressureSolver< Real > poisson
Definition covolume.hpp:369
DV< Real > u2
Definition covolume.hpp:368
std::function< Real(Real)> sum
Definition covolume.hpp:374
DV< Real > u1
Definition covolume.hpp:368
DV< Real > a
Definition covolume.hpp:368
void setDec(const TessellationView< Real > &view)
Install the DEC viscous term from the published view (facet-edge CSR with edge lengths).
Definition covolume.hpp:428
FaceMesh< Real > m
Definition covolume.hpp:355
Kokkos::View< int *, Mem > cellFace
Definition mesh.hpp:49
int nInterior
Definition mesh.hpp:35
Kokkos::View< int *, Mem > faceCellB
Definition mesh.hpp:40
KOKKOS_INLINE_FUNCTION Real conn(int f, int c) const
Definition mesh.hpp:57
Kokkos::View< Real *, Mem > faceDist
Definition mesh.hpp:44
KOKKOS_INLINE_FUNCTION Real normal(int f, int c) const
Definition mesh.hpp:55
Kokkos::View< int *, Mem > faceCellA
Definition mesh.hpp:40
int nCells
Definition mesh.hpp:35
KOKKOS_INLINE_FUNCTION Real centroid(int f, int c) const
Definition mesh.hpp:56
KOKKOS_INLINE_FUNCTION int cellFacesBegin(int i) const
Definition mesh.hpp:53
Kokkos::View< Real *, Mem > cellFaceSign
Definition mesh.hpp:50
KOKKOS_INLINE_FUNCTION int cellFacesEnd(int i) const
Definition mesh.hpp:54
Kokkos::View< Real *, Mem > cellVolume
Definition mesh.hpp:51
int nFaces
Definition mesh.hpp:35
Kokkos::View< Real *, Mem > faceArea
Definition mesh.hpp:42
Kokkos::View< Real *, Mem > faceHa
Definition mesh.hpp:45
Definition covolume.hpp:111
peclet::core::solver::GraphAMGDevice amg
Definition covolume.hpp:125
DV< Real > extraDiag
Definition covolume.hpp:122
void setup(const FaceMesh< Real > &mesh, bool withAmg)
Definition covolume.hpp:166
Real lastRes
Definition covolume.hpp:124
Kokkos::View< double *, peclet::core::MemSpace > zd
Definition covolume.hpp:142
int maxIter
Definition covolume.hpp:116
void setHooks(std::function< void(const DV< Real > &, int)> ex, std::function< Real(Real)> s)
Definition covolume.hpp:136
DV< Real > Kd
Definition covolume.hpp:141
Real dot(const DV< Real > &a, const DV< Real > &bb) const
Definition covolume.hpp:252
int solve(const DV< Real > &f, const DV< Real > &p)
Solve −L p = f (mean of f removed, mean of p pinned to zero). Returns iterations.
Definition covolume.hpp:276
std::function< void(const DV< Real > &, int)> exchange
Definition covolume.hpp:130
Real tol
Definition covolume.hpp:115
Real lapScale
Definition covolume.hpp:120
void precond(const DV< Real > &rr, const DV< Real > &zz) const
Definition covolume.hpp:259
std::function< Real(Real)> sum
Definition covolume.hpp:131
DV< Real > z
Definition covolume.hpp:141
bool useAmg
Definition covolume.hpp:114
Real Vtot
Definition covolume.hpp:143
DV< Real > b
Definition covolume.hpp:141
int lastIters
Definition covolume.hpp:123
Real localVtot_
Definition covolume.hpp:132
void applyK(const DV< Real > &zz, const DV< Real > &qq) const
Definition covolume.hpp:231
DV< Real > r
Definition covolume.hpp:141
FaceMesh< Real > m
Definition covolume.hpp:113
Kokkos::View< double *, peclet::core::MemSpace > rd
Definition covolume.hpp:142
bool deflate
Definition covolume.hpp:121
peclet::core::ExecSpace Exec
Definition covolume.hpp:112
DV< Real > q
Definition covolume.hpp:141
void setupVelocity(const FaceMesh< Real > &mesh, Real nu, Real dt, bool withAmg)
Definition covolume.hpp:147