21 #ifndef FUB_CUTCELL_METHOD_KBN_STABILISATION_HPP
22 #define FUB_CUTCELL_METHOD_KBN_STABILISATION_HPP
54 template <
typename FM,
68 static constexpr
int Rank = Equation::Rank();
69 static constexpr std::size_t
sRank =
static_cast<std::size_t
>(
Rank);
112 const Eigen::Matrix<double, Rank, 1>& boundary_normal,
122 using FM::ComputeStableDt;
167 template <
typename FM,
typename RiemannSolver>
173 template <
typename FM,
typename RiemannSolver>
175 const RiemannSolver& rs)
176 : FM(fm), riemann_solver_(rs) {
181 template <
typename FM,
typename RiemannSolver>
185 const Equation& equation = FM::GetEquation();
186 const Eigen::Matrix<double, Rank, 1> unit = UnitVector<Rank>(
Direction::X);
188 std::array<std::ptrdiff_t, sRank> cell{is...};
190 Load(state_, states, cell);
191 if (state_.density > 0.0) {
192 const Eigen::Matrix<double, Rank, 1> normal =
195 Reflect(reflected_, state_, unit, equation);
196 riemann_solver_.SolveRiemannProblem(solution_, reflected_, state_,
199 Store(references, solution_, cell);
205 template <
typename FM,
typename RiemannSolver>
208 const Eigen::Matrix<double, Rank, 1>& boundary_normal,
Direction dir,
210 const Equation& equation = FM::GetEquation();
211 const Eigen::Matrix<double, Rank, 1> unit = UnitVector<Rank>(
Direction::X);
216 Reflect(reflected_, state, unit, equation);
217 riemann_solver_.SolveRiemannProblem(solution_, reflected_, state,
221 const int d =
static_cast<int>(dir);
222 const double u_advective =
223 reference_state.momentum[d] / reference_state.density;
224 const double u_solution = solution_.momentum[d] / solution_.density;
226 equation.Flux(flux, reference_state, dir);
227 flux.momentum[d] += solution_.pressure - reference_state.pressure;
229 u_solution * solution_.pressure - u_advective * reference_state.pressure;
232 template <
typename FM,
typename RiemannSolver>
238 FUB_ASSERT(Extents<0>(boundary_fluxes) == Extents<0>(states));
239 ForEachIndex(Box<0>(reference_states), [&](
auto... is) {
242 std::array<std::ptrdiff_t, sRank> cell{is...};
243 Load(state_, states, cell);
244 Load(reference_state_, reference_states, cell);
245 const Eigen::Matrix<double, Rank, 1> normal =
248 this->ComputeBoundaryFlux(boundary_flux_left_, state_, reference_state_,
249 normal, dir, dt, dx);
252 Store(boundary_fluxes, boundary_flux_left_, cell);
259 template <
typename FM,
typename RiemannSolver>
263 double min_dt = std::numeric_limits<double>::infinity();
264 static constexpr
int kWidth = FM::GetStencilWidth();
270 const int d =
static_cast<int>(dir);
272 std::array<View<const Complete>, StencilSize> stencil_views;
273 std::array<ArrayView, StencilSize> stencil_volumes;
274 for (std::size_t i = 0; i < StencilSize; ++i) {
277 {
static_cast<std::ptrdiff_t
>(i),
278 static_cast<std::ptrdiff_t
>(StencilSize - i) - 1});
279 stencil_volumes[i] = volumes.Subview(
281 {
static_cast<std::ptrdiff_t
>(i),
282 static_cast<std::ptrdiff_t
>(StencilSize - i) - 1}));
284 std::tuple views = std::tuple_cat(std::tuple(faces),
AsTuple(stencil_volumes),
288 std::tuple args{rest...};
289 std::array<span<const double>, StencilSize> volumes =
290 AsArray(Take<StencilSize>(args));
291 std::array states = std::apply(
292 [](
const auto&... xs)
294 return {
Begin(xs)...};
296 Drop<StencilSize>(args));
297 std::array<Array1d, StencilSize> alphas;
298 alphas.fill(Array1d::Zero());
299 Array1d betas = Array1d::Zero();
300 int n =
static_cast<int>(faces.size());
302 betas = Array1d::Map(faces.data());
303 for (std::size_t i = 0; i < StencilSize; ++i) {
304 Load(stencil_array_[i], states[i]);
305 alphas[i] = Array1d::Map(volumes[i].data());
307 Array1d dts = FM::ComputeStableDt(stencil_array_, betas, alphas, dx, dir);
308 min_dt = std::min(min_dt, dts.minCoeff());
309 for (std::size_t i = 0; i < StencilSize; ++i) {
314 n =
static_cast<int>(faces.size());
316 std::copy_n(faces.data(), n, betas.data());
318 for (std::size_t i = 0; i < StencilSize; ++i) {
319 LoadN(stencil_array_[i], states[i], n);
320 std::copy_n(volumes[i].data(), n, alphas[i].data());
323 Array1d dts = FM::ComputeStableDt(stencil_array_, betas, alphas, dx, dir);
324 min_dt = std::min(min_dt, dts.minCoeff());
329 template <
typename FM,
typename RiemannSolver>
335 static constexpr
int kWidth = FM::GetStencilWidth();
340 const int d =
static_cast<int>(dir);
341 ArrayView faces = cutcell_data.
face_fractions[d].Subview(fluxbox);
342 std::array<View<const Complete>, StencilSize> stencil_views;
343 std::array<ArrayView, StencilSize> stencil_volumes;
344 for (std::size_t i = 0; i < StencilSize; ++i) {
347 {
static_cast<std::ptrdiff_t
>(i),
348 static_cast<std::ptrdiff_t
>(StencilSize - i) - 1});
349 stencil_volumes[i] = volumes.Subview(
351 {
static_cast<std::ptrdiff_t
>(i),
352 static_cast<std::ptrdiff_t
>(StencilSize - i) - 1}));
355 std::tuple_cat(std::tuple(fluxes, faces),
AsTuple(stencil_volumes),
362 std::tuple args{rest...};
363 std::array<span<const double>, StencilSize> volumes =
364 AsArray(Take<StencilSize>(args));
365 std::array states = std::apply(
366 [](
const auto&... xs)
368 return {
Begin(xs)...};
370 Drop<StencilSize>(args));
371 std::array<Array1d, StencilSize> alphas;
372 alphas.fill(Array1d::Zero());
373 Array1d betas = Array1d::Zero();
374 int n =
static_cast<int>(get<0>(fend) - get<0>(fit));
376 betas = Array1d::Map(faces.data());
377 for (std::size_t i = 0; i < StencilSize; ++i) {
378 Load(stencil_array_[i], states[i]);
379 alphas[i] = Array1d::Map(volumes[i].data());
381 FM::ComputeNumericFlux(numeric_flux_array_, betas,
382 stencil_array_, alphas, dt, dx, dir);
383 for (
int i = 0; i < betas.size(); ++i) {
385 [&](
auto&& flux [[maybe_unused]]) {
387 (betas[i] > 0.0 && !std::isnan(flux[i])));
389 numeric_flux_array_);
391 Store(fit, numeric_flux_array_);
393 for (std::size_t i = 0; i < StencilSize; ++i) {
398 n =
static_cast<int>(get<0>(fend) - get<0>(fit));
400 std::copy_n(faces.data(), n, betas.data());
402 for (std::size_t i = 0; i < StencilSize; ++i) {
403 LoadN(stencil_array_[i], states[i], n);
404 std::copy_n(volumes[i].data(), n, alphas[i].data());
407 FM::ComputeNumericFlux(numeric_flux_array_, betas,
408 stencil_array_, alphas, dt, dx, dir);
409 StoreN(fit, numeric_flux_array_, n);
413 template <
typename FM,
typename RiemannSolver>
428 regular, boundary, geom, dt, dx, dir);
430 stabilised_fluxes, shielded_left_fluxes, shielded_right_fluxes,
431 regular_fluxes,
AsConst(boundary_fluxes));
#define FUB_ASSERT(x)
Definition: assert.hpp:39
Definition: KbnStabilisation.hpp:56
KbnCutCellMethod(const FM &fm)
Constructs a CutCell method from a given base flux method.
Definition: KbnStabilisation.hpp:168
Complete solution_
Definition: KbnStabilisation.hpp:148
double ComputeStableDt(const View< const Complete > &states, const CutCellData< Rank > &cutcell_data, double dx, Direction dir)
Definition: KbnStabilisation.hpp:260
static constexpr int StencilWidth
Definition: KbnStabilisation.hpp:70
Conservative shielded_left_flux_
Definition: KbnStabilisation.hpp:156
Complete state_
Definition: KbnStabilisation.hpp:147
void ComputeBoundaryFlux(Conservative &flux, Complete &state, const Complete &reference_state, const Eigen::Matrix< double, Rank, 1 > &boundary_normal, Direction dir, Duration dt, double dx)
This function can be used to compute a boundary flux for a given cut-cell.
Definition: KbnStabilisation.hpp:206
Conservative boundary_flux_right_
Definition: KbnStabilisation.hpp:154
Conservative boundary_flux_left_
Definition: KbnStabilisation.hpp:153
void ComputeCutCellFluxes(const View< Conservative > &stabilised_fluxes, const View< Conservative > &shielded_left_fluxes, const View< Conservative > &shielded_right_fluxes, const View< Conservative > &doubly_shielded_fluxes, const View< Conservative > &boundary_fluxes, const View< const Conservative > ®ular_fluxes, const View< const Complete > &states, const CutCellData< Rank > &cutcell_data, Duration dt, double dx, Direction dir)
Definition: KbnStabilisation.hpp:414
Complete reference_state_
Definition: KbnStabilisation.hpp:150
void ComputeBoundaryFluxes(const View< Conservative > &boundary_fluxes, const View< const Complete > &states, const View< const Complete > &reference_states, const CutCellData< Rank > &cutcell_data, Duration dt, double dx, Direction dir)
This function can be used to compute a boundary flux for all cut cells.
Definition: KbnStabilisation.hpp:233
std::array< CompleteArray, StencilSize > stencil_array_
Definition: KbnStabilisation.hpp:159
void ComputeRegularFluxes(const View< Conservative > ®ular_fluxes, const View< const Complete > &states, const CutCellData< Rank > &cutcell_data, Duration dt, double dx, Direction dir)
Definition: KbnStabilisation.hpp:330
::fub::CompleteArray< Equation > CompleteArray
Definition: KbnStabilisation.hpp:64
static constexpr std::size_t sRank
Definition: KbnStabilisation.hpp:69
::fub::Complete< Equation > Complete
Definition: KbnStabilisation.hpp:63
static constexpr int Rank
Definition: KbnStabilisation.hpp:68
std::array< Complete, StencilSize > stencil_
Definition: KbnStabilisation.hpp:146
ConservativeArray numeric_flux_array_
Definition: KbnStabilisation.hpp:160
Conservative regular_flux_
Definition: KbnStabilisation.hpp:152
static constexpr std::size_t StencilSize
Definition: KbnStabilisation.hpp:72
RiemannSolver riemann_solver_
Definition: KbnStabilisation.hpp:162
Conservative shielded_right_flux_
Definition: KbnStabilisation.hpp:155
typename FM::Equation Equation
Definition: KbnStabilisation.hpp:60
Complete reflected_
Definition: KbnStabilisation.hpp:149
void PreAdvanceHierarchy(const View< Complete > &references, const View< const Complete > &states, const CutCellData< Rank > &cutcell_data)
This function computes a reference state for each cut-cell.
Definition: KbnStabilisation.hpp:182
Conservative doubly_shielded_flux_
Definition: KbnStabilisation.hpp:157
Conservative cutcell_flux_
Definition: KbnStabilisation.hpp:151
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:81
Function ForEachIndex(const layout_left::mapping< Extents > &mapping, Function function)
Iterate through the multi-dimensional index space descibed by mapping and invoke function for each su...
Definition: ForEach.hpp:74
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
auto Shrink(const layout_left::mapping< Extent > &layout, Direction dir, std::ptrdiff_t n=1)
Definition: Equation.hpp:78
Eigen::Vector2d GetBoundaryNormal(const CutCellData< 2 > &ccdata, const std::array< std::ptrdiff_t, 2 > &index)
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
View< State > Subview(const BasicView< State, Layout, Rank > &state, const IndexBox< Rank > &box)
Definition: Equation.hpp:86
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
constexpr const int kDefaultChunkSize
Definition: Eigen.hpp:39
void StoreN(nodeduce_t< ViewPointer< Conservative< Eq >>> pointer, const ConservativeArray< Eq > &state, int n)
Definition: StateArray.hpp:416
IndexBox< Rank > Grow(const IndexBox< Rank > &box, Direction dir, const std::array< std::ptrdiff_t, 2 > &shifts)
Definition: PatchDataView.hpp:106
constexpr std::array< std::ptrdiff_t, Extents::rank()> AsArray(Extents e) noexcept
Definition: PatchDataView.hpp:154
void ForEachRow(const Tuple &views, Function f)
Definition: StateRow.hpp:172
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
ViewPointer< State > Begin(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:769
void LoadN(CompleteArray< Eq, N > &state, const BasicView< const Complete< Eq >, Layout, Rank > &view, int size, nodeduce_t< const std::array< std::ptrdiff_t, std::size_t(Rank)> & > pos)
Definition: StateArray.hpp:310
void Rotate(Conservative< IdealGasMix< 2 >> &rotated, const Conservative< IdealGasMix< 2 >> &state, const Eigen::Matrix< double, 2, 2 > &rotation, const IdealGasMix< 2 > &)
Defines how to rotate a given state of the euler equations.
bool IsCutCell(const CutCellData< 2 > &geom, const std::array< std::ptrdiff_t, 2 > &index)
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
void Advance(ViewPointer< State > &pointer, std::ptrdiff_t n) noexcept
Definition: State.hpp:825
constexpr auto AsTuple(const TupleLike &t)
Definition: tuple.hpp:69
Eigen::Matrix< double, 2, 2 > MakeRotation(const Eigen::Matrix< double, 2, 1 > &a, const Eigen::Matrix< double, 2, 1 > &b)
Definition: Eigen.hpp:103
void ComputeStableFluxComponents(const PatchDataView< double, 2, layout_stride > &stabilised_fluxes, const PatchDataView< double, 2, layout_stride > &shielded_left_fluxes, const PatchDataView< double, 2, layout_stride > &shielded_right_fluxes, const PatchDataView< const double, 2, layout_stride > ®ular_fluxes, const PatchDataView< const double, 2, layout_stride > &boundary_fluxes, const CutCellData< 2 > &geom, Duration dt, double dx, Direction dir)
void Reflect(Complete< IdealGasMix< 1 >> &reflected, const Complete< IdealGasMix< 1 >> &state, const Eigen::Matrix< double, 1, 1 > &normal, const IdealGasMix< 1 > &gas)
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
ViewPointer< State > End(const BasicView< State, Layout, Rank > &view)
Definition: State.hpp:782
void ForEachComponent(F function, Ts &&... states)
Definition: State.hpp:624
BasicView< const State, Layout, Rank > AsConst(const BasicView< State, Layout, Rank > &v)
Definition: State.hpp:431
Definition: State.hpp:403
Definition: CutCellData.hpp:34
PatchDataView< const double, Rank > volume_fractions
Definition: CutCellData.hpp:38
std::array< PatchDataView< const double, Rank >, sRank > face_fractions
Definition: CutCellData.hpp:40
Definition: PatchDataView.hpp:56
Definition: PatchDataView.hpp:201
PatchDataView< T, R, layout_stride > Subview(const IndexBox< R > &box) const
Definition: PatchDataView.hpp:245
Definition: StateRow.hpp:51
Definition: State.hpp:750