20#ifndef PECLET_AMR_DISTRIBUTED_ADAPT_HPP
21#define PECLET_AMR_DISTRIBUTED_ADAPT_HPP
29#include "peclet/core/common/types.hpp"
35template <
int Dim,
unsigned Bits>
37 const std::vector<double>&
u,
double eps = 0.01) {
41 const int F = 2 * Dim;
42 std::vector<double>
e(
static_cast<std::size_t
>(n), 0.0);
44 const double ui =
u[
static_cast<std::size_t
>(
i)];
46 for (
int axis = 0; axis < Dim; ++axis) {
47 const double up = g[
static_cast<std::size_t
>(
i) *
F + 2 * axis + 0];
48 const double um = g[
static_cast<std::size_t
>(
i) *
F + 2 * axis + 1];
51 const double d2 =
up - 2.0 *
ui +
um;
52 const double nrm = std::fabs(
up -
ui) + std::fabs(
ui -
um) +
53 eps * (std::fabs(
up) + 2.0 * std::fabs(
ui) + std::fabs(
um));
57 e[
static_cast<std::size_t
>(
i)] = (
den2 > 0.0) ? std::sqrt(
num2 /
den2) : 0.0;
71template <
int Dim,
unsigned Bits>
73 const std::vector<double>&
f) {
75 using BO =
typename DO::Octree;
76 using Coord =
typename BO::Coord;
77 using M =
typename BO::M;
80 const int S = 2 * Dim;
83 double val = 0.0,
sj = 0.0;
86 std::vector<Side>
sides(
static_cast<std::size_t
>(n) *
S);
87 std::vector<std::array<Coord, Dim>>
rq;
88 std::vector<std::size_t>
rslot;
91 const auto&
lo = b[0];
92 const long si = 1L <<
t.level(
i);
93 for (
int axis = 0; axis < Dim; ++axis)
94 for (
int dd = 0;
dd < 2; ++
dd) {
95 const std::size_t slot =
static_cast<std::size_t
>(
i) *
S + axis * 2 +
dd;
97 (
dd == 0) ?
static_cast<long>(
lo[axis]) +
si :
static_cast<long>(
lo[axis]) - 1;
100 std::array<Coord, Dim>
p =
lo;
101 p[axis] =
static_cast<Coord
>(
pc);
102 const Index j =
t.find(M::encode(
p).code());
104 sides[slot].val =
f[
static_cast<std::size_t
>(
j)];
105 sides[slot].sj =
static_cast<double>(1L <<
t.level(
j));
106 sides[slot].ok =
true;
112 std::array<long, Dim> g{};
114 for (
int a = 0;
a < Dim; ++
a)
117 for (
int a = 0;
a < Dim; ++
a)
123 std::array<Coord, Dim> gc{};
124 for (
int a = 0;
a < Dim; ++
a)
125 gc[
a] =
static_cast<Coord
>(g[
a]);
126 rslot.push_back(slot);
134 for (std::size_t k = 0; k <
rq.size(); ++k)
141 std::vector<std::array<double, Dim>>
grad(
static_cast<std::size_t
>(n), std::array<double, Dim>{});
143 const double si =
static_cast<double>(1L <<
t.level(
i));
144 const double ui =
f[
static_cast<std::size_t
>(
i)];
145 for (
int axis = 0; axis < Dim; ++axis) {
146 const Side&
P =
sides[
static_cast<std::size_t
>(
i) *
S + axis * 2 + 0];
147 const Side&
Mi =
sides[
static_cast<std::size_t
>(
i) *
S + axis * 2 + 1];
150 const double sp = (
P.val -
ui) / (0.5 * (
si +
P.sj));
151 const double sm = (
ui -
Mi.val) / (0.5 * (
si +
Mi.sj));
161template <
int Dim,
unsigned Bits>
167 using Code =
typename BO::Code;
168 using M =
typename BO::M;
176 std::vector<std::array<double, Dim>>
grads;
183 for (
unsigned oct = 0;
oct < (1u << Dim); ++
oct) {
184 Code cc = M::from_code(
parent).child(
pl,
oct).code();
Index refineIf(Pred &&pred)
Split every leaf for which pred(code, level) is true (and level > 0) into its 2^Dim children one leve...
Index coarsenIf(Pred &&pred)
Merge complete sibling groups (all 2^Dim children present, all at the same level) whose parent satisf...
std::vector< double > faceNeighborGather(const std::vector< double > &field, double sentinel=kNoNeighbor) const
For each local leaf and each of the 2*Dim faces, the neighbouring leaf's field value.
std::vector< int > coverLevels(const std::vector< std::array< Coord, Dim > > &coords) const
For each global fine coord (already wrapped into the domain), the level of the covering leaf on its o...
Index balance()
Bring the whole distributed octree to a 2:1-balanced state.
std::vector< double > coverValues(const std::vector< std::array< Coord, Dim > > &coords, const std::vector< double > &field, double sentinel=kNoNeighbor) const
For each global fine coord, the covering leaf's field value on its owner (sentinel if none).
const IVec< Dim > & blockFineOrigin() const
const IVec< Dim > & globalFineSize() const
const IVec< Dim > & blockBrick() const
double minmod(double a, double b)
std::vector< double > distributedAdapt(DistributedOctree< Dim, Bits > &d, const std::vector< double > &f, double refineThresh, double coarsenThresh, unsigned finestLevel=0, double eps=0.01, bool linear=true)
One distributed solution-adaptive step.
std::vector< int > flagByIndicator(const BlockOctree< Dim, Bits > &t, const std::vector< double > &ind, double refineThresh, double coarsenThresh, unsigned finestLevel=0)
std::vector< std::array< double, Dim > > transferGradients(const DistributedOctree< Dim, Bits > &d, const std::vector< double > &f)
transferField's minmod prolongation gradients on a DistributedOctree: bit-identical to the block-loca...
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).
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,...
std::vector< double > lohnerIndicatorDistributed(const DistributedOctree< Dim, Bits > &d, const std::vector< double > &u, double eps=0.01)
Löhner indicator per local leaf, using the owner-based face-neighbour halo so cross-block neighbours ...