26#ifndef PECLET_AMR_MG_STAGE_HPP
27#define PECLET_AMR_MG_STAGE_HPP
41#include "peclet/core/common/mpi.hpp"
42#include "peclet/core/common/view.hpp"
43#include "peclet/core/decomp/block_decomposer.hpp"
44#include "peclet/core/decomp/redistribute_topology.hpp"
45#include "peclet/core/decomp/stage_comm.hpp"
46#include "peclet/core/decomp/stage_target.hpp"
59template <
int Dim,
unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
69 virtual const char*
kind()
const = 0;
118 int bottom,
double omega) {
137template <
int Dim,
unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
164 namespace cd = core::decomp;
167 for (
int a = 0;
a < Dim; ++
a)
169 for (
int a = 0;
a < Dim; ++
a)
171 throw std::runtime_error(
172 "amr::ReplicatedTailStage: periodic-only (as the whole distributed pressure path is); "
173 "a non-periodic bottom must be gated the way flow gates its anchored path");
175 for (
int a = 0;
a < Dim; ++
a)
178 throw std::runtime_error(
179 "amr::ReplicatedTailStage: the moved level does not tile its block with root cells (the "
180 "lift is not nested)");
181 target_.kind = cd::StageKind::Replicated;
182 target_.dec.init(1, G_);
183 target_.ownerOf = {0};
184 target_.groupOf.clear();
194 throw std::runtime_error(
195 "amr::ReplicatedTailStage: a cell of this rank's block is not one of its root leaves "
196 "(the lift is not nested)");
200 std::array<typename Octree::Coord, Dim>
f{};
201 for (
int a = 0;
a < Dim; ++
a)
205 comm_ = cd::makeStageComm<Dim>(comm, target_);
209 const int F = 2 * Dim;
211 std::vector<std::vector<double>>
aCol(
static_cast<std::size_t
>(
F),
212 std::vector<double>(
static_cast<std::size_t
>(n), 1.0));
215 for (
int f = 0;
f <
F; ++
f)
216 aCol[
static_cast<std::size_t
>(
f)][
static_cast<std::size_t
>(
i)] =
217 aloc[
static_cast<std::size_t
>(
i) *
F +
static_cast<std::size_t
>(
f)];
218 std::vector<std::vector<double>>
tCol(
static_cast<std::size_t
>(
F),
219 std::vector<double>(
static_cast<std::size_t
>(nt_), 1.0));
220 std::vector<const double*>
aSrc(
static_cast<std::size_t
>(
F));
221 std::vector<double*>
aDst(
static_cast<std::size_t
>(
F));
222 for (
int f = 0;
f <
F; ++
f) {
223 aSrc[
static_cast<std::size_t
>(
f)] =
aCol[
static_cast<std::size_t
>(
f)].data();
224 aDst[
static_cast<std::size_t
>(
f)] =
tCol[
static_cast<std::size_t
>(
f)].data();
227 std::vector<double>
aTail(
static_cast<std::size_t
>(nt_) *
F);
229 for (
int f = 0;
f <
F; ++
f)
230 aTail[
static_cast<std::size_t
>(
r) *
F +
static_cast<std::size_t
>(
f)] =
231 tCol[
static_cast<std::size_t
>(
f)][
static_cast<std::size_t
>(
r)];
233 mg_ = std::make_unique<Multigrid<Dim, Bits>>();
234 mg_->buildRaw(oct_, h0, std::move(
aTail),
true,
true, bottomExtent);
239 dSrc_ =
View<double>(
"stage_dsrc",
static_cast<std::size_t
>(n));
240 dDst_ =
View<double>(
"stage_ddst",
static_cast<std::size_t
>(n));
241 srcMirror_ = Kokkos::View<double*, Kokkos::HostSpace>(
"stage_src",
static_cast<std::size_t
>(n));
242 dstMirror_ = Kokkos::View<double*, Kokkos::HostSpace>(
"stage_dst",
static_cast<std::size_t
>(n));
243 tbMirror_ = Kokkos::View<double*, Kokkos::HostSpace>(
"stage_tb",
static_cast<std::size_t
>(nt_));
244 txMirror_ = Kokkos::View<double*, Kokkos::HostSpace>(
"stage_tx",
static_cast<std::size_t
>(nt_));
247 const char*
kind()
const override {
return "replicated"; }
251 bool active()
const override {
return true; }
254 std::size_t
numLevels()
const override {
return mg_->numLevels(); }
256 std::string
bottomName()
const override {
return mg_->bottomName(); }
267 Kokkos::deep_copy(srcMirror_, dSrc_);
268 topo_.forward({srcMirror_.data()}, {tbMirror_.data()});
269 Kokkos::deep_copy(mg_->b(0), tbMirror_);
270 Kokkos::deep_copy(mg_->x(0), 0.0);
278 Kokkos::deep_copy(txMirror_, mg_->x(0));
279 topo_.backward({txMirror_.data()}, {dstMirror_.data()});
280 Kokkos::deep_copy(dDst_, dstMirror_);
282 Kokkos::parallel_for(
289 core::decomp::StageTarget<Dim> target_;
290 core::decomp::StageComm comm_;
291 core::decomp::RedistributeTopology<Dim, double> topo_;
293 std::unique_ptr<Multigrid<Dim, Bits>> mg_;
297 Kokkos::View<double*, Kokkos::HostSpace> srcMirror_, dstMirror_, tbMirror_, txMirror_;
const std::vector< double > & opennessRaw() const
unsigned level(Index i) const
const IVec< Dim > & globalRootSize() const
const std::array< bool, Dim > & periodic() const
Index findGlobalRoot(const IVec< Dim > &g) const
Local leaf covering global root-cell g, or -1 if not owned by this rank (lmax==0).
const decomp::BlockDecomposer< Dim > & decomposition() const
The ORB over the global ROOT grid in the CURRENT root units — rank r owns block r.
const IVec< Dim > & blockBrick() const
One stage of the pressure hierarchy (docs/amr_mg_depth.md §6.5).
virtual View< double > targetX()=0
The continued ladder's level-0 solution — what moveDown reads.
virtual void moveDown(View< double > dst, Index nDst)=0
The target's level-0 solution → the first nDst rows of dst.
void apply(View< const double > residual, View< double > correction, Index n, int pre, int post, int bottom, double omega)
The whole stage for one V-cycle, in the CORRECTION SCHEME §6.5 prescribes: the caller hands in the re...
BlockOctree< Dim, Bits > Octree
a level's cells on one block
virtual void moveUp(View< const double > src, Index nSrc)=0
src (this rank's rows of the moved level, device; may be longer than nSrc) → the target's level-0 rhs...
virtual const char * kind() const =0
"replicated" | "sibling" | "repartition".
virtual std::string bottomName() const =0
"jacobi" | "amg": what solves the continued ladder's coarsest level, WITHOUT the stage's diagnosticSu...
virtual bool active() const =0
Whether THIS rank owns a target block, i.e.
virtual ~MgStage()=default
virtual const Octree & targetOctree() const =0
The moved level's cells on this rank's target block.
virtual void cycle(int pre, int post, int bottom, double omega)=0
One cycle of the continued ladder on targetComm(). Called on active ranks only.
virtual void setRemoveMean(bool on)=0
Per-level constant-nullspace projection for the singular periodic pressure; the owner forwards its ow...
virtual Index numLeaves(std::size_t L) const =0
Cells of continued-ladder level L on this rank's target block — the GLOBAL count for the replicated s...
virtual std::size_t numLevels() const =0
Levels of the continued ladder, its level 0 (the moved level) included. Local.
core::decomp::BlockDecomposer< Dim > Decomposition
the target partition's type
virtual void setBottom(typename Multigrid< Dim, Bits >::Bottom b)=0
What solves the continued ladder's coarsest level (docs/amr_mg_depth.md §6.6).
virtual MPI_Comm targetComm() const =0
The communicator every collective of the continued ladder runs on.
virtual const Decomposition & targetDecomposition() const =0
The decomposition of the moved level's grid this stage targets.
virtual const char * diagnosticSuffix() const =0
What pressure_mg_bottom appends for this stage — "+tail" for the replicated one, which is the spellin...
Bottom
What solves the coarsest level (docs/amr_mg_depth.md §6.6).
The REPLICATED stage (docs/amr_mg_depth.md §6.5.1): the target decomposition is one block — the whole...
void moveUp(View< const double > src, Index nSrc) override
src (this rank's rows of the moved level, device; may be longer than nSrc) → the target's level-0 rhs...
MPI_Comm targetComm() const override
The communicator every collective of the continued ladder runs on.
std::size_t numLevels() const override
Levels of the continued ladder, its level 0 (the moved level) included. Local.
Index numLeaves(std::size_t L) const override
Cells of continued-ladder level L on this rank's target block — the GLOBAL count for the replicated s...
void cycle(int pre, int post, int bottom, double omega) override
One cycle of the continued ladder on targetComm(). Called on active ranks only.
typename Base::Octree Octree
the gathered level, one block
bool active() const override
Whether THIS rank owns a target block, i.e.
void setBottom(typename Multigrid< Dim, Bits >::Bottom b) override
What solves the continued ladder's coarsest level (docs/amr_mg_depth.md §6.6).
const Octree & targetOctree() const override
The moved level's cells on this rank's target block.
const Decomposition & targetDecomposition() const override
The decomposition of the moved level's grid this stage targets.
void moveDown(View< double > dst, Index nDst) override
The target's level-0 solution → the first nDst rows of dst.
std::string bottomName() const override
"jacobi" | "amg": what solves the continued ladder's coarsest level, WITHOUT the stage's diagnosticSu...
void setRemoveMean(bool on) override
Per-level constant-nullspace projection for the singular periodic pressure; the owner forwards its ow...
const char * diagnosticSuffix() const override
What pressure_mg_bottom appends for this stage — "+tail" for the replicated one, which is the spellin...
Multigrid< Dim, Bits > & multigrid()
The continued ladder itself — a single-rank Multigrid, exposed for the WO5 bottom selector.
void build(const DO &d, const Vec< Dim > &h0, const Poisson &ap, Index n, Index nExt, Index bottomExtent, MPI_Comm comm)
Build the stage from the level it fires at: d is that level's distributed octree (lifted,...
typename Base::Decomposition Decomposition
one block: the whole level
View< double > targetX() override
The continued ladder's level-0 solution — what moveDown reads.
const char * kind() const override
"replicated" | "sibling" | "repartition".
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,...