21 #ifndef FUB_IDEAL_GAS_FLUX_METHOD_MUSCL_HANCOCK_METHOD
22 #define FUB_IDEAL_GAS_FLUX_METHOD_MUSCL_HANCOCK_METHOD
32 template <
typename Equation>
36 [](
double& cons,
double qL,
double qM,
double qR) {
37 const double sL = qM - qL;
38 const double sR = qR - qM;
39 cons = 0.5 * (sL + sR);
44 template <
typename Equation,
int N>
48 [](
auto&& cons,
auto qL,
auto qM,
auto qR) {
51 cons = 0.5 * (sL + sR);
56 template <
typename Equation,
int N>
61 [=](
auto&& cons,
auto qL,
auto qM,
auto qR) {
65 cons = 0.5 * (sL + sR);
72 template <
typename Equation>
78 template <
typename Equation,
int N>
84 template <
typename Equation,
int N>
93 template <
typename Equation>
97 [](
double& cons,
double qL,
double qM,
double qR) {
98 const double sL = qM - qL;
99 const double sR = qR - qM;
101 cons = std::max(0.0, std::min(sL, sR));
103 cons = std::min(0.0, std::max(sL, sR));
109 template <
typename Equation,
int N>
113 [](
auto&& cons,
auto qL,
auto qM,
auto qR) {
117 cons = (sR > 0).select(zero.max(sL.min(sR)), zero.min(sL.max(sR)));
122 template <
typename Equation,
int N>
127 [=](
auto&& cons,
auto qL,
auto qM,
auto qR) {
131 cons = (sR > 0).select(zero.max(sL.min(sR)), zero.min(sL.max(sR)));
139 double c = 2.0 * sL * sR;
140 return (c > 0.0) ? c / (sL + sR) : 0.0;
146 Array1d result = (r > 0.0).select(r / (sL + sR), 0.0);
151 template <
typename Equation>
155 [
this](
double& cons,
double qL,
double qM,
double qR) {
156 const double sL = qM - qL;
157 const double sR = qR - qM;
163 template <
typename Equation>
168 [
this, mask](
auto&& cons,
auto qL,
auto qM,
auto qR) {
169 const Array1d sL = mask.select(qM - qL, 0.0);
170 const Array1d sR = mask.select(qR - qM, 0.0);
176 template <
typename Equation>
180 [
this](
auto&& cons,
auto qL,
auto qM,
auto qR) {
189 template <
typename EquationT,
190 typename BaseMethod =
191 GodunovMethod<EquationT, ExactRiemannSolver<EquationT>>,
192 typename SlopeLimiter = MinMod>
210 return flux_method_.ComputeStableDt(states.template subspan<1, 2>(), dx,
216 return flux_method_.ComputeStableDt(states.template subspan<1, 2>(), dx,
225 states.template subspan<1, 2>(), face_fraction,
226 volume_fraction.template subspan<1, 2>(), dx, dir);
279 typename BaseMethod =
281 typename Slope = MinMod>
283 :
FluxMethod<MusclHancock<Equation, BaseMethod, Slope>> {
287 template <
typename Equation>
290 template <
typename Equation,
typename Method>
294 template <
typename Equation,
typename Method,
typename SlopeLimiter>
298 const double lambda_half = 0.5 * dt.count() / dx;
303 slope_limiter_.ComputeLimitedSlope(slope_, stencil.template first<3>());
306 [](
double& qL,
double& qR,
double state,
double slope) {
307 qL = state - 0.5 * slope;
308 qR = state + 0.5 * slope;
315 Flux(equation_, flux_left_, q_left_, dir);
316 Flux(equation_, flux_right_, q_right_, dir);
319 [&lambda_half](
double& rec,
double qR,
double fL,
double fR) {
320 rec = qR + lambda_half * (fL - fR);
322 AsCons(rec_[0]),
AsCons(q_right_), flux_left_, flux_right_);
329 slope_limiter_.ComputeLimitedSlope(slope_, stencil.template last<3>());
332 [](
double& qL,
double& qR,
double state,
double slope) {
333 qL = state - 0.5 * slope;
334 qR = state + 0.5 * slope;
341 Flux(equation_, flux_left_, q_left_, dir);
342 Flux(equation_, flux_right_, q_right_, dir);
345 [&lambda_half](
double& rec,
double qL,
double fL,
double fR) {
346 rec = qL + lambda_half * (fL - fR);
348 AsCons(rec_[1]),
AsCons(q_left_), flux_left_, flux_right_);
355 flux_method_.ComputeNumericFlux(flux,
span{rec_}, dt, dx, dir);
358 template <
typename Equation,
typename Method,
typename SlopeLimiter>
363 const double lambda_half = 0.5 * dt.count() / dx;
369 [dx](
double& qL,
double& qR,
double state,
double slope) {
370 qL = state - 0.5 * slope * dx;
371 qR = state + 0.5 * slope * dx;
378 Flux(equation_, flux_left_, q_left_, dir);
379 Flux(equation_, flux_right_, q_right_, dir);
382 [&lambda_half](
double& rec,
double qR,
double fL,
double fR) {
383 rec = qR + lambda_half * (fL - fR);
385 AsCons(rec_[0]),
AsCons(q_right_), flux_left_, flux_right_);
393 [dx](
double& qL,
double& qR,
double state,
double slope) {
394 qL = state - 0.5 * slope * dx;
395 qR = state + 0.5 * slope * dx;
402 Flux(equation_, flux_left_, q_left_, dir);
403 Flux(equation_, flux_right_, q_right_, dir);
406 [&lambda_half](
double& rec,
double qL,
double fL,
double fR) {
407 rec = qL + lambda_half * (fL - fR);
409 AsCons(rec_[1]),
AsCons(q_left_), flux_left_, flux_right_);
416 flux_method_.ComputeNumericFlux(flux,
span{rec_}, dt, dx, dir);
419 template <
typename Equation,
typename Method,
typename SlopeLimiter>
423 const Array1d lambda_half = Array1d::Constant(0.5 * dt.count() / dx);
428 slope_limiter_.ComputeLimitedSlope(slope_arr_, stencil.template first<3>());
431 [](
auto&& qL,
auto&& qR,
const auto& state,
const auto& slope) {
432 qL = state - 0.5 * slope;
433 qR = state + 0.5 * slope;
441 Flux(equation_, flux_left_arr_, q_left_arr_, dir);
442 Flux(equation_, flux_right_arr_, q_right_arr_, dir);
445 [&lambda_half](
auto&& rec,
auto qR,
auto fL,
auto fR) {
446 rec = qR + lambda_half * (fL - fR);
448 AsCons(rec_arr_[0]),
AsCons(q_right_arr_), flux_left_arr_,
456 slope_limiter_.ComputeLimitedSlope(slope_arr_, stencil.template last<3>());
459 [](
auto&& qL,
auto&& qR,
const auto& state,
const auto& slope) {
460 qL = state - 0.5 * slope;
461 qR = state + 0.5 * slope;
469 Flux(equation_, flux_left_arr_, q_left_arr_, dir);
470 Flux(equation_, flux_right_arr_, q_right_arr_, dir);
473 [&lambda_half](
auto&& rec,
auto qL,
auto fL,
auto fR) {
474 rec = qL + lambda_half * (fL - fR);
476 AsCons(rec_arr_[1]),
AsCons(q_left_arr_), flux_left_arr_,
484 flux_method_.ComputeNumericFlux(flux,
span{rec_arr_}, dt, dx, dir);
487 template <
typename Equation,
typename Method,
typename SlopeLimiter>
492 MaskArray valid_face = face_fractions > 0.0;
493 if (valid_face.any()) {
494 const Array1d lambda_half = Array1d::Constant(0.5 * dt.count() / dx);
499 MaskArray left_slope_mask = volume_fractions[0] > 0.0 &&
500 volume_fractions[1] > 0.0 &&
501 volume_fractions[2] > 0.0;
502 slope_limiter_.ComputeLimitedSlope(slope_arr_, stencil.template first<3>(),
506 [=](
auto&& qL,
auto&& qR,
const auto& state,
const auto& slope) {
507 Array1d q0 = valid_face.select(state, 0.0);
508 qL = q0 - 0.5 * slope;
509 qR = q0 + 0.5 * slope;
517 Flux(equation_, flux_left_arr_, q_left_arr_, valid_face, dir);
518 Flux(equation_, flux_right_arr_, q_right_arr_, valid_face, dir);
521 [&lambda_half](
auto&& rec,
auto qR,
auto fL,
auto fR) {
522 rec = qR + lambda_half * (fL - fR);
524 AsCons(rec_arr_[0]),
AsCons(q_right_arr_), flux_left_arr_,
532 MaskArray right_slope_mask = volume_fractions[1] > 0.0 &&
533 volume_fractions[2] > 0.0 &&
534 volume_fractions[3] > 0.0;
535 slope_limiter_.ComputeLimitedSlope(slope_arr_, stencil.template last<3>(),
539 [=](
auto&& qL,
auto&& qR,
const auto& state,
const auto& slope) {
540 Array1d q0 = valid_face.select(state, 0.0);
541 qL = q0 - 0.5 * slope;
542 qR = q0 + 0.5 * slope;
550 Flux(equation_, flux_left_arr_, q_left_arr_, valid_face, dir);
551 Flux(equation_, flux_right_arr_, q_right_arr_, valid_face, dir);
554 [&lambda_half](
auto&& rec,
auto qL,
auto fL,
auto fR) {
555 rec = qL + lambda_half * (fL - fR);
557 AsCons(rec_arr_[1]),
AsCons(q_left_arr_), flux_left_arr_,
565 flux_method_.ComputeNumericFlux(flux, face_fractions,
span{rec_arr_},
566 volume_fractions.template subspan<1, 2>(),
This class applies a base flux nethod on a view of states.
Definition: flux_method/FluxMethod.hpp:57
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
void CompleteFromCons(Equation &&equation, Complete< std::decay_t< Equation >> &complete, const Conservative< std::decay_t< Equation >> &cons)
Definition: CompleteFromCons.hpp:42
FluxMethod(F &&) -> FluxMethod< execution::OpenMpSimdTag, std::decay_t< F >>
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
void Flux(Eq &&equation, Conservative< Equation > &flux, const Complete< Equation > &state, Direction dir, [[maybe_unused]] double x=0.0)
Definition: Equation.hpp:108
std::conditional_t< N==1||M==1, Eigen::Array< T, N, M >, Eigen::Array< T, N, M, Eigen::RowMajor > > Array
Definition: Eigen.hpp:50
MusclHancockMethod(const Equation &) -> MusclHancockMethod< Equation >
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
Array< double, 1 > Array1d
Definition: Eigen.hpp:53
Direction
This is a type safe type to denote a dimensional split direction.
Definition: Direction.hpp:30
const Conservative< Eq > & AsCons(const Conservative< Eq > &x)
Definition: State.hpp:438
void ForEachComponent(F function, Ts &&... states)
Definition: State.hpp:624
Array< bool, 1 > MaskArray
Definition: Eigen.hpp:59
Definition: StateArray.hpp:178
Definition: StateArray.hpp:135
Definition: flux_method/GodunovMethod.hpp:93
Definition: flux_method/MusclHancockMethod.hpp:92
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:110
void ComputeLimitedSlope(Conservative< Equation > &cons, span< const Complete< Equation >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:94
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 > stencil, MaskArray mask)
Definition: flux_method/MusclHancockMethod.hpp:123
Definition: flux_method/MusclHancockMethod.hpp:283
Definition: flux_method/MusclHancockMethod.hpp:193
Array1d ComputeStableDt(span< const CompleteArray, 4 > states, Array1d face_fraction, span< const Array1d, 4 > volume_fraction, double dx, Direction dir)
Definition: flux_method/MusclHancockMethod.hpp:220
CompleteArray q_right_arr_
Definition: flux_method/MusclHancockMethod.hpp:273
EquationT Equation
Definition: flux_method/MusclHancockMethod.hpp:194
typename Equation::Complete Complete
Definition: flux_method/MusclHancockMethod.hpp:195
Equation equation_
Definition: flux_method/MusclHancockMethod.hpp:250
Array1d ComputeStableDt(span< const CompleteArray, 4 > states, double dx, Direction dir) noexcept
Definition: flux_method/MusclHancockMethod.hpp:214
Conservative flux_left_
Definition: flux_method/MusclHancockMethod.hpp:258
Equation & GetEquation() noexcept
Definition: flux_method/MusclHancockMethod.hpp:246
std::array< Complete, 2 > rec_
Definition: flux_method/MusclHancockMethod.hpp:256
std::array< CompleteArray, 2 > rec_arr_
Definition: flux_method/MusclHancockMethod.hpp:264
SlopeLimiter slope_limiter_
Definition: flux_method/MusclHancockMethod.hpp:252
CompleteArray q_left_arr_
Definition: flux_method/MusclHancockMethod.hpp:271
Conservative slope_
Definition: flux_method/MusclHancockMethod.hpp:257
ConservativeArray slope_arr_
Definition: flux_method/MusclHancockMethod.hpp:266
ConservativeArray flux_right_arr_
Definition: flux_method/MusclHancockMethod.hpp:269
Complete q_right_
Definition: flux_method/MusclHancockMethod.hpp:262
MusclHancock(const Equation &eq, const BaseMethod &method)
Definition: flux_method/MusclHancockMethod.hpp:203
typename Equation::Conservative Conservative
Definition: flux_method/MusclHancockMethod.hpp:196
Conservative flux_right_
Definition: flux_method/MusclHancockMethod.hpp:259
ConservativeArray flux_left_arr_
Definition: flux_method/MusclHancockMethod.hpp:267
BaseMethod flux_method_
Definition: flux_method/MusclHancockMethod.hpp:251
const Equation & GetEquation() const noexcept
Definition: flux_method/MusclHancockMethod.hpp:245
double ComputeStableDt(span< const Complete, 4 > states, double dx, Direction dir) noexcept
Definition: flux_method/MusclHancockMethod.hpp:208
void ComputeNumericFlux(Conservative &flux, span< const Complete, 4 > stencil, Duration dt, double dx, Direction dir)
Definition: flux_method/MusclHancockMethod.hpp:295
MusclHancock(const Equation &eq)
Definition: flux_method/MusclHancockMethod.hpp:201
Complete q_left_
Definition: flux_method/MusclHancockMethod.hpp:261
static constexpr int GetStencilWidth() noexcept
Definition: flux_method/MusclHancockMethod.hpp:206
Definition: flux_method/MusclHancockMethod.hpp:71
void ComputeLimitedSlope(Conservative< Equation > &cons, span< const Complete< Equation >, 3 >)
Definition: flux_method/MusclHancockMethod.hpp:73
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 >, MaskArray)
Definition: flux_method/MusclHancockMethod.hpp:85
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 >)
Definition: flux_method/MusclHancockMethod.hpp:79
Definition: flux_method/MusclHancockMethod.hpp:31
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 > stencil, MaskArray mask)
Definition: flux_method/MusclHancockMethod.hpp:57
void ComputeLimitedSlope(ConservativeArray< Equation, N > &cons, span< const CompleteArray< Equation, N >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:45
void ComputeLimitedSlope(Conservative< Equation > &cons, span< const Complete< Equation >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:33
Definition: flux_method/MusclHancockMethod.hpp:137
void ComputeLimitedSlope(ConservativeArray< Equation > &cons, span< const CompleteArray< Equation >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:177
double operator()(double sL, double sR) const noexcept
Definition: flux_method/MusclHancockMethod.hpp:138
Array1d operator()(Array1d sL, Array1d sR) const noexcept
Definition: flux_method/MusclHancockMethod.hpp:144
void ComputeLimitedSlope(ConservativeArray< Equation > &cons, span< const CompleteArray< Equation >, 3 > stencil, MaskArray mask)
Definition: flux_method/MusclHancockMethod.hpp:164
void ComputeLimitedSlope(Conservative< Equation > &cons, span< const Complete< Equation >, 3 > stencil)
Definition: flux_method/MusclHancockMethod.hpp:152