ryujin 2.5.0 revision c64172211cf21344cb9b9b0f3a1266aa6400d392
Loading...
Searching...
No Matches
hyperbolic_system.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2020 - 2026 by the ryujin authors
4//
5
6#pragma once
7
8#include <ryujin/base/compile_time_options.h>
10#include <ryujin/base/gpu.h>
11#include <ryujin/base/loop.h>
13#include <ryujin/base/simd.h>
19
20#include <deal.II/base/memory_space.h>
21#include <deal.II/base/parameter_acceptor.h>
22#include <deal.II/base/tensor.h>
23
24#include <array>
25#include <memory>
26#include <string>
27#include <vector>
28
29namespace ryujin
30{
31 namespace EulerBarotropic
32 {
33 template <int dim,
34 typename Number,
35 typename MemorySpace = dealii::MemorySpace::Host>
36 class HyperbolicSystemView;
37
52 {
53 public:
63
67 HyperbolicSystem(const std::string &subsection = "/HyperbolicSystem");
68
74 template <int dim,
75 typename Number = double,
76 typename MemorySpace = dealii::MemorySpace::Host>
78
86 template <int dim,
87 typename Number,
88 typename MemorySpace = dealii::MemorySpace::Host>
89 auto view() const
90 {
92 }
93
107 template <typename MemorySpace = dealii::MemorySpace::Host,
108 int dim,
109 typename ScalarNumber>
111 const OfflineData<dim, ScalarNumber> &offline_data,
112 StateVector<ScalarNumber> &state_vector,
113 const bool skip_constrained_dofs = true) const;
114
115 private:
120
125 void update_parameters();
126
127 Mirrored<Parameters> parameters_;
128
129 std::string barotropic_equation_of_state_;
130
131 std::vector<std::unique_ptr<BarotropicEquationOfState>>
132 barotropic_equation_of_state_list_;
133
134 const BarotropicEquationOfState *selected_barotropic_equation_of_state_ =
135 nullptr;
136
137 template <int, typename, typename>
139
141 }; /* HyperbolicSystem */
142
143
165 template <int dim, typename Number, typename MemorySpace>
167 {
168 public:
169 static_assert(
170 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
171 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
172 "Unexpected memory space");
173
178
183
187 static constexpr unsigned int problem_dimension = 1 + dim;
188
192 using state_type = dealii::Tensor<1, problem_dimension, Number>;
193
197 using flux_type =
198 dealii::Tensor<1, problem_dimension, dealii::Tensor<1, dim, Number>>;
199
204
208 static constexpr unsigned int n_precomputed_values = 3;
209
213 using precomputed_type = std::array<Number, n_precomputed_values>;
214
218 static constexpr unsigned int n_initial_precomputed_values = 0;
219
224 std::array<Number, n_initial_precomputed_values>;
225
226 template <int n_comp>
229
235
242
244
248
253 HyperbolicSystemView(const HyperbolicSystem &hyperbolic_system)
254 : parameters_(
255 hyperbolic_system.parameters_.template view<MemorySpace>())
256 , barotropic_equation_of_state_(
257 hyperbolic_system.selected_barotropic_equation_of_state_)
258 {
259 }
260
262
266
272 DEAL_II_ALWAYS_INLINE inline const std::string &
274 {
275 return barotropic_equation_of_state_->name();
276 }
277
278 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber reference_density() const
279 {
280 return ScalarNumber(parameters_->reference_density);
281 }
282
283 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber
285 {
286 return ScalarNumber(parameters_->vacuum_state_relaxation_small);
287 }
288
289 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber
291 {
292 return ScalarNumber(parameters_->vacuum_state_relaxation_large);
293 }
294
296
305
310 DEAL_II_ALWAYS_INLINE inline Number
311 beos_specific_internal_energy(const Number &rho) const
312 {
313 const auto &beos = barotropic_equation_of_state_;
314
315 if constexpr (std::is_same_v<ScalarNumber, Number>) {
316 return ScalarNumber(beos->specific_internal_energy(rho));
317 } else {
318 Number e;
319 for (unsigned int k = 0; k < Number::size(); ++k) {
320 e[k] = ScalarNumber(beos->specific_internal_energy(rho[k]));
321 }
322 return e;
323 }
324 }
325
329 DEAL_II_ALWAYS_INLINE inline Number beos_pressure(const Number &rho) const
330 {
331 const auto &beos = barotropic_equation_of_state_;
332
333 if constexpr (std::is_same_v<ScalarNumber, Number>) {
334 return ScalarNumber(beos->pressure(rho));
335 } else {
336 Number p;
337 for (unsigned int k = 0; k < Number::size(); ++k) {
338 p[k] = ScalarNumber(beos->pressure(rho[k]));
339 }
340 return p;
341 }
342 }
343
348 DEAL_II_ALWAYS_INLINE inline Number
349 beos_speed_of_sound(const Number &rho) const
350 {
351 const auto &beos = barotropic_equation_of_state_;
352
353 if constexpr (std::is_same_v<ScalarNumber, Number>) {
354 return ScalarNumber(beos->speed_of_sound(rho));
355 } else {
356 Number a;
357 for (unsigned int k = 0; k < Number::size(); ++k) {
358 a[k] = ScalarNumber(beos->speed_of_sound(rho[k]));
359 }
360 return a;
361 }
362 }
363
365
369
370 static constexpr bool have_gamma = false;
371 static constexpr bool have_covolume_constant = false;
372 static constexpr bool have_energy_equation = false;
373
375
379
384 static DEAL_II_HOST_DEVICE Number density(const state_type &U);
385
392 DEAL_II_HOST_DEVICE Number filter_vacuum_density(const Number &rho) const;
393
398 static DEAL_II_HOST_DEVICE dealii::Tensor<1, dim, Number>
399 momentum(const state_type &U);
400
408 DEAL_II_HOST_DEVICE Number total_energy(
409 const state_type &U, const Number &specific_internal_energy) const;
410
416 DEAL_II_HOST_DEVICE state_type
418 const Number &specific_internal_energy,
419 const Number &pressure) const;
420
426 DEAL_II_HOST_DEVICE bool is_admissible(const state_type &U) const;
427
429
433
443 template <int component>
445 const state_type &U,
446 const Number &p,
447 const state_type &U_bar,
448 const Number &p_bar,
449 const dealii::Tensor<1, dim, Number> &normal) const;
450
473 template <typename Lambda>
475 apply_boundary_conditions(const dealii::types::boundary_id id,
476 const state_type &U,
477 const dealii::Tensor<1, dim, Number> &normal,
478 const Lambda &get_dirichlet_data) const;
479
481
485
495 DEAL_II_HOST_DEVICE flux_type f(const state_type &U,
496 const Number &p) const;
497
517 DEAL_II_HOST_DEVICE
521 const unsigned int i,
522 const state_type &U_i) const;
523
524 DEAL_II_HOST_DEVICE
528 const unsigned int *js,
529 const state_type &U_j) const;
530
535 DEAL_II_HOST_DEVICE
538 const flux_contribution_type &flux_j,
539 const dealii::Tensor<1, dim, Number> &c_ij) const;
540
544 static constexpr bool have_high_order_flux = false;
545
546 DEAL_II_HOST_DEVICE
548 const flux_contribution_type &flux_i,
549 const flux_contribution_type &flux_j,
550 const dealii::Tensor<1, dim, Number> &c_ij) const = delete;
551
553
557
559 static constexpr bool have_source_terms = false;
560
561 DEAL_II_HOST_DEVICE
563 const unsigned int i,
564 const state_type &U_i,
565 const ScalarNumber tau) const = delete;
566
567 DEAL_II_HOST_DEVICE
569 const unsigned int *js,
570 const state_type &U_j,
571 const ScalarNumber tau) const = delete;
572
574
578
589 template <typename ST>
590 DEAL_II_HOST_DEVICE state_type expand_state(const ST &state) const;
591
604 template <typename ST>
605 DEAL_II_HOST_DEVICE state_type
606 from_initial_state(const ST &initial_state) const;
607
612 DEAL_II_HOST_DEVICE
613 state_type from_primitive_state(const state_type &primitive_state) const;
614
618 DEAL_II_HOST_DEVICE
620
626 template <typename Lambda>
628 const state_type &state, const Lambda &lambda) const;
629
630 private:
632
636
637 const HyperbolicSystem::Parameters *const parameters_;
638
639 /* Only valid (and dereferenced) on the host: */
640 const BarotropicEquationOfState *const barotropic_equation_of_state_;
641
643 }; /* HyperbolicSystemView */
644
645
646 /*
647 * -------------------------------------------------------------------------
648 * Inline definitions
649 * -------------------------------------------------------------------------
650 */
651
652
653 inline HyperbolicSystem::HyperbolicSystem(const std::string &subsection)
654 : Interface::HyperbolicSystem(
655 "Compressible Euler equations "
656 "(barotropic EOS, optimized barotropic)",
657 {{{"rho", "m"},
658 {"rho", "m_1", "m_2"},
659 {"rho", "m_1", "m_2", "m_3"}}},
660 {{{"rho", "v"},
661 {"rho", "v_1", "v_2"},
662 {"rho", "v_1", "v_2", "v_3"}}},
663 {{{"e", "p", "a"}, {"e", "p", "a"}, {"e", "p", "a"}}},
664 {},
665 subsection)
666 , parameters_("euler_barotropic_hyperbolic_system_parameters",
668 {
669 /* reference remains valid due to implicit_transfers_host_resident */
670 auto &parameters = *parameters_.view();
671
672 barotropic_equation_of_state_list_ =
674
675 barotropic_equation_of_state_ = "isothermal";
676 add_parameter("barotropic equation of state",
677 barotropic_equation_of_state_,
678 "The barotropic equation of state. Valid names are given "
679 "by any of the subsections defined below",
680 this->prm,
682 barotropic_equation_of_state_list_));
683
684 parameters.reference_density = 1.;
685 add_parameter("reference density",
686 parameters.reference_density,
687 "Problem specific density reference");
688
689 parameters.vacuum_state_relaxation_small = 1.e2;
690 add_parameter("vacuum state relaxation small",
691 parameters.vacuum_state_relaxation_small,
692 "Problem specific vacuum relaxation parameter");
693
694 parameters.vacuum_state_relaxation_large = 1.e4;
695 add_parameter("vacuum state relaxation large",
696 parameters.vacuum_state_relaxation_large,
697 "Problem specific vacuum relaxation parameter");
698
699 ParameterAcceptor::parse_parameters_call_back.connect(
700 [this] { update_parameters(); });
701
702 update_parameters();
703 }
704
705
706 inline void HyperbolicSystem::update_parameters()
707 {
708 selected_barotropic_equation_of_state_ =
710 barotropic_equation_of_state_list_,
711 barotropic_equation_of_state_);
712 problem_name_ = "Compressible Euler equations (" +
713 selected_barotropic_equation_of_state_->name() +
714 " EOS, optimized barotropic)";
715
716 /* invalidates view on default memory space */
717 parameters_.view();
718 }
719
720
721 template <typename MemorySpace, int dim, typename ScalarNumber>
723 const OfflineData<dim, ScalarNumber> &offline_data,
724 StateVector<ScalarNumber> &state_vector,
725 const bool skip_constrained_dofs) const
726 {
727 using HostSpace = dealii::MemorySpace::Host;
728
729 const unsigned int n_internal = offline_data.n_locally_internal();
730 const unsigned int n_owned = offline_data.n_locally_owned();
731
733
734 auto &U = state_vector.state;
735 auto &precomputed = state_vector.precomputed;
736
737 /*
738 * Compute the specific internal energy, pressure, and speed of sound.
739 * This requires calling into the selected equation of state, which
740 * is only possible on the host memory space. Thus, temporarily
741 * transfer the state vector and the precomputed values to the host
742 * memory space:
743 */
744
745 constexpr bool transfer =
747 !std::is_same_v<MemorySpace, dealii::MemorySpace::Host>;
748
749 [[maybe_unused]] const bool host_resident =
750 U.template is_resident<HostSpace>();
751
752 if constexpr (transfer) {
753 U.template copy_to_memory_space<HostSpace>();
754 precomputed.template move_to_memory_space<HostSpace>();
755 }
756
757 {
758 const auto sparsity_simd_view =
759 offline_data.sparsity_pattern_simd().template view<HostSpace>();
760
761 /* We only read the hyperbolic state vector: */
762 const auto U_view =
763 std::as_const(U)
764 .template view<ScalarView::problem_dimension, HostSpace>();
765 const auto precomputed_view =
767 .template view<ScalarView::n_precomputed_values, HostSpace>();
768
769 const auto hyperbolic_system_views =
770 make_select_view<dim, ScalarNumber, HostSpace>(*this);
771
772 const auto body = [=](auto sentinel, unsigned int i) {
773 using T = decltype(sentinel);
775 using precomputed_type = typename View::precomputed_type;
776
777 const unsigned int row_length = sparsity_simd_view.row_length(i);
778 if (skip_constrained_dofs && row_length == 1)
779 return;
780
781 const auto view = hyperbolic_system_views.template view<T>();
782
783 const auto U_i = U_view.template read_tensor<T>(i);
784 const auto rho_i = view.density(U_i);
785
786 /* Calls into the selected equation of state: */
787 const auto e_i = view.beos_specific_internal_energy(rho_i);
788 const auto p_i = view.beos_pressure(rho_i);
789 const auto a_i = view.beos_speed_of_sound(rho_i);
790
791 const precomputed_type prec_i{e_i, p_i, a_i};
792 precomputed_view.template write_tensor<T>(prec_i, i);
793 };
794
795 loop<HostSpace, ScalarNumber>(
796 "hyperbolic_kernel_01b", body, 0, n_internal, n_owned);
797 }
798
799 if constexpr (transfer) {
800 /* Drop the (now stale) host mirror unless it was resident before: */
801 if (!host_resident)
802 U.template move_to_memory_space<MemorySpace>();
803 precomputed.template move_to_memory_space<MemorySpace>();
804 }
805 }
806
807
808 template <int dim, typename Number, typename MemorySpace>
809 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
814
815
816 template <int dim, typename Number, typename MemorySpace>
817 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
819 const Number &rho) const
820 {
821 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
822 const Number rho_cutoff_large =
823 reference_density() * vacuum_state_relaxation_large() * eps;
824
825 return ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
826 std::abs(rho), rho_cutoff_large, Number(0.), rho);
827 }
828
829
830 template <int dim, typename Number, typename MemorySpace>
831 DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor<1, dim, Number>
833 const state_type &U)
834 {
835 dealii::Tensor<1, dim, Number> result;
836 for (unsigned int i = 0; i < dim; ++i)
837 result[i] = U[1 + i];
838 return result;
839 }
840
841
842 template <int dim, typename Number, typename MemorySpace>
843 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
845 const state_type &U, const Number &specific_internal_energy) const
846 {
847 const auto rho = density(U);
848 const auto rho_inverse = ScalarNumber(1.) / rho;
849 const auto m = momentum(U);
850
851 return rho * specific_internal_energy +
852 ScalarNumber(0.5) * rho_inverse * m.norm_square();
853 }
854
855
856 template <int dim, typename Number, typename MemorySpace>
857 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
859 const state_type &U,
860 const Number &specific_internal_energy,
861 const Number &pressure) const -> state_type
862 {
863 const auto rho = density(U);
864 const auto rho_inverse = ScalarNumber(1.) / rho;
865 const auto m = momentum(U);
866
867 state_type result;
868
869 result[0] =
870 specific_internal_energy + rho_inverse * pressure -
871 ScalarNumber(0.5) * rho_inverse * rho_inverse * m.norm_square();
872 for (unsigned int i = 0; i < dim; ++i)
873 result[1 + i] = rho_inverse * m[i];
874
875 return result;
876 }
877
878
879 template <int dim, typename Number, typename MemorySpace>
880 DEAL_II_HOST_DEVICE_ALWAYS_INLINE bool
882 const state_type &U) const
883 {
884 const auto rho = density(U);
885 constexpr auto gt = dealii::SIMDComparison::greater_than;
886 using T = Number;
887 const auto test =
888 ryujin::compare_and_apply_mask<gt>(rho, T(0.), T(0.), T(-1.));
889
890#ifdef DEBUG_OUTPUT
891 if (!(test == Number(0.))) {
892 std::cout << std::fixed << std::setprecision(16);
893 std::cout << "Bounds violation: Negative state [rho, e] detected!\n";
894 std::cout << "\t\trho: " << rho << "\n";
895 }
896#endif
897
898 return (test == Number(0.));
899 }
900
901
902 template <int dim, typename Number, typename MemorySpace>
903 template <int component>
904 DEAL_II_ALWAYS_INLINE inline auto
907 const state_type & /*U*/,
908 const Number & /*p*/,
909 const state_type & /*U_bar*/,
910 const Number & /*p_bar*/,
911 const dealii::Tensor<1, dim, Number> & /*normal*/) const
912 -> state_type
913 {
914 // FIXME
915 AssertThrow(false, dealii::ExcNotImplemented());
916 __builtin_trap();
917 return state_type{};
918 }
919
920
921 template <int dim, typename Number, typename MemorySpace>
922 template <typename Lambda>
923 DEAL_II_ALWAYS_INLINE inline auto
925 dealii::types::boundary_id id,
926 const state_type &U,
927 const dealii::Tensor<1, dim, Number> &normal,
928 const Lambda &get_dirichlet_data) const -> state_type
929 {
930 state_type result = U;
931
932 if (id == Boundary::dirichlet) {
933 result = get_dirichlet_data();
934
935 } else if (id == Boundary::dirichlet_momentum) {
936 /* Only enforce Dirichlet conditions on the momentum: */
937 auto m_dirichlet = momentum(get_dirichlet_data());
938 for (unsigned int k = 0; k < dim; ++k)
939 result[k + 1] = m_dirichlet[k];
940
941 } else if (id == Boundary::dirichlet_velocity) {
942 /* Only enforce Dirichlet conditions on the velocity: */
943 const auto U_dirichlet = get_dirichlet_data();
944 const auto rho_dirichlet = density(U_dirichlet);
945 const auto v_dirichlet = momentum(U_dirichlet) / rho_dirichlet;
946 const auto rho = density(result);
947 for (unsigned int k = 0; k < dim; ++k)
948 result[k + 1] = rho * v_dirichlet[k];
949
950 } else if (id == Boundary::slip) {
951 auto m = momentum(U);
952 m -= 1. * (m * normal) * normal;
953 for (unsigned int k = 0; k < dim; ++k)
954 result[k + 1] = m[k];
955
956 } else if (id == Boundary::no_slip) {
957 for (unsigned int k = 0; k < dim; ++k)
958 result[k + 1] = Number(0.);
959
960 } else if (id == Boundary::dynamic) {
961 /*
962 * On dynamic boundary conditions, we distinguish four cases:
963 *
964 * - supersonic inflow: prescribe full state
965 * - subsonic inflow:
966 * decompose into Riemann invariants and leave R_2
967 * characteristic untouched.
968 * - supersonic outflow: do nothing
969 * - subsonic outflow:
970 * decompose into Riemann invariants and prescribe incoming
971 * R_1 characteristic.
972 */
973 const auto m = momentum(U);
974 const auto rho = density(U);
975
976 /*
977 * We do not have precomputed values available. Thus, simply query
978 * the pressure and speed of sound oracle:
979 */
980 const auto p = beos_pressure(rho);
981 const auto a = beos_speed_of_sound(rho);
982 const auto vn = m * normal / rho;
983
984 /* Supersonic inflow: */
985 if (vn < -a) {
986 result = get_dirichlet_data();
987 }
988
989 /* Subsonic inflow: */
990 if (vn >= -a && vn <= 0.) {
991 const auto U_dirichlet = get_dirichlet_data();
992 const auto rho_dirichlet = density(U_dirichlet);
993 const auto p_dirichlet = beos_pressure(rho_dirichlet);
994
995 result = prescribe_riemann_characteristic<2>(
996 U_dirichlet, p_dirichlet, U, p, normal);
997 }
998
999 /* Subsonic outflow: */
1000 if (vn > 0. && vn <= a) {
1001 const auto U_dirichlet = get_dirichlet_data();
1002 const auto rho_dirichlet = density(U_dirichlet);
1003 const auto p_dirichlet = beos_pressure(rho_dirichlet);
1004
1005 result = prescribe_riemann_characteristic<1>(
1006 U, p, U_dirichlet, p_dirichlet, normal);
1007 }
1008 /* Supersonic outflow: do nothing, i.e., keep U as is */
1009
1010 } else {
1011 AssertThrow(false, dealii::ExcNotImplemented());
1012 }
1013
1014 return result;
1015 }
1016
1017
1018 template <int dim, typename Number, typename MemorySpace>
1019 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1021 const Number &p) const
1022 -> flux_type
1023 {
1024 const auto rho_inverse = ScalarNumber(1.) / density(U);
1025 const auto m = momentum(U);
1026
1027 flux_type result;
1028
1029 result[0] = m;
1030 for (unsigned int i = 0; i < dim; ++i) {
1031 result[1 + i] = m * (m[i] * rho_inverse);
1032 result[1 + i][i] += p;
1033 }
1034
1035 return result;
1036 }
1037
1038
1039 template <int dim, typename Number, typename MemorySpace>
1040 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1042 const PrecomputedVectorView &pv,
1043 const InitialPrecomputedVectorView & /*piv*/,
1044 const unsigned int i,
1045 const state_type &U_i) const -> flux_contribution_type
1046 {
1047 const auto &[e_i, p_i, a_i] =
1048 pv.template read_tensor<Number, precomputed_type>(i);
1049 return f(U_i, p_i);
1050 }
1051
1052
1053 template <int dim, typename Number, typename MemorySpace>
1054 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1056 const PrecomputedVectorView &pv,
1057 const InitialPrecomputedVectorView & /*piv*/,
1058 const unsigned int *js,
1059 const state_type &U_j) const -> flux_contribution_type
1060 {
1061 const auto &[e_j, p_j, a_j] =
1062 pv.template read_tensor<Number, precomputed_type>(js);
1063 return f(U_j, p_j);
1064 }
1065
1066
1067 template <int dim, typename Number, typename MemorySpace>
1068 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1070 const flux_contribution_type &flux_i,
1071 const flux_contribution_type &flux_j,
1072 const dealii::Tensor<1, dim, Number> &c_ij) const -> state_type
1073 {
1074 return -contract(add(flux_i, flux_j), c_ij);
1075 }
1076
1077
1078 template <int dim, typename Number, typename MemorySpace>
1079 template <typename ST>
1080 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1082 const ST &state) const -> state_type
1083 {
1084 using T = typename ST::value_type;
1085 static_assert(std::is_same_v<Number, T>, "template mismatch");
1086
1087 constexpr auto dim2 = ST::dimension - 1;
1088 static_assert(dim >= dim2,
1089 "the space dimension of the argument state must not be "
1090 "larger than the one of the target state");
1091
1092 state_type result;
1093 result[0] = state[0];
1094 for (unsigned int i = 1; i < dim2 + 1; ++i)
1095 result[i] = state[i];
1096
1097 return result;
1098 }
1099
1100
1101 template <int dim, typename Number, typename MemorySpace>
1102 template <typename ST>
1103 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1105 const ST &initial_state) const -> state_type
1106 {
1107 const auto primitive_state = expand_state(initial_state);
1108 return from_primitive_state(primitive_state);
1109 }
1110
1111
1112 template <int dim, typename Number, typename MemorySpace>
1113 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1115 const state_type &primitive_state) const -> state_type
1116 {
1117 const auto rho = density(primitive_state);
1118
1119 auto state = primitive_state;
1120 /* Fix up momentum: */
1121 for (unsigned int i = 1; i < dim + 1; ++i)
1122 state[i] *= rho;
1123
1124 return state;
1125 }
1126
1127
1128 template <int dim, typename Number, typename MemorySpace>
1129 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1131 const state_type &state) const -> state_type
1132 {
1133 const auto rho = density(state);
1134 const auto rho_inverse = Number(1.) / rho;
1135
1136 auto primitive_state = state;
1137 /* Fix up velocity: */
1138 for (unsigned int i = 1; i < dim + 1; ++i)
1139 primitive_state[i] *= rho_inverse;
1140
1141 return primitive_state;
1142 }
1143
1144
1145 template <int dim, typename Number, typename MemorySpace>
1146 template <typename Lambda>
1147 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1149 const state_type &state, const Lambda &lambda) const -> state_type
1150 {
1151 auto result = state;
1152 const auto M = lambda(momentum(state));
1153 for (unsigned int d = 0; d < dim; ++d)
1154 result[1 + d] = M[d];
1155 return result;
1156 }
1157 } // namespace EulerBarotropic
1158} // namespace ryujin
HyperbolicSystemView(const HyperbolicSystem &hyperbolic_system)
DEAL_II_HOST_DEVICE bool is_admissible(const state_type &U) const
DEAL_II_HOST_DEVICE Number total_energy(const state_type &U, const Number &specific_internal_energy) const
DEAL_II_HOST_DEVICE flux_contribution_type flux_contribution(const PrecomputedVectorView &pv, const InitialPrecomputedVectorView &piv, const unsigned int i, const state_type &U_i) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber vacuum_state_relaxation_small() const
DEAL_II_HOST_DEVICE state_type nodal_source(const PrecomputedVectorView &pv, const unsigned int i, const state_type &U_i, const ScalarNumber tau) const =delete
static constexpr unsigned int problem_dimension
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
DEAL_II_ALWAYS_INLINE Number beos_pressure(const Number &rho) const
static constexpr unsigned int n_initial_precomputed_values
DEAL_II_HOST_DEVICE state_type from_primitive_state(const state_type &primitive_state) const
static DEAL_II_HOST_DEVICE Number density(const state_type &U)
std::array< Number, n_precomputed_values > precomputed_type
dealii::Tensor< 1, problem_dimension, Number > state_type
DEAL_II_HOST_DEVICE state_type from_initial_state(const ST &initial_state) const
typename get_value_type< Number >::type ScalarNumber
DEAL_II_HOST_DEVICE Number filter_vacuum_density(const Number &rho) const
static constexpr unsigned int n_precomputed_values
dealii::Tensor< 1, problem_dimension, dealii::Tensor< 1, dim, Number > > flux_type
DEAL_II_ALWAYS_INLINE Number beos_specific_internal_energy(const Number &rho) const
DEAL_II_HOST_DEVICE state_type total_energy_derivative(const state_type &U, const Number &specific_internal_energy, const Number &pressure) const
DEAL_II_HOST_DEVICE state_type apply_galilei_transform(const state_type &state, const Lambda &lambda) const
DEAL_II_HOST_DEVICE 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_HOST_DEVICE_ALWAYS_INLINE ScalarNumber reference_density() const
static DEAL_II_HOST_DEVICE dealii::Tensor< 1, dim, Number > momentum(const state_type &U)
DEAL_II_HOST_DEVICE state_type to_primitive_state(const state_type &state) const
DEAL_II_HOST_DEVICE state_type expand_state(const ST &state) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber vacuum_state_relaxation_large() const
DEAL_II_ALWAYS_INLINE Number beos_speed_of_sound(const Number &rho) const
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
DEAL_II_HOST_DEVICE flux_type f(const state_type &U, const Number &p) const
DEAL_II_HOST_DEVICE 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 const std::string & barotropic_equation_of_state() const
std::array< Number, n_initial_precomputed_values > initial_precomputed_type
DEAL_II_HOST_DEVICE 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
void fill_precomputed_values(const OfflineData< dim, ScalarNumber > &offline_data, StateVector< ScalarNumber > &state_vector, const bool skip_constrained_dofs=true) const
HyperbolicSystem(const std::string &subsection="/HyperbolicSystem")
dealii::Tensor< 1, problem_dimension, Number > state_type
static Base & select(const std::vector< std::unique_ptr< Base > > &objects, const std::string &name)
Definition library.h:189
static std::vector< std::unique_ptr< Base > > create(Args... args)
Definition library.h:148
static dealii::Patterns::Selection selection(const std::vector< std::unique_ptr< Base > > &objects)
Definition library.h:178
constexpr bool have_separate_memory_spaces
Definition gpu.h:29
@ dirichlet_momentum
@ dirichlet_velocity
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)
MultiComponentVector< Number > state
MultiComponentVector< Number > precomputed