22 #ifndef FUB_AMREX_BOUNDARY_CONDITION_ISENTROPIC_PRESSURE_EXPANSION_HPP
23 #define FUB_AMREX_BOUNDARY_CONDITION_ISENTROPIC_PRESSURE_EXPANSION_HPP
30 inline std::array<std::ptrdiff_t, 1>
31 MapToSrc(
const std::array<std::ptrdiff_t, 1>& dest,
32 const ::amrex::Geometry& geom,
int side,
Direction dir) {
33 const int boundary = (side == 0) * geom.Domain().smallEnd(
int(dir)) +
34 (side == 1) * geom.Domain().bigEnd(
int(dir));
35 const auto distance = dest[std::size_t(dir)] - boundary;
36 const int sign = int((distance > 0) - (distance < 0));
37 std::array<std::ptrdiff_t, 1> src{dest};
38 src[std::size_t(dir)] -=
static_cast<int>(2 * distance - sign);
61 void FillBoundary(::amrex::MultiFab& mf, const ::amrex::Geometry& geom);
70 template <
typename EulerEquation>
76 static constexpr
int N = EulerEquation::Rank();
79 dest.energy = src.energy - rhoE_kin;
80 const double h_before = (dest.energy + dest.pressure) / dest.density;
82 const double h_after = (dest.energy + dest.pressure) / dest.density;
83 const double h_diff = h_after - h_before;
84 const double e_kin_new =
85 2.0 * (1.0 - efficiency) * h_diff + old_velocity.matrix().squaredNorm();
88 std::sqrt(e_kin_new) * old_velocity.matrix().normalized();
89 dest.momentum = dest.density * u_border;
93 template <
typename EulerEquation>
96 : equation_{eq}, outer_pressure_{options.outer_pressure},
97 dir_{options.direction}, side_{options.side} {}
99 template <
typename EulerEquation>
101 const EulerEquation& eq,
double outer_pressure,
Direction dir,
int side)
102 : equation_{eq}, outer_pressure_{outer_pressure}, dir_{dir}, side_{side} {}
104 template <
typename EulerEquation>
110 template <
typename EulerEquation>
115 FillBoundary(mf, gridding, level);
119 template <
typename EulerEquation>
121 ::amrex::MultiFab& mf, const ::amrex::Geometry& geom) {
122 const int ngrow = mf.nGrow(
int(dir_));
123 ::amrex::Box grown_box = geom.growNonPeriodicDomain(ngrow);
124 ::amrex::BoxList boundaries =
125 ::amrex::complementIn(grown_box, ::amrex::BoxList{geom.Domain()});
128 if (boundaries.isEmpty()) {
132 ::amrex::FArrayBox& fab = mf[mfi];
135 ::amrex::shift(boundary,
int(dir_),
GetSign(side_) * ngrow);
136 if (!geom.Domain().intersects(shifted)) {
139 ::amrex::Box box_to_fill = mfi.growntilebox() & boundary;
140 if (!box_to_fill.isEmpty()) {
141 auto states = MakeView<Complete<EulerEquation>>(fab, equation_,
145 Index<EulerEquation::Rank()> dest{is...};
146 Index<EulerEquation::Rank()> src =
148 Load(state, states, src);
149 ExpandState(equation_, expanded, state, outer_pressure_, 1.0);
150 Store(states, expanded, dest);
#define FUB_ASSERT(x)
Definition: assert.hpp:39
This class modifies and initializes a PatchLevel in a PatchHierarchy.
Definition: AMReX/GriddingAlgorithm.hpp:60
PatchHierarchy & GetPatchHierarchy() noexcept
Definition: AMReX/GriddingAlgorithm.hpp:108
This boundary models an isentropic pressure expansion for the one-dimensional ideal gas equations for...
Definition: boundary_condition/IsentropicPressureExpansion.hpp:47
void FillBoundary(::amrex::MultiFab &mf, const GriddingAlgorithm &gridding, int level)
Definition: boundary_condition/IsentropicPressureExpansion.hpp:105
int side_
Definition: boundary_condition/IsentropicPressureExpansion.hpp:67
IsentropicPressureExpansion(const EulerEquation &eq, const IsentropicPressureBoundaryOptions &options)
Definition: boundary_condition/IsentropicPressureExpansion.hpp:94
Direction dir_
Definition: boundary_condition/IsentropicPressureExpansion.hpp:66
double outer_pressure_
Definition: boundary_condition/IsentropicPressureExpansion.hpp:65
EulerEquation equation_
Definition: boundary_condition/IsentropicPressureExpansion.hpp:64
const ::amrex::Geometry & GetGeometry(int level) const
Returns a Geometry object for a specified level.
void ForEachFab(Tag, const ::amrex::FabArrayBase &fabarray, F function)
Iterate through all local FArrayBox objects in a MultiFab.
Definition: ForEachFab.hpp:34
The amrex namespace.
Definition: AverageState.hpp:33
void ExpandState(EulerEquation &eq, Complete< EulerEquation > &dest, const Complete< EulerEquation > &src, double pressure_dest, double efficiency)
Definition: boundary_condition/IsentropicPressureExpansion.hpp:71
void ForEachIndex(const ::amrex::Box &box, F function)
Definition: ForEachIndex.hpp:29
IndexBox< Rank > AsIndexBox(const ::amrex::Box &box)
Definition: ViewFArrayBox.hpp:51
std::array< std::ptrdiff_t, 1 > MapToSrc(const std::array< std::ptrdiff_t, 1 > &dest, const ::amrex::Geometry &geom, int side, Direction dir)
Definition: boundary_condition/IsentropicPressureExpansion.hpp:31
double KineticEnergy(double density, const Eigen::Array< double, Dim, 1 > &momentum) noexcept
Definition: EulerEquation.hpp:28
constexpr struct fub::euler::SetIsentropicPressureFn SetIsentropicPressure
constexpr struct fub::euler::VelocityFn Velocity
constexpr SequentialTag seq
Definition: Execution.hpp:31
std::conditional_t< N==1||M==1, Eigen::Array< T, N, M >, Eigen::Array< T, N, M, Eigen::RowMajor > > Array
Definition: Eigen.hpp:50
void Load(State &state, const BasicView< const State, Layout, Rank > &view, const std::array< std::ptrdiff_t, State::Equation::Rank()> &index)
Definition: State.hpp:640
int GetSign(int side)
Definition: AnyBoundaryCondition.hpp:104
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
std::array< std::ptrdiff_t, static_cast< std::size_t >(Rank)> Index
Definition: PatchDataView.hpp:34
void Store(const BasicView< Conservative< Eq >, Layout, Eq::Rank()> &view, const Conservative< Eq > &state, const std::array< std::ptrdiff_t, Eq::Rank()> &index)
Definition: State.hpp:663
IndexBox< Rank > Box(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:486
Definition: boundary_condition/IsentropicPressureBoundary.hpp:38