47#ifndef PECLET_AMR_GHOST_PROJECTION_SAMPLED_HPP
48#define PECLET_AMR_GHOST_PROJECTION_SAMPLED_HPP
65#include "peclet/core/common/host_parallel.hpp"
66#include "peclet/core/common/types.hpp"
67#include "peclet/core/scheme/ghost_closure.hpp"
90 for (
int k = 0; k < n; ++k) {
92 for (
int r = k + 1;
r < n; ++
r)
93 if (std::fabs(
A[
r * n + k]) > std::fabs(
A[
piv * n + k]))
95 if (std::fabs(
A[
piv * n + k]) < 1
e-14)
98 for (
int c = k;
c < n; ++
c) {
99 const double tmp =
A[k * n +
c];
101 A[
piv * n +
c] = tmp;
103 const double tb = b[k];
107 for (
int r = k + 1;
r < n; ++
r) {
108 const double f =
A[
r * n + k] /
A[k * n + k];
109 for (
int c = k;
c < n; ++
c)
110 A[
r * n +
c] -=
f *
A[k * n +
c];
114 for (
int k = n - 1; k >= 0; --k) {
115 for (
int c = k + 1;
c < n; ++
c)
116 b[k] -=
A[k * n +
c] * b[
c];
117 b[k] /=
A[k * n + k];
147template <
unsigned Bits,
class WrapFn,
class EmitFn>
156 for (
int d = 0; d < 3; ++d) {
163 const std::array<long, 3>
q{
r.lo[0],
r.lo[1],
r.lo[2]};
164 const auto [slot,
L] =
pres.probeSlot(
q);
180 for (
int d = 0; d < 3; ++d)
181 ext = std::max(
ext,
r.hi[d] -
r.lo[d] + 1);
183 while ((1L << (k + 3)) <
ext)
185 const long st = 1L << k;
186 auto alignUp = [k,
st](
long v) {
return ((
v +
st - 1) >> k) << k; };
189 for (
long x =
alignUp(
r.lo[0]); x <=
r.hi[0]; x +=
st)
190 (
void)
pres.probeSlot(std::array<long, 3>{x,
y,
z});
195 const std::array<long, 3>
llo =
pres.loOf(slot);
196 const long s =
static_cast<long>(1) <<
L;
198 for (
int d = 0; d < 3; ++d) {
199 const long u =
llo[d] + (
r.lo[d] -
wq[d]);
200 if (
u +
s - 1 <
r.hi[d]) {
211 for (
int d = 1; d < 3; ++d)
212 if (
r.hi[d] -
r.lo[d] >
r.hi[
ax] -
r.lo[
ax])
215 unsigned long long x =
static_cast<unsigned long long>(
r.lo[
ax] ^
r.hi[
ax]);
219 const long cut = ((
r.lo[
ax] >> k) + 1) << k;
221 throw std::runtime_error(
"amr::forEachCoveringSlot: descent stack overflow");
260template <
unsigned Bits,
class SdfFn>
269 std::array<long, 3>
q{};
270 for (
int d = 0; d < 3; ++d)
271 q[d] =
static_cast<long>(std::floor((
probe[d] - origin[d]) / h0[d])) -
frameShift[d];
274 return {
false, -1.0f};
276 const double s =
static_cast<double>(
Index(1) <<
pres.levelOf(
j));
278 for (
int d = 0; d < 3; ++d)
279 c[d] = origin[d] + (
static_cast<double>(
lo[d] +
frameShift[d]) + 0.5 *
s) * h0[d];
281 return {
sd > 0.0,
static_cast<float>(
sd)};
285 return (
flM &&
flP && 0.5f * (
sM +
sP) >= 0.0f) ? 1.0 : 0.0;
308template <
unsigned Bits,
class SdfFn>
314 GhostOverlaySampled ov;
315 const Index n =
t.numLeaves();
320 const auto fe =
pres.fineExt();
322 const std::array<long, 3>
gfine =
324 : std::array<long, 3>{
static_cast<long>(
fe[0]),
static_cast<long>(
fe[1]),
325 static_cast<long>(
fe[2])};
328 for (
int d = 0; d < 3; ++d)
329 q[d] =
static_cast<long>(std::floor((
p[d] - origin[d]) / h0[d])) -
shiftG[d];
333 std::vector<Vec<3>>
cen(
static_cast<std::size_t
>(n));
334 std::vector<char> fluid(
static_cast<std::size_t
>(n));
336 auto b =
t.bounds(
i);
337 const double s =
static_cast<double>(
Index(1) <<
t.level(
i));
339 for (
int d = 0; d < 3; ++d)
341 (
static_cast<double>(b[0][d]) +
static_cast<double>(
shiftG[d]) + 0.5 *
s) * h0[d];
342 cen[
static_cast<std::size_t
>(
i)] =
c;
343 fluid[
static_cast<std::size_t
>(
i)] =
sdf(
c) > 0.0 ? 1 : 0;
351 std::vector<Vec<3>>
cenG(
static_cast<std::size_t
>(
ng));
352 std::vector<char>
fluidG(
static_cast<std::size_t
>(
ng));
353 for (
Index g = 0; g <
ng; ++g) {
354 const auto lo =
pres.loOf(n + g);
355 const double s =
static_cast<double>(
Index(1) <<
pres.levelOf(n + g));
357 for (
int d = 0; d < 3; ++d)
358 c[d] = origin[d] + (
static_cast<double>(
lo[d] +
shiftG[d]) + 0.5 *
s) * h0[d];
359 cenG[
static_cast<std::size_t
>(g)] =
c;
360 fluidG[
static_cast<std::size_t
>(g)] =
sdf(
c) > 0.0 ? 1 : 0;
402 for (
int d = 0; d < 3; ++d) {
404 nb[d] = std::max<long>(1,
gfine[d] / 4);
407 const long nbx = std::max(std::max(
nb[0],
nb[1]),
nb[2]);
409 std::array<long, 3>
q{};
410 for (
int d = 0; d < 3; ++d) {
411 const long g =
p[d] +
shiftG[d];
417 using Code =
typename Oct::Code;
424 std::array<typename Oct::Coord, 3>
q{};
425 for (
int d = 0; d < 3; ++d)
427 return Oct::M::encode(
q).code();
460 std::vector<Index>& idx, std::vector<double>& w) ->
bool {
466 for (
int d = 0; d < 3; ++d) {
467 qlo[d] =
static_cast<long>(std::floor((
p[d] - origin[d] -
rho[d]) / h0[d])) -
shiftG[d];
468 qhi[d] =
static_cast<long>(std::floor((
p[d] - origin[d] +
rho[d]) / h0[d])) -
shiftG[d];
470 std::vector<Index>
slots;
483 std::vector<Cand>
cand;
490 double r2 = 0,
q2 = 0;
491 for (
int d = 0; d < 3; ++d) {
504 const long bx =
static_cast<long>((
cj[0] - origin[0]) /
hb[0]) %
nbx;
505 const long by =
static_cast<long>((
cj[1] - origin[1]) /
hb[1]) %
nbx;
506 const long bz =
static_cast<long>((
cj[2] - origin[2]) /
hb[2]) %
nbx;
513 [](
const Cand&
a,
const Cand& b) { return a.d2 != b.d2 ? a.d2 < b.d2 : a.key < b.key; });
517 return a.bin != b.bin ? a.bin < b.bin : a.key < b.key;
520 std::vector<Index>
pts;
523 for (
int d = 0; d < 3; ++d) {
524 lo[d] =
static_cast<long>(std::floor((
p[d] - origin[d] -
rho[d]) /
hb[d]));
525 hi[d] =
static_cast<long>(std::floor((
p[d] - origin[d] +
rho[d]) /
hb[d]));
533 auto it = std::lower_bound(
cand.begin(),
cand.end(),
bl,
534 [](
const Cand&
c,
long v) { return c.bin < v; });
536 pts.push_back(
it->slot);
538 const int need =
deg >= 2 ? 12 : 5;
539 if (
static_cast<long>(
pts.size()) <
need)
541 double A[100] = {},
e0[10] = {};
546 for (
int dd = 0;
dd < 3; ++
dd) {
555 for (
int r = 0;
r <
nm; ++
r)
556 for (
int c = 0;
c <
nm; ++
c)
564 for (
int dd = 0;
dd < 3; ++
dd) {
574 for (
int k = 0; k <
nm; ++k)
582 ov.rowOf.assign(
static_cast<std::size_t
>(n), -1);
583 ov.sampStart.assign(1, 0);
584 std::vector<Index>
sIdx;
585 std::vector<double>
sW;
605 float rescale = 0.0f;
608 float th[6] = {}, w_bc[6] = {}, w_n1[6] = {}, w_n2[6] = {}, wm_n1[6] = {}, wm_n2[6] = {};
609 double invh[3] = {0.0, 0.0, 0.0};
610 int8_t sampFluid[15] = {};
612 std::vector<Index>
sIdx;
613 std::vector<double>
sW;
614 long nIdentity = 0, nLS2 = 0, nLS1 = 0, nDegraded = 0, nSolidSlot = 0;
616 std::vector<std::unique_ptr<RowStage>> stages(
static_cast<std::size_t
>(n));
619 std::vector<uint8_t>
sfPer(
static_cast<std::size_t
>(n), 0),
mfPer(
static_cast<std::size_t
>(n), 0);
622 if (!fluid[
static_cast<std::size_t
>(
i)])
624 const unsigned Li =
t.level(
i);
625 const double h =
pres.cellWidth(
i);
626 const Vec<3>&
c =
cen[
static_cast<std::size_t
>(
i)];
631 float Cq[3][5],
F[3][4];
632 for (
int a = 0;
a < 3; ++
a) {
633 const double ha =
pres.cellWidth(
i,
a);
634 for (
int q = -2;
q <= 2; ++
q) {
636 p[
a] +=
static_cast<double>(
q) *
ha;
637 Cq[
a][
q + 2] =
static_cast<float>(
sdf(
p));
639 for (
int m = 0; m < 4; ++m)
640 F[
a][m] = 0.5f * (
Cq[
a][m] +
Cq[
a][m + 1]);
646 const float si0 =
static_cast<float>(
sdf(
c));
647 pres.forEachFaceFull(
i, [&](
Index j,
int axis,
int dir,
double,
double,
double) {
648 const int face = 2 * axis + (dir > 0 ? 0 : 1);
652 if (0.5f * (
si0 +
sj) >= 0.0f)
656 for (
int k = 0; k < 6; ++k) {
658 const int m = (k & 1) ? 1 : 2;
659 const bool virtOpen =
F[
a][m] >= 0.0f &&
Cq[
a][(k & 1) ? 1 : 3] > 0.0f &&
Cq[
a][2] > 0.0f;
663 ++
sfPer[
static_cast<std::size_t
>(
i)];
664 const float mag = std::fabs(
F[
a][m]) > 0.0f ? std::fabs(
F[
a][m]) : 1e-6f;
668 ++
mfPer[
static_cast<std::size_t
>(
i)];
672 for (
int a = 0;
a < 3; ++
a)
681 one.rescale.resize(1);
682 one.coupled.resize(1);
690 detail::GhostOverlayRef ref{
one};
694 auto st = std::make_unique<RowStage>();
695 st->cell =
one.cell[0];
696 st->rescale =
one.rescale[0];
697 st->coupled =
one.coupled[0];
698 for (
int k = 0; k < 6; ++k) {
699 st->state[k] =
one.state[
static_cast<std::size_t
>(k)];
700 st->th[k] =
one.th[
static_cast<std::size_t
>(k)];
701 st->w_bc[k] =
one.w_bc[
static_cast<std::size_t
>(k)];
702 st->w_n1[k] =
one.w_n1[
static_cast<std::size_t
>(k)];
703 st->w_n2[k] =
one.w_n2[
static_cast<std::size_t
>(k)];
704 st->wm_n1[k] =
one.wm_n1[
static_cast<std::size_t
>(k)];
705 st->wm_n2[k] =
one.wm_n2[
static_cast<std::size_t
>(k)];
707 for (
int a = 0;
a < 3; ++
a)
708 st->invh[
a] = 1.0 /
pres.cellWidth(
i,
a);
711 for (
int a = 0;
a < 3; ++
a)
712 for (
int q = -2;
q <= 2; ++
q) {
713 const int sl =
a * 5 + (
q + 2);
716 p[
a] +=
static_cast<double>(
q) *
pres.cellWidth(
i,
a);
722 const std::array<long, 3>
lc{
lcq[0],
lcq[1],
lcq[2]};
729 if (
q == 0 || (
j >= 0 &&
pres.levelOf(
j) ==
Li)) {
732 st->sIdx.push_back(
j);
733 st->sW.push_back(1.0);
736 st->sIdx.push_back(
j);
737 st->sW.push_back(1.0);
753 for (
int d = 0; d < 3; ++d) {
754 const double hd =
pres.cellWidth(
i, d);
755 H[d] = (
j >= 0) ?
pres.cellWidth(
j, d) :
hd;
758 std::vector<Index> idx;
759 std::vector<double> w;
777 for (std::size_t k = 0; k < idx.size(); ++k) {
778 st->sIdx.push_back(idx[k]);
779 st->sW.push_back(w[k]);
783 stages[
static_cast<std::size_t
>(
i)] = std::move(
st);
796 ov.nSignForced +=
sfPer[
static_cast<std::size_t
>(
i)];
797 ov.nMixedFace +=
mfPer[
static_cast<std::size_t
>(
i)];
801 ov.base.cell.push_back(
st->cell);
802 ov.base.rescale.push_back(
st->rescale);
803 ov.base.coupled.push_back(
st->coupled);
804 for (
int k = 0; k < 6; ++k) {
805 ov.base.state.push_back(
st->state[k]);
806 ov.base.th.push_back(
st->th[k]);
807 ov.base.w_bc.push_back(
st->w_bc[k]);
808 ov.base.w_n1.push_back(
st->w_n1[k]);
809 ov.base.w_n2.push_back(
st->w_n2[k]);
810 ov.base.wm_n1.push_back(
st->wm_n1[k]);
811 ov.base.wm_n2.push_back(
st->wm_n2[k]);
814 for (
int sl = 0;
sl < 15; ++
sl) {
815 ov.sampFluid.push_back(
st->sampFluid[
sl]);
817 ov.sampStart.push_back(
acc);
819 sIdx.insert(
sIdx.end(),
st->sIdx.begin(),
st->sIdx.end());
820 sW.insert(
sW.end(),
st->sW.begin(),
st->sW.end());
821 ov.nIdentity +=
st->nIdentity;
824 ov.nDegraded +=
st->nDegraded;
825 ov.nSolidSlot +=
st->nSolidSlot;
826 for (
int a = 0;
a < 3; ++
a)
827 ov.base.invh.push_back(
st->invh[
a]);
828 ov.rowOf[
static_cast<std::size_t
>(
i)] = ov.base.n;
831 ov.sampIdx = std::move(
sIdx);
832 ov.sampW = std::move(
sW);
834 "[peclet.amr] sampled ghost overlay: %lld rows | slots identity %ld, LS2 %ld, "
835 "LS1 %ld, degraded %ld, solid %ld | csr %lld | sign-forced faces %ld, closed mixed "
837 static_cast<long long>(ov.base.n), ov.nIdentity, ov.nLS2, ov.nLS1, ov.nDegraded,
838 ov.nSolidSlot,
static_cast<long long>(ov.sampIdx.size()), ov.nSignForced,
845 const std::vector<double>& x) {
846 const std::size_t
s =
static_cast<std::size_t
>(
r * 15 +
a * 5 + (
q + 2));
849 v += ov.
sampW[
static_cast<std::size_t
>(k)] *
850 x[
static_cast<std::size_t
>(ov.
sampIdx[
static_cast<std::size_t
>(k)])];
857 std::vector<double>&
y) {
860 const std::size_t
rr =
static_cast<std::size_t
>(
r);
863 y[
static_cast<std::size_t
>(
c)] = 0.0;
872 for (
int k = 0; k < 6; ++k) {
874 if (
st != scheme::GP_QUAD &&
st != scheme::GP_LIN)
877 const int sgn = (k & 1) ? -1 : 1;
878 const int mn = (k & 1) ? 1 : 0;
879 const int mf = (k & 1) ? 2 : -1;
880 const double w1 = g.
wm_n1[
rr * 6 +
static_cast<std::size_t
>(k)];
881 const double w2 = g.
wm_n2[
rr * 6 +
static_cast<std::size_t
>(k)];
883 if (
st == scheme::GP_QUAD &&
w2 != 0.0)
886 y[
static_cast<std::size_t
>(
c)] =
893 const std::array<std::vector<double>, 3>&
u,
894 std::vector<double>& d) {
897 const std::size_t
rr =
static_cast<std::size_t
>(
r);
900 d[
static_cast<std::size_t
>(
c)] = 0.0;
903 auto U = [&](
int a,
int m) {
904 return 0.5 * (
gpsSample(ov,
r,
a, m - 1,
u[
static_cast<std::size_t
>(
a)]) +
911 for (
int k = 0; k < 6; ++k) {
913 if (
st == scheme::GP_COUPLED)
916 const int sgn = (k & 1) ? -1 : 1;
917 const int mg = (k & 1) ? 0 : 1;
918 const int mn = (k & 1) ? 1 : 0;
919 const int mf = (k & 1) ? 2 : -1;
920 if (
st == scheme::GP_EXPLICIT) {
924 if (
st == scheme::GP_BC_ONLY)
926 double val = g.
w_n1[
rr * 6 +
static_cast<std::size_t
>(k)] *
U(
a,
mn);
927 if (
st == scheme::GP_QUAD)
928 val += g.
w_n2[
rr * 6 +
static_cast<std::size_t
>(k)] *
U(
a,
mf);
931 d[
static_cast<std::size_t
>(
c)] = g.
rescale[
rr] * (d[
static_cast<std::size_t
>(
c)] +
ihd *
dd);
954template <
unsigned Bits,
class Mom,
class SdfFn>
959 const Index n =
t.numLeaves();
960 const double h0 =
pres.cellWidth(0) /
static_cast<double>(
Index(1) <<
t.level(0));
961 std::vector<std::vector<detail::ScalarEnt>>
per(
static_cast<std::size_t
>(n));
967 const unsigned Li =
t.level(
i);
969 for (
int k = 0; k < 6; ++k) {
977 auto b =
t.bounds(
i);
978 const double s =
static_cast<double>(
Index(1) <<
Li);
980 for (
int d = 0; d < 3; ++d)
982 (
static_cast<double>(b[0][d]) +
static_cast<double>(
frameShift[d]) + 0.5 *
s) * h0;
983 const double h =
pres.cellWidth(
i);
987 for (
int k = 0; k < 6; ++k) {
989 p[k / 2] += ((k % 2 == 0) ? +1.0 : -1.0) *
h;
1002 per[
static_cast<std::size_t
>(
i)].
push_back(detail::ScalarEnt{cell, w});
1005 const double rsr =
mom.rhsScale(
i);
1006 push(
i,
mom.acRaw()[
static_cast<std::size_t
>(
i)] /
rsr);
1007 for (
int k = 0; k < 6; ++k) {
1008 const double a =
mom.offRaw()[
static_cast<std::size_t
>(
i) * 6 + k];
1010 if (
a != 0.0 &&
nb >= 0)
1018 for (
int d = 0; d < 3; ++d) {
1019 const double hd =
pres.cellWidth(
i, d);
1020 beta[d] = mu / (
hd *
hd);
1022 const double AC0v = idiag + ((2.0 * beta[0] + 2.0 * beta[1]) + 2.0 * beta[2]);
1026 for (
int k = 0; k < 6; ++k) {
1029 const int q = (k % 2 == 0) ? +1 : -1;
1030 const std::size_t
sl =
static_cast<std::size_t
>(
r * 15 + (k / 2) * 5 + (
q + 2));
1038 const double invV = 1.0 /
mom.lap().cellVolume(
i);
1060 int c,
double invh) {
1061 auto fl = [&](
int q) {
1062 return ov.
sampFluid[
static_cast<std::size_t
>(
r * 15 +
c * 5 + (
q + 2))] != 0;
1065 const bool ap =
fl(+1),
am =
fl(-1);
1067 return (
F(+1) -
F(-1)) * 0.5 * invh;
1069 return fl(+2) ? (-3.0 *
F(0) + 4.0 *
F(+1) -
F(+2)) * 0.5 * invh : (
F(+1) -
F(0)) * invh;
1071 return fl(-2) ? (3.0 *
F(0) - 4.0 *
F(-1) +
F(-2)) * 0.5 * invh : (
F(0) -
F(-1)) * invh;
1086 std::vector<double>
w;
1089template <
unsigned Bits,
class IsCutFn,
class OkFn>
1095 g.
start.assign(1, 0);
1096 const Index n =
t.numLeaves();
1098 const std::size_t
s =
static_cast<std::size_t
>(
r * 15 +
a * 5 + (
q + 2));
1100 g.
idx.push_back(ov.
sampIdx[
static_cast<std::size_t
>(
e)]);
1101 g.
w.push_back(
wgt * ov.
sampW[
static_cast<std::size_t
>(
e)]);
1111 g.
cell.push_back(
i);
1112 const double h =
pres.cellWidth(
i);
1114 for (
int a = 0;
a < 3; ++
a) {
1116 auto fl = [&](
int q) {
1117 return ov.
sampFluid[
static_cast<std::size_t
>(
r * 15 +
a * 5 + (
q + 2))] != 0;
1119 const bool ap =
fl(+1),
am =
fl(-1);
1179#ifdef KOKKOS_INLINE_FUNCTION
1219 auto cell = ov.
cell;
1225 auto invh = ov.
invh;
1229 Kokkos::parallel_for(
1242 bool Sh[5] = {
false,
false,
false,
false,
false};
1244 auto X = [&](
int a,
int q) {
1247 for (
int m = 0; m < 5; ++m)
1250 const int idx =
q + 2;
1252 const Index s =
r * 15 +
a * 5 + idx;
1262 const double ih = invh(
r * 3);
1263 const double rx = invh(
r * 3 + 1) /
ih,
ry = invh(
r * 3 + 2) /
ih;
1264 const double r2[3] = {1.0,
rx *
rx,
ry *
ry};
1266 for (
int k = 0; k < 6; ++k) {
1268 if (
s != scheme::GP_QUAD &&
s != scheme::GP_LIN)
1270 const int a = k / 2;
1271 const int sgn = (k & 1) ? -1 : 1;
1272 const int mn = (k & 1) ? 1 : 0;
1273 const int mf = (k & 1) ? 2 : -1;
1276 if (
s == scheme::GP_QUAD &&
w2 != 0.0)
1288 auto cell = ov.
cell;
1294 auto invh = ov.
invh;
1298 Kokkos::parallel_for(
1309 bool Sh[5] = {
false,
false,
false,
false,
false};
1311 auto S = [&](
int a,
int q) {
1314 for (
int m = 0; m < 5; ++m)
1317 const int idx =
q + 2;
1319 const Index s =
r * 15 +
a * 5 + idx;
1330 auto U = [&](
int a,
int m) {
return 0.5 * (
S(
a, m - 1) +
S(
a, m)); };
1332 const double ih = invh(
r * 3);
1333 const double r1[3] = {1.0, invh(
r * 3 + 1) /
ih, invh(
r * 3 + 2) /
ih};
1335 for (
int k = 0; k < 6; ++k) {
1337 if (
s == scheme::GP_COUPLED)
1339 const int a = k / 2;
1340 const int sgn = (k & 1) ? -1 : 1;
1341 const int mg = (k & 1) ? 0 : 1;
1342 const int mn = (k & 1) ? 1 : 0;
1343 const int mf = (k & 1) ? 2 : -1;
1344 if (
s == scheme::GP_EXPLICIT) {
1348 if (
s == scheme::GP_BC_ONLY)
1351 if (
s == scheme::GP_QUAD)
1369 d.
n =
static_cast<Index>(
h.cell.size());
1383 auto cell = ov.
cell;
1384 auto start = ov.
start;
1387 Kokkos::parallel_for(
1391 for (
int a = 0;
a < 3; ++
a) {
1393 for (
Index e = start(
s * 3 +
a);
e < start(
s * 3 +
a + 1); ++
e)
Cell-centered FV Poisson operator on one (periodic) block octree.
Per-block adaptive octree over block-local Morton codes.
void forEachCoveringSlot(const AmrPoisson< 3, Bits > &pres, const long lo[3], const long hi[3], WrapFn &&wrapLocal, EmitFn &&emit, bool descendPending=false)
DD1 (docs/amr_march_perf_and_distributed_plan.md) — the LS cloud's probe descent.
bool gpsSolveDense(int n, double *A, double *b)
Gaussian elimination with partial pivoting (small dense normal equations).
void compactCsr(const std::vector< std::vector< Ent > > &per, Csr &out, Index n)
void gpsMonomials(const double d[3], int deg, double *m, int &nm)
auto makeBinaryOpenFnMixed(const BlockOctree< 3, Bits > &t, const AmrPoisson< 3, Bits > &pres, SdfFn sdfFn, const Vec< 3 > &h0, Vec< 3 > origin, std::array< long, 3 > frameShift={})
The canonical (sub)face openness for mixed-level cut bands: open iff both adjacent ACTUAL leaf center...
GhostOverlaySampled buildGhostOverlaySampled(const BlockOctree< 3, Bits > &t, const AmrPoisson< 3, Bits > &pres, SdfFn &&sdf, int matrixOrder, int rhsOrder, Vec< 3 > origin=Vec< 3 >{}, const std::array< long, 3 > *globalFine=nullptr, std::array< long, 3 > frameShift={}, bool discovery=false, double rhoFactor=2.2, long maxSamples=0)
Build the sampled overlay.
GhostOverlaySampledDev uploadGhostOverlaySampled(const GhostOverlaySampled &h)
double gpsSample(const GhostOverlaySampled &ov, Index r, int a, int q, const std::vector< double > &x)
Evaluate slot (r, a, q) of a scalar leaf field. Empty functional reads 0.
GhostGradCsrHost buildSampledGradCsr(const GhostOverlaySampled &ov, const BlockOctree< 3, Bits > &t, const AmrPoisson< 3, Bits > &pres, IsCutFn &&isCut, OkFn &&classicOk)
void ghostApplyDeltaSampled(const GhostOverlaySampledDev &ov, View< const double > x, View< double > y)
Device matrix overlay (== ghostApplyDeltaSampledHost). Distinct rows per thread: no atomics.
void ghostDivergDeltaSampledHost(const GhostOverlaySampled &ov, const std::array< std::vector< double >, 3 > &u, std::vector< double > &d)
Divergence overlay (sampled): the sampled analog of ghostDivergDeltaHost (u_bc = 0).
void applyGhostGradCsr(const GhostGradCsrDev &ov, View< const double > f, View< double > gx, View< double > gy, View< double > gz)
void ghostDivergDeltaSampled(const GhostOverlaySampledDev &ov, View< const double > u0, View< const double > u1, View< const double > u2, View< double > d)
Device divergence overlay (== ghostDivergDeltaSampledHost).
GhostGradCsrDev uploadGhostGradCsr(const GhostGradCsrHost &h)
double gpsDirGrad(const GhostOverlaySampled &ov, Index r, const std::vector< double > &fld, int c, double invh)
Directional ghost cell-gradient on a sampled row (the mixed-level gradOfDir): the same cascade — cent...
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,...
CfCsr buildMomSeamDelta(const GhostOverlaySampled &ov, const BlockOctree< 3, Bits > &t, const AmrPoisson< 3, Bits > &pres, const Mom &mom, SdfFn &&sdf, Vec< 3 > origin, double idiag, double mu, long *nSkipped=nullptr, std::array< long, 3 > frameShift={})
Momentum ξ-overlay seam correction (plan §6.2, rung 1): at overlay rows with a different-level ±1 nei...
void ghostApplyDeltaSampledHost(const GhostOverlaySampled &ov, const std::vector< double > &x, std::vector< double > &y)
Matrix overlay (sampled): y currently holds the BINARY L matvec; overwrite overlay rows with y = rho·...
Scalar-input CSR overlay: out(i) += Σ_k coef·f(slot) over rows with C/F faces.
Device CSR gradient overlay (sampled mode) + upload + apply (the variable-length analog of GhostGradO...
Host CSR form of the SAMPLED directional gradient overlay (variable-length stencils — a seam row's ca...
std::vector< Index > start
[m*3 + 1] per (cell, axis)
std::vector< Index > cell
[m] cut leaf
Device mirror of GhostOverlaySampled (uploaded once per setSolid).
Sampled overlay: the classic per-row fields (weights, states, rescale — base; base....
std::vector< Index > sampStart
[base.n*15 + 1]
std::vector< Index > sampIdx
std::vector< Index > rowOf
[numLeaves] row index of a leaf, -1 if none
std::vector< double > sampW
std::vector< int8_t > sampFluid
[base.n*15] virtual position is fluid (gradient cascade)
Host ghost-projection overlay: one row per non-clean fluid leaf (== cut cell: some ±1 center sample s...
std::vector< float > wm_n2
[n*6] matrix (implicit phi) weights (matrixOrder)
std::vector< int8_t > coupled
[n] 1 if the row has any phi coupling at all
std::vector< Index > cell
[n] leaf index
std::vector< float > wm_n1
std::vector< int8_t > state
[n*6]
std::vector< float > w_n2
[n*6] RHS/diagnostic closure weights (rhsOrder)
std::vector< float > rescale
[n] rho = min(1, min_f D_f) of the MATRIX weights
std::vector< float > w_n1
std::vector< double > invh
[n*3] 1/cellWidth PER AXIS of the row (Phase 3)