21 #ifndef FUB_HYPERBOLIC_METHOD_HPP
22 #define FUB_HYPERBOLIC_METHOD_HPP
29 #include <type_traits>
40 template <
typename IntegratorContext>
struct ReconstructionBase {
41 virtual ~ReconstructionBase() =
default;
42 virtual std::unique_ptr<ReconstructionBase> Clone()
const = 0;
47 template <
typename IntegratorContext>
struct TimeIntegratorBase {
48 virtual ~TimeIntegratorBase() =
default;
49 virtual std::unique_ptr<TimeIntegratorBase> Clone()
const = 0;
50 virtual void UpdateConservatively(IntegratorContext& context,
int level,
54 template <
typename IntegratorContext>
struct FluxMethodBase {
55 virtual ~FluxMethodBase() =
default;
56 virtual std::unique_ptr<FluxMethodBase> Clone()
const = 0;
58 virtual Duration ComputeStableDt(IntegratorContext& context,
int level,
60 virtual void ComputeNumericFluxes(IntegratorContext& context,
int level,
62 virtual int GetStencilWidth()
const = 0;
83 typename = std::enable_if_t<!decays_to<R, AnyReconstruction>()>>
89 std::unique_ptr<detail::ReconstructionBase<IntegratorContext>>
reconstruct_;
105 template <
typename R,
106 typename = std::enable_if_t<!decays_to<R, AnyTimeIntegrator>()>>
113 std::unique_ptr<detail::TimeIntegratorBase<IntegratorContext>>
integrator_;
129 template <
typename R,
130 typename = std::enable_if_t<!decays_to<R, AnyFluxMethod>()>>
144 std::unique_ptr<detail::FluxMethodBase<IntegratorContext>>
flux_method_;
162 template <
typename IntegratorContext>
165 : reconstruct_{other.reconstruct_ ? other.reconstruct_->Clone() : nullptr} {
168 template <
typename IntegratorContext>
175 reconstruct_ =
nullptr;
180 template <
typename IntegratorContext>
182 IntegratorContext& context,
int level,
Duration dt) {
183 reconstruct_->CompleteFromCons(context, level, dt);
187 template <
typename IntegratorContext,
typename R>
188 struct ReconstructionWrapper : ReconstructionBase<IntegratorContext> {
189 ReconstructionWrapper(
const R& rec) : rec_{rec} {}
190 ReconstructionWrapper(R&& rec) : rec_{std::move(rec)} {}
191 std::unique_ptr<ReconstructionBase<IntegratorContext>>
192 Clone()
const override {
193 return std::make_unique<ReconstructionWrapper>(rec_);
197 rec_.CompleteFromCons(context, level, dt);
203 template <
typename IntegratorContext>
204 template <
typename R,
typename>
207 std::make_unique<detail::ReconstructionWrapper<IntegratorContext,
209 std::forward<R>(rec))) {}
214 template <
typename IntegratorContext>
217 : integrator_{other.integrator_ ? other.integrator_->Clone() : nullptr} {}
219 template <
typename IntegratorContext>
226 integrator_ =
nullptr;
231 template <
typename IntegratorContext>
234 integrator_->UpdateConservatively(context, level, dt, dir);
238 template <
typename IntegratorContext,
typename I>
239 struct TimeIntegratorWrapper : TimeIntegratorBase<IntegratorContext> {
240 TimeIntegratorWrapper(
const I& integrator) : integrator_{integrator} {}
241 TimeIntegratorWrapper(I&& integrator) : integrator_{std::move(integrator)} {}
242 std::unique_ptr<TimeIntegratorBase<IntegratorContext>>
243 Clone()
const override {
244 return std::make_unique<TimeIntegratorWrapper>(integrator_);
246 void UpdateConservatively(IntegratorContext& context,
int level,
Duration dt,
248 integrator_.UpdateConservatively(context, level, dt, dir);
254 template <
typename IntegratorContext>
255 template <
typename I,
typename>
258 std::make_unique<detail::TimeIntegratorWrapper<IntegratorContext,
260 std::forward<I>(integrator))) {}
265 template <
typename IntegratorContext>
267 : flux_method_{other.flux_method_ ? other.flux_method_->Clone() : nullptr} {
270 template <
typename IntegratorContext>
276 flux_method_ =
nullptr;
281 template <
typename IntegratorContext>
283 IntegratorContext& context) {
284 flux_method_->PreAdvanceHierarchy(context);
287 template <
typename IntegratorContext>
291 return flux_method_->ComputeStableDt(context, level, dir);
294 template <
typename IntegratorContext>
297 flux_method_->ComputeNumericFluxes(context, level, dt, dir);
300 template <
typename IntegratorContext>
302 return flux_method_->GetStencilWidth();
306 template <
typename I,
typename... Args>
307 using PreAdvanceHierarchyT =
310 template <
typename IntegratorContext,
typename I>
311 struct FluxMethodWrapper : FluxMethodBase<IntegratorContext> {
312 FluxMethodWrapper(
const I& flux_method) : flux_method_{flux_method} {}
313 FluxMethodWrapper(I&& flux_method) : flux_method_{std::move(flux_method)} {}
314 std::unique_ptr<FluxMethodBase<IntegratorContext>> Clone()
const override {
315 return std::make_unique<FluxMethodWrapper>(flux_method_);
317 Duration ComputeStableDt(IntegratorContext& context,
int level,
319 return flux_method_.ComputeStableDt(context, level, dir);
321 void ComputeNumericFluxes(IntegratorContext& context,
int level,
Duration dt,
323 flux_method_.ComputeNumericFluxes(context, level, dt, dir);
325 int GetStencilWidth()
const override {
326 return flux_method_.GetStencilWidth();
329 if constexpr (is_detected<PreAdvanceHierarchyT, I&,
330 IntegratorContext&>::value) {
331 flux_method_.PreAdvanceHierarchy(context);
338 template <
typename IntegratorContext>
339 template <
typename I,
typename>
343 detail::FluxMethodWrapper<IntegratorContext, std::decay_t<I>>>(
344 std::forward<I>(flux_method))) {}
This is a polymorphic wrapper class for FluxMethod strategies used by IntegratorContext.
Definition: HyperbolicMethod.hpp:119
AnyFluxMethod(AnyFluxMethod &&other) noexcept=default
AnyFluxMethod & operator=(AnyFluxMethod &&other) noexcept=default
std::unique_ptr< detail::FluxMethodBase< IntegratorContext > > flux_method_
Definition: HyperbolicMethod.hpp:144
void ComputeNumericFluxes(IntegratorContext &context, int level, Duration dt, Direction dir)
Definition: HyperbolicMethod.hpp:295
int GetStencilWidth() const
Definition: HyperbolicMethod.hpp:301
Duration ComputeStableDt(IntegratorContext &context, int level, Direction dir)
Definition: HyperbolicMethod.hpp:289
AnyFluxMethod & operator=(const AnyFluxMethod &other)
Definition: HyperbolicMethod.hpp:272
void PreAdvanceHierarchy(IntegratorContext &context)
Definition: HyperbolicMethod.hpp:282
This is a polymorphic wrapper class for reconstruction strategies used by IntegratorContext.
Definition: HyperbolicMethod.hpp:72
AnyReconstruction(AnyReconstruction &&other) noexcept=default
std::unique_ptr< detail::ReconstructionBase< IntegratorContext > > reconstruct_
Definition: HyperbolicMethod.hpp:89
AnyReconstruction & operator=(AnyReconstruction &&other) noexcept=default
AnyReconstruction & operator=(const AnyReconstruction &other)
Definition: HyperbolicMethod.hpp:170
AnyReconstruction()=delete
void CompleteFromCons(IntegratorContext &context, int level, Duration dt)
Definition: HyperbolicMethod.hpp:181
This is a polymorphic wrapper class for TimeIntegator strategies used by IntegratorContext.
Definition: HyperbolicMethod.hpp:95
void UpdateConservatively(IntegratorContext &context, int level, Duration dt, Direction dir)
Definition: HyperbolicMethod.hpp:232
AnyTimeIntegrator()=delete
std::unique_ptr< detail::TimeIntegratorBase< IntegratorContext > > integrator_
Definition: HyperbolicMethod.hpp:113
AnyTimeIntegrator & operator=(AnyTimeIntegrator &&other) noexcept=default
AnyTimeIntegrator & operator=(const AnyTimeIntegrator &other)
Definition: HyperbolicMethod.hpp:221
AnyTimeIntegrator(AnyTimeIntegrator &&other) noexcept=default
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
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
Definition: HyperbolicMethod.hpp:150
AnyTimeIntegrator< IntegratorContext > time_integrator
Definition: HyperbolicMethod.hpp:152
AnyReconstruction< IntegratorContext > reconstruction
Definition: HyperbolicMethod.hpp:153
AnyFluxMethod< IntegratorContext > flux_method
Definition: HyperbolicMethod.hpp:151
This file adds basic type traits utilities which are not yet implemented in all standard libraries.