Gyselalib++
vector_field_common.hpp
1 // SPDX-License-Identifier: MIT
2 
3 #pragma once
4 #include <ddc/ddc.hpp>
5 
6 #include "ddc_aliases.hpp"
7 
8 template <class FieldType, class NDTypeSeq>
10 
11 template <class T>
12 inline constexpr bool enable_vector_field = false;
13 
14 template <class T>
15 inline constexpr bool enable_borrowed_vector_field = false;
16 
17 template <class T>
18 inline constexpr bool is_vector_field_v
19  = enable_vector_field<std::remove_const_t<std::remove_reference_t<T>>>;
20 
21 template <class T>
22 inline constexpr bool is_borrowed_vector_field_v
23  = is_vector_field_v<
24  T> && (std::is_lvalue_reference_v<T> || enable_borrowed_vector_field<std::remove_cv_t<std::remove_reference_t<T>>>);
25 
26 namespace ddcHelper {
27 
28 template <
29  class FieldDst,
30  class FieldSrc,
31  std::enable_if_t<
32  is_borrowed_vector_field_v<FieldDst> && is_borrowed_vector_field_v<FieldSrc>,
33  bool> = true>
34 auto deepcopy(FieldDst&& dst, FieldSrc&& src)
35 {
36  static_assert(std::is_same_v<
37  typename std::remove_reference_t<FieldDst>::NDTypeTag,
38  typename std::remove_reference_t<FieldSrc>::NDTypeTag>);
39 
40  assert(dst.idx_range().extents() == src.idx_range().extents());
41 
42  dst.deepcopy(src);
43  return get_field(dst);
44 }
45 
46 template <class QueryTag, class VectorFieldType>
47 inline constexpr auto get(VectorFieldType&& field) noexcept
48 {
49  return field.template get<QueryTag>();
50 }
51 
52 
53 } // namespace ddcHelper
54 
55 template <class FieldType, class... DDims>
56 class VectorFieldCommon<FieldType, ddc::detail::TypeSeq<DDims...>>
57 {
58  static_assert(ddc::is_chunk_v<FieldType>);
59  using data_type = typename FieldType::element_type;
60 
61 public:
63  using element_type =
64  typename ddc::detail::TaggedVector<std::remove_const_t<data_type>, DDims...>;
65 
72  using discrete_domain_type = typename FieldType::discrete_domain_type;
74  using index_range_type = discrete_domain_type;
75 
77  using element_ref_type = typename ddc::detail::TaggedVector<data_type&, DDims...>;
78 
80  using NDTypeTag = ddc::detail::TypeSeq<DDims...>;
81 
83  using chunk_span_type = typename FieldType::span_type;
85  using chunk_view_type = typename FieldType::view_type;
86 
87 protected:
88  static constexpr std::size_t NDims = sizeof...(DDims);
89 
90  std::array<FieldType, NDims> m_values;
91 
92 protected:
94  KOKKOS_DEFAULTED_FUNCTION VectorFieldCommon() = default;
95 
97  template <
98  class... FieldTypes,
99  class = std::enable_if_t<std::conjunction_v<std::is_same<FieldTypes, FieldType>...>>,
100  std::enable_if_t<
101  !std::conjunction_v<
102  std::bool_constant<ddc::is_borrowed_chunk_v<FieldTypes>>...>,
103  int> = 0>
104  explicit VectorFieldCommon(FieldTypes&&... fields) : m_values {std::move(fields)...}
105  {
106  }
107 
109  template <
110  class... FieldTypes,
111  class = std::enable_if_t<std::conjunction_v<std::is_same<FieldTypes, FieldType>...>>,
112  std::enable_if_t<
113  std::conjunction_v<std::bool_constant<ddc::is_borrowed_chunk_v<FieldTypes>>...>,
114  int> = 0>
115  KOKKOS_FUNCTION explicit VectorFieldCommon(FieldTypes&&... fields)
116  : m_values {std::forward<FieldTypes>(fields)...}
117  {
118  }
119 
120 public:
121  constexpr index_range_type idx_range() const noexcept
122  {
123  return m_values[0].domain();
124  }
125 
129  template <class... QueryDDims>
130  constexpr IdxRange<QueryDDims...> idx_range() const noexcept
131  {
132  return ddc::select<QueryDDims...>(idx_range());
133  }
134 
135  static constexpr int rank() noexcept
136  {
137  return FieldType::rank();
138  }
139 
140  template <class FieldSrc>
141  void deepcopy(FieldSrc const& src)
142  {
143  ((ddc::parallel_deepcopy(
144  m_values[ddc::type_seq_rank_v<DDims, NDTypeTag>].span_view(),
145  ddcHelper::get<DDims>(src))),
146  ...);
147  }
148 };
Definition: vector_field_common.hpp:9
A class which describes the real space in the temporal direction.
Definition: geometry.hpp:45