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