21 #ifndef FUB_AMREX_CUTCELL_FLUX_METHOD_HPP
22 #define FUB_AMREX_CUTCELL_FLUX_METHOD_HPP
33 #include <AMReX_EBAmrUtil.H>
39 inline ::amrex::Vector<std::string>
40 AddPrefix(const ::amrex::Vector<std::string>& names,
41 const std::string& prefix) {
42 ::amrex::Vector<std::string> new_names{};
43 new_names.reserve(names.size());
44 for (
const std::string& name : names) {
45 new_names.push_back(fmt::format(
"{}_{}", prefix, name));
50 template <
typename Tag,
typename Base>
class FluxMethod {
61 const Base&
GetBase() const noexcept;
78 template <typename Tag, typename FM>
81 template <typename Tag, typename FM>
85 template <
typename Tag,
typename FM>
89 template <
typename Tag,
typename FM>
91 return FM::GetStencilWidth();
94 template <
typename Tag,
typename FM>
99 template <
typename Tag,
typename FM>
101 if constexpr (
is_detected<detail::PreAdvanceHierarchyT, FM&,
109 ForEachFab(Tag(), references, [&](const ::amrex::MFIter& mfi) {
110 if (context.
GetFabType(level, mfi) == ::amrex::FabType::singlevalued) {
111 const Equation& eq = flux_method_->GetEquation();
112 const ::amrex::Box box = mfi.growntilebox();
113 View<Complete<Equation>> refs =
114 MakeView<Complete<Equation>>(references[mfi], eq, box);
115 View<const Complete<Equation>> states =
116 MakeView<const Complete<Equation>>(references[mfi], eq, box);
117 CutCellData<AMREX_SPACEDIM> geom =
118 hierarchy.GetCutCellData(level, mfi);
119 flux_method_->PreAdvanceHierarchy(refs, states, geom);
127 template <
typename T,
typename... Args>
128 using ComputeBoundaryFluxesT =
129 decltype(std::declval<T>().ComputeBoundaryFluxes(std::declval<Args>()...));
131 template <
typename T,
typename... Args>
132 using ComputeCutCellFluxes =
133 decltype(std::declval<T>().ComputeCutCellFluxes(std::declval<Args>()...));
135 template <
typename T,
typename... Args>
136 using ComputeGradients =
137 decltype(std::declval<T>().ComputeGradients(std::declval<Args>()...));
140 template <
typename Tag,
typename FM>
146 const ::amrex::MultiFab& scratch = context.
GetScratch(level);
149 ::amrex::MultiFab& fluxes = context.
GetFluxes(level, dir);
155 [[maybe_unused]] ::amrex::MultiFab gradient_x;
156 [[maybe_unused]] ::amrex::MultiFab gradient_y;
157 [[maybe_unused]] ::amrex::MultiFab gradient_z;
159 const double dx = context.
GetDx(level, dir);
160 const Eigen::Matrix<double, AMREX_SPACEDIM, 1> dx_vec{AMREX_D_DECL(
164 boundary_fluxes.setVal(0.0);
165 if constexpr (
is_detected<detail::ComputeBoundaryFluxesT, FM&,
171 ForEachFab(Tag(), scratch, [&](const ::amrex::MFIter& mfi) {
172 const Equation& equation = flux_method_->GetEquation();
174 const ::amrex::FabType type = context.
GetFabType(level, mfi);
175 if (type == ::amrex::FabType::singlevalued) {
177 auto boundary_flux = MakeView<Conservative<Equation>>(
178 boundary_fluxes[mfi], equation, box);
180 MakeView<const Complete<Equation>>(scratch[mfi], equation, box);
182 MakeView<const Complete<Equation>>(references[mfi], equation, box);
183 flux_method_->ComputeBoundaryFluxes(boundary_flux, states, refs, geom,
195 Eigen::Matrix<double, AMREX_SPACEDIM, 1>>::value) {
196 const ::amrex::BoxArray ba = scratch.boxArray();
197 const ::amrex::DistributionMapping dm = scratch.DistributionMap();
198 const int ncons = fluxes.nComp();
199 const ::amrex::IntVect ngrow = scratch.nGrowVect();
200 gradient_x.define(ba, dm, ncons, ngrow);
201 gradient_y.define(ba, dm, ncons, ngrow);
202 gradient_z.define(ba, dm, ncons, ngrow);
203 ::amrex::TagBoxArray limiter_flags(ba, dm, ngrow);
204 ::amrex::TagCutCells(limiter_flags, context.
GetData(level));
207 ForEachFab(Tag(), scratch, [&](const ::amrex::MFIter& mfi) {
209 const ::amrex::FabType type = context.
GetFabType(level, mfi);
210 if (type == ::amrex::FabType::singlevalued) {
213 const Equation& equation = flux_method_->GetEquation();
215 MakeView<const Conservative<Equation>>(scratch[mfi], equation, box);
217 MakeView<Conservative<Equation>>(gradient_x[mfi], equation, box);
219 MakeView<Conservative<Equation>>(gradient_y[mfi], equation, box);
221 MakeView<Conservative<Equation>>(gradient_z[mfi], equation, box);
222 flux_method_->ComputeGradients(grad_x, grad_y, grad_z, states, flags,
228 const ::amrex::Geometry& geom = hierarchy.
GetGeometry(level);
229 const Equation& equation = flux_method_->GetEquation();
231 VarNames<Conservative<Equation>, ::amrex::Vector<std::string>>(
234 debug.AddSnapshot(fmt::format(
"Gradients_{}",
int(dir)));
236 snapshot.SaveData(gradient_y,
AddPrefix(names,
"GradY_"), geom);
237 snapshot.SaveData(gradient_z,
AddPrefix(names,
"GradZ_"), geom);
240 static constexpr
int gcw = GetStencilWidth();
242 ForEachFab(Tag(), fluxes, [&](const ::amrex::MFIter& mfi) {
243 const Equation& equation = flux_method_->GetEquation();
246 auto [cell_box, face_box] =
248 const ::amrex::FabType type = context.
GetFabType(level, mfi);
249 if (type == ::amrex::FabType::singlevalued) {
253 MakeView<Conservative<Equation>>(fluxes[mfi], equation, face_box);
254 auto states = MakeView<const Complete<Equation>>(scratch[mfi], equation,
256 flux_method_->ComputeRegularFluxes(flux, states, geom, dt, dx, dir);
259 MakeView<Conservative<Equation>>(fluxes_s[mfi], equation, face_box);
261 MakeView<Conservative<Equation>>(fluxes_sL[mfi], equation, face_box);
263 MakeView<Conservative<Equation>>(fluxes_sR[mfi], equation, face_box);
265 MakeView<Conservative<Equation>>(fluxes_ds[mfi], equation, face_box);
266 auto flux_B = MakeView<Conservative<Equation>>(boundary_fluxes[mfi],
269 MakeView<const Complete<Equation>>(scratch[mfi], equation, cell_box);
270 if constexpr (
is_detected<detail::ComputeCutCellFluxes, FM&,
282 Eigen::Matrix<double, AMREX_SPACEDIM, 1>,
285 MakeView<Conservative<Equation>>(fluxes[mfi], equation, face_box);
286 auto grad_x = MakeView<const Conservative<Equation>>(
287 gradient_x[mfi], equation, cell_box);
288 auto grad_y = MakeView<const Conservative<Equation>>(
289 gradient_y[mfi], equation, cell_box);
290 auto grad_z = MakeView<const Conservative<Equation>>(
291 gradient_z[mfi], equation, cell_box);
292 flux_method_->ComputeCutCellFluxes(flux_s, flux_sL, flux_sR, flux_ds,
293 flux, flux_B, grad_x, grad_y, grad_z,
294 states, geom, dt, dx_vec, dir);
296 auto flux = MakeView<const Conservative<Equation>>(fluxes[mfi],
298 flux_method_->ComputeCutCellFluxes(flux_s, flux_sL, flux_sR, flux_ds,
299 flux_B, flux, states, geom, dt, dx,
302 }
else if (type == ::amrex::FabType::regular) {
304 MakeView<Conservative<Equation>>(fluxes[mfi], equation, face_box);
306 MakeView<const Complete<Equation>>(scratch[mfi], equation, cell_box);
307 flux_method_->ComputeNumericFluxes(Tag(), flux, states, dt, dx, dir);
312 const ::amrex::Geometry& geom = hierarchy.
GetGeometry(level);
313 const Equation& equation = flux_method_->GetEquation();
315 VarNames<Conservative<Equation>, ::amrex::Vector<std::string>>(
318 debug.AddSnapshot(fmt::format(
"Fluxes_{}",
int(dir)));
320 snapshot.SaveData(fluxes_s,
AddPrefix(names,
"StableFlux_"), geom);
321 snapshot.SaveData(fluxes_sL,
AddPrefix(names,
"ShieldedFromLeftFlux_"), geom);
322 snapshot.SaveData(fluxes_sR,
AddPrefix(names,
"ShieldedFromRightFlux_"),
324 snapshot.SaveData(boundary_fluxes.ToMultiFab(0.0, 0.0),
325 AddPrefix(names,
"BoundaryFlux_"), geom);
328 template <
typename Tag,
typename FM>
331 const ::amrex::MultiFab& scratch = context.
GetScratch(level);
332 const ::amrex::MultiFab& fluxes = context.
GetFluxes(level, dir);
333 const double dx = context.
GetDx(level, dir);
335 Duration(std::numeric_limits<double>::infinity())};
337 static constexpr
int gcw = GetStencilWidth();
339 ForEachFab(Tag(), fluxes, [&](const ::amrex::MFIter& mfi) {
340 const Equation& equation = flux_method_->GetEquation();
343 auto [cell_box, face_box] =
346 MakeView<const Complete<Equation>>(scratch[mfi], equation, cell_box);
347 const ::amrex::FabType type = context.
GetFabType(level, mfi);
348 if (type == ::amrex::FabType::singlevalued) {
351 *min_dt = std::min(*min_dt,
Duration(flux_method_->ComputeStableDt(
352 states, geom, dx, dir)));
353 }
else if (type == ::amrex::FabType::regular) {
354 *min_dt = std::min(*min_dt,
Duration(flux_method_->ComputeStableDt(
355 Tag(), states, dx, dir)));
static constexpr int GetStencilWidth() noexcept
Returns the stencil width of this flux method.
Definition: flux_method/FluxMethod.hpp:183
double ComputeStableDt(const View< const Complete > &states, double dx, Direction dir)
This function computes a time step size such that no signal will leave any cell covered by this view.
Definition: flux_method/FluxMethod.hpp:318
void ComputeNumericFluxes(const View< Conservative > &fluxes, const View< const Complete > &states, Duration dt, double dx, Direction dir)
This function computes numerical fluxes.
Definition: flux_method/FluxMethod.hpp:218
This class is a possibly empty handle to a existing DebugSnapshotProxy.
Definition: output/DebugOutput.hpp:132
void SaveData(const ::amrex::MultiFab &mf, const std::string &name, const ::amrex::Geometry &geom, ::amrex::SrcComp component=::amrex::SrcComp(0))
Saves a current hierarchy state with given component names.
This class stores a list of snapshots and returns proxy objects to those.
Definition: output/DebugOutput.hpp:201
Definition: AMReX/cutcell/FluxMethod.hpp:50
FluxMethod(Tag, Base &&fm)
void ComputeNumericFluxes(IntegratorContext &context, int level, Duration dt, Direction dir)
Definition: AMReX/cutcell/FluxMethod.hpp:141
void PreAdvanceHierarchy(IntegratorContext &context)
Definition: AMReX/cutcell/FluxMethod.hpp:100
FluxMethod(Tag, const Base &fm)
FluxMethod(Base &&fm)
Definition: AMReX/cutcell/FluxMethod.hpp:54
FluxMethod(const Base &fm)
Definition: AMReX/cutcell/FluxMethod.hpp:55
Local< Tag, Base > flux_method_
Definition: AMReX/cutcell/FluxMethod.hpp:72
const Base & GetBase() const noexcept
Definition: AMReX/cutcell/FluxMethod.hpp:95
typename Base::Equation Equation
Definition: AMReX/cutcell/FluxMethod.hpp:52
static constexpr int GetStencilWidth() noexcept
Definition: AMReX/cutcell/FluxMethod.hpp:90
Duration ComputeStableDt(IntegratorContext &context, int level, Direction dir)
Definition: AMReX/cutcell/FluxMethod.hpp:329
This class manages data and the numerical method to perform cut cell simulations with the AMReX libra...
Definition: AMReX/cutcell/IntegratorContext.hpp:46
::amrex::MultiFab & GetShieldedFromRightFluxes(int level, Direction dir)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::MultiFab & GetScratch(int level)
Returns the MultiFab associated with level data with ghost cells on the specifed level number and dir...
::amrex::MultiCutFab & GetBoundaryFluxes(int level)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::MultiFab & GetFluxes(int level, Direction dir)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::MultiFab & GetData(int level)
Returns the MultiFab associated with level data on the specifed level number.
const PatchHierarchy & GetPatchHierarchy() const noexcept
Returns a reference to const PatchHierarchy which is a member of the GriddingAlgorithm.
::amrex::MultiFab & GetShieldedFromLeftFluxes(int level, Direction dir)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::MultiFab & GetDoublyShieldedFluxes(int level, Direction dir)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::MultiFab & GetReferenceStates(int level)
Returns the MultiFab associated with flux data on the specifed level number and direction.
::amrex::FabType GetFabType(int level, const ::amrex::MFIter &mfi) const noexcept
Returns the refinement ratio in the specified direction.
double GetDx(int level, Direction dir) const noexcept
Returns the refinement ratio in the specified direction.
::amrex::MultiFab & GetStabilizedFluxes(int level, Direction dir)
Returns the MultiFab associated with flux data on the specifed level number and direction.
const std::shared_ptr< GriddingAlgorithm > & GetGriddingAlgorithm() const noexcept
Returns a shared pointer to the underlying GriddingAlgorithm which owns the simulation.
Definition: AMReX/cutcell/PatchHierarchy.hpp:139
const std::shared_ptr< DebugStorage > & GetDebugStorage() const noexcept
Returns a shared pointer to the debug storage.
CutCellData< AMREX_SPACEDIM > GetCutCellData(int level, const ::amrex::MFIter &mfi) const
Returns the number of cycles done for a specific level.
int GetNumberOfLevels() const noexcept
const ::amrex::Geometry & GetGeometry(int level) const
Returns the number of cycles done for a specific level.
Definition: AMReX/cutcell/tagging_method/TagBuffer.hpp:29
void TagCellsForRefinement(::amrex::TagBoxArray &tags, const GriddingAlgorithm &gridding, int level, Duration time_point) const noexcept
void ForEachFab(Tag, const ::amrex::FabArrayBase &fabarray, F function)
Iterate through all local FArrayBox objects in a MultiFab.
Definition: ForEachFab.hpp:34
Definition: FillCutCellData.hpp:30
inline ::amrex::Vector< std::string > AddPrefix(const ::amrex::Vector< std::string > &names, const std::string &prefix)
Definition: AMReX/cutcell/FluxMethod.hpp:40
std::array<::amrex::Box, 2 > GetCellsAndFacesInStencilRange(const ::amrex::Box &cell_tilebox, const ::amrex::Box &face_validbox, int stencil_width, Direction dir)
PatchDataView< T, AMREX_SPACEDIM+1 > MakePatchDataView(::amrex::BaseFab< T > &fab)
Definition: ViewFArrayBox.hpp:86
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
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
typename detail::LocalType< Tag, T >::type Local
Definition: Execution.hpp:56
const T & Min(const std::optional< T > &x)
Definition: Execution.hpp:58
Definition: State.hpp:403
Definition: CutCellData.hpp:34
Definition: PatchDataView.hpp:201
This is std::true_type if Op<Args...> is a valid SFINAE expression.
Definition: type_traits.hpp:92