19#ifndef PECLET_CORE_AMR_ASSEMBLY_HPP
20#define PECLET_CORE_AMR_ASSEMBLY_HPP
22#ifdef PECLET_CORE_HAVE_MORTON
37template <
int Dim,
unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
52 static constexpr int kFaces = 2 * Dim;
53 KOKKOS_INLINE_FUNCTION
static int faceIndex(
int axis,
int dir) {
54 return 2 * axis + (dir > 0 ? 0 : 1);
56 KOKKOS_INLINE_FUNCTION
double openness(
Index leaf,
int axis,
int dir)
const {
63 for (
int d = 0; d < Dim - 1; ++d)
64 a *=
static_cast<Real>(s) *
h0;
68 const Real dist = 0.5 * (
static_cast<Real>(si) +
static_cast<Real>(sj)) *
h0;
69 return areaOf(si < sj ? si : sj) / dist;
71 KOKKOS_INLINE_FUNCTION
Coord wrap(
long c,
int axis)
const {
72 const long e =
static_cast<long>(
fineExt[axis]);
73 return static_cast<Coord>(((c % e) + e) % e);
80 for (
int d = 0; d < Dim; ++d)
89 std::array<Coord, Dim> lo = M::from_code(
ov.
codes(i)).decode();
91 const double wall =
areaOf(si) / (0.5 *
static_cast<Real>(si) *
h0);
93 for (
int axis = 0; axis < Dim; ++axis)
94 for (
int dir = -1; dir <= 1; dir += 2) {
95 const long pc = (dir > 0) ?
static_cast<long>(lo[axis]) +
static_cast<long>(si)
96 :
static_cast<long>(lo[axis]) - 1;
97 const bool domainBoundary = !
periodic && (pc < 0 || pc >=
static_cast<long>(
fineExt[axis]));
101 s += (1.0 -
openness(i, axis, dir)) * wall;
108 template <
class Sink>
110 std::array<Coord, Dim> lo = M::from_code(
ov.
codes(i)).decode();
113 for (
int axis = 0; axis < Dim; ++axis)
114 for (
int dir = -1; dir <= 1; dir += 2) {
115 const long pc = (dir > 0) ?
static_cast<long>(lo[axis]) +
static_cast<long>(si)
116 :
static_cast<long>(lo[axis]) - 1;
119 std::array<Coord, Dim> p = lo;
120 p[axis] =
wrap(pc, axis);
127 const int nsub = 1 << (Dim - 1);
128 for (
int k = 0; k < nsub; ++k) {
129 std::array<Coord, Dim> q = lo;
130 q[axis] =
wrap(pc, axis);
132 for (
int t = 0; t < Dim; ++t) {
135 const Coord off = ((k >> bit) & 1) ? sj :
Coord(0);
136 q[t] =
wrap(
static_cast<long>(lo[t]) +
static_cast<long>(off), t);
151template <
int Dim,
unsigned Bits>
159 for (
int d = 0; d < Dim; ++d)
171 op.
invVol =
View<double>(Kokkos::view_alloc(
"amr::invVol", Kokkos::WithoutInitializing),
172 static_cast<std::size_t
>(op.
n));
173 op.
bcDiag =
View<double>(Kokkos::view_alloc(
"amr::bcDiag", Kokkos::WithoutInitializing),
174 static_cast<std::size_t
>(op.
n));
178 Kokkos::parallel_for(
180 invVol(
i) = 1.0 /
e.cellVolume(
i);
181 bcDiag(
i) =
e.bcDiag(
i);
Cell-centered FV Poisson operator on one (periodic) block octree.
const std::array< Coord, Dim > & fineExt() const
Per-axis fine-grid extent (brick·2^lmax) — the periodic wrap modulus.
const std::vector< double > & opennessRaw() const
bool immersedWall() const
Csr buildFaceCsr(Index n, const Emit &emit)
Build a face-CSR on device from a per-cell emit functor.
FvOp assembleFv(const AmrPoisson< Dim, Bits > &ap, const BlockOctreeView< Dim, Bits > &ov)
Assemble the FvOp entirely on the device from a host AmrPoisson's geometry (h0, periodicity,...
View< T > toDevice(const std::vector< T > &h, const std::string &label)
Upload a host std::vector into a freshly-sized device View (empty vector => empty view).
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).
typename Host::Coord Coord
View< std::uint8_t > levels
Index locate(Code p) const
Leaf containing Morton code p, or -1. Callable in a device kernel.
An assembled face-CSR: row offsets (size n+1), neighbour index + coefficient per face (size nFaces).
View< double > coef
coefficient per face, size nFaces
View< Index > nbr
neighbour leaf per face, size nFaces
View< Index > start
CSR row offsets, size n+1; start(n) == nFaces.
Device-callable reproduction of AmrPoisson's per-cell face walk + geometry.
Real areaOf(Coord s) const
Coord fineExt[Dim]
periodic-wrap modulus per axis
static int faceIndex(int axis, int dir)
static constexpr int kFaces
double openness(Index leaf, int axis, int dir) const
Real cellVolume(Index i) const
typename View_t::Coord Coord
View< const double > alpha
per-leaf·(2·Dim) openness, or empty when !hasOpen
Coord wrap(long c, int axis) const
void operator()(Index i, Sink &sink) const
Emit each face of leaf i as sink(neighbourLeaf, coef=openness·A_f/d_f) — the exact enumeration (axis-...
double bcDiag(Index i) const
Σ over leaf i's Dirichlet-wall faces of A_f/(½·cellWidth) — mirrors AmrPoisson::boundaryDiag.
View_t ov
device octree (codes/levels/locate)
Real cellWidth(Index i) const
typename View_t::Code Code
Real coeff(Coord si, Coord sj) const
View< double > invVol
1/V_i, size n
View< double > faceW
w_f = openness·A_f/d_f per face, size nFaces
View< Index > faceStart
CSR row offsets, size n+1.
View< double > bcDiag
Dirichlet boundary diagonal per cell (0 if periodic), size n.
View< Index > faceNbr
neighbour leaf per face, size nFaces