flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
colocated_advection.hpp
Go to the documentation of this file.
1
21#ifndef PECLET_FLOW_COLOCATED_ADVECTION_HPP
22#define PECLET_FLOW_COLOCATED_ADVECTION_HPP
23
24#include <Kokkos_Core.hpp>
25#include <Kokkos_MathematicalFunctions.hpp>
26
27#include "staggered_advection.hpp" // sadv::koren / tvd / fou_flux / ViewAcc (reused verbatim)
28
29namespace cadv {
30
31// Advecting (normal) velocity at the +fd face of the cell at (x,y,z). Independent of the advected
32// component `comp` (all three components are co-located at the center, so one cell is the control
33// volume for all of them and one face flux serves all three).
34//
35// `uf` selects what U/V/W ARE:
36// true — the projected MAC face field `uf_/vf_/wf_` in flow's LOW-face convention (U(i) is the
37// velocity at the -x face of cell i, i.e. at i-1/2), so the +fd face of cell (x,y,z) is
38// the low face of its +fd neighbour: index (x+1,y,z) for fd=0. Read verbatim — this is
39// the field the projection made solenoidal, so in the ALL-FLUID bulk (every face
40// openness 1) the advective flux sum telescopes to zero exactly. At a CUT cell it does
41// not: the projection zeroes the openness-WEIGHTED divergence
42// sum(o_f u_f^+ - o_f u_f^-) (divergOpen) while the flux form here is unweighted, so
43// the band carries a residual — small, and far smaller than the O(h^2) cell divergence
44// the average carries everywhere. Same trade amr records (docs/decisions/amr.md:13:
45// "div-free bulk, residual-small band").
46// false — the cell-centered velocities; the face value is their average 1/2(U(i)+U(i+1)).
47template <class A>
48KOKKOS_INLINE_FUNCTION double adv_vel(int /*comp*/, int fd, int x, int y, int z, A U, A V, A W,
49 bool uf) {
50 if (fd == 0)
51 return uf ? U(x + 1, y, z) : 0.5 * (U(x, y, z) + U(x + 1, y, z));
52 if (fd == 1)
53 return uf ? V(x, y + 1, z) : 0.5 * (V(x, y, z) + V(x, y + 1, z));
54 return uf ? W(x, y, z + 1) : 0.5 * (W(x, y, z) + W(x, y, z + 1));
55}
56
57// Conservative Koren-TVD advection A = sum_dir (F_plus - F_minus) of component comp; PHI is its
58// field.
59template <class A>
60KOKKOS_INLINE_FUNCTION double advect(int comp, int x, int y, int z, A U, A V, A W, A PHI, bool uf) {
61 double out = 0.0;
62 for (int fd = 0; fd < 3; ++fd) {
63 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
64 const double velp = cadv::adv_vel(comp, fd, x, y, z, U, V, W, uf);
65 const double velm = cadv::adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W, uf);
66 const double Fp =
67 sadv::tvd(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), PHI(x + ox, y + oy, z + oz),
68 PHI(x + 2 * ox, y + 2 * oy, z + 2 * oz), velp);
69 const double Fm =
70 sadv::tvd(PHI(x - 2 * ox, y - 2 * oy, z - 2 * oz), PHI(x - ox, y - oy, z - oz),
71 PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velm);
72 out += Fp - Fm;
73 }
74 return out;
75}
76
77// Conservative second-order-upwind advection (SOU flux; same advecting velocities as
78// cadv::advect).
79template <class A>
80KOKKOS_INLINE_FUNCTION double advect_sou(int comp, int x, int y, int z, A U, A V, A W, A PHI,
81 bool uf) {
82 double out = 0.0;
83 for (int fd = 0; fd < 3; ++fd) {
84 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
85 const double velp = cadv::adv_vel(comp, fd, x, y, z, U, V, W, uf);
86 const double velm = cadv::adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W, uf);
87 const double Fp =
88 sadv::sou(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), PHI(x + ox, y + oy, z + oz),
89 PHI(x + 2 * ox, y + 2 * oy, z + 2 * oz), velp);
90 const double Fm =
91 sadv::sou(PHI(x - 2 * ox, y - 2 * oy, z - 2 * oz), PHI(x - ox, y - oy, z - oz),
92 PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velm);
93 out += Fp - Fm;
94 }
95 return out;
96}
97
98// FOU advection OPERATOR coefficients added to a cell's 7-point stencil (consistent with
99// advect_fou): diagonal cC gets max(velp,0)-min(velm,0) >= 0, off-diagonals <= 0. Added (not
100// assigned) into out-params.
101template <class A>
102KOKKOS_INLINE_FUNCTION void fou_operator(int comp, int x, int y, int z, A U, A V, A W, double dt,
103 double& cC, double& cxm, double& cxp, double& cym,
104 double& cyp, double& czm, double& czp, bool uf) {
105 for (int fd = 0; fd < 3; ++fd) {
106 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
107 const double velp = cadv::adv_vel(comp, fd, x, y, z, U, V, W, uf);
108 const double velm = cadv::adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W, uf);
109 cC += dt * (Kokkos::fmax(velp, 0.0) - Kokkos::fmin(velm, 0.0));
110 const double cp = dt * Kokkos::fmin(velp, 0.0), cm = dt * (-Kokkos::fmax(velm, 0.0));
111 if (fd == 0) {
112 cxp += cp;
113 cxm += cm;
114 } else if (fd == 1) {
115 cyp += cp;
116 cym += cm;
117 } else {
118 czp += cp;
119 czm += cm;
120 }
121 }
122}
123
124// Conservative first-order-upwind advection of comp (low-order flux, same advecting velocities).
125template <class A>
126KOKKOS_INLINE_FUNCTION double advect_fou(int comp, int x, int y, int z, A U, A V, A W, A PHI,
127 bool uf) {
128 double out = 0.0;
129 for (int fd = 0; fd < 3; ++fd) {
130 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
131 const double velp = cadv::adv_vel(comp, fd, x, y, z, U, V, W, uf);
132 const double velm = cadv::adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W, uf);
133 out += sadv::fou_flux(PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velp) -
134 sadv::fou_flux(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), velm);
135 }
136 return out;
137}
138
139} // namespace cadv
140
141#endif // PECLET_FLOW_COLOCATED_ADVECTION_HPP
double adv_vel(int, int fd, int x, int y, int z, A U, A V, A W, bool uf)
void fou_operator(int comp, int x, int y, int z, A U, A V, A W, double dt, double &cC, double &cxm, double &cxp, double &cym, double &cyp, double &czm, double &czp, bool uf)
double advect_sou(int comp, int x, int y, int z, A U, A V, A W, A PHI, bool uf)
double advect_fou(int comp, int x, int y, int z, A U, A V, A W, A PHI, bool uf)
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 — portable (Kokkos) staggered MAC momentum advection (Koren TVD + FOU).
static constexpr double U