21 #ifndef FUB_DIMENSIONAL_SPLIT_LEVEL_INTEGRATOR_HPP
22 #define FUB_DIMENSIONAL_SPLIT_LEVEL_INTEGRATOR_HPP
34 #include "fub/split_method/GodunovSplitting.hpp"
52 template <
int R,
typename IntegratorContext,
53 typename SplitMethod = GodunovSplitting>
57 static constexpr
int Rank = R;
73 template <
typename OtherSplitMethod>
76 OtherSplitMethod>& other)
80 SplitMethod splitting = SplitMethod())
81 : IntegratorContext(std::move(context)),
82 SplitMethod(std::move(splitting)) {}
85 SplitMethod splitting = SplitMethod())
87 std::move(splitting)) {}
89 const IntegratorContext&
GetContext() const noexcept {
return *
this; }
90 IntegratorContext&
GetContext() noexcept {
return *
this; }
99 [[maybe_unused]]
Duration time_step_size,
100 [[maybe_unused]] std::pair<int, int> subcycle);
104 [[maybe_unused]]
Duration time_step_size,
105 [[maybe_unused]] std::pair<int, int> subcycle);
107 using IntegratorContext::GetCounterRegistry;
108 using IntegratorContext::GetCycles;
109 using IntegratorContext::GetMpiCommunicator;
110 using IntegratorContext::GetTimePoint;
112 using IntegratorContext::FillGhostLayerSingleLevel;
113 using IntegratorContext::FillGhostLayerTwoLevels;
115 using IntegratorContext::GetRatioToCoarserLevel;
116 using IntegratorContext::LevelExists;
118 using IntegratorContext::CoarsenConservatively;
120 using IntegratorContext::ComputeNumericFluxes;
121 using IntegratorContext::CopyDataToScratch;
122 using IntegratorContext::CopyScratchToData;
123 using IntegratorContext::UpdateConservatively;
125 using IntegratorContext::AccumulateCoarseFineFluxes;
126 using IntegratorContext::ApplyFluxCorrection;
127 using IntegratorContext::ResetCoarseFineFluxes;
147 std::pair<int, int> subcycle);
150 template <
int R,
typename IntegratorContext,
typename SplitMethod>
157 template <
int R,
typename IntegratorContext,
typename SplitMethod>
167 template <
int R,
typename IntegratorContext,
typename SplitMethod>
170 std::pair<int, int> subcycle) {
173 if (regrid_level == 0) {
174 IntegratorContext::FillGhostLayerSingleLevel(0);
176 for (
int ilvl = std::max(1, regrid_level);
177 IntegratorContext::LevelExists(ilvl); ++ilvl) {
178 IntegratorContext::FillGhostLayerTwoLevels(ilvl, ilvl - 1);
181 const Duration coarse_time_point = IntegratorContext::GetTimePoint(0);
182 const Duration this_time_point = IntegratorContext::GetTimePoint(level);
183 if (level < regrid_level && this_time_point != coarse_time_point) {
185 IntegratorContext::FillGhostLayerTwoLevels(level, level - 1);
187 IntegratorContext::FillGhostLayerSingleLevel(level);
192 template <
int R,
typename IntegratorContext,
typename SplitMethod>
196 std::pair<int, int> subcycle) {
201 return boost::outcome_v2::success();
204 template <
int Rank,
typename Context,
typename SplitMethod>
209 Context::FillGhostLayerTwoLevels(level, level - 1);
211 Context::FillGhostLayerSingleLevel(level);
213 Duration min_dt(std::numeric_limits<double>::max());
214 for (
int d = 0; d < Rank; ++d) {
216 min_dt = std::min(min_dt, Context::ComputeStableDt(level, dir));
221 template <
int Rank,
typename Context,
typename SplitMethod>
225 std::pair<int, int> subcycle) {
226 auto AdvanceLevel_Split = [&](
Direction dir) {
227 return [&, this_level, dir, count_split_steps = 0](
229 if (count_split_steps > 0) {
231 Context::ApplyBoundaryCondition(this_level, dir);
233 count_split_steps += 1;
237 const Duration local_dt = Context::ComputeStableDt(this_level, dir);
238 MPI_Comm comm = GetMpiCommunicator();
240 if (level_dt < split_dt) {
245 Context::ComputeNumericFluxes(this_level, split_dt, dir);
249 Context::UpdateConservatively(this_level, split_dt, dir);
256 const double scale = split_dt.count();
257 Context::AccumulateCoarseFineFluxes(this_level, scale, dir);
259 return boost::outcome_v2::success();
267 [&](
auto... directions) {
268 return GetSplitMethod().Advance(dt, AdvanceLevel_Split(directions)...);
270 MakeSplitDirections<Rank>(
static_cast<int>(GetCycles(0)), subcycle));
This Level Integrator applies a very general AMR integration scheme in context of dimensional splitti...
Definition: DimensionalSplitLevelIntegrator.hpp:55
void PostAdvanceHierarchy([[maybe_unused]] Duration time_step_size)
Definition: DimensionalSplitLevelIntegrator.hpp:159
const IntegratorContext & GetContext() const noexcept
Definition: DimensionalSplitLevelIntegrator.hpp:89
DimensionalSplitLevelIntegrator(int_constant< R >, IntegratorContext context, SplitMethod splitting=SplitMethod())
Definition: DimensionalSplitLevelIntegrator.hpp:84
DimensionalSplitLevelIntegrator(DimensionalSplitLevelIntegrator &&other)=default
void PreAdvanceLevel([[maybe_unused]] int level, [[maybe_unused]] Duration time_step_size, [[maybe_unused]] std::pair< int, int > subcycle)
Definition: DimensionalSplitLevelIntegrator.hpp:169
DimensionalSplitLevelIntegrator()=delete
DimensionalSplitLevelIntegrator(const DimensionalSplitLevelIntegrator &other)=default
DimensionalSplitLevelIntegrator(IntegratorContext context, SplitMethod splitting=SplitMethod())
Definition: DimensionalSplitLevelIntegrator.hpp:79
static constexpr int Rank
Definition: DimensionalSplitLevelIntegrator.hpp:57
IntegratorContext & GetContext() noexcept
Definition: DimensionalSplitLevelIntegrator.hpp:90
DimensionalSplitLevelIntegrator & operator=(DimensionalSplitLevelIntegrator &&other)=default
void PreAdvanceHierarchy()
Definition: DimensionalSplitLevelIntegrator.hpp:152
DimensionalSplitLevelIntegrator & operator=(const DimensionalSplitLevelIntegrator &other)=default
const SplitMethod & GetSplitMethod() const noexcept
Definition: DimensionalSplitLevelIntegrator.hpp:92
Result< void, TimeStepTooLarge > AdvanceLevelNonRecursively(int level_number, Duration dt, std::pair< int, int > subcycle)
Advance a specified patch level and all finer levels by time dt.
Definition: DimensionalSplitLevelIntegrator.hpp:224
DimensionalSplitLevelIntegrator(const DimensionalSplitLevelIntegrator< Rank, IntegratorContext, OtherSplitMethod > &other)
Definition: DimensionalSplitLevelIntegrator.hpp:74
Result< void, TimeStepTooLarge > PostAdvanceLevel([[maybe_unused]] int level, [[maybe_unused]] Duration time_step_size, [[maybe_unused]] std::pair< int, int > subcycle)
Definition: DimensionalSplitLevelIntegrator.hpp:195
Duration ComputeStableDt(int level_number)
Returns a stable dt on a specified level across all spatial directions.
Definition: DimensionalSplitLevelIntegrator.hpp:206
void CompleteFromCons(Equation &&equation, Complete< std::decay_t< Equation >> &complete, const Conservative< std::decay_t< Equation >> &cons)
Definition: CompleteFromCons.hpp:42
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
Duration MinAll(MPI_Comm comm, Duration local_duration)
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
boost::outcome_v2::result< T, E > Result
Definition: outcome.hpp:32
std::integral_constant< int, I > int_constant
Definition: type_traits.hpp:183
This is std::true_type if Op<Args...> is a valid SFINAE expression.
Definition: type_traits.hpp:92