Gyselalib++
multipatch_field.hpp
1 // SPDX-License-Identifier: MIT
2 
3 #pragma once
4 #include "multipatch_type.hpp"
5 
6 
7 template <class T>
8 inline constexpr bool enable_multipatch_field = false;
9 
10 template <class T>
11 inline constexpr bool is_multipatch_field_v
12  = enable_multipatch_field<std::remove_const_t<std::remove_reference_t<T>>>;
13 
28 template <template <typename P> typename T, class... Patches>
29 class MultipatchField : public MultipatchType<T, Patches...>
30 {
31  static_assert(
32  (has_data_access_methods_v<T<Patches>> && ...),
33  "The MultipatchField type should only contain instances of objects that can be "
34  "manipulated like fields.");
35 
36 public:
38  using base_type = MultipatchType<T, Patches...>;
39 
41  using typename base_type::PatchOrdering;
42 
44  template <class Patch>
46 
48  template <class Patch>
50 
52  template <class Patch>
54 
55  template <template <typename P> typename OT, class... OPatches>
56  friend class MultipatchField;
57 
58  static_assert(
59  !is_mem_type_v<typename base_type::example_element>,
60  "For correct GPU handling a FieldMem object must be saved in a MultipatchFieldMem "
61  "type.");
62 
63 public:
71  using memory_space = typename base_type::example_element::memory_space;
73  using element_type = typename base_type::example_element::element_type;
74 
76  template <class Patch>
78 
79 public:
85  explicit KOKKOS_FUNCTION MultipatchField(T<Patches>... args) : base_type(args...) {}
86 
101  template <class MultipatchObj, std::enable_if_t<!is_mem_type_v<MultipatchObj>, bool> = true>
102  KOKKOS_FUNCTION MultipatchField(MultipatchObj& other)
103  : base_type(std::move(T<Patches>(other.template get<Patches>()))...)
104  {
105  static_assert(is_multipatch_type_v<MultipatchObj>);
106  }
107 
117  template <class MultipatchObj, std::enable_if_t<is_mem_type_v<MultipatchObj>, bool> = true>
118  explicit MultipatchField(MultipatchObj& other)
119  : base_type(std::move(T<Patches>(other.template get<Patches>()))...)
120  {
121  static_assert(is_multipatch_type_v<MultipatchObj>);
122  }
123 
130  template <template <typename P> typename OT, class... OPatches>
132  : base_type(std::make_tuple(other.template get<Patches>()...))
133  {
134  static_assert(
135  std::is_same_v<ddc::detail::TypeSeq<Patches...>, ddc::detail::TypeSeq<OPatches...>>,
136  "Cannot create a MultipatchField from a temporary MultipatchField with a different "
137  "ordering");
138  static_assert(
139  std::is_same_v<std::tuple<T<Patches>...>, std::tuple<OT<OPatches>...>>,
140  "MultipatchFields are not equivalent");
141  }
142 
143  KOKKOS_FUNCTION ~MultipatchField() {}
144 
151  template <class Patch>
152  KOKKOS_FUNCTION auto get() const
153  {
154  return ::get_field(std::get<T<Patch>>(base_type::m_tuple));
155  }
156 
162  auto idx_range() const
163  {
164  return MultipatchType<InternalIdxRangeOnPatch, Patches...>(
165  get_idx_range(std::get<T<Patches>>(base_type::m_tuple))...);
166  }
167 
173  KOKKOS_FUNCTION auto get_field()
174  {
175  return MultipatchField<InternalFieldOnPatch, Patches...>(
176  ::get_field(std::get<T<Patches>>(base_type::m_tuple))...);
177  }
178 
185  KOKKOS_FUNCTION auto span_view()
186  {
187  return get_field();
188  }
189 
195  KOKKOS_FUNCTION auto get_const_field() const
196  {
197  return MultipatchField<InternalConstFieldOnPatch, Patches...>(
199  }
200 
207  KOKKOS_FUNCTION auto span_cview()
208  {
209  return get_const_field();
210  }
211 };
212 
213 template <template <typename P> typename T, class... Patches>
214 inline constexpr bool enable_multipatch_type<MultipatchField<T, Patches...>> = true;
215 
216 template <template <typename P> typename T, class... Patches>
217 inline constexpr bool enable_data_access_methods<MultipatchField<T, Patches...>> = true;
218 
219 template <template <typename P> typename T, class... Patches>
220 inline constexpr bool enable_multipatch_field<MultipatchField<T, Patches...>> = true;
221 
222 namespace ddcHelper {
223 
229 template <template <typename P> typename T1, template <typename P> typename T2, class... Patches>
231 {
232  if constexpr (ddc::is_chunk_v<typename MultipatchField<T1, Patches...>::example_element>) {
233  (ddc::parallel_deepcopy(dst.template get<Patches>(), src.template get<Patches>()), ...);
234  } else {
235  (ddcHelper::deepcopy(dst.template get<Patches>(), src.template get<Patches>()), ...);
236  }
237 }
238 
239 } // namespace ddcHelper
A class to store field objects on patches.
Definition: multipatch_field.hpp:30
typename base_type::example_element::element_type element_type
The type of the elements inside the field.
Definition: multipatch_field.hpp:73
typename T< Patch >::discrete_domain_type InternalIdxRangeOnPatch
An internal type alias that is only instantiated if the idx_range method is called.
Definition: multipatch_field.hpp:45
KOKKOS_FUNCTION MultipatchField(MultipatchObj &other)
Create a MultipatchField class by copying an instance of another compatible MultipatchField.
Definition: multipatch_field.hpp:102
typename T< Patch >::view_type InternalConstFieldOnPatch
An internal type alias that is only instantiated if the get_const_field method is called.
Definition: multipatch_field.hpp:53
MultipatchField(MultipatchField< OT, OPatches... > &&other)
Create a MultipatchField class from an r-value (temporary) instance of another MultipatchField which ...
Definition: multipatch_field.hpp:131
typename InternalIdxRangeOnPatch< Patch >::discrete_element_type idx_type
The type used to index the field on the specified patch.
Definition: multipatch_field.hpp:77
KOKKOS_FUNCTION auto get() const
Retrieve an object from the patch that it is defined on.
Definition: multipatch_field.hpp:152
KOKKOS_FUNCTION auto span_cview()
Get a MultipatchField containing constant fields so the values cannot be modified.
Definition: multipatch_field.hpp:207
KOKKOS_FUNCTION auto get_const_field() const
Get a MultipatchField containing constant fields so the values cannot be modified.
Definition: multipatch_field.hpp:195
MultipatchField(MultipatchObj &other)
Create a MultipatchField class from a compatible MultipatchFieldMem.
Definition: multipatch_field.hpp:118
KOKKOS_FUNCTION MultipatchField(T< Patches >... args)
Instantiate the MultipatchField class from an arbitrary number of objects.
Definition: multipatch_field.hpp:85
typename base_type::example_element::memory_space memory_space
The memory space (CPU/GPU) where the data is saved.
Definition: multipatch_field.hpp:71
KOKKOS_FUNCTION auto get_field()
Get a MultipatchField containing modifiable fields.
Definition: multipatch_field.hpp:173
auto idx_range() const
Get a MultipatchType containing the index ranges on which the fields are defined.
Definition: multipatch_field.hpp:162
KOKKOS_FUNCTION auto span_view()
Get a MultipatchField containing modifiable fields.
Definition: multipatch_field.hpp:185
typename T< Patch >::span_type InternalFieldOnPatch
An internal type alias that is only instantiated if the get_const_field method is called.
Definition: multipatch_field.hpp:49
A class to store several objects that are of a type which is templated by the patch.
Definition: multipatch_type.hpp:32
ddc::detail::TypeSeq< Patches... > PatchOrdering
A tag storing the order of Patches in this MultipatchType.
Definition: multipatch_type.hpp:35
std::tuple< T< Patches >... > m_tuple
The internal tuple containing the data.
Definition: multipatch_type.hpp:45
A class which describes the real space in the temporal direction.
Definition: geometry.hpp:45