18#ifndef PECLET_AMR_SCALAR_TRANSPORT_HPP
19#define PECLET_AMR_SCALAR_TRANSPORT_HPP
28#include "peclet/core/common/types.hpp"
32template <
int Dim,
unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
46 for (
int d = 0; d < Dim; ++d)
47 fineExt_[d] =
static_cast<Coord>(
t.brick()[d] * (
Index(1) <<
t.lmax()));
59 for (
int d = 0; d < Dim; ++d)
74 template <
class VelFn>
75 void step(
const std::vector<double>&
c, std::vector<double>&
cOut,
double dt,
double D,
78 cOut.assign(
static_cast<std::size_t
>(n), 0.0);
80 const double ci =
c[
static_cast<std::size_t
>(
i)];
83 const double cj =
c[
static_cast<std::size_t
>(
j)];
84 const double unOut =
oSign *
static_cast<double>(vel(
fc, axis));
98 const auto&
lo = b[0];
101 for (
int axis = 0; axis < Dim; ++axis)
102 for (
int dir = -1; dir <= 1; dir += 2) {
103 const long pc = (dir > 0) ?
static_cast<long>(
lo[axis]) +
static_cast<long>(
si)
104 :
static_cast<long>(
lo[axis]) - 1;
105 const long facePlane = (dir > 0) ?
static_cast<long>(
lo[axis]) +
static_cast<long>(
si)
106 :
static_cast<long>(
lo[axis]);
107 std::array<Coord, Dim>
p =
lo;
108 p[axis] = wrap(
pc, axis);
112 fn(
j0, axis, dir, faceArea(
si, axis),
113 faceCentre(
lo, axis,
facePlane, std::array<Coord, Dim>{},
si),
118 const int nsub = 1 << (Dim - 1);
119 for (
int k = 0; k <
nsub; ++k) {
120 std::array<Coord, Dim>
q =
lo;
121 q[axis] = wrap(
pc, axis);
122 std::array<Coord, Dim> off{};
124 for (
int t = 0;
t < Dim; ++
t) {
128 q[
t] = wrap(
static_cast<long>(
lo[
t]) +
static_cast<long>(off[
t]),
t);
132 fn(
jj, axis, dir, faceArea(
sj, axis), faceCentre(
lo, axis,
facePlane, off,
sj),
133 0.5 * (
static_cast<Real>(
si) +
static_cast<Real>(
sj)) * geo_.h0[axis]);
140 Coord wrap(
long c,
int axis)
const {
141 long e =
static_cast<long>(fineExt_[axis]);
142 return static_cast<Coord>(((
c %
e) +
e) %
e);
147 for (
int d = 0; d < Dim; ++d)
149 a *=
static_cast<Real>(
s) * geo_.h0[d];
155 const std::array<Coord, Dim>& off,
Coord tw)
const {
157 for (
int d = 0; d < Dim; ++d) {
161 fc[d] = geo_.origin[d] +
162 (
static_cast<Real>(
lo[d] + off[d]) + 0.5 *
static_cast<Real>(
tw)) * geo_.h0[d];
167 const Octree* t_ =
nullptr;
169 std::array<Coord, Dim> fineExt_{};
morton::Morton< Dim, Bits > M
unsigned level(Index i) const
Index find(Code p) const
Leaf containing Morton code p, or -1. Host wrapper over amrLocate.
std::array< std::array< Coord, Dim >, 2 > bounds(Index i) const
Inclusive integer bounds [lo, hi] of leaf i in fine units.
typename M::coord_type Coord
typename M::code_type Code
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)).
BlockOctree< Dim, Bits > Octree
Real cellVolume(Index i) const
Real cellWidth(Index i, int axis) const
Phase 3: per-axis cell width; the scalar form is the cubic one (docs/amr_anisotropic....
void init(const Octree &t, const AmrGeometry< Dim > &geo)
typename Octree::Coord Coord
ScalarTransport()=default
ScalarTransport(const Octree &t, const AmrGeometry< Dim > &geo)
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
typename Octree::Code Code
std::vector< std::array< double, Dim > > transferFieldGradients(const BlockOctree< Dim, Bits > &oldT, const std::vector< double > &oldF)
Per-old-leaf minmod prolongation gradients (per fine-coordinate unit) — transferField's stencil,...
World-space placement of a block-local octree: fine coordinate (0,..,0) sits at origin,...