19#ifndef PECLET_CORE_AMR_SCALAR_TRANSPORT_HPP
20#define PECLET_CORE_AMR_SCALAR_TRANSPORT_HPP
22#ifdef PECLET_CORE_HAVE_MORTON
34template <
int Dim,
unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
48 for (
int d = 0; d < Dim; ++d)
49 fineExt_[d] =
static_cast<Coord>(
t.brick()[d] * (
Index(1) <<
t.lmax()));
56 for (
int d = 0; d < Dim; ++d)
71 template <
class VelFn>
72 void step(
const std::vector<double>&
c, std::vector<double>&
cOut,
double dt,
double D,
75 cOut.assign(
static_cast<std::size_t
>(n), 0.0);
77 const double ci =
c[
static_cast<std::size_t
>(
i)];
80 const double cj =
c[
static_cast<std::size_t
>(
j)];
95 const auto&
lo = b[0];
98 for (
int axis = 0; axis < Dim; ++axis)
99 for (
int dir = -1; dir <= 1; dir += 2) {
100 const long pc = (dir > 0) ?
static_cast<long>(
lo[axis]) +
static_cast<long>(
si)
101 :
static_cast<long>(
lo[axis]) - 1;
102 const long facePlane = (dir > 0) ?
static_cast<long>(
lo[axis]) +
static_cast<long>(
si)
103 :
static_cast<long>(
lo[axis]);
104 std::array<Coord, Dim> p =
lo;
105 p[axis] = wrap(
pc, axis);
109 fn(
j0, axis, dir, faceArea(
si),
110 faceCentre(
lo, axis,
facePlane, std::array<Coord, Dim>{},
si),
114 const int nsub = 1 << (Dim - 1);
115 for (
int k = 0; k <
nsub; ++k) {
116 std::array<Coord, Dim>
q =
lo;
117 q[axis] = wrap(
pc, axis);
118 std::array<Coord, Dim> off{};
120 for (
int t = 0;
t < Dim; ++
t) {
124 q[
t] = wrap(
static_cast<long>(
lo[
t]) +
static_cast<long>(off[
t]),
t);
129 0.5 * (
static_cast<Real>(
si) +
static_cast<Real>(
sj)) * geo_.h0);
136 Coord wrap(
long c,
int axis)
const {
137 long e =
static_cast<long>(fineExt_[axis]);
138 return static_cast<Coord>(((
c %
e) +
e) %
e);
142 for (
int d = 0; d < Dim - 1; ++d)
143 a *=
static_cast<Real>(
s) * geo_.h0;
149 const std::array<Coord, Dim>& off,
Coord tw)
const {
151 for (
int d = 0; d < Dim; ++d) {
155 fc[d] = geo_.origin[d] +
156 (
static_cast<Real>(
lo[d] + off[d]) + 0.5 *
static_cast<Real>(
tw)) * geo_.h0;
161 const Octree* t_ =
nullptr;
163 std::array<Coord, Dim> fineExt_{};
morton::Morton< Dim, Bits > M
typename M::coord_type Coord
unsigned level(Index i) const
Index find(Code p) const
Leaf containing Morton code p, or -1. Host wrapper over amrLocate.
typename M::code_type Code
std::array< std::array< Coord, Dim >, 2 > bounds(Index i) const
Inclusive integer bounds [lo, hi] of leaf i in fine units.
ScalarTransport(const Octree &t, const AmrGeometry< Dim > &geo)
BlockOctree< Dim, Bits > Octree
typename Octree::Coord Coord
ScalarTransport()=default
void step(const std::vector< double > &c, std::vector< double > &cOut, double dt, double D, VelFn &&vel) const
One explicit Euler step: cOut = c + dt*(-div(u c) + D lap(c)).
typename Octree::Code Code
Real cellVolume(Index i) const
void forEachFace(Index i, Fn &&fn) const
Visit each (sub)face of leaf i.
double totalMass(const std::vector< double > &c) const
Total scalar content sum_i V_i c_i (conserved by a divergence-free update).
Real cellWidth(Index i) const
void init(const Octree &t, const AmrGeometry< Dim > &geo)
Kokkos::View< T *, MemSpace > View
1D device array.
double Real
Default host floating type. Device kernels may use float; conversions happen at the boundary.
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).