ryujin 2.1.1 revision b04fb4aba7bd97ddfa5994a6b4b6e8586eb15db2
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 <compile_time_options.h>
9
10#include <ryujin/interface/hyperbolic_system.h>
11
13
14#include <convenience_macros.h>
15#include <discretization.h>
16#include <gpu.h>
17#include <loop.h>
19#include <patterns_conversion.h>
20#include <simd.h>
21#include <state_vector.h>
22
23#include <deal.II/base/memory_space.h>
24#include <deal.II/base/parameter_acceptor.h>
25#include <deal.II/base/tensor.h>
26
27#include <array>
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
51 class HyperbolicSystem final : public Interface::HyperbolicSystem
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
132 barotropic_equation_of_state_list_;
133
134 using BarotropicEquationOfState =
136 std::shared_ptr<BarotropicEquationOfState>
137 selected_barotropic_equation_of_state_;
138
139 template <int, typename, typename>
141
143 }; /* HyperbolicSystem */
144
145
167 template <int dim, typename Number, typename MemorySpace>
169 {
170 public:
171 static_assert(
172 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
173 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
174 "Unexpected memory space");
175
180
185
189 static constexpr unsigned int problem_dimension = 1 + dim;
190
194 using state_type = dealii::Tensor<1, problem_dimension, Number>;
195
199 using flux_type =
200 dealii::Tensor<1, problem_dimension, dealii::Tensor<1, dim, Number>>;
201
206
210 static constexpr unsigned int n_precomputed_values = 3;
211
215 using precomputed_type = std::array<Number, n_precomputed_values>;
216
220 static constexpr unsigned int n_initial_precomputed_values = 0;
221
226 std::array<Number, n_initial_precomputed_values>;
227
228 template <int n_comp>
231
237
244
246
250
255 HyperbolicSystemView(const HyperbolicSystem &hyperbolic_system)
256 : parameters_(
257 hyperbolic_system.parameters_.template view<MemorySpace>())
258 , barotropic_equation_of_state_(
259 hyperbolic_system.selected_barotropic_equation_of_state_.get())
260 {
261 }
262
264
268
274 DEAL_II_ALWAYS_INLINE inline const std::string &
276 {
277 return barotropic_equation_of_state_->name();
278 }
279
280 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber reference_density() const
281 {
282 return ScalarNumber(parameters_->reference_density);
283 }
284
285 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber
287 {
288 return ScalarNumber(parameters_->vacuum_state_relaxation_small);
289 }
290
291 DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber
293 {
294 return ScalarNumber(parameters_->vacuum_state_relaxation_large);
295 }
296
298
307
312 DEAL_II_ALWAYS_INLINE inline Number
313 beos_specific_internal_energy(const Number &rho) const
314 {
315 const auto &beos = barotropic_equation_of_state_;
316
317 if constexpr (std::is_same_v<ScalarNumber, Number>) {
318 return ScalarNumber(beos->specific_internal_energy(rho));
319 } else {
320 Number e;
321 for (unsigned int k = 0; k < Number::size(); ++k) {
322 e[k] = ScalarNumber(beos->specific_internal_energy(rho[k]));
323 }
324 return e;
325 }
326 }
327
331 DEAL_II_ALWAYS_INLINE inline Number beos_pressure(const Number &rho) const
332 {
333 const auto &beos = barotropic_equation_of_state_;
334
335 if constexpr (std::is_same_v<ScalarNumber, Number>) {
336 return ScalarNumber(beos->pressure(rho));
337 } else {
338 Number p;
339 for (unsigned int k = 0; k < Number::size(); ++k) {
340 p[k] = ScalarNumber(beos->pressure(rho[k]));
341 }
342 return p;
343 }
344 }
345
350 DEAL_II_ALWAYS_INLINE inline Number
351 beos_speed_of_sound(const Number &rho) const
352 {
353 const auto &beos = barotropic_equation_of_state_;
354
355 if constexpr (std::is_same_v<ScalarNumber, Number>) {
356 return ScalarNumber(beos->speed_of_sound(rho));
357 } else {
358 Number a;
359 for (unsigned int k = 0; k < Number::size(); ++k) {
360 a[k] = ScalarNumber(beos->speed_of_sound(rho[k]));
361 }
362 return a;
363 }
364 }
365
367
371
372 static constexpr bool have_gamma = false;
373 static constexpr bool have_covolume_constant = false;
374 static constexpr bool have_energy_equation = false;
375
377
381
386 static DEAL_II_HOST_DEVICE Number density(const state_type &U);
387
394 DEAL_II_HOST_DEVICE Number filter_vacuum_density(const Number &rho) const;
395
400 static DEAL_II_HOST_DEVICE dealii::Tensor<1, dim, Number>
401 momentum(const state_type &U);
402
410 DEAL_II_HOST_DEVICE Number total_energy(
411 const state_type &U, const Number &specific_internal_energy) const;
412
418 DEAL_II_HOST_DEVICE state_type
420 const Number &specific_internal_energy,
421 const Number &pressure) const;
422
428 DEAL_II_HOST_DEVICE bool is_admissible(const state_type &U) const;
429
431
435
445 template <int component>
447 const state_type &U,
448 const Number &p,
449 const state_type &U_bar,
450 const Number &p_bar,
451 const dealii::Tensor<1, dim, Number> &normal) const;
452
475 template <typename Lambda>
477 apply_boundary_conditions(const dealii::types::boundary_id id,
478 const state_type &U,
479 const dealii::Tensor<1, dim, Number> &normal,
480 const Lambda &get_dirichlet_data) const;
481
483
487
497 DEAL_II_HOST_DEVICE flux_type f(const state_type &U,
498 const Number &p) const;
499
519 DEAL_II_HOST_DEVICE
523 const unsigned int i,
524 const state_type &U_i) const;
525
526 DEAL_II_HOST_DEVICE
530 const unsigned int *js,
531 const state_type &U_j) const;
532
537 DEAL_II_HOST_DEVICE
540 const flux_contribution_type &flux_j,
541 const dealii::Tensor<1, dim, Number> &c_ij) const;
542
546 static constexpr bool have_high_order_flux = false;
547
548 DEAL_II_HOST_DEVICE
550 const flux_contribution_type &flux_i,
551 const flux_contribution_type &flux_j,
552 const dealii::Tensor<1, dim, Number> &c_ij) const = delete;
553
555
559
561 static constexpr bool have_source_terms = false;
562
563 DEAL_II_HOST_DEVICE
565 const unsigned int i,
566 const state_type &U_i,
567 const ScalarNumber tau) const = delete;
568
569 DEAL_II_HOST_DEVICE
571 const unsigned int *js,
572 const state_type &U_j,
573 const ScalarNumber tau) const = delete;
574
576
580
591 template <typename ST>
592 DEAL_II_HOST_DEVICE state_type expand_state(const ST &state) const;
593
606 template <typename ST>
607 DEAL_II_HOST_DEVICE state_type
608 from_initial_state(const ST &initial_state) const;
609
614 DEAL_II_HOST_DEVICE
615 state_type from_primitive_state(const state_type &primitive_state) const;
616
620 DEAL_II_HOST_DEVICE
621 state_type to_primitive_state(const state_type &state) const;
622
628 template <typename Lambda>
630 const state_type &state, const Lambda &lambda) const;
631
632 private:
634
638
639 const HyperbolicSystem::Parameters *const parameters_;
640
641 /* Only valid (and dereferenced) on the host: */
643 *const barotropic_equation_of_state_;
644
646 }; /* HyperbolicSystemView */
647
648
649 /*
650 * -------------------------------------------------------------------------
651 * Inline definitions
652 * -------------------------------------------------------------------------
653 */
654
655
656 inline HyperbolicSystem::HyperbolicSystem(const std::string &subsection)
657 : Interface::HyperbolicSystem(
658 "Compressible Euler equations "
659 "(barotropic EOS, optimized barotropic)",
660 {{{"rho", "m"},
661 {"rho", "m_1", "m_2"},
662 {"rho", "m_1", "m_2", "m_3"}}},
663 {{{"rho", "v"},
664 {"rho", "v_1", "v_2"},
665 {"rho", "v_1", "v_2", "v_3"}}},
666 {{{"e", "p", "a"}, {"e", "p", "a"}, {"e", "p", "a"}}},
667 {},
668 subsection)
669 , parameters_("euler_barotropic_hyperbolic_system_parameters",
671 {
672 /* reference remains valid due to implicit_transfers_host_resident */
673 auto &parameters = *parameters_.view();
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
681 parameters.reference_density = 1.;
682 add_parameter("reference density",
683 parameters.reference_density,
684 "Problem specific density reference");
685
686 parameters.vacuum_state_relaxation_small = 1.e2;
687 add_parameter("vacuum state relaxation small",
688 parameters.vacuum_state_relaxation_small,
689 "Problem specific vacuum relaxation parameter");
690
691 parameters.vacuum_state_relaxation_large = 1.e4;
692 add_parameter("vacuum state relaxation large",
693 parameters.vacuum_state_relaxation_large,
694 "Problem specific vacuum relaxation parameter");
695
696 /*
697 * And finally populate the equation of state list with all equation of
698 * state configurations defined in the EquationOfState namespace:
699 */
701 barotropic_equation_of_state_list_, subsection);
702
703 ParameterAcceptor::parse_parameters_call_back.connect(
704 [this] { update_parameters(); });
705
706 update_parameters();
707 }
708
709
710 inline void HyperbolicSystem::update_parameters()
711 {
712 bool initialized = false;
713 for (auto &it : barotropic_equation_of_state_list_)
714
715 /* Populate EOS-specific quantities and functions */
716 if (it->name() == barotropic_equation_of_state_) {
717 selected_barotropic_equation_of_state_ = it;
718 problem_name_ = "Compressible Euler equations (" + it->name() +
719 " EOS, optimized barotropic)";
720 initialized = true;
721 break;
722 }
723
724 AssertThrow(initialized,
725 dealii::ExcMessage("Could not find a barotropic equation "
726 "of state description with name \"" +
727 barotropic_equation_of_state_ + "\""));
728
729 /* invalidates view on default memory space */
730 parameters_.view();
731 }
732
733
734 template <typename MemorySpace, int dim, typename ScalarNumber>
736 const OfflineData<dim, ScalarNumber> &offline_data,
737 StateVector<ScalarNumber> &state_vector,
738 const bool skip_constrained_dofs) const
739 {
740 using HostSpace = dealii::MemorySpace::Host;
741
742 const unsigned int n_internal = offline_data.n_locally_internal();
743 const unsigned int n_owned = offline_data.n_locally_owned();
744
746
747 auto &U = state_vector.U;
748 auto &precomputed = state_vector.precomputed;
749
750 /*
751 * Compute the specific internal energy, pressure, and speed of sound.
752 * This requires calling into the selected equation of state, which
753 * is only possible on the host memory space. Thus, temporarily
754 * transfer the state vector and the precomputed values to the host
755 * memory space:
756 */
757
758 constexpr bool transfer =
760 !std::is_same_v<MemorySpace, dealii::MemorySpace::Host>;
761
762 [[maybe_unused]] const bool host_resident =
763 U.template is_resident<HostSpace>();
764
765 if constexpr (transfer) {
766 U.template copy_to_memory_space<HostSpace>();
767 precomputed.template move_to_memory_space<HostSpace>();
768 }
769
770 {
771 const auto sparsity_simd_view =
772 offline_data.sparsity_pattern_simd().template view<HostSpace>();
773
774 /* We only read the hyperbolic state vector: */
775 const auto U_view =
776 std::as_const(U)
777 .template view<ScalarView::problem_dimension, HostSpace>();
778 const auto precomputed_view =
780 .template view<ScalarView::n_precomputed_values, HostSpace>();
781
782 const auto hyperbolic_system_views =
783 make_select_view<dim, ScalarNumber, HostSpace>(*this);
784
785 const auto body = [=](auto sentinel, unsigned int i) {
786 using T = decltype(sentinel);
788 using precomputed_type = typename View::precomputed_type;
789
790 const unsigned int row_length = sparsity_simd_view.row_length(i);
791 if (skip_constrained_dofs && row_length == 1)
792 return;
793
794 const auto view = hyperbolic_system_views.template view<T>();
795
796 const auto U_i = U_view.template read_tensor<T>(i);
797 const auto rho_i = view.density(U_i);
798
799 /* Calls into the selected equation of state: */
800 const auto e_i = view.beos_specific_internal_energy(rho_i);
801 const auto p_i = view.beos_pressure(rho_i);
802 const auto a_i = view.beos_speed_of_sound(rho_i);
803
804 const precomputed_type prec_i{e_i, p_i, a_i};
805 precomputed_view.template write_tensor<T>(prec_i, i);
806 };
807
808 loop<HostSpace, ScalarNumber>(
809 "hyperbolic_kernel_01b", body, 0, n_internal, n_owned);
810 }
811
812 if constexpr (transfer) {
813 /* Drop the (now stale) host mirror unless it was resident before: */
814 if (!host_resident)
815 U.template move_to_memory_space<MemorySpace>();
816 precomputed.template move_to_memory_space<MemorySpace>();
817 }
818 }
819
820
821 template <int dim, typename Number, typename MemorySpace>
822 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
827
828
829 template <int dim, typename Number, typename MemorySpace>
830 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
832 const Number &rho) const
833 {
834 constexpr ScalarNumber eps = std::numeric_limits<ScalarNumber>::epsilon();
835 const Number rho_cutoff_large =
836 reference_density() * vacuum_state_relaxation_large() * eps;
837
838 return ryujin::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
839 std::abs(rho), rho_cutoff_large, Number(0.), rho);
840 }
841
842
843 template <int dim, typename Number, typename MemorySpace>
844 DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor<1, dim, Number>
846 const state_type &U)
847 {
848 dealii::Tensor<1, dim, Number> result;
849 for (unsigned int i = 0; i < dim; ++i)
850 result[i] = U[1 + i];
851 return result;
852 }
853
854
855 template <int dim, typename Number, typename MemorySpace>
856 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
858 const state_type &U, const Number &specific_internal_energy) const
859 {
860 const auto rho = density(U);
861 const auto rho_inverse = ScalarNumber(1.) / rho;
862 const auto m = momentum(U);
863
864 return rho * specific_internal_energy +
865 ScalarNumber(0.5) * rho_inverse * m.norm_square();
866 }
867
868
869 template <int dim, typename Number, typename MemorySpace>
870 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
872 const state_type &U,
873 const Number &specific_internal_energy,
874 const Number &pressure) const -> state_type
875 {
876 const auto rho = density(U);
877 const auto rho_inverse = ScalarNumber(1.) / rho;
878 const auto m = momentum(U);
879
880 state_type result;
881
882 result[0] =
883 specific_internal_energy + rho_inverse * pressure -
884 ScalarNumber(0.5) * rho_inverse * rho_inverse * m.norm_square();
885 for (unsigned int i = 0; i < dim; ++i)
886 result[1 + i] = rho_inverse * m[i];
887
888 return result;
889 }
890
891
892 template <int dim, typename Number, typename MemorySpace>
893 DEAL_II_HOST_DEVICE_ALWAYS_INLINE bool
895 const state_type &U) const
896 {
897 const auto rho = density(U);
898 constexpr auto gt = dealii::SIMDComparison::greater_than;
899 using T = Number;
900 const auto test =
901 ryujin::compare_and_apply_mask<gt>(rho, T(0.), T(0.), T(-1.));
902
903#ifdef DEBUG_OUTPUT
904 if (!(test == Number(0.))) {
905 std::cout << std::fixed << std::setprecision(16);
906 std::cout << "Bounds violation: Negative state [rho, e] detected!\n";
907 std::cout << "\t\trho: " << rho << "\n";
908 }
909#endif
910
911 return (test == Number(0.));
912 }
913
914
915 template <int dim, typename Number, typename MemorySpace>
916 template <int component>
917 DEAL_II_ALWAYS_INLINE inline auto
920 const state_type & /*U*/,
921 const Number & /*p*/,
922 const state_type & /*U_bar*/,
923 const Number & /*p_bar*/,
924 const dealii::Tensor<1, dim, Number> & /*normal*/) const
925 -> state_type
926 {
927 // FIXME
928 AssertThrow(false, dealii::ExcNotImplemented());
929 __builtin_trap();
930 return state_type{};
931 }
932
933
934 template <int dim, typename Number, typename MemorySpace>
935 template <typename Lambda>
936 DEAL_II_ALWAYS_INLINE inline auto
938 dealii::types::boundary_id id,
939 const state_type &U,
940 const dealii::Tensor<1, dim, Number> &normal,
941 const Lambda &get_dirichlet_data) const -> state_type
942 {
943 state_type result = U;
944
945 if (id == Boundary::dirichlet) {
946 result = get_dirichlet_data();
947
948 } else if (id == Boundary::dirichlet_momentum) {
949 /* Only enforce Dirichlet conditions on the momentum: */
950 auto m_dirichlet = momentum(get_dirichlet_data());
951 for (unsigned int k = 0; k < dim; ++k)
952 result[k + 1] = m_dirichlet[k];
953
954 } else if (id == Boundary::dirichlet_velocity) {
955 /* Only enforce Dirichlet conditions on the velocity: */
956 const auto U_dirichlet = get_dirichlet_data();
957 const auto rho_dirichlet = density(U_dirichlet);
958 const auto v_dirichlet = momentum(U_dirichlet) / rho_dirichlet;
959 const auto rho = density(result);
960 for (unsigned int k = 0; k < dim; ++k)
961 result[k + 1] = rho * v_dirichlet[k];
962
963 } else if (id == Boundary::slip) {
964 auto m = momentum(U);
965 m -= 1. * (m * normal) * normal;
966 for (unsigned int k = 0; k < dim; ++k)
967 result[k + 1] = m[k];
968
969 } else if (id == Boundary::no_slip) {
970 for (unsigned int k = 0; k < dim; ++k)
971 result[k + 1] = Number(0.);
972
973 } else if (id == Boundary::dynamic) {
974 /*
975 * On dynamic boundary conditions, we distinguish four cases:
976 *
977 * - supersonic inflow: prescribe full state
978 * - subsonic inflow:
979 * decompose into Riemann invariants and leave R_2
980 * characteristic untouched.
981 * - supersonic outflow: do nothing
982 * - subsonic outflow:
983 * decompose into Riemann invariants and prescribe incoming
984 * R_1 characteristic.
985 */
986 const auto m = momentum(U);
987 const auto rho = density(U);
988
989 /*
990 * We do not have precomputed values available. Thus, simply query
991 * the pressure and speed of sound oracle:
992 */
993 const auto p = beos_pressure(rho);
994 const auto a = beos_speed_of_sound(rho);
995 const auto vn = m * normal / rho;
996
997 /* Supersonic inflow: */
998 if (vn < -a) {
999 result = get_dirichlet_data();
1000 }
1001
1002 /* Subsonic inflow: */
1003 if (vn >= -a && vn <= 0.) {
1004 const auto U_dirichlet = get_dirichlet_data();
1005 const auto rho_dirichlet = density(U_dirichlet);
1006 const auto p_dirichlet = beos_pressure(rho_dirichlet);
1007
1008 result = prescribe_riemann_characteristic<2>(
1009 U_dirichlet, p_dirichlet, U, p, normal);
1010 }
1011
1012 /* Subsonic outflow: */
1013 if (vn > 0. && vn <= a) {
1014 const auto U_dirichlet = get_dirichlet_data();
1015 const auto rho_dirichlet = density(U_dirichlet);
1016 const auto p_dirichlet = beos_pressure(rho_dirichlet);
1017
1018 result = prescribe_riemann_characteristic<1>(
1019 U, p, U_dirichlet, p_dirichlet, normal);
1020 }
1021 /* Supersonic outflow: do nothing, i.e., keep U as is */
1022
1023 } else {
1024 AssertThrow(false, dealii::ExcNotImplemented());
1025 }
1026
1027 return result;
1028 }
1029
1030
1031 template <int dim, typename Number, typename MemorySpace>
1032 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1034 const Number &p) const
1035 -> flux_type
1036 {
1037 const auto rho_inverse = ScalarNumber(1.) / density(U);
1038 const auto m = momentum(U);
1039
1040 flux_type result;
1041
1042 result[0] = m;
1043 for (unsigned int i = 0; i < dim; ++i) {
1044 result[1 + i] = m * (m[i] * rho_inverse);
1045 result[1 + i][i] += p;
1046 }
1047
1048 return result;
1049 }
1050
1051
1052 template <int dim, typename Number, typename MemorySpace>
1053 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1055 const PrecomputedVectorView &pv,
1056 const InitialPrecomputedVectorView & /*piv*/,
1057 const unsigned int i,
1058 const state_type &U_i) const -> flux_contribution_type
1059 {
1060 const auto &[e_i, p_i, a_i] =
1061 pv.template read_tensor<Number, precomputed_type>(i);
1062 return f(U_i, p_i);
1063 }
1064
1065
1066 template <int dim, typename Number, typename MemorySpace>
1067 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1069 const PrecomputedVectorView &pv,
1070 const InitialPrecomputedVectorView & /*piv*/,
1071 const unsigned int *js,
1072 const state_type &U_j) const -> flux_contribution_type
1073 {
1074 const auto &[e_j, p_j, a_j] =
1075 pv.template read_tensor<Number, precomputed_type>(js);
1076 return f(U_j, p_j);
1077 }
1078
1079
1080 template <int dim, typename Number, typename MemorySpace>
1081 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1083 const flux_contribution_type &flux_i,
1084 const flux_contribution_type &flux_j,
1085 const dealii::Tensor<1, dim, Number> &c_ij) const -> state_type
1086 {
1087 return -contract(add(flux_i, flux_j), c_ij);
1088 }
1089
1090
1091 template <int dim, typename Number, typename MemorySpace>
1092 template <typename ST>
1093 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1095 const ST &state) const -> state_type
1096 {
1097 using T = typename ST::value_type;
1098 static_assert(std::is_same_v<Number, T>, "template mismatch");
1099
1100 constexpr auto dim2 = ST::dimension - 1;
1101 static_assert(dim >= dim2,
1102 "the space dimension of the argument state must not be "
1103 "larger than the one of the target state");
1104
1105 state_type result;
1106 result[0] = state[0];
1107 for (unsigned int i = 1; i < dim2 + 1; ++i)
1108 result[i] = state[i];
1109
1110 return result;
1111 }
1112
1113
1114 template <int dim, typename Number, typename MemorySpace>
1115 template <typename ST>
1116 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1118 const ST &initial_state) const -> state_type
1119 {
1120 const auto primitive_state = expand_state(initial_state);
1121 return from_primitive_state(primitive_state);
1122 }
1123
1124
1125 template <int dim, typename Number, typename MemorySpace>
1126 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1128 const state_type &primitive_state) const -> state_type
1129 {
1130 const auto rho = density(primitive_state);
1131
1132 auto state = primitive_state;
1133 /* Fix up momentum: */
1134 for (unsigned int i = 1; i < dim + 1; ++i)
1135 state[i] *= rho;
1136
1137 return state;
1138 }
1139
1140
1141 template <int dim, typename Number, typename MemorySpace>
1142 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1144 const state_type &state) const -> state_type
1145 {
1146 const auto rho = density(state);
1147 const auto rho_inverse = Number(1.) / rho;
1148
1149 auto primitive_state = state;
1150 /* Fix up velocity: */
1151 for (unsigned int i = 1; i < dim + 1; ++i)
1152 primitive_state[i] *= rho_inverse;
1153
1154 return primitive_state;
1155 }
1156
1157
1158 template <int dim, typename Number, typename MemorySpace>
1159 template <typename Lambda>
1160 DEAL_II_HOST_DEVICE_ALWAYS_INLINE auto
1162 const state_type &state, const Lambda &lambda) const -> state_type
1163 {
1164 auto result = state;
1165 const auto M = lambda(momentum(state));
1166 for (unsigned int d = 0; d < dim; ++d)
1167 result[1 + d] = M[d];
1168 return result;
1169 }
1170 } // namespace EulerBarotropic
1171} // 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
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)
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)
std::set< std::shared_ptr< BarotropicEquationOfState > > equation_of_state_list_type
MultiComponentVector< Number > U
MultiComponentVector< Number > precomputed