21#ifndef PECLET_AMR_ADAPT_HPP
22#define PECLET_AMR_ADAPT_HPP
33#include "peclet/core/common/types.hpp"
38inline double minmod(
double a,
double b) {
41 return (std::fabs(a) < std::fabs(b)) ? a : b;
50template <
int Dim,
unsigned Bits>
52 const std::vector<double>& oldF) {
54 using Coord =
typename BO::Coord;
55 using M =
typename BO::M;
56 auto centroid = [](
const BO& t, Index i) {
57 auto o = M::from_code(t.code(i)).decode();
58 const double s =
static_cast<double>(Coord(1) << t.level(i));
59 std::array<double, Dim> c{};
60 for (
int d = 0; d < Dim; ++d)
61 c[d] =
static_cast<double>(o[d]) + 0.5 * s;
65 std::vector<std::array<double, Dim>> grad(
static_cast<std::size_t
>(no),
66 std::array<double, Dim>{});
67 for (Index i = 0; i < no; ++i) {
68 auto ci = centroid(oldT, i);
69 const double ui = oldF[
static_cast<std::size_t
>(i)];
70 for (
int axis = 0; axis < Dim; ++axis) {
75 auto cp = centroid(oldT, jp);
76 auto cm = centroid(oldT, jm);
77 const double sp = (oldF[
static_cast<std::size_t
>(jp)] - ui) / (cp[axis] - ci[axis]);
78 const double sm = (ui - oldF[
static_cast<std::size_t
>(jm)]) / (ci[axis] - cm[axis]);
90template <
int Dim,
unsigned Bits>
95 const std::type_identity_t<std::vector<std::array<double, Dim>>>* gradIn =
nullptr) {
97 using Code =
typename BO::Code;
98 using Coord =
typename BO::Coord;
99 using M =
typename BO::M;
101 auto centroid = [](
const BO& t, Index i) {
102 auto o = M::from_code(t.code(i)).decode();
103 const double s =
static_cast<double>(Coord(1) << t.level(i));
104 std::array<double, Dim> c{};
105 for (
int d = 0; d < Dim; ++d)
106 c[d] =
static_cast<double>(o[d]) + 0.5 * s;
112 std::vector<std::array<double, Dim>> grad;
113 if (linear && gradIn) {
120 std::vector<double>
nf(
static_cast<std::size_t
>(
nn), 0.0);
121 std::vector<Index>
n2o(
static_cast<std::size_t
>(
nn), -1);
124 const unsigned Lj =
newT.level(
j);
128 const unsigned Lo =
oldT.level(
o);
130 nf[
static_cast<std::size_t
>(
j)] =
oldF[
static_cast<std::size_t
>(
o)];
131 }
else if (
Lo >
Lj) {
133 n2o[
static_cast<std::size_t
>(
j)] =
o;
135 nf[
static_cast<std::size_t
>(
j)] =
oldF[
static_cast<std::size_t
>(
o)];
139 double v =
oldF[
static_cast<std::size_t
>(
o)];
140 for (
int d = 0; d < Dim; ++d)
141 v +=
grad[
static_cast<std::size_t
>(
o)][d] * (
cn[d] -
co[d]);
142 nf[
static_cast<std::size_t
>(
j)] =
v;
147 auto oj = M::from_code(
cj).decode();
148 const Coord
sj = Coord(Coord(1) <<
Lj);
149 double vol = 0.0,
acc = 0.0;
151 auto ok = M::from_code(
oldT.code(k)).decode();
153 for (
int d = 0; d < Dim; ++d)
160 const double w = std::pow(2.0,
static_cast<double>(Dim *
static_cast<int>(
oldT.level(k))));
161 acc += w *
oldF[
static_cast<std::size_t
>(k)];
164 nf[
static_cast<std::size_t
>(
j)] = (
vol > 0.0) ?
acc /
vol : 0.0;
174 std::vector<double>
sv(
static_cast<std::size_t
>(
no), 0.0),
175 vv(
static_cast<std::size_t
>(
no), 0.0);
177 const Index o =
n2o[
static_cast<std::size_t
>(
j)];
180 const double w = std::pow(2.0,
static_cast<double>(Dim *
static_cast<int>(
newT.level(
j))));
181 sv[
static_cast<std::size_t
>(
o)] += w *
nf[
static_cast<std::size_t
>(
j)];
182 vv[
static_cast<std::size_t
>(
o)] += w;
185 const Index o =
n2o[
static_cast<std::size_t
>(
j)];
186 if (
o < 0 ||
vv[
static_cast<std::size_t
>(
o)] <= 0.0)
188 nf[
static_cast<std::size_t
>(
j)] +=
189 oldF[
static_cast<std::size_t
>(
o)] -
190 sv[
static_cast<std::size_t
>(
o)] /
vv[
static_cast<std::size_t
>(
o)];
201template <
int Dim,
unsigned Bits>
205 const Index n =
t.numLeaves();
206 std::vector<int>
f(
static_cast<std::size_t
>(n),
kKeep);
208 const unsigned L =
t.level(
i);
209 const double e =
ind[
static_cast<std::size_t
>(
i)];
211 f[
static_cast<std::size_t
>(
i)] =
kRefine;
218template <
int Dim,
unsigned Bits>
228template <
int Dim,
unsigned Bits>
230 const std::vector<int>&
flags,
bool linear =
true) {
232 using Code =
typename BO::Code;
233 using M =
typename BO::M;
237 for (
unsigned oct = 0;
oct < (1u << Dim); ++
oct) {
238 Code cc = M::from_code(
parent).child(
pl,
oct).code();
246 nt.refineIf([&](Code
c,
unsigned) {
256template <
int Dim,
unsigned Bits>
Per-block adaptive octree over block-local Morton codes.
Index coarsenIf(Pred &&pred)
Merge complete sibling groups (all 2^Dim children present, all at the same level) whose parent satisf...
Index faceNeighbor(Index i, int axis, int dir) const
The leaf across leaf i's face on axis in direction dir (±1), or -1 if it lies outside the block.
double minmod(double a, double b)
std::vector< double > lohnerIndicator(const BlockOctree< Dim, Bits > &t, const std::vector< double > &u, double eps=0.01)
Löhner normalized second-difference indicator E_i ∈ [0,1], per leaf, for scalar u (indexed by leaf sl...
AdaptResult< Dim, Bits > adaptField(const BlockOctree< Dim, Bits > &t, const std::vector< double > &f, const std::vector< int > &flags, bool linear=true)
Apply adaptation flags (one level of refine/coarsen) to t carrying field f, then 2:1-balance and rema...
std::vector< int > flagByIndicator(const BlockOctree< Dim, Bits > &t, const std::vector< double > &ind, double refineThresh, double coarsenThresh, unsigned finestLevel=0)
AdaptResult< Dim, Bits > adapt(const BlockOctree< Dim, Bits > &t, const std::vector< double > &f, double refineThresh, double coarsenThresh, unsigned finestLevel=0, double eps=0.01, bool linear=true)
All-in-one solution-adaptive step: Löhner indicator → flags → adaptField.
std::vector< double > transferField(const BlockOctree< Dim, Bits > &oldT, const std::vector< double > &oldF, const BlockOctree< Dim, Bits > &newT, bool linear=true, const std::type_identity_t< std::vector< std::array< double, Dim > > > *gradIn=nullptr)
Conservative remap of a leaf field from oldT to newT (same domain).
AdaptFlag
Per-leaf adaptation flags from an indicator: refine where ind > refineThresh (and the leaf can go fin...
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,...
BlockOctree< Dim, Bits > octree
std::vector< double > field