8#include <compile_time_options.h>
10#include <ryujin/interface/hyperbolic_system.h>
23#include <deal.II/base/memory_space.h>
24#include <deal.II/base/parameter_acceptor.h>
25#include <deal.II/base/tensor.h>
31 namespace ScalarConservation
35 typename MemorySpace = dealii::MemorySpace::Host>
36 class HyperbolicSystemView;
66 typename Number = double,
67 typename MemorySpace = dealii::MemorySpace::Host>
79 typename MemorySpace = dealii::MemorySpace::Host>
98 template <
typename MemorySpace = dealii::MemorySpace::Host,
100 typename ScalarNumber>
104 const bool skip_constrained_dofs =
true)
const;
116 void update_parameters();
125 std::shared_ptr<Flux> selected_flux_;
127 template <
int,
typename,
typename>
144 template <
int dim,
typename Number,
typename MemorySpace>
149 std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
150 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
151 "Unexpected memory space");
171 using state_type = dealii::Tensor<1, problem_dimension, Number>;
177 dealii::Tensor<1, problem_dimension, dealii::Tensor<1, dim, Number>>;
203 std::array<Number, n_initial_precomputed_values>;
205 template <
int n_comp>
234 hyperbolic_system.parameters_.template view<MemorySpace>())
235 , flux_(hyperbolic_system.selected_flux_.get())
250 DEAL_II_ALWAYS_INLINE
inline const std::string &
flux()
const
252 return flux_->name();
274 DEAL_II_ALWAYS_INLINE
inline dealii::Tensor<1, dim, Number>
280 DEAL_II_ALWAYS_INLINE
inline dealii::Tensor<1, dim, Number>
312 DEAL_II_HOST_DEVICE Number
322 const Number &u)
const;
331 DEAL_II_HOST_DEVICE Number
339 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
bool
354 template <
typename Lambda>
358 const dealii::Tensor<1, dim, Number> &normal,
359 const Lambda &get_dirichlet_data)
const;
371 DEAL_II_HOST_DEVICE dealii::Tensor<1, dim, Number>
379 DEAL_II_HOST_DEVICE dealii::Tensor<1, dim, Number>
406 const unsigned int i,
413 const unsigned int *js,
424 const dealii::Tensor<1, dim, Number> &c_ij)
const;
432 const dealii::Tensor<1, dim, Number> &c_ij)
const =
delete;
444 const unsigned int i,
449 const unsigned int *js,
469 template <
typename ST>
483 return primitive_state;
501 template <
typename Lambda>
533 "Scalar conservation equation",
534 {{{
"u"}, {
"u"}, {
"u"}}},
535 {{{
"u"}, {
"u"}, {
"u"}}},
537 {
"f_1",
"f_2",
"df_1",
"df_2"},
538 {
"f_1",
"f_2",
"f_3",
"df_1",
"df_2",
"df_3"}}},
541 , parameters_(
"scalar_conservation_hyperbolic_system_parameters",
545 add_parameter(
"flux",
547 "The scalar flux. Valid names are given by any of the "
548 "subsections defined below");
561 ParameterAcceptor::parse_parameters_call_back.connect(
562 [
this] { update_parameters(); });
563 for (
auto &it : flux_list_)
564 it->parse_parameters_call_back.connect([this] { update_parameters(); });
570 inline void HyperbolicSystem::update_parameters()
572 bool initialized =
false;
573 for (
auto &it : flux_list_)
576 if (it->name() == flux_) {
578 problem_name_ =
"Scalar conservation equation (" + it->name() +
": " +
579 it->flux_formula() +
")";
586 dealii::ExcMessage(
"Could not find a flux description with name \"" +
590 auto ¶meters = *parameters_.view();
592 parameters.derivative_approximation_delta =
593 selected_flux_->derivative_approximation_delta();
597 template <
typename MemorySpace,
int dim,
typename ScalarNumber>
601 const bool skip_constrained_dofs)
const
603 using HostSpace = dealii::MemorySpace::Host;
610 auto &U = state_vector.
U;
620 constexpr bool transfer =
622 !std::is_same_v<MemorySpace, dealii::MemorySpace::Host>;
624 [[maybe_unused]]
const bool host_resident =
625 U.template is_resident<HostSpace>();
627 if constexpr (transfer) {
628 U.template copy_to_memory_space<HostSpace>();
629 precomputed.template move_to_memory_space<HostSpace>();
633 const auto sparsity_simd_view =
639 .template view<ScalarView::problem_dimension, HostSpace>();
640 const auto precomputed_view =
642 .template view<ScalarView::n_precomputed_values, HostSpace>();
644 const auto hyperbolic_system_views =
645 make_select_view<dim, ScalarNumber, HostSpace>(*
this);
647 const auto body = [=](
auto sentinel,
unsigned int i) {
648 using T =
decltype(sentinel);
652 const unsigned int row_length = sparsity_simd_view.row_length(i);
653 if (skip_constrained_dofs && row_length == 1)
656 const auto view = hyperbolic_system_views.template view<T>();
658 const auto U_i = U_view.template read_tensor<T>(i);
659 const auto u_i =
view.state(U_i);
662 const auto f_i =
view.flux_function(u_i);
663 const auto df_i =
view.flux_gradient_function(u_i);
665 precomputed_type prec_i;
668 prec_i[dim + k] = df_i[k];
670 precomputed_view.template write_tensor<T>(prec_i, i);
673 loop<HostSpace, ScalarNumber>(
674 "hyperbolic_kernel_01b", body, 0, n_internal, n_owned);
677 if constexpr (transfer) {
680 U.template move_to_memory_space<MemorySpace>();
681 precomputed.template move_to_memory_space<MemorySpace>();
686 template <
int dim,
typename Number,
typename MemorySpace>
687 DEAL_II_ALWAYS_INLINE
inline dealii::Tensor<1, dim, Number>
689 const Number &u)
const
691 const auto &flux = flux_;
692 dealii::Tensor<1, dim, Number> result;
695 for (
unsigned int k = 0; k < dim; ++k) {
696 if constexpr (std::is_same_v<ScalarNumber, Number>) {
697 result[k] = flux->value(u, k);
699 for (
unsigned int s = 0; s < Number::size(); ++s) {
700 result[k][s] = flux->value(u[s], k);
708 template <
int dim,
typename Number,
typename MemorySpace>
709 DEAL_II_ALWAYS_INLINE
inline dealii::Tensor<1, dim, Number>
711 const Number &u)
const
713 const auto &flux = flux_;
714 dealii::Tensor<1, dim, Number> result;
717 for (
unsigned int k = 0; k < dim; ++k) {
718 if constexpr (std::is_same_v<ScalarNumber, Number>) {
719 result[k] = flux->gradient(u, k);
721 for (
unsigned int s = 0; s < Number::size(); ++s) {
722 result[k][s] = flux->gradient(u[s], k);
731 template <
int dim,
typename Number,
typename MemorySpace>
732 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
739 template <
int dim,
typename Number,
typename MemorySpace>
740 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
742 const Number &u)
const
748 template <
int dim,
typename Number,
typename MemorySpace>
749 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
751 const Number &u)
const
757 template <
int dim,
typename Number,
typename MemorySpace>
758 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
760 const Number &k,
const Number &u)
const
762 return std::abs(k - u);
766 template <
int dim,
typename Number,
typename MemorySpace>
767 DEAL_II_HOST_DEVICE_ALWAYS_INLINE Number
769 const Number &k,
const Number &u)
const
771 constexpr auto gte = dealii::SIMDComparison::greater_than_or_equal;
773 return ryujin::compare_and_apply_mask<gte>(u, k, Number(1.), Number(-1.));
777 template <
int dim,
typename Number,
typename MemorySpace>
778 template <
typename Lambda>
779 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
781 dealii::types::boundary_id
id,
783 const dealii::Tensor<1, dim, Number> & ,
784 const Lambda &get_dirichlet_data)
const ->
state_type
789 result = get_dirichlet_data();
794 "Invalid boundary ID »Boundary::dirichlet_momentum«, "
795 "enforcing Dirichlet boundary conditions on a momentum "
796 "is not possible for scalar conservation equations."));
801 "Invalid boundary ID »Boundary::dirichlet_velocity«, "
802 "enforcing Dirichlet boundary conditions on a momentum "
803 "is not possible for scalar conservation equations."));
808 dealii::ExcMessage(
"Invalid boundary ID »Boundary::slip«, slip "
809 "boundary conditions are unavailable for scalar "
810 "conservation equations."));
815 dealii::ExcMessage(
"Invalid boundary ID »Boundary::no_slip«, "
816 "no-slip boundary conditions are unavailable "
817 "for scalar conservation equations."));
822 dealii::ExcMessage(
"Invalid boundary ID »Boundary::dynamic«, "
823 "dynamic boundary conditions are unavailable "
824 "for scalar conservation equations."));
828 Assert(
false, dealii::ExcNotImplemented());
835 template <
int dim,
typename Number,
typename MemorySpace>
836 DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor<1, dim, Number>
840 dealii::Tensor<1, dim, Number> result;
841 for (
unsigned int k = 0; k < dim; ++k)
847 template <
int dim,
typename Number,
typename MemorySpace>
848 DEAL_II_HOST_DEVICE_ALWAYS_INLINE dealii::Tensor<1, dim, Number>
853 dealii::Tensor<1, dim, Number> result;
854 for (
unsigned int k = 0; k < dim; ++k)
860 template <
int dim,
typename Number,
typename MemorySpace>
861 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
865 const unsigned int i,
870 result[0] = construct_flux_tensor(
871 pv.template read_tensor<Number, precomputed_type>(i));
876 template <
int dim,
typename Number,
typename MemorySpace>
877 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
881 const unsigned int *js,
886 result[0] = construct_flux_tensor(
887 pv.template read_tensor<Number, precomputed_type>(js));
892 template <
int dim,
typename Number,
typename MemorySpace>
893 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
auto
897 const dealii::Tensor<1, dim, Number> &c_ij)
const ->
state_type
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
DEAL_II_HOST_DEVICE dealii::Tensor< 1, dim, Number > construct_flux_gradient_tensor(const precomputed_type &precomputed_state) const
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
DEAL_II_HOST_DEVICE_ALWAYS_INLINE state_type from_primitive_state(const state_type &primitive_state) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE ScalarNumber derivative_approximation_delta() const
DEAL_II_HOST_DEVICE Number square_entropy_derivative(const Number &u) const
dealii::Tensor< 1, problem_dimension, Number > state_type
DEAL_II_HOST_DEVICE_ALWAYS_INLINE bool is_admissible(const state_type &) const
std::array< Number, n_precomputed_values > precomputed_type
DEAL_II_HOST_DEVICE_ALWAYS_INLINE state_type apply_galilei_transform(const state_type &state, const Lambda &) const
DEAL_II_HOST_DEVICE flux_contribution_type flux_contribution(const PrecomputedVectorView &pv, const InitialPrecomputedVectorView &, const unsigned int i, const state_type &) const
DEAL_II_HOST_DEVICE Number square_entropy(const Number &u) const
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, dim, Number > flux_gradient_function(const Number &u) const
static constexpr unsigned int n_precomputed_values
flux_type flux_contribution_type
std::array< Number, n_initial_precomputed_values > initial_precomputed_type
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 & flux() const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE state_type expand_state(const ST &state) const
DEAL_II_HOST_DEVICE Number kruzkov_entropy(const Number &k, const Number &u) const
dealii::Tensor< 1, problem_dimension, dealii::Tensor< 1, dim, Number > > flux_type
static DEAL_II_HOST_DEVICE Number state(const state_type &U)
DEAL_II_HOST_DEVICE dealii::Tensor< 1, dim, Number > construct_flux_tensor(const precomputed_type &precomputed_state) const
DEAL_II_HOST_DEVICE_ALWAYS_INLINE state_type to_primitive_state(const state_type &state) 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 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_source_terms
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, dim, Number > flux_function(const Number &u) const
static constexpr bool have_high_order_flux
static constexpr unsigned int n_initial_precomputed_values
state_type high_order_flux_divergence(const flux_contribution_type &, const flux_contribution_type &, const dealii::Tensor< 1, dim, Number > &c_ij) const =delete
HyperbolicSystemView(const HyperbolicSystem &hyperbolic_system)
DEAL_II_HOST_DEVICE Number kruzkov_entropy_derivative(const Number &k, const Number &u) const
typename get_value_type< Number >::type ScalarNumber
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")
constexpr bool have_separate_memory_spaces
@ implicit_transfers_host_resident
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)
void populate_flux_list(flux_list_type &flux_list, const std::string &subsection)
std::set< std::shared_ptr< Flux > > flux_list_type
double derivative_approximation_delta
MultiComponentVector< Number > U
MultiComponentVector< Number > precomputed