flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
scalar_transport.hpp
Go to the documentation of this file.
1
20#ifndef PECLET_FLOW_SCALAR_TRANSPORT_HPP
21#define PECLET_FLOW_SCALAR_TRANSPORT_HPP
22
23#include <Kokkos_Core.hpp>
24#include <memory>
25#include <string>
26
27#include "mac_cutcell.hpp"
28#include "policy.hpp"
30#include "vof/phase_change.hpp"
31
32namespace peclet::flow {
33
34// Per-scalar BC on a domain face: 0 periodic (via the halo/periodic fill), 1 Neumann zero-flux
35// (ghost = inner, i.e. adiabatic wall), 2 Dirichlet value (ghost = 2*value - inner reflection).
36enum class ScalarBc { Periodic = 0, Neumann = 1, Dirichlet = 2 };
37
38// The cut-cell scalar state (doc/scalar_ibm_design.md §5.5; defined in
39// scalar_cutcell_operator.hpp).
40struct ScalarCutState;
41
42// One transported scalar. `c` aliases the Solver's registered field (fields_); the rest is private
43// scratch on the same G=2 block. Bands are double (a scalar is cheap; no float-quantization
44// concern).
46 std::string name;
47 CCField c, cOld, b; // solution (registered), time base c^n, rhs
48 CCField AC, AW, AE, AS, AN, AB, AT; // implicit diffusion+time 7-band operator
49 double D = 0.0; // constant diffusivity, INTERNAL: D' = Dphys*tRef/hRef^2
50 double Dphys = 0.0; // the caller's diffusivity (L^2/T), kept so a reference
51 // scale pinned later re-derives D (refreshUnitDerived)
52 int scheme = 1; // explicit advection flux: 0 FOU, 1 Koren TVD, 2 SOU
53 int iters = 50; // RB-GS sweeps for the implicit diffusion solve
54 int bc[6] = {0, 0, 0, 0, 0, 0}; // -x,+x,-y,+y,-z,+z (ScalarBc)
55 double bcVal[6] = {0, 0, 0, 0, 0, 0};
56 bool stencilBuilt = false;
57 // Optional PER-CELL Dirichlet condition (WO-P01): where `dmask > 1/2` the cell's row is replaced
58 // by `c = dval`. Unallocated (extent 0) by default and every consumer branches on that, so a
59 // scalar that never asks for it runs the validated operator bit-for-bit. This is what pins
60 // interfacial cells at the saturation temperature in the phase-change energy solve.
62 // Optional CONSISTENT-ENERGY mode (WO-P23): the scalar is a temperature whose transport is done
63 // GEOMETRICALLY (with the colour advection's own fluxes, `vof/energy_advect.hpp`) and whose
64 // diffusion operator carries per-cell `k(C)` and a `rho c_p(C)` time term instead of the constant
65 // `D`. Off, and both fields unallocated, unless `set_phase_change_energy` ran — every consumer
66 // branches on that, so a scalar that never asks for it runs the validated operator bit-for-bit.
67 bool energy = false;
68 CCField kcell, rcp; // k(C) and (rho c_p)(C) on the cells, refreshed by the solver each step
69 CCField gfmB; // WO-P23: the plane-anchored Dirichlet RHS contribution (allocated with it)
70 // Cut-cell scalar (doc/scalar_ibm_design.md, opt-in `add_scalar(..., cutcell=True)`): advanced by
71 // `advanceScalarCutCell` instead of the kernels above, which a cut-cell scalar never reaches
72 // (§5.5). Neither member enters any legacy arithmetic.
73 bool cutcell = false;
74 std::shared_ptr<ScalarCutState> cut;
75};
76
77// Variable-coefficient sibling of `scalarBuildDiffusionOpen` (WO-P23):
78//
79// A_C = rcp(i)*idt + sum_f k_f open_f , A_off = -k_f open_f
80//
81// with the face conductivity `k_f = pcFaceConductivity(k(i), k(j), mask(i), mask(j))` — the
82// arithmetic mean of the two cells' `k(C)` EXCEPT where one of the two carries the per-cell
83// Dirichlet condition, in which case the OTHER cell's `k` is used (see the derivation in
84// `vof/phase_change.hpp`: a Dirichlet row is an identity row, so this coefficient's only job is to
85// set the conductance with which the pure neighbour reaches a boundary condition that already sits
86// at the interface).
87//
88// `mask` is the per-cell Dirichlet mask (all zeros if there is none).
89// **Phase 3 (`flow/doc/anisotropic_vof.md` §7, V5.4).** `wx/wy/wz` are the per-axis Laplacian
90// weights `1/h_a'^2` — the same `w_a` Phase 2 put on `scalarBuildDiffusionOpen` above, on the
91// momentum fold's `beta_b` and on the pressure operator. A face normal to axis `a` carries
92// `k_f w_a o_f` and the diagonal is the sum of the six, exactly as before. Every `w_a` is EXACTLY
93// 1.0 in cell units and on the armed isotropic path, and `x * 1.0 == x` in IEEE-754, so the
94// isotropic operator is bit-identical.
96 CCField AB, CCField AT, CCConst ox, CCConst oy, CCConst oz,
97 CCConst kc, CCConst rcp, CCConst mask, double idt, C3 e, int g,
98 double wx = 1.0, double wy = 1.0, double wz = 1.0) {
100 using MD = MDRange3<CCExec>;
101 Kokkos::parallel_for(
102 "peclet::flow::scalar_build_diff_vark", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
103 KOKKOS_LAMBDA(int lx, int ly, int lz) {
104 const long sx = 1, sy = e.x, sz = (long)e.x * e.y;
105 const long i = (long)lx + (long)ly * sy + (long)lz * sz;
106 const double ki = kc(i);
107 const bool mi = mask(i) > 0.5;
108 const double tw =
109 vof::pcFaceConductivity(ki, kc(i - sx), mi, mask(i - sx) > 0.5) * wx * ox(i);
110 const double te =
111 vof::pcFaceConductivity(ki, kc(i + sx), mi, mask(i + sx) > 0.5) * wx * ox(i + sx);
112 const double ts =
113 vof::pcFaceConductivity(ki, kc(i - sy), mi, mask(i - sy) > 0.5) * wy * oy(i);
114 const double tn =
115 vof::pcFaceConductivity(ki, kc(i + sy), mi, mask(i + sy) > 0.5) * wy * oy(i + sy);
116 const double tb =
117 vof::pcFaceConductivity(ki, kc(i - sz), mi, mask(i - sz) > 0.5) * wz * oz(i);
118 const double tt =
119 vof::pcFaceConductivity(ki, kc(i + sz), mi, mask(i + sz) > 0.5) * wz * oz(i + sz);
120 AW(i) = -tw;
121 AE(i) = -te;
122 AS(i) = -ts;
123 AN(i) = -tn;
124 AB(i) = -tb;
125 AT(i) = -tt;
126 AC(i) = rcp(i) * idt + te + tw + tn + ts + tt + tb;
127 });
128}
129
130// RHS of the consistent-energy solve: `b = rcp(i) * idt * T*`, with `T*` the GEOMETRICALLY advected
131// temperature (the advective term is already in it, so there is none here). Together with the
132// `rcp*idt` diagonal above this is `rho c_p (T^{n+1} - T*)/dt = div(k grad T^{n+1})`.
133inline void scalarBuildRhsHeat(CCField b, CCConst cOld, CCConst rcp, double idt, C3 e, int g) {
135 using MD = MDRange3<CCExec>;
136 Kokkos::parallel_for(
137 "peclet::flow::scalar_build_rhs_heat", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
138 KOKKOS_LAMBDA(int lx, int ly, int lz) {
139 const long i = (long)lx + (long)ly * e.x + (long)lz * (long)e.x * e.y;
140 b(i) = rcp(i) * idt * cOld(i);
141 });
142}
143
144// Replace the rows of the per-cell Dirichlet set by the identity: A_C = 1, all off-diagonals 0.
145// Run AFTER scalarBuildDiffusionOpen (and after applyScalarBcStencil, which may have reopened a
146// domain face on the same row).
148 CCField AB, CCField AT, CCConst mask, C3 e, int g) {
150 using MD = MDRange3<CCExec>;
151 Kokkos::parallel_for(
152 "peclet::flow::scalar_mask_stencil", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
153 KOKKOS_LAMBDA(int lx, int ly, int lz) {
154 const long i = (long)lx + (long)ly * e.x + (long)lz * (long)e.x * e.y;
155 if (!(mask(i) > 0.5))
156 return;
157 AC(i) = 1.0;
158 AW(i) = 0.0;
159 AE(i) = 0.0;
160 AS(i) = 0.0;
161 AN(i) = 0.0;
162 AB(i) = 0.0;
163 AT(i) = 0.0;
164 });
165}
166
167// RHS + solution seed of the per-cell Dirichlet set: b = value, and the field itself is set so the
168// neighbours' first smoothing sweep already reads the imposed value.
169inline void scalarMaskRhs(CCField b, CCField c, CCConst mask, CCConst val, C3 e, int g) {
171 using MD = MDRange3<CCExec>;
172 Kokkos::parallel_for(
173 "peclet::flow::scalar_mask_rhs", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
174 KOKKOS_LAMBDA(int lx, int ly, int lz) {
175 const long i = (long)lx + (long)ly * e.x + (long)lz * (long)e.x * e.y;
176 if (!(mask(i) > 0.5))
177 return;
178 b(i) = val(i);
179 c(i) = val(i);
180 });
181}
182
183// WO-P23: the PLANE-ANCHORED (ghost-fluid) form of the per-cell Dirichlet set. Rewrites the rows
184// of the PURE cells that touch a masked (interfacial) cell so the Dirichlet value is imposed at the
185// PLIC PLANE rather than at the masked cell's centre:
186//
187// ... - k open (T_j - T_i)/1 -> ... - k open (T_G - T_i)/theta ,
188//
189// with theta the distance (in cells) from cell i's centre to cell j's plane along the face's own
190// axis (`pcGfmTheta`). The band toward the masked cell is zeroed and the Dirichlet contribution
191// goes into `gfmB`, which the RHS build adds — the masked cell's own value is then never read by
192// any neighbour, which is exactly what makes the condition one-sided-correct on BOTH sides. The
193// Dirichlet value is `tgam` (the INTERFACE temperature `T_G`), NOT the masked cell's carried value
194// `dval`: those are different numbers under the plane-anchored scheme (`pcCarriedValue`).
195//
196// Runs AFTER the base diffusion build (it consumes that build's band value to avoid
197// double-counting, the same trick `patchScalarDirichletFace` uses) and touches only unmasked rows,
198// so it commutes with `scalarMaskStencil`. `useK` selects the per-cell k(C) over the constant D.
200 CCField AT, CCField gfmB, CCConst ox, CCConst oy, CCConst oz,
202 CCConst gphi, CCConst kc, double Dconst, bool useK, double thMin,
203 double thMax, C3 e, int g, double wx = 1.0, double wy = 1.0,
204 double wz = 1.0, vof::VofMetric gm = vof::VofMetric{}) {
205 const double wa[3] = {wx, wy, wz};
206 CCExec space;
207 using MD = MDRange3<CCExec>;
208 Kokkos::parallel_for(
209 "peclet::flow::scalar_mask_gfm", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
210 KOKKOS_LAMBDA(int lx, int ly, int lz) {
211 const long sx = 1, sy = e.x, sz = (long)e.x * e.y;
212 const long i = (long)lx + (long)ly * sy + (long)lz * sz;
213 gfmB(i) = 0.0;
214 if (mask(i) > 0.5)
215 return; // masked rows are the identity (scalarMaskStencil); nothing to do
216 const long st[3] = {sx, sy, sz};
217 const double kd = useK ? kc(i) : Dconst;
218 double acc = 0.0, dac = 0.0;
219 for (int d = 0; d < 3; ++d)
220 for (int sgn = -1; sgn <= 1; sgn += 2) {
221 const long j = i + (long)sgn * st[d];
222 if (!(mask(j) > 0.5))
223 continue;
224 // face openness: the `-` face of the higher-indexed cell of the pair
225 const double of = (d == 0) ? ((sgn < 0) ? ox(i) : ox(i + sx))
226 : (d == 1) ? ((sgn < 0) ? oy(i) : oy(i + sy))
227 : ((sgn < 0) ? oz(i) : oz(i + sz));
228 // V5.3/V5.4: the axis pullback of the PHYSICAL (plane distance, normal) pair, and
229 // this axis's Laplacian weight. Both are the identity at equal spacings.
230 const double nvec[3] = {gnx(j), gny(j), gnz(j)};
231 const double th =
232 vof::pcGfmThetaKAniso(gphi(j), nvec, d, (double)sgn, 0.0, thMin, thMax, gm);
233 const double coef = kd * wa[d] * of / th;
234 // replace this face's interior coupling (band = -k_f of, AC += k_f of) by the Dirichlet
235 // one, without double counting: AC += coef + band, band = 0.
236 CCField band = (d == 0) ? ((sgn < 0) ? AW : AE)
237 : (d == 1) ? ((sgn < 0) ? AS : AN)
238 : ((sgn < 0) ? AB : AT);
239 acc += coef + band(i);
240 band(i) = 0.0;
241 dac += coef * tgam(j);
242 }
243 AC(i) += acc;
244 gfmB(i) = dac;
245 });
246}
247
248// **WO-P3g — the SECOND-ORDER sibling of `scalarMaskGfm`.** Same contract, same inputs plus a
249// per-cell curvature field `kap` and the row `order`; `order == 1 && !useKappa` reproduces
250// `scalarMaskGfm` line for line (it is not called then — `advanceScalars` branches outside the
251// kernel — but the two bodies are kept side by side so the difference is readable).
252//
253// What changes, and only this: the axis that carries the Dirichlet row is discretized by the
254// non-uniform THREE-point second difference through `(T_behind, T_i, T_Gamma)` instead of the
255// two-point `(T_i, T_Gamma)` one (`vof::pcGfmRow`, which writes the coefficient family out), and
256// the distance `theta` is measured to the CURVED interface rather than to the interfacial cell's
257// tangent plane (`vof::pcGfmThetaK`). `T_behind` is the cell one step AWAY from the interface along
258// the same axis; where it is itself an identity row or its face is closed there is no third point
259// and the row falls back to the shipped two-point form.
260//
261// The `behind` band is SCALED in place (`band *= a_behind`, `AC += (a_behind - 1) k_f o_f`), which
262// is why this kernel must run after the base diffusion build and before `scalarMaskStencil`, in
263// exactly the slot `scalarMaskGfm` occupies. Each axis touches only its own two bands and a masked
264// pair on the same axis takes the two-point branch on both sides, so no band is written twice.
266 CCField AT, CCField gfmB, CCConst ox, CCConst oy, CCConst oz,
268 CCConst gphi, CCConst kap, CCConst kc, double Dconst, bool useK,
269 double thMin, double thMax, int order, bool useKappa, C3 e, int g,
270 double wx = 1.0, double wy = 1.0, double wz = 1.0,
271 vof::VofMetric gm = vof::VofMetric{}) {
272 const double wa[3] = {wx, wy, wz};
273 CCExec space;
274 using MD = MDRange3<CCExec>;
275 Kokkos::parallel_for(
276 "peclet::flow::scalar_mask_gfm2", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
277 KOKKOS_LAMBDA(int lx, int ly, int lz) {
278 const long sx = 1, sy = e.x, sz = (long)e.x * e.y;
279 const long i = (long)lx + (long)ly * sy + (long)lz * sz;
280 gfmB(i) = 0.0;
281 if (mask(i) > 0.5)
282 return;
283 const long st[3] = {sx, sy, sz};
284 const double kd = useK ? kc(i) : Dconst;
285 double acc = 0.0, dac = 0.0;
286 for (int d = 0; d < 3; ++d)
287 for (int sgn = -1; sgn <= 1; sgn += 2) {
288 const long j = i + (long)sgn * st[d];
289 if (!(mask(j) > 0.5))
290 continue;
291 const double of = (d == 0) ? ((sgn < 0) ? ox(i) : ox(i + sx))
292 : (d == 1) ? ((sgn < 0) ? oy(i) : oy(i + sy))
293 : ((sgn < 0) ? oz(i) : oz(i + sz));
294 const double nvec[3] = {gnx(j), gny(j), gnz(j)};
295 const double kj = useKappa ? kap(j) : 0.0;
296 const double th =
297 vof::pcGfmThetaKAniso(gphi(j), nvec, d, (double)sgn, kj, thMin, thMax, gm);
298 CCField band = (d == 0) ? ((sgn < 0) ? AW : AE)
299 : (d == 1) ? ((sgn < 0) ? AS : AN)
300 : ((sgn < 0) ? AB : AT);
301 CCField bandB = (d == 0) ? ((sgn < 0) ? AE : AW)
302 : (d == 1) ? ((sgn < 0) ? AN : AS)
303 : ((sgn < 0) ? AT : AB);
304 const long jb = i - (long)sgn * st[d];
305 const double bb = bandB(i); // -k_f o_f of the face AWAY from the interface
306 const bool behind = !(mask(jb) > 0.5) && (bb != 0.0);
307 const vof::PcGfmRow row = vof::pcGfmRow(th, behind, order);
308 const double coef = kd * wa[d] * of * row.aGamma;
309 acc += coef + band(i);
310 band(i) = 0.0;
311 dac += coef * tgam(j);
312 if (behind && row.aBehind != 1.0) {
313 acc += -(row.aBehind - 1.0) * bb; // bb = -k_f o_f, so this is +(a-1) k_f o_f
314 bandB(i) = row.aBehind * bb;
315 }
316 }
317 AC(i) += acc;
318 gfmB(i) = dac;
319 });
320}
321
322// Add the plane-anchored Dirichlet contribution to the RHS of the unmasked rows.
323inline void scalarAddGfmRhs(CCField b, CCConst gfmB, CCConst mask, C3 e, int g) {
325 using MD = MDRange3<CCExec>;
326 Kokkos::parallel_for(
327 "peclet::flow::scalar_gfm_rhs", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
328 KOKKOS_LAMBDA(int lx, int ly, int lz) {
329 const long i = (long)lx + (long)ly * e.x + (long)lz * (long)e.x * e.y;
330 if (mask(i) > 0.5)
331 return;
332 b(i) += gfmB(i);
333 });
334}
335
336// Build the implicit diffusion+time 7-band operator over inner cells:
337// A_C = idt + sum_f D_a*open_f, A_off = -D_a*open_face, D_a = D*w_a
338// with w_a = 1/h_a'^2 the per-axis metric weight (doc/anisotropic_metric.md §2; w == 1.0 exactly
339// on the isotropic path, so D_a == D there and the operator is bit-identical). The advection is
340// index-native and unchanged.
341// Openness-weighted (closed faces drop out) — the scalar analog of buildCutcellOp with the 1/dt
342// diagonal. ox(i) is the -x face openness of cell i (== +x face of cell i-1), matching divergOpen.
344 CCField AB, CCField AT, CCConst ox, CCConst oy, CCConst oz,
345 double D, double idt, C3 e, int g, double wx = 1.0,
346 double wy = 1.0, double wz = 1.0) {
348 const double Dx = D * wx, Dy = D * wy, Dz = D * wz;
349 using MD = MDRange3<CCExec>;
350 Kokkos::parallel_for(
351 "peclet::flow::scalar_build_diff", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
352 KOKKOS_LAMBDA(int lx, int ly, int lz) {
353 const long sx = 1, sy = e.x, sz = (long)e.x * e.y;
354 const long i = (long)lx + (long)ly * sy + (long)lz * sz;
355 const double tw = Dx * ox(i), te = Dx * ox(i + sx);
356 const double ts = Dy * oy(i), tn = Dy * oy(i + sy);
357 const double tb = Dz * oz(i), tt = Dz * oz(i + sz);
358 AW(i) = -tw;
359 AE(i) = -te;
360 AS(i) = -ts;
361 AN(i) = -tn;
362 AB(i) = -tb;
363 AT(i) = -tt;
364 AC(i) = idt + te + tw + tn + ts + tt + tb;
365 });
366}
367
368// b = idt*c^n - div(open u c^n): explicit conservative openness-weighted advection into the RHS.
369// U/V/W are the MAC face-normal velocities (staggered: C[fd].u; collocated: uf_/vf_/wf_) — U(i) is
370// the -x face velocity of cell i, co-located with ox(i). scheme: 0 FOU, 1 Koren TVD, 2 SOU.
372 CCConst oy, CCConst oz, double idt, int scheme, C3 e, int g) {
374 using MD = MDRange3<CCExec>;
375 Kokkos::parallel_for(
376 "peclet::flow::scalar_build_rhs", MD(space, {g, g, g}, {e.x - g, e.y - g, e.z - g}),
377 KOKKOS_LAMBDA(int lx, int ly, int lz) {
378 const long sx = 1, sy = e.x, sz = (long)e.x * e.y;
379 const long i = (long)lx + (long)ly * sy + (long)lz * sz;
380 double adv = 0.0;
381 // per axis fd: flux through the +fd face (open(i+s), vel U(i+s)) minus the -fd face
382 // (open(i), vel U(i)). Face value from the upwind limiter on the 4-cell stencil.
383 for (int fd = 0; fd < 3; ++fd) {
384 const long s = (fd == 0) ? sx : (fd == 1) ? sy : sz;
385 CCConst Uf = (fd == 0) ? U : (fd == 1) ? V : W;
386 CCConst Of = (fd == 0) ? ox : (fd == 1) ? oy : oz;
387 const double velm = Uf(i), velp = Uf(i + s);
388 const double om = Of(i), op = Of(i + s);
389 const double cLL = cOld(i - 2 * s), cL = cOld(i - s), cR = cOld(i), cRR = cOld(i + s),
390 cRRR = cOld(i + 2 * s);
391 double Fp, Fm;
392 if (scheme == 0) { // first-order upwind
393 Fp = op * sadv::fou_flux(cR, cRR, velp);
394 Fm = om * sadv::fou_flux(cL, cR, velm);
395 } else if (scheme == 2) { // second-order upwind (unlimited)
396 Fp = op * sadv::sou(cL, cR, cRR, cRRR, velp);
397 Fm = om * sadv::sou(cLL, cL, cR, cRR, velm);
398 } else { // Koren TVD (default)
399 Fp = op * sadv::tvd(cL, cR, cRR, cRRR, velp);
400 Fm = om * sadv::tvd(cLL, cL, cR, cRR, velm);
401 }
402 adv += Fp - Fm;
403 }
404 b(i) = idt * cOld(i) - adv;
405 });
406}
407
408} // namespace peclet::flow
409
410#endif // PECLET_FLOW_SCALAR_TRANSPORT_HPP
flow — portable (Kokkos) cut-cell pressure-operator face openness from an SDF.
double pcFaceConductivity(double ki, double kj, bool mi, bool mj)
Face conductivity of the variable-coefficient energy operator, k(C) arithmetic in the colour with ONE...
PcGfmRow pcGfmRow(double theta, bool behind, int order)
double pcGfmThetaKAniso(double phiC, const double n[3], int d, double s, double kappa, double thetaMin, double thetaMax, const VofMetric &g)
The same on an ANISOTROPIC cell (Phase 3, flow/doc/anisotropic_vof.md §7, V5.3).
void scalarMaskRhs(CCField b, CCField c, CCConst mask, CCConst val, C3 e, int g)
void scalarMaskGfm2(CCField AC, CCField AW, CCField AE, CCField AS, CCField AN, CCField AB, CCField AT, CCField gfmB, CCConst ox, CCConst oy, CCConst oz, CCConst mask, CCConst tgam, CCConst gnx, CCConst gny, CCConst gnz, CCConst gphi, CCConst kap, CCConst kc, double Dconst, bool useK, double thMin, double thMax, int order, bool useKappa, C3 e, int g, double wx=1.0, double wy=1.0, double wz=1.0, vof::VofMetric gm=vof::VofMetric{})
void scalarBuildDiffusionOpen(CCField AC, CCField AW, CCField AE, CCField AS, CCField AN, CCField AB, CCField AT, CCConst ox, CCConst oy, CCConst oz, double D, double idt, C3 e, int g, double wx=1.0, double wy=1.0, double wz=1.0)
void scalarAddGfmRhs(CCField b, CCConst gfmB, CCConst mask, C3 e, int g)
void scalarMaskGfm(CCField AC, CCField AW, CCField AE, CCField AS, CCField AN, CCField AB, CCField AT, CCField gfmB, CCConst ox, CCConst oy, CCConst oz, CCConst mask, CCConst tgam, CCConst gnx, CCConst gny, CCConst gnz, CCConst gphi, CCConst kc, double Dconst, bool useK, double thMin, double thMax, C3 e, int g, double wx=1.0, double wy=1.0, double wz=1.0, vof::VofMetric gm=vof::VofMetric{})
void scalarMaskStencil(CCField AC, CCField AW, CCField AE, CCField AS, CCField AN, CCField AB, CCField AT, CCConst mask, C3 e, int g)
Kokkos::View< double *, CCMem > CCField
Kokkos::DefaultExecutionSpace CCExec
void scalarBuildDiffusionVarK(CCField AC, CCField AW, CCField AE, CCField AS, CCField AN, CCField AB, CCField AT, CCConst ox, CCConst oy, CCConst oz, CCConst kc, CCConst rcp, CCConst mask, double idt, C3 e, int g, double wx=1.0, double wy=1.0, double wz=1.0)
void scalarBuildRhsHeat(CCField b, CCConst cOld, CCConst rcp, double idt, C3 e, int g)
Kokkos::View< const double *, CCMem > CCConst
void scalarBuildRhs(CCField b, CCConst cOld, CCConst U, CCConst V, CCConst W, CCConst ox, CCConst oy, CCConst oz, double idt, int scheme, C3 e, int g)
double fou_flux(double L, double R, double vel)
double tvd(double LL, double L, double R, double RR, double vel)
double sou(double LL, double L, double R, double RR, double vel)
flow — VoF phase change (Part II, rungs P0/P1): the container-free kernel set.
flow — the multidimensional iteration policies: iteration order follows storage.
flow — portable (Kokkos) staggered MAC momentum advection (Koren TVD + FOU).
std::shared_ptr< ScalarCutState > cut
static constexpr double AC
static constexpr double U