8#include <compile_time_options.h>
20#include <deal.II/base/parameter_acceptor.h>
21#include <deal.II/base/tensor.h>
37 template <
typename Number>
38 DEAL_II_ALWAYS_INLINE
inline Number
safe_division(
const Number &numerator,
39 const Number &denominator)
42 constexpr ScalarNumber
min = std::numeric_limits<ScalarNumber>::min();
44 return std::max(numerator, Number(0.)) /
45 std::max(denominator, Number(
min));
49 template <
int dim,
typename Number>
71 "Compressible Euler equations (arbitrary EOS)";
82 template <
int dim,
typename Number =
double>
91 template <
int dim,
typename Number>
105 template <
int dim,
typename ScalarNumber>
110 const bool skip_constrained_dofs =
true)
const;
118 std::string equation_of_state_;
120 double reference_density_;
121 double vacuum_state_relaxation_small_;
122 double vacuum_state_relaxation_large_;
124 bool compute_strict_bounds_;
133 equation_of_state_list_;
136 std::shared_ptr<EquationOfState> selected_equation_of_state_;
138 template <
int dim,
typename Number>
163 template <
int dim,
typename Number>
185 using state_type = dealii::Tensor<1, problem_dimension, Number>;
191 dealii::Tensor<1, problem_dimension, dealii::Tensor<1, dim, Number>>;
203 []() -> std::array<std::string, problem_dimension> {
204 if constexpr (dim == 1)
205 return {
"rho",
"m",
"E"};
206 else if constexpr (dim == 2)
207 return {
"rho",
"m_1",
"m_2",
"E"};
208 else if constexpr (dim == 3)
209 return {
"rho",
"m_1",
"m_2",
"m_3",
"E"};
218 []() -> std::array<std::string, problem_dimension> {
219 if constexpr (dim == 1)
220 return {
"rho",
"v",
"e"};
221 else if constexpr (dim == 2)
222 return {
"rho",
"v_1",
"v_2",
"e"};
223 else if constexpr (dim == 3)
224 return {
"rho",
"v_1",
"v_2",
"v_3",
"e"};
242 std::array<std::string, n_precomputed_values>{
244 "surrogate_gamma_min",
245 "surrogate_specific_entropy",
246 "surrogate_harten_entropy"}};
257 std::array<Number, n_initial_precomputed_values>;
263 std::array<std::string, n_initial_precomputed_values>{};
269 StateVector<ScalarNumber, problem_dimension, n_precomputed_values>;
290 dealii::VectorizedArray<ScalarNumber>::size(),
291 dealii::MemorySpace::Host,
309 dealii::VectorizedArray<ScalarNumber>::size(),
310 dealii::MemorySpace::Host,
324 : hyperbolic_system_(hyperbolic_system)
336 return hyperbolic_system_.equation_of_state_;
341 return hyperbolic_system_.reference_density_;
347 return hyperbolic_system_.vacuum_state_relaxation_small_;
353 return hyperbolic_system_.vacuum_state_relaxation_large_;
358 return hyperbolic_system_.compute_strict_bounds_;
372 const Number &e)
const
374 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
376 if constexpr (std::is_same_v<ScalarNumber, Number>) {
380 for (
unsigned int k = 0; k < Number::size(); ++k) {
391 DEAL_II_ALWAYS_INLINE
inline Number
394 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
396 if constexpr (std::is_same_v<ScalarNumber, Number>) {
397 return ScalarNumber(eos->specific_internal_energy(rho, p));
400 for (
unsigned int k = 0; k < Number::size(); ++k) {
401 e[k] =
ScalarNumber(eos->specific_internal_energy(rho[k], p[k]));
411 DEAL_II_ALWAYS_INLINE
inline Number
414 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
416 if constexpr (std::is_same_v<ScalarNumber, Number>) {
420 for (
unsigned int k = 0; k < Number::size(); ++k) {
421 p[k] =
ScalarNumber(eos->specific_entropy(rho[k], e[k]));
431 DEAL_II_ALWAYS_INLINE
inline Number
434 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
436 if constexpr (std::is_same_v<ScalarNumber, Number>) {
440 for (
unsigned int k = 0; k < Number::size(); ++k) {
452 const Number &e)
const
454 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
456 if constexpr (std::is_same_v<ScalarNumber, Number>) {
460 for (
unsigned int k = 0; k < Number::size(); ++k) {
471 DEAL_II_ALWAYS_INLINE
inline Number
474 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
476 if constexpr (std::is_same_v<ScalarNumber, Number>) {
480 for (
unsigned int k = 0; k < Number::size(); ++k) {
492 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
501 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
511 const auto &eos = hyperbolic_system_.selected_equation_of_state_;
588 const Number &gamma_min)
const;
601 const Number &gamma_min)
const;
616 const Number &gamma_min)
const;
657 const Number &gamma)
const;
678 template <
int component>
684 const dealii::Tensor<1, dim, Number> &normal)
const;
704 template <
typename Lambda>
708 const dealii::Tensor<1, dim, Number> &normal,
709 const Lambda &get_dirichlet_data)
const;
751 const unsigned int i,
757 const unsigned int *js,
767 const dealii::Tensor<1, dim, Number> &c_ij)
const;
777 const dealii::Tensor<1, dim, Number> &c_ij)
const =
delete;
789 const unsigned int i,
794 const unsigned int *js,
814 template <
typename ST>
829 template <
typename ST>
849 template <
typename Lambda>
851 const Lambda &lambda)
const;
874 const std::string &subsection )
875 : ParameterAcceptor(subsection)
877 equation_of_state_ =
"polytropic gas";
881 "The equation of state. Valid names are given by any of the "
882 "subsections defined below");
884 compute_strict_bounds_ =
true;
886 "compute strict bounds",
887 compute_strict_bounds_,
888 "Compute strict, but significantly more expensive bounds at various "
889 "places: (a) an expensive, but better upper wavespeed estimate in "
890 "the approximate WaveSpeedEstimator; (b) entropy "
891 "viscosity-commutator "
892 "with correct gamma_min over the stencil; (c) mathematically correct "
893 "surrogate specific entropy minimum with gamma_min over the "
896 reference_density_ = 1.;
897 add_parameter(
"reference density",
899 "Problem specific density reference");
901 vacuum_state_relaxation_small_ = 1.e2;
902 add_parameter(
"vacuum state relaxation small",
903 vacuum_state_relaxation_small_,
904 "Problem specific vacuum relaxation parameter");
906 vacuum_state_relaxation_large_ = 1.e4;
907 add_parameter(
"vacuum state relaxation large",
908 vacuum_state_relaxation_large_,
909 "Problem specific vacuum relaxation parameter");
916 equation_of_state_list_, subsection);
918 const auto populate_functions = [
this]() {
919 bool initialized =
false;
920 for (
auto &it : equation_of_state_list_)
923 if (it->name() == equation_of_state_) {
924 selected_equation_of_state_ = it;
926 "Compressible Euler equations (" + it->name() +
" EOS)";
934 "Could not find an equation of state description with name \"" +
935 equation_of_state_ +
"\""));
938 ParameterAcceptor::parse_parameters_call_back.connect(populate_functions);
939 populate_functions();
943 template <
int dim,
typename ScalarNumber>
948 const bool skip_constrained_dofs)
const
952 const auto sparsity_simd_view =
954 using VA = dealii::VectorizedArray<ScalarNumber>;
956 const auto U_view = std::get<0>(state_vector).view();
957 const auto precomputed_view = std::get<1>(state_vector).view();
961 const auto body = [&](
auto sentinel,
unsigned int i) {
962 using T =
decltype(sentinel);
966 const unsigned int row_length = sparsity_simd_view.row_length(i);
967 if (skip_constrained_dofs && row_length == 1)
970 const auto U_i = U_view.template read_tensor<T>(i);
971 const auto view = this->view<dim, T>();
972 const auto rho_i =
view.density(U_i);
973 const auto e_i =
view.internal_energy(U_i) / rho_i;
976 const auto p_i =
view.eos_pressure(rho_i, e_i);
978 const auto gamma_i =
view.surrogate_gamma(U_i, p_i);
979 using PT = precomputed_type;
980 const PT prec_i{p_i, gamma_i, T(0.), T(0.)};
981 precomputed_view.template write_tensor<T>(prec_i, i);
984 cpu_simd_loop<ScalarNumber>(
"time_step_1", body, 0, n_internal, n_owned);
985 precomputed_view.update_ghost_values();
989 const auto body_stencil = [&](
auto sentinel,
unsigned int i) {
990 using T =
decltype(sentinel);
994 const unsigned int row_length = sparsity_simd_view.row_length(i);
995 if (skip_constrained_dofs && row_length == 1)
998 const auto U_i = U_view.template read_tensor<T>(i);
999 auto prec_i = precomputed_view.template read_tensor<T, PT>(i);
1001 auto &[p_i, gamma_min_i, s_i, eta_i] = prec_i;
1003 const auto view = this->view<dim, T>();
1005 constexpr unsigned int stride_size = get_stride_size<T>;
1006 const unsigned int *js = sparsity_simd_view.columns(i) + stride_size;
1007 for (
unsigned int col_idx = 1; col_idx < row_length;
1008 ++col_idx, js += stride_size) {
1010 const auto U_j = U_view.template read_tensor<T>(js);
1011 const auto prec_j = precomputed_view.template read_tensor<T, PT>(js);
1012 const auto p_j = std::get<0>(prec_j);
1013 const auto gamma_j =
view.surrogate_gamma(U_j, p_j);
1014 gamma_min_i = std::min(gamma_min_i, gamma_j);
1017 s_i =
view.surrogate_specific_entropy(U_i, gamma_min_i);
1018 eta_i =
view.surrogate_harten_entropy(U_i, gamma_min_i);
1019 precomputed_view.template write_tensor<T>(prec_i, i);
1022 cpu_simd_loop<ScalarNumber>(
1023 "time_step_1", body_stencil, 0, n_internal, n_owned);
1027 template <
int dim,
typename Number>
1028 DEAL_II_ALWAYS_INLINE
inline Number
1035 template <
int dim,
typename Number>
1036 DEAL_II_ALWAYS_INLINE
inline Number
1038 const Number &rho)
const
1040 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
1041 const Number rho_cutoff_large =
1042 reference_density() * vacuum_state_relaxation_large() * eps;
1044 return dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
1045 std::abs(rho), rho_cutoff_large, Number(0.), rho);
1049 template <
int dim,
typename Number>
1050 DEAL_II_ALWAYS_INLINE
inline dealii::Tensor<1, dim, Number>
1053 dealii::Tensor<1, dim, Number> result;
1054 for (
unsigned int i = 0; i < dim; ++i)
1055 result[i] = U[1 + i];
1060 template <
int dim,
typename Number>
1061 DEAL_II_ALWAYS_INLINE
inline Number
1068 template <
int dim,
typename Number>
1069 DEAL_II_ALWAYS_INLINE
inline Number
1075 const Number rho_inverse =
ScalarNumber(1.) / density(U);
1076 const auto m = momentum(U);
1077 const Number E = total_energy(U);
1078 return E -
ScalarNumber(0.5) * m.norm_square() * rho_inverse;
1082 template <
int dim,
typename Number>
1083 DEAL_II_ALWAYS_INLINE
inline auto
1094 const Number rho_inverse =
ScalarNumber(1.) / density(U);
1095 const auto u = momentum(U) * rho_inverse;
1100 for (
unsigned int i = 0; i < dim; ++i) {
1101 result[1 + i] = -u[i];
1109 template <
int dim,
typename Number>
1110 DEAL_II_ALWAYS_INLINE
inline Number
1112 const state_type &U,
const Number &gamma_min)
const
1114 const auto b = Number(eos_covolume_constant());
1115 const auto pinf = Number(eos_interpolation_pinfty());
1116 const auto q = Number(eos_interpolation_q());
1118 const auto rho = density(U);
1121 const auto covolume = Number(1.) - b * rho;
1123 const auto shift = internal_energy(U) - rho * q - pinf * covolume;
1125 return shift *
ryujin::pow(rho_inverse - b, gamma_min) / covolume;
1129 template <
int dim,
typename Number>
1130 DEAL_II_ALWAYS_INLINE
inline Number
1132 const state_type &U,
const Number &gamma_min)
const
1134 const auto b = Number(eos_covolume_constant());
1135 const auto pinf = Number(eos_interpolation_pinfty());
1136 const auto q = Number(eos_interpolation_q());
1138 const auto rho = density(U);
1139 const auto m = momentum(U);
1140 const auto E = total_energy(U);
1141 const auto rho_rho_e_q =
1142 rho * E -
ScalarNumber(0.5) * m.norm_square() - rho * rho * q;
1144 const auto exponent =
ScalarNumber(1.) / (gamma_min + Number(1.));
1146 const auto covolume = Number(1.) - b * rho;
1147 const auto covolume_term =
ryujin::pow(covolume, gamma_min - Number(1.));
1149 const auto rho_pinfcov = rho * pinf * covolume;
1152 positive_part(rho_rho_e_q - rho_pinfcov) * covolume_term, exponent);
1156 template <
int dim,
typename Number>
1157 DEAL_II_ALWAYS_INLINE
inline auto
1159 const state_type &U,
const Number &eta,
const Number &gamma_min)
const
1176 const auto b = Number(eos_covolume_constant());
1177 const auto pinf = Number(eos_interpolation_pinfty());
1178 const auto q = Number(eos_interpolation_q());
1180 const auto rho = density(U);
1181 const auto m = momentum(U);
1182 const auto E = total_energy(U);
1184 const auto covolume = Number(1.) - b * rho;
1185 const auto covolume_inverse =
ScalarNumber(1.) / covolume;
1187 const auto shift = rho * E -
ScalarNumber(0.5) * m.norm_square() -
1188 rho * rho * q - rho * pinf * covolume;
1190 constexpr auto eps = std::numeric_limits<ScalarNumber>::epsilon();
1191 const auto regularization = m.norm() * eps;
1193 std::max(regularization, eta * covolume_inverse), gamma_min);
1195 factor *= fixed_power<2>(covolume_inverse) / (gamma_min + Number(1.));
1199 const auto first_term = E -
ScalarNumber(2.) * rho * q -
1201 const auto second_term = -(gamma_min - Number(1.)) * shift * b;
1203 result[0] = factor * (covolume * first_term + second_term);
1204 for (
unsigned int i = 0; i < dim; ++i)
1205 result[1 + i] = -factor * covolume * m[i];
1206 result[dim + 1] = factor * covolume * rho;
1212 template <
int dim,
typename Number>
1213 DEAL_II_ALWAYS_INLINE
inline Number
1215 const Number &p)
const
1217 const auto b = Number(eos_covolume_constant());
1218 const auto pinf = Number(eos_interpolation_pinfty());
1219 const auto q = Number(eos_interpolation_q());
1221 const auto rho = density(U);
1222 const auto rho_e = internal_energy(U);
1223 const auto covolume = Number(1.) - b * rho;
1225 const auto numerator = (p + pinf) * covolume;
1226 const auto denominator = rho_e - rho * q - covolume * pinf;
1231 template <
int dim,
typename Number>
1232 DEAL_II_ALWAYS_INLINE
inline Number
1234 const state_type &U,
const Number &gamma)
const
1236 const auto b = Number(eos_covolume_constant());
1237 const auto pinf = Number(eos_interpolation_pinfty());
1238 const auto q = Number(eos_interpolation_q());
1240 const auto rho = density(U);
1241 const auto rho_e = internal_energy(U);
1242 const auto covolume = Number(1.) - b * rho;
1250 template <
int dim,
typename Number>
1251 DEAL_II_ALWAYS_INLINE
inline Number
1253 const state_type &U,
const Number &gamma)
const
1255 const auto b = Number(eos_covolume_constant());
1256 const auto pinf = Number(eos_interpolation_pinfty());
1257 const auto q = Number(eos_interpolation_q());
1259 const auto rho = density(U);
1260 const auto rho_e = internal_energy(U);
1261 const auto covolume = Number(1.) - b * rho;
1264 (rho_e - rho * q - pinf * covolume) / (covolume * covolume * rho);
1265 radicand *= gamma * (gamma - 1.);
1270 template <
int dim,
typename Number>
1271 DEAL_II_ALWAYS_INLINE
inline bool
1274 const auto b = Number(eos_covolume_constant());
1275 const auto pinf = Number(eos_interpolation_pinfty());
1276 const auto q = Number(eos_interpolation_q());
1278 const auto rho = density(U);
1279 const auto rho_e = internal_energy(U);
1280 const auto covolume = Number(1.) - b * rho;
1282 const auto shift = rho_e - rho * q - pinf * covolume;
1284 constexpr auto gt = dealii::SIMDComparison::greater_than;
1287 dealii::compare_and_apply_mask<gt>(rho, T(0.), T(0.), T(-1.)) +
1288 dealii::compare_and_apply_mask<gt>(shift, T(0.), T(0.), T(-1.));
1291 if (!(test == Number(0.))) {
1292 std::cout << std::fixed << std::setprecision(16);
1293 std::cout <<
"Bounds violation: Negative state [rho, e] detected!\n";
1294 std::cout <<
"\t\trho: " << rho <<
"\n";
1295 std::cout <<
"\t\tint (shifted): " << shift <<
"\n";
1299 return (test == Number(0.));
1303 template <
int dim,
typename Number>
1304 template <
int component>
1305 DEAL_II_ALWAYS_INLINE
inline auto
1310 const Number &p_bar,
1311 const dealii::Tensor<1, dim, Number> &normal)
const ->
state_type
1313 static_assert(component == 1 || component == 2,
1314 "component has to be 1 or 2");
1316 const auto b = Number(eos_covolume_constant());
1317 const auto pinf = Number(eos_interpolation_pinfty());
1318 const auto q = Number(eos_interpolation_q());
1330 const auto m = momentum(U);
1331 const auto rho = density(U);
1332 const auto vn = m * normal / rho;
1334 const auto gamma = surrogate_gamma(U, p);
1335 const auto a = surrogate_speed_of_sound(U, gamma);
1336 const auto covolume = 1. - b * rho;
1338 const auto m_bar = momentum(U_bar);
1339 const auto rho_bar = density(U_bar);
1340 const auto vn_bar = m_bar * normal / rho_bar;
1342 const auto gamma_bar = surrogate_gamma(U_bar, p_bar);
1343 const auto a_bar = surrogate_speed_of_sound(U_bar, gamma_bar);
1344 const auto covolume_bar = 1. - b * rho_bar;
1357 component == 1 ? vn_bar - 2. * a_bar / (gamma_bar - 1.) * covolume_bar
1358 : vn - 2. * a / (gamma - 1.) * covolume;
1361 component == 2 ? vn_bar + 2. * a_bar / (gamma_bar - 1.) * covolume_bar
1362 : vn + 2. * a / (gamma - 1.) * covolume;
1371 dealii::ExcMessage(
"Encountered R_2 < R_1 in dynamic boundary value "
1372 "enforcement. This implies that the interpolation "
1373 "with Riemann characteristics failed."));
1375 const auto vperp = m / rho - vn * normal;
1377 const auto S = (p + pinf) *
ryujin::pow(Number(1.) / rho - b, gamma);
1394 const auto vn_new = Number(0.5) * (R_1 + R_2);
1424 const auto a_new_square =
1425 ryujin::fixed_power<2>((gamma - 1.) * (R_2 - R_1) / (4. * covolume));
1427 auto term =
ryujin::pow(a_new_square / (gamma * S), 1. / (gamma - 1.));
1429 term *= std::pow(covolume, 2. / (gamma - 1.));
1432 const auto rho_new = term / (1. + b * term);
1434 const auto covolume_new = (1. - b * rho_new);
1435 const auto p_new = a_new_square / gamma * rho_new * covolume_new - pinf;
1441 const auto rho_e_new =
1442 rho_new * q + (p_new + gamma * pinf) * covolume_new / (gamma - 1.);
1446 for (
unsigned int d = 0; d < dim; ++d) {
1447 U_new[1 + d] = rho_new * (vn_new * normal + vperp)[d];
1450 rho_e_new + 0.5 * rho_new * (vn_new * vn_new + vperp.norm_square());
1456 template <
int dim,
typename Number>
1457 template <
typename Lambda>
1458 DEAL_II_ALWAYS_INLINE
inline auto
1460 dealii::types::boundary_id
id,
1462 const dealii::Tensor<1, dim, Number> &normal,
1463 const Lambda &get_dirichlet_data)
const ->
state_type
1468 result = get_dirichlet_data();
1475 const auto m_dirichlet = momentum(get_dirichlet_data());
1476 const auto rho = density(result);
1477 const auto m = momentum(result);
1479 for (
unsigned int k = 0; k < dim; ++k)
1480 result[k + 1] = m_dirichlet[k];
1482 Number(0.5) / rho * (m_dirichlet.norm_square() - m.norm_square());
1489 const auto U_dirichlet = get_dirichlet_data();
1490 const auto rho_dirichlet = density(U_dirichlet);
1491 const auto v_dirichlet = momentum(U_dirichlet) / rho_dirichlet;
1492 const auto rho = density(result);
1493 const auto v = momentum(result) / rho;
1495 for (
unsigned int k = 0; k < dim; ++k)
1496 result[k + 1] = rho * v_dirichlet[k];
1498 Number(0.5) * rho * (v_dirichlet.norm_square() - v.norm_square());
1501 auto m = momentum(U);
1502 m -= 1. * (m * normal) * normal;
1503 for (
unsigned int k = 0; k < dim; ++k)
1504 result[k + 1] = m[k];
1507 for (
unsigned int k = 0; k < dim; ++k)
1508 result[k + 1] = Number(0.);
1523 const auto m = momentum(U);
1524 const auto rho = density(U);
1525 const auto rho_e = internal_energy(U);
1532 const auto p = eos_pressure(rho, rho_e / rho);
1533 const auto gamma = surrogate_gamma(U, p);
1534 const auto a = surrogate_speed_of_sound(U, gamma);
1535 const auto vn = m * normal / rho;
1539 result = get_dirichlet_data();
1543 if (vn >= -a && vn <= 0.) {
1544 const auto U_dirichlet = get_dirichlet_data();
1545 const auto rho_dirichlet = density(U_dirichlet);
1546 const auto rho_e_dirichlet = internal_energy(U_dirichlet);
1547 const auto p_dirichlet =
1548 eos_pressure(rho_dirichlet, rho_e_dirichlet / rho_dirichlet);
1550 result = prescribe_riemann_characteristic<2>(
1551 U_dirichlet, p_dirichlet, U, p, normal);
1555 if (vn > 0. && vn <= a) {
1556 const auto U_dirichlet = get_dirichlet_data();
1557 const auto rho_dirichlet = density(U_dirichlet);
1558 const auto rho_e_dirichlet = internal_energy(U_dirichlet);
1559 const auto p_dirichlet =
1560 eos_pressure(rho_dirichlet, rho_e_dirichlet / rho_dirichlet);
1562 result = prescribe_riemann_characteristic<1>(
1563 U, p, U_dirichlet, p_dirichlet, normal);
1568 AssertThrow(
false, dealii::ExcNotImplemented());
1575 template <
int dim,
typename Number>
1576 DEAL_II_ALWAYS_INLINE
inline auto
1580 const auto rho_inverse =
ScalarNumber(1.) / density(U);
1581 const auto m = momentum(U);
1582 const auto E = total_energy(U);
1587 for (
unsigned int i = 0; i < dim; ++i) {
1588 result[1 + i] = m * (m[i] * rho_inverse);
1589 result[1 + i][i] += p;
1591 result[dim + 1] = m * (rho_inverse * (E + p));
1597 template <
int dim,
typename Number>
1598 DEAL_II_ALWAYS_INLINE
inline auto
1602 const unsigned int i,
1605 const auto &[p_i, gamma_min_i, s_i, eta_i] =
1606 pv.template read_tensor<Number, precomputed_type>(i);
1611 template <
int dim,
typename Number>
1612 DEAL_II_ALWAYS_INLINE
inline auto
1616 const unsigned int *js,
1619 const auto &[p_j, gamma_min_j, s_j, eta_j] =
1620 pv.template read_tensor<Number, precomputed_type>(js);
1625 template <
int dim,
typename Number>
1626 DEAL_II_ALWAYS_INLINE
inline auto
1630 const dealii::Tensor<1, dim, Number> &c_ij)
const ->
state_type
1636 template <
int dim,
typename Number>
1637 template <
typename ST>
1641 using T =
typename ST::value_type;
1642 static_assert(std::is_same_v<Number, T>,
"template mismatch");
1644 constexpr auto dim2 = ST::dimension - 2;
1645 static_assert(dim >= dim2,
1646 "the space dimension of the argument state must not be "
1647 "larger than the one of the target state");
1650 result[0] = state[0];
1651 result[dim + 1] = state[dim2 + 1];
1652 for (
unsigned int i = 1; i < dim2 + 1; ++i)
1653 result[i] = state[i];
1659 template <
int dim,
typename Number>
1660 template <
typename ST>
1661 DEAL_II_ALWAYS_INLINE
inline auto
1665 auto primitive_state = expand_state(initial_state);
1668 const auto rho = density(primitive_state);
1669 const auto p = total_energy(primitive_state);
1670 const auto e = eos_specific_internal_energy(rho, p);
1671 primitive_state[dim + 1] = e;
1673 return from_primitive_state(primitive_state);
1677 template <
int dim,
typename Number>
1678 DEAL_II_ALWAYS_INLINE
inline auto
1682 const auto rho = density(primitive_state);
1684 const auto u = momentum(primitive_state);
1686 const auto &e = total_energy(primitive_state);
1688 auto state = primitive_state;
1690 for (
unsigned int i = 1; i < dim + 1; ++i)
1694 state[dim + 1] = rho * e + Number(0.5) * rho * u * u;
1700 template <
int dim,
typename Number>
1701 DEAL_II_ALWAYS_INLINE
inline auto
1705 const auto rho = density(state);
1706 const auto rho_inverse = Number(1.) / rho;
1707 const auto rho_e = internal_energy(state);
1709 auto primitive_state = state;
1711 for (
unsigned int i = 1; i < dim + 1; ++i)
1712 primitive_state[i] *= rho_inverse;
1714 primitive_state[dim + 1] = rho_e * rho_inverse;
1716 return primitive_state;
1720 template <
int dim,
typename Number>
1721 template <
typename Lambda>
1725 auto result = state;
1726 const auto M = lambda(momentum(state));
1727 for (
unsigned int d = 0; d < dim; ++d)
1728 result[1 + d] = M[d];
dealii::Tensor< 1, problem_dimension, Number > state_type
Vectors::StateVector< ScalarNumber, problem_dimension, n_precomputed_values > StateVector
state_type from_initial_state(const ST &initial_state) const
std::array< Number, n_initial_precomputed_values > initial_precomputed_type
Number surrogate_harten_entropy(const state_type &U, const Number &gamma_min) const
static constexpr bool have_energy_equation
static Number internal_energy(const state_type &U)
state_type to_primitive_state(const state_type &state) const
state_type high_order_flux_divergence(const flux_contribution_type &flux_i, const flux_contribution_type &flux_j, const dealii::Tensor< 1, dim, Number > &c_ij) const =delete
DEAL_II_ALWAYS_INLINE Number eos_cold_curve_bound(const Number &rho) const
static constexpr bool have_high_order_flux
typename get_value_type< Number >::type ScalarNumber
static dealii::Tensor< 1, dim, Number > momentum(const state_type &U)
Number surrogate_pressure(const state_type &U, const Number &gamma) const
Number surrogate_speed_of_sound(const state_type &U, const Number &gamma) const
DEAL_II_ALWAYS_INLINE const std::string & equation_of_state() const
static constexpr bool have_covolume_constant
flux_contribution_type flux_contribution(const PrecomputedVectorView &pv, const InitialPrecomputedVectorView &piv, const unsigned int i, const state_type &U_i) const
state_type nodal_source(const PrecomputedVectorView &pv, const unsigned int *js, const state_type &U_j, const ScalarNumber tau) const =delete
DEAL_II_ALWAYS_INLINE ScalarNumber vacuum_state_relaxation_large() const
static constexpr unsigned int n_precomputed_values
DEAL_II_ALWAYS_INLINE ScalarNumber reference_density() const
static const auto component_names
DEAL_II_ALWAYS_INLINE ScalarNumber eos_covolume_constant() const
state_type from_primitive_state(const state_type &primitive_state) const
static state_type internal_energy_derivative(const state_type &U)
DEAL_II_ALWAYS_INLINE Number eos_temperature(const Number &rho, const Number &e) const
DEAL_II_ALWAYS_INLINE Number eos_specific_entropy(const Number &rho, const Number &e) const
static constexpr bool have_source_terms
DEAL_II_ALWAYS_INLINE Number eos_pressure(const Number &rho, const Number &e) const
static constexpr unsigned int problem_dimension
flux_type flux_contribution_type
Number surrogate_specific_entropy(const state_type &U, const Number &gamma_min) const
static const auto precomputed_names
static const auto primitive_component_names
DEAL_II_ALWAYS_INLINE ScalarNumber eos_interpolation_pinfty() const
static Number total_energy(const state_type &U)
bool is_admissible(const state_type &U) const
DEAL_II_ALWAYS_INLINE bool compute_strict_bounds() const
state_type flux_divergence(const flux_contribution_type &flux_i, const flux_contribution_type &flux_j, const dealii::Tensor< 1, dim, Number > &c_ij) const
DEAL_II_ALWAYS_INLINE Number eos_specific_internal_energy(const Number &rho, const Number &p) const
HyperbolicSystemView(const HyperbolicSystem &hyperbolic_system)
DEAL_II_ALWAYS_INLINE ScalarNumber eos_interpolation_q() const
Number filter_vacuum_density(const Number &rho) const
flux_type f(const state_type &U, const Number &p) const
state_type prescribe_riemann_characteristic(const state_type &U, const Number &p, const state_type &U_bar, const Number &p_bar, const dealii::Tensor< 1, dim, Number > &normal) const
state_type expand_state(const ST &state) const
std::array< Number, n_precomputed_values > precomputed_type
state_type surrogate_harten_entropy_derivative(const state_type &U, const Number &eta, const Number &gamma_min) const
static const auto initial_precomputed_names
DEAL_II_ALWAYS_INLINE ScalarNumber vacuum_state_relaxation_small() const
Number surrogate_gamma(const state_type &U, const Number &p) const
static constexpr unsigned int n_initial_precomputed_values
state_type nodal_source(const PrecomputedVectorView &pv, const unsigned int i, const state_type &U_i, const ScalarNumber tau) const =delete
DEAL_II_ALWAYS_INLINE Number eos_speed_of_sound(const Number &rho, const Number &e) const
dealii::Tensor< 1, problem_dimension, dealii::Tensor< 1, dim, Number > > flux_type
static Number density(const state_type &U)
state_type apply_boundary_conditions(const dealii::types::boundary_id id, const state_type &U, const dealii::Tensor< 1, dim, Number > &normal, const Lambda &get_dirichlet_data) const
static constexpr bool have_gamma
state_type apply_galilei_transform(const state_type &state, const Lambda &lambda) const
HyperbolicSystem(const std::string &subsection="/HyperbolicSystem")
void fill_precomputed_values(const OfflineData< dim, ScalarNumber > &offline_data, typename HyperbolicSystemView< dim, ScalarNumber >::StateVector &state_vector, const bool skip_constrained_dofs=true) const
static std::string problem_name
dealii::Tensor< 1, problem_dimension, Number > state_type
typename get_value_type< Number >::type ScalarNumber
const auto & n_locally_owned() const
const auto & sparsity_pattern_simd() const
const auto & n_locally_internal() const
void populate_equation_of_state_list(equation_of_state_list_type &equation_of_state_list, const std::string &subsection)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor< 1, problem_dim, T > contract(const FT &flux_ij, const TT &c_ij)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE FT add(const FT &flux_left_ij, const FT &flux_right_ij)
DEAL_II_HOST_DEVICE T pow(const T x, const T b)
DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number positive_part(const Number number)
std::set< std::shared_ptr< EquationOfState > > equation_of_state_list_type
DEAL_II_ALWAYS_INLINE Number safe_division(const Number &numerator, const Number &denominator)