8#include <compile_time_options.h>
29 class SelectedComponentsExtractorView;
78 template <
typename Description,
int dim,
typename Number>
101 template <
typename MemorySpace>
103 decltype(std::declval<const HyperbolicVector &>()
104 .template view<MemorySpace>());
105 template <
typename MemorySpace>
107 decltype(std::declval<const PrecomputedVector &>()
108 .template view<MemorySpace>());
109 template <
typename MemorySpace>
111 decltype(std::declval<const InitialPrecomputedVector &>()
112 .template view<MemorySpace>());
113 template <
typename MemorySpace>
115 .template view<MemorySpace>());
130 2 * View::problem_dimension;
155 const std::vector<std::string> &additional_names = {},
156 const std::vector<std::reference_wrapper<const ScalarVector>>
157 &additional_vectors = {});
167 void prepare(
const std::vector<std::string> &selected);
184 template <
typename MemorySpace = dealii::MemorySpace::Host>
211 template <
typename MemorySpace = dealii::MemorySpace::Host>
222 dealii::ObserverPointer<const OfflineData<dim, Number>> offline_data_;
223 dealii::ObserverPointer<const HyperbolicSystem> hyperbolic_system_;
224 dealii::ObserverPointer<const ParabolicSystem> parabolic_system_;
228 const std::vector<std::string> additional_names_;
229 const std::vector<std::reference_wrapper<const ScalarVector>>
235 const unsigned int additional_offset_;
241 const unsigned int n_scalar_;
259 unsigned int n_selected_ = 0;
266 bool read_conserved_ =
false;
267 bool read_primitive_ =
false;
268 bool read_precomputed_ =
false;
269 bool read_initial_ =
false;
270 bool read_scalar_ =
false;
276 template <
typename MemorySpace>
278 const unsigned int *selection_ =
nullptr;
280 HyperbolicVectorView<MemorySpace> U_view_;
281 PrecomputedVectorView<MemorySpace> precomputed_view_;
282 InitialPrecomputedVectorView<MemorySpace> initial_view_;
292 "selected_components_scalar_views"};
293 const ScalarVectorView<MemorySpace> *scalar_views_ =
nullptr;
295 bool prepared_ =
false;
298 mutable Payload<dealii::MemorySpace::Host> host_payload_;
299 mutable Payload<dealii::MemorySpace::Default> default_payload_;
304 template <
typename MemorySpace>
305 Payload<MemorySpace> &payload()
const;
307 template <
typename,
int,
typename,
typename>
329 typename MemorySpace>
333 static_assert(std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
334 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
335 "Unexpected memory space");
351 EquationView::n_precomputed_values;
353 EquationView::n_initial_precomputed_values;
370 dealii::LinearAlgebra::distributed::Vector<Number, MemorySpace>;
391 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
unsigned int n_selected()
const
413 template <
typename T = Number>
414 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
void
424 using Payload =
typename Extractor::template Payload<MemorySpace>;
430 const Payload &payload);
434 const unsigned int *selection_;
435 unsigned int n_selected_;
438 bool read_conserved_;
439 bool read_primitive_;
440 bool read_precomputed_;
469 template <
typename Description,
int dim,
typename Number>
474 const ParabolicSystem ¶bolic_system,
475 const InitialPrecomputedVector &initial_precomputed,
476 const std::vector<std::string> &additional_names,
477 const std::vector<std::reference_wrapper<const ScalarVector>>
479 : offline_data_(&offline_data)
480 , hyperbolic_system_(&hyperbolic_system)
481 , parabolic_system_(¶bolic_system)
482 , initial_precomputed_(initial_precomputed)
483 , additional_names_(additional_names)
484 , additional_vectors_(additional_vectors)
485 , additional_offset_(parabolic_offset +
486 parabolic_system.parabolic_component_names().size())
487 , n_scalar_(additional_offset_ - parabolic_offset +
488 additional_vectors.size())
490 Assert(additional_names_.size() == additional_vectors_.size(),
491 dealii::ExcMessage(
"The number of additional component names does "
492 "not match the number of additional vectors."));
496 template <
typename Description,
int dim,
typename Number>
498 const std::vector<std::string> &selected)
500 std::vector<unsigned int> selection;
501 selection.reserve(selected.size());
503 for (
const auto &entry : selected) {
504 const auto search = [&](
const auto &names,
const unsigned int offset) {
505 const auto pos = std::find(std::begin(names), std::end(names), entry);
506 if (pos == std::end(names))
508 const unsigned int index = std::distance(std::begin(names), pos);
509 selection.push_back(offset + index);
514 search(View::component_names, conserved_offset) ||
515 search(View::primitive_component_names, primitive_offset) ||
516 search(View::precomputed_names, precomputed_offset) ||
517 search(View::initial_precomputed_names, initial_offset) ||
518 search(parabolic_system_->parabolic_component_names(),
520 search(additional_names_, additional_offset_);
524 "Invalid component name: \"" + entry +
525 "\" is not a valid conserved, primitive, precomputed, "
526 "initial, parabolic, or additional component name."));
529 n_selected_ =
static_cast<unsigned int>(selection.size());
536 const auto selects = [&](
const unsigned int begin,
const unsigned int end) {
538 selection.begin(), selection.end(), [&](
const auto offset) {
539 return begin <= offset && offset < end;
543 read_conserved_ = selects(conserved_offset, primitive_offset);
544 read_primitive_ = selects(primitive_offset, precomputed_offset);
545 read_precomputed_ = selects(precomputed_offset, initial_offset);
546 read_initial_ = selects(initial_offset, parabolic_offset);
547 read_scalar_ = selects(parabolic_offset, parabolic_offset + n_scalar_);
550 std::copy(selection.begin(), selection.end(), selection_.view());
557 const std::size_t size = read_scalar_ ? n_scalar_ : 0;
558 host_payload_.scalar_views_storage_.reinit(
560 default_payload_.scalar_views_storage_.reinit(
563 host_payload_.prepared_ =
false;
564 default_payload_.prepared_ =
false;
568 template <
typename Description,
int dim,
typename Number>
569 template <
typename MemorySpace>
572 const StateVector &state_vector)
const
574 using HostSpace = dealii::MemorySpace::Host;
576 auto &payload = this->
template payload<MemorySpace>();
578 payload.selection_ = selection_.template view<MemorySpace>();
586 if (read_conserved_ || read_primitive_)
587 payload.U_view_ = std::get<0>(state_vector).template view<MemorySpace>();
589 if (read_precomputed_)
590 payload.precomputed_view_ =
591 std::get<1>(state_vector).template view<MemorySpace>();
594 payload.initial_view_ = initial_precomputed_.template view<MemorySpace>();
603 auto *scalar_views = payload.scalar_views_storage_.view();
606 const auto *selection = selection_.template view<HostSpace>();
607 const auto ¶bolic = std::get<2>(state_vector);
609 for (
unsigned int k = 0; k < n_selected_; ++k) {
610 const auto offset = selection[k];
611 if (offset < parabolic_offset)
614 const auto component = offset - parabolic_offset;
615 if (offset < additional_offset_)
616 scalar_views[component] =
617 parabolic[component].template view<MemorySpace>();
619 scalar_views[component] =
620 additional_vectors_[offset - additional_offset_]
622 .template view<MemorySpace>();
625 payload.scalar_views_ = std::as_const(payload.scalar_views_storage_)
626 .template view<MemorySpace>();
629 payload.prepared_ =
true;
633 template <
typename Description,
int dim,
typename Number>
641 template <
typename Description,
int dim,
typename Number>
642 template <
typename MemorySpace>
643 SelectedComponentsExtractorView<Description, dim, Number, MemorySpace>
646 Assert(this->
template payload<MemorySpace>().prepared_,
648 "Invalid state: prepare_extraction() has to be called for the "
649 "selected memory space before a view can be created."));
651 return SelectedComponentsExtractorView<
Description,
655 *
this, this->
template payload<MemorySpace>());
659 template <
typename Description,
int dim,
typename Number>
660 template <
typename MemorySpace>
661 auto SelectedComponentsExtractor<Description, dim, Number>::payload() const
662 -> Payload<MemorySpace> &
664 static_assert(std::is_same_v<MemorySpace, dealii::MemorySpace::Host> ||
665 std::is_same_v<MemorySpace, dealii::MemorySpace::Default>,
666 "Unexpected memory space");
668 if constexpr (std::is_same_v<MemorySpace, dealii::MemorySpace::Host>)
669 return host_payload_;
671 return default_payload_;
678 typename MemorySpace>
679 SelectedComponentsExtractorView<Description, dim, Number, MemorySpace>::
680 SelectedComponentsExtractorView(
const Extractor &extractor,
681 const Payload &payload)
682 : extractor_(&extractor)
683 , selection_(payload.selection_)
684 , n_selected_(extractor.n_selected_)
685 , read_conserved_(extractor.read_conserved_)
686 , read_primitive_(extractor.read_primitive_)
687 , read_precomputed_(extractor.read_precomputed_)
688 , read_initial_(extractor.read_initial_)
689 , U_view_(payload.U_view_)
690 , precomputed_view_(payload.precomputed_view_)
691 , initial_view_(payload.initial_view_)
692 , system_views_(*extractor.hyperbolic_system_)
693 , scalar_views_(payload.scalar_views_)
701 typename MemorySpace>
703 extract() const -> std::vector<ScalarVector>
705 using HostSpace = dealii::MemorySpace::Host;
707 const auto &offline_data = *extractor_->offline_data_;
708 const auto &scalar_partitioner = offline_data.scalar_partitioner();
711 const auto *selection = extractor_->selection_.template view<HostSpace>();
713 std::vector<ScalarVector> extracted_components(n_selected_);
714 for (
auto &it : extracted_components)
715 it.reinit(scalar_partitioner);
717 for (
unsigned int k = 0; k < n_selected_; ++k) {
718 const auto offset = selection[k];
719 auto &destination = extracted_components[k];
721 if (offset < Extractor::primitive_offset) {
722 U_view_.extract_component(destination,
723 offset - Extractor::conserved_offset);
725 }
else if (offset < Extractor::precomputed_offset) {
730 const auto U_view = U_view_;
731 const auto system_views = system_views_;
732 const auto component = offset - Extractor::primitive_offset;
733 auto *data = destination.begin();
735 const auto body = [=](
auto sentinel,
unsigned int i) {
736 using T =
decltype(sentinel);
738 const auto U_i = U_view.template read_tensor<T>(i);
739 const auto primitive_i =
740 system_views.template view<T>().to_primitive_state(U_i);
742 if constexpr (std::is_same_v<T, dealii::VectorizedArray<Number>>)
743 primitive_i[component].store(data + i);
745 data[i] = primitive_i[component];
748 loop<MemorySpace, Number>(
"extract_primitive_component",
751 offline_data.n_locally_internal(),
752 offline_data.n_locally_owned());
754 }
else if (offset < Extractor::initial_offset) {
755 precomputed_view_.extract_component(
756 destination, offset - Extractor::precomputed_offset);
758 }
else if (offset < Extractor::parabolic_offset) {
759 initial_view_.extract_component(destination,
760 offset - Extractor::initial_offset);
763 scalar_views_[offset - Extractor::parabolic_offset].extract_component(
768 return extracted_components;
775 typename MemorySpace>
776 template <
typename T>
777 DEAL_II_HOST_DEVICE_ALWAYS_INLINE
void
787 T staging[Extractor::parabolic_offset];
789 if (read_conserved_ || read_primitive_) {
790 const auto U_i = U_view_.template read_tensor<T>(i);
791 for (
unsigned int d = 0; d < problem_dimension; ++d)
792 staging[Extractor::conserved_offset + d] = U_i[d];
794 if (read_primitive_) {
795 const auto primitive_i =
796 system_views_.template view<T>().to_primitive_state(U_i);
797 for (
unsigned int d = 0; d < problem_dimension; ++d)
798 staging[Extractor::primitive_offset + d] = primitive_i[d];
802 if (read_precomputed_) {
803 const auto precomputed_i = precomputed_view_.template read_tensor<T>(i);
804 for (
unsigned int d = 0; d < n_precomputed_values; ++d)
805 staging[Extractor::precomputed_offset + d] = precomputed_i[d];
809 const auto initial_i = initial_view_.template read_tensor<T>(i);
810 for (
unsigned int d = 0; d < n_initial_precomputed_values; ++d)
811 staging[Extractor::initial_offset + d] = initial_i[d];
819 for (
unsigned int k = 0; k < n_selected_; ++k) {
820 const auto offset = selection_[k];
822 if (offset < Extractor::parabolic_offset)
823 result[k] = staging[offset];
825 result[k] = scalar_views_[offset - Extractor::parabolic_offset]
826 .template read_entry<T>(i);
Euler::Description Description
Euler::HyperbolicSystem HyperbolicSystem
ryujin::StubParabolicSystem ParabolicSystem