9#ifndef PECLET_FLOW_STAGGERED_ADVECTION_HPP
10#define PECLET_FLOW_STAGGERED_ADVECTION_HPP
12#include <Kokkos_Core.hpp>
13#include <Kokkos_MathematicalFunctions.hpp>
17KOKKOS_INLINE_FUNCTION
double koren(
double up_m1,
double up,
double down,
double vel) {
18 const double num = up - up_m1, den = down - up;
19 double r = (Kokkos::fabs(den) < 1e-10) ? 0.0 : num / den;
20 if (Kokkos::fabs(den) < 1e-10 && Kokkos::fabs(num) < 1e-10)
23 Kokkos::fmax(0.0, Kokkos::fmin(2.0 * r, Kokkos::fmin((1.0 + 2.0 * r) / 3.0, 2.0)));
24 return vel * (up + 0.5 * psi * (down - up));
26KOKKOS_INLINE_FUNCTION
double tvd(
double LL,
double L,
double R,
double RR,
double vel) {
27 return (vel > 0.0) ?
koren(LL, L, R, vel) :
koren(RR, R, L, vel);
29KOKKOS_INLINE_FUNCTION
double fou_flux(
double L,
double R,
double vel) {
30 return vel * (vel > 0.0 ? L : R);
35KOKKOS_INLINE_FUNCTION
double sou(
double LL,
double L,
double R,
double RR,
double vel) {
36 return (vel > 0.0) ? vel * (1.5 * L - 0.5 * LL) : vel * (1.5 * R - 0.5 * RR);
41 Kokkos::View<const double*, Kokkos::DefaultExecutionSpace::memory_space>
d;
43 KOKKOS_INLINE_FUNCTION
double operator()(
int x,
int y,
int z)
const {
44 return d(
static_cast<long>(x) +
static_cast<long>(y) *
ex +
45 static_cast<long>(z) *
static_cast<long>(
ex) *
ey);
51KOKKOS_INLINE_FUNCTION
double adv_vel(
int comp,
int fd,
int x,
int y,
int z, A U, A V, A W) {
54 return 0.5 * (U(x, y, z) + U(x + 1, y, z));
56 return 0.5 * (V(x - 1, y + 1, z) + V(x, y + 1, z));
57 return 0.5 * (W(x - 1, y, z + 1) + W(x, y, z + 1));
61 return 0.5 * (U(x + 1, y - 1, z) + U(x + 1, y, z));
63 return 0.5 * (V(x, y, z) + V(x, y + 1, z));
64 return 0.5 * (W(x, y - 1, z + 1) + W(x, y, z + 1));
67 return 0.5 * (U(x + 1, y, z - 1) + U(x + 1, y, z));
69 return 0.5 * (V(x, y + 1, z - 1) + V(x, y + 1, z));
70 return 0.5 * (W(x, y, z) + W(x, y, z + 1));
76KOKKOS_INLINE_FUNCTION
double advect(
int comp,
int x,
int y,
int z, A U, A V, A W, A PHI) {
78 for (
int fd = 0; fd < 3; ++fd) {
79 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
80 const double velp =
adv_vel(comp, fd, x, y, z, U, V, W);
81 const double velm =
adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W);
82 const double Fp =
tvd(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), PHI(x + ox, y + oy, z + oz),
83 PHI(x + 2 * ox, y + 2 * oy, z + 2 * oz), velp);
84 const double Fm =
tvd(PHI(x - 2 * ox, y - 2 * oy, z - 2 * oz), PHI(x - ox, y - oy, z - oz),
85 PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velm);
94KOKKOS_INLINE_FUNCTION
double advect_sou(
int comp,
int x,
int y,
int z, A U, A V, A W, A PHI) {
96 for (
int fd = 0; fd < 3; ++fd) {
97 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
98 const double velp =
adv_vel(comp, fd, x, y, z, U, V, W);
99 const double velm =
adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W);
100 const double Fp =
sou(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), PHI(x + ox, y + oy, z + oz),
101 PHI(x + 2 * ox, y + 2 * oy, z + 2 * oz), velp);
102 const double Fm =
sou(PHI(x - 2 * ox, y - 2 * oy, z - 2 * oz), PHI(x - ox, y - oy, z - oz),
103 PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velm);
113KOKKOS_INLINE_FUNCTION
void fou_operator(
int comp,
int x,
int y,
int z, A U, A V, A W,
double dt,
114 double& cC,
double& cxm,
double& cxp,
double& cym,
115 double& cyp,
double& czm,
double& czp) {
116 for (
int fd = 0; fd < 3; ++fd) {
117 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
118 const double velp =
adv_vel(comp, fd, x, y, z, U, V, W);
119 const double velm =
adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W);
120 cC += dt * (Kokkos::fmax(velp, 0.0) - Kokkos::fmin(velm, 0.0));
121 const double cp = dt * Kokkos::fmin(velp, 0.0), cm = dt * (-Kokkos::fmax(velm, 0.0));
125 }
else if (fd == 1) {
139 double dt,
double sx,
double sy,
double sz,
140 double& cC,
double& cxm,
double& cxp,
double& cym,
141 double& cyp,
double& czm,
double& czp) {
142 for (
int fd = 0; fd < 3; ++fd) {
143 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
144 const double s = (fd == 0) ? sx : (fd == 1) ? sy : sz;
145 const double velp = s *
adv_vel(comp, fd, x, y, z, U, V, W);
146 const double velm = s *
adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W);
147 cC += dt * (Kokkos::fmax(velp, 0.0) - Kokkos::fmin(velm, 0.0));
148 const double cp = dt * Kokkos::fmin(velp, 0.0), cm = dt * (-Kokkos::fmax(velm, 0.0));
152 }
else if (fd == 1) {
164KOKKOS_INLINE_FUNCTION
double advect_fou(
int comp,
int x,
int y,
int z, A U, A V, A W, A PHI) {
166 for (
int fd = 0; fd < 3; ++fd) {
167 const int ox = (fd == 0), oy = (fd == 1), oz = (fd == 2);
168 const double velp =
adv_vel(comp, fd, x, y, z, U, V, W);
169 const double velm =
adv_vel(comp, fd, x - ox, y - oy, z - oz, U, V, W);
170 out +=
fou_flux(PHI(x, y, z), PHI(x + ox, y + oy, z + oz), velp) -
171 fou_flux(PHI(x - ox, y - oy, z - oz), PHI(x, y, z), velm);
double adv_vel(int comp, int fd, int x, int y, int z, A U, A V, A W)
double advect(int comp, int x, int y, int z, A U, A V, A W, A PHI)
double advect_sou(int comp, int x, int y, int z, A U, A V, A W, A PHI)
double fou_flux(double L, double R, double vel)
void fou_operator_aniso(int comp, int x, int y, int z, A U, A V, A W, double dt, double sx, double sy, double sz, double &cC, double &cxm, double &cxp, double &cym, double &cyp, double &czm, double &czp)
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)
double tvd(double LL, double L, double R, double RR, double vel)
double sou(double LL, double L, double R, double RR, double vel)
double advect_fou(int comp, int x, int y, int z, A U, A V, A W, A PHI)
double koren(double up_m1, double up, double down, double vel)
double operator()(int x, int y, int z) const
Kokkos::View< const double *, Kokkos::DefaultExecutionSpace::memory_space > d