7 #include <ddc/kernels/splines.hpp>
9 #include <sll/math_tools.hpp>
11 #include "ddc_aliases.hpp"
12 #include "deriv_details.hpp"
13 #include "idx_range_slice.hpp"
16 inline constexpr
bool enable_deriv_field =
false;
19 inline constexpr
bool enable_borrowed_deriv_field =
false;
22 inline constexpr
bool is_deriv_field_v
23 = enable_deriv_field<std::remove_const_t<std::remove_reference_t<T>>>;
26 inline constexpr
bool is_borrowed_deriv_field_v
27 = (std::is_lvalue_reference_v<T>)
28 || (enable_borrowed_deriv_field<std::remove_cv_t<std::remove_reference_t<T>>>);
30 template <
class FieldType,
class SupportType>
42 template <
class FieldType,
class... DDims>
56 using deriv_tags = detail::deriv_sub_set_t<ddc::detail::TypeSeq<DDims...>>;
91 std::experimental::dextents<std::size_t,
sizeof...(DDims)>,
92 std::experimental::layout_stride>;
97 std::experimental::dextents<std::size_t,
sizeof...(DDims)>,
98 std::experimental::layout_stride>;
108 typename ddc::detail::convert_type_seq_to_discrete_domain_t<physical_grids>;
115 typename ddc::detail::convert_type_seq_to_discrete_domain_t<deriv_tags>;
128 static constexpr
int n_fields = 1 << ddc::type_seq_size_v<deriv_tags>;
130 template <
class,
class,
int,
class>
133 template <
class,
class,
class,
class>
171 template <
class DElem>
172 KOKKOS_FUNCTION std::pair<int, index_type>
get_index(DElem elem)
const
177 index_type index(physical_index, deriv_index);
178 return std::pair<int, index_type>(get_array_index(deriv_index), index);
196 template <
class... Tag>
201 + (
int(ddc::select<Tag>(idx) != Idx<Tag>(0))
202 << ddc::type_seq_rank_v<Tag, deriv_tags>));
215 template <
class QueryDDim,
class... ODDims>
216 KOKKOS_FUNCTION constexpr
auto get_slicer_for(Idx<ODDims...>
const& slice_idx,
int array_idx)
219 if constexpr (!ddc::in_tags_v<QueryDDim, ddc::detail::TypeSeq<ODDims...>>) {
220 return std::experimental::full_extent;
222 if constexpr (ddc::in_tags_v<QueryDDim, physical_deriv_grids>) {
225 if (array_idx & (1 << ddc::type_seq_rank_v<ddc::Deriv<QueryDDim>,
deriv_tags>)) {
227 return m_cross_derivative_idx_range.get_index(
228 ddc::select<QueryDDim>(slice_idx));
231 if constexpr (ddc::in_tags_v<QueryDDim, physical_grids>) {
234 (ddc::select<QueryDDim>(slice_idx)
235 - ddc::select<QueryDDim>(m_physical_idx_range).front()));
237 if constexpr (ddc::in_tags_v<QueryDDim, deriv_tags>) {
239 if (array_idx & (1 << ddc::type_seq_rank_v<QueryDDim, deriv_tags>)) {
241 return std::size_t((ddc::select<QueryDDim>(slice_idx) - Idx<QueryDDim>(1)));
244 assert(ddc::select<QueryDDim>(slice_idx) == Idx<QueryDDim>(0));
245 return std::size_t(0);
261 template <
class QueryDDim,
class... ODDims>
263 IdxRange<ODDims...>
const& slice_idx_range,
266 if constexpr (!ddc::in_tags_v<QueryDDim, ddc::detail::TypeSeq<ODDims...>>) {
267 return std::experimental::full_extent;
269 if constexpr (ddc::in_tags_v<QueryDDim, physical_deriv_grids>) {
272 IdxRange<QueryDDim> idx_range_requested(slice_idx_range);
273 if (array_idx & (1 << ddc::type_seq_rank_v<ddc::Deriv<QueryDDim>,
deriv_tags>)) {
275 assert(m_cross_derivative_idx_range.contains(idx_range_requested));
276 return std::pair<std::size_t, std::size_t>(
277 m_cross_derivative_idx_range.get_index(idx_range_requested.front()),
278 m_cross_derivative_idx_range.get_index(idx_range_requested.back()) + 1);
281 if constexpr (ddc::in_tags_v<QueryDDim, physical_grids>) {
283 return std::pair<std::size_t, std::size_t>(
284 ddc::select<QueryDDim>(slice_idx_range).front()
285 - ddc::select<QueryDDim>(m_physical_idx_range).front(),
286 ddc::select<QueryDDim>(slice_idx_range).back() + 1
287 - ddc::select<QueryDDim>(m_physical_idx_range).front());
289 if constexpr (ddc::in_tags_v<QueryDDim, deriv_tags>) {
291 if (array_idx & (1 << ddc::type_seq_rank_v<QueryDDim, deriv_tags>)) {
293 return std::pair<std::size_t, std::size_t>(
294 ddc::select<QueryDDim>(slice_idx_range).front() - Idx<QueryDDim>(1),
295 ddc::select<QueryDDim>(slice_idx_range).back() + 1 - Idx<QueryDDim>(1));
298 assert(ddc::select<QueryDDim>(slice_idx_range).front() == Idx<QueryDDim>(0));
299 assert(ddc::select<QueryDDim>(slice_idx_range).back()
300 == ddc::select<QueryDDim>(slice_idx_range).front());
301 return std::pair<std::size_t, std::size_t>(0, 1);
318 template <
class... ODims>
322 using provided_tags = ddc::detail::TypeSeq<ODims...>;
323 using provided_deriv_tags = detail::deriv_sub_set_t<provided_tags>;
326 using remaining_deriv_tags = ddc::type_seq_remove_t<deriv_tags, provided_deriv_tags>;
327 using remaining_deriv_idx_range_type =
328 typename ddc::detail::convert_type_seq_to_discrete_domain_t<remaining_deriv_tags>;
331 remaining_deriv_idx_range_type no_deriv_idx_range = detail::get_idx_range_from_element(
332 detail::no_derivative_element<remaining_deriv_tags>());
337 detail::select_default(idx_range, m_physical_idx_range));
343 int const array_idx = get_array_index(deriv_idx_range.front());
348 auto subview = std::experimental::
349 submdspan(internal_view, get_slicer_for<DDims>(full_idx_range, array_idx)...);
353 typename chunk_type::memory_space,
354 typename decltype(subview)::layout_type>
355 local_field(subview, full_idx_range);
358 if constexpr (ddc::type_seq_size_v<remaining_deriv_tags> == 0) {
361 return local_field[no_deriv_idx_range.front()];
376 template <
class... ODims>
380 using provided_tags = ddc::detail::TypeSeq<ODims...>;
381 using provided_deriv_tags = detail::deriv_sub_set_t<provided_tags>;
382 using provided_physical_tags = ddc::type_seq_remove_t<provided_tags, provided_deriv_tags>;
383 using provided_deriv_idx_range_type
384 = ddc::detail::convert_type_seq_to_discrete_domain_t<provided_deriv_tags>;
385 using provided_deriv_index_type =
386 typename provided_deriv_idx_range_type::discrete_element_type;
389 using remaining_deriv_tags = ddc::type_seq_remove_t<deriv_tags, provided_deriv_tags>;
390 using remaining_deriv_idx_range_type =
391 typename ddc::detail::convert_type_seq_to_discrete_domain_t<remaining_deriv_tags>;
392 using remaining_deriv_index_type =
393 typename remaining_deriv_idx_range_type::discrete_element_type;
396 using sliced_tags = ddc::type_seq_merge_t<provided_physical_tags, deriv_tags>;
397 using sliced_idx_range_type =
398 typename ddc::detail::convert_type_seq_to_discrete_domain_t<sliced_tags>;
399 using sliced_index_type =
typename sliced_idx_range_type::discrete_element_type;
400 using final_tags = ddc::type_seq_remove_t<ddc::detail::TypeSeq<DDims...>, sliced_tags>;
401 using final_idx_range_type =
402 typename ddc::detail::convert_type_seq_to_discrete_domain_t<final_tags>;
405 provided_deriv_index_type requested_derivs(elem);
406 remaining_deriv_index_type no_deriv_elements(
407 detail::no_derivative_element<remaining_deriv_tags>());
411 sliced_index_type slice_idx(elem, no_deriv_elements);
414 int const array_idx = get_array_index(deriv_index);
417 final_idx_range_type final_idx_range(m_physical_idx_range);
422 auto subview = std::experimental::
423 submdspan(internal_view, get_slicer_for<DDims>(slice_idx, array_idx)...);
426 final_idx_range_type,
427 typename chunk_type::memory_space,
428 typename decltype(subview)::layout_type>
429 local_field(subview, final_idx_range);
445 to_subidx_range_collection<physical_deriv_grids> cross_derivative_idx_range)
446 : m_physical_idx_range(physical_idx_range)
447 , m_deriv_idx_range(deriv_idx_range)
448 , m_cross_derivative_idx_range(cross_derivative_idx_range)
464 template <
class... QueryDDims>
465 constexpr
auto operator[](Idx<QueryDDims...>
const& slice_spec)
const
467 return get_internal_field(slice_spec).span_cview();
479 template <
class... QueryDDims>
480 constexpr
auto operator[](Idx<QueryDDims...>
const& slice_spec)
482 return get_internal_field(slice_spec);
496 template <
class... QueryDDims>
497 KOKKOS_FUNCTION constexpr
auto operator[](IdxRange<QueryDDims...>
const& oidx_range)
499 return get_internal_field(oidx_range);
513 template <
class... QueryDDims>
514 KOKKOS_FUNCTION constexpr
auto operator[](IdxRange<QueryDDims...>
const& oidx_range)
const
516 return get_internal_field(oidx_range).span_cview();
530 template <
class... ODims>
533 static_assert(((ddc::in_tags_v<ODims, deriv_tags>)&&...));
534 using provided_deriv_tags = ddc::detail::TypeSeq<ODims...>;
535 using remaining_deriv_tags = ddc::type_seq_remove_t<deriv_tags, provided_deriv_tags>;
536 using remaining_deriv_idx_range_type =
537 typename ddc::detail::convert_type_seq_to_discrete_domain_t<remaining_deriv_tags>;
538 using remaining_deriv_index_type =
539 typename remaining_deriv_idx_range_type::discrete_element_type;
543 remaining_deriv_index_type deriv_elements(default_derivatives);
545 detail::select_default(provided_deriv_idx_range.front(), default_derivatives));
547 int const array_idx = get_array_index(deriv_index);
550 auto subview_all_dims = std::experimental::submdspan(
552 get_slicer_for<DDims>(provided_deriv_idx_range, array_idx)...);
553 auto subview = std::experimental::
554 submdspan(subview_all_dims, get_slicer_for<DDims>(deriv_elements, array_idx)...);
565 IdxRange<> no_specified_dims;
566 return get_mdspan(no_specified_dims);
578 IdxRange<> no_specified_dims;
579 return get_internal_field(no_specified_dims);
591 IdxRange<> no_specified_dims;
592 return get_internal_field(no_specified_dims).span_cview();
ddc::type_seq_remove_t< ddc::detail::TypeSeq< DDims... >, deriv_tags > physical_grids
A type sequence containing all the physical dimensions on which the fields are defined.
Definition: derivative_field_common.hpp:62
constexpr KOKKOS_FUNCTION auto operator[](IdxRange< QueryDDims... > const &oidx_range)
Get a Field describing a subset of the data.
Definition: derivative_field_common.hpp:497
std::array< internal_mdspan_type, n_fields > internal_fields
The internal fields describing the values and derivatives.
Definition: derivative_field_common.hpp:149
typename FieldType::view_type chunk_view
The type of a constant view of this field. This is a DDC keyword used to make this class interchangea...
Definition: derivative_field_common.hpp:104
auto get_mdspan()
Get the mdspan holding the values of the function from the internal array internal_fields.
Definition: derivative_field_common.hpp:563
IdxRange< DDims... > discrete_domain_type
The IdxRange on which the fields in this object are defined.
Definition: derivative_field_common.hpp:73
detail::deriv_sub_set_t< ddc::detail::TypeSeq< DDims... > > deriv_tags
A type sequence containing all derivatives present in this object.
Definition: derivative_field_common.hpp:56
typename ddc::detail::convert_type_seq_to_discrete_domain_t< deriv_tags > discrete_deriv_idx_range_type
The IdxRange which describes the derivatives present on each field.
Definition: derivative_field_common.hpp:115
to_subidx_range_collection< physical_deriv_grids > m_cross_derivative_idx_range
The physical index ranges on which the derivatives are defined.
Definition: derivative_field_common.hpp:158
std::experimental::mdspan< const element_type, std::experimental::dextents< std::size_t, sizeof...(DDims)>, std::experimental::layout_stride > internal_mdview_type
The type of a constant view on the memory block stored in the array internal_fields.
Definition: derivative_field_common.hpp:98
KOKKOS_FUNCTION int get_array_index(Idx< Tag... > idx) const
An internal function which provides the index of a field inside the internal_fields array.
Definition: derivative_field_common.hpp:197
discrete_element_type index_type
The Idx which can be used to index this object.
Definition: derivative_field_common.hpp:85
discrete_deriv_idx_range_type m_deriv_idx_range
The index range of available derivatives.
Definition: derivative_field_common.hpp:155
typename discrete_deriv_idx_range_type::mlength_type discrete_deriv_vector_type
The Idx which describes the order of the derivatives in each dimension.
Definition: derivative_field_common.hpp:125
typename detail::strip_deriv_t< deriv_tags > physical_deriv_grids
A type sequence containing all physical dimensions for which derivatives are present in this object.
Definition: derivative_field_common.hpp:59
physical_idx_range_type m_physical_idx_range
The physical index range on which the values are defined.
Definition: derivative_field_common.hpp:152
Idx< DDims... > discrete_element_type
The Idx which can be used to index this object.
Definition: derivative_field_common.hpp:83
std::experimental::mdspan< element_type, std::experimental::dextents< std::size_t, sizeof...(DDims)>, std::experimental::layout_stride > internal_mdspan_type
The type of the memory block stored in the array internal_fields.
Definition: derivative_field_common.hpp:92
FieldType chunk_type
The type of the field stored in the array.
Definition: derivative_field_common.hpp:53
typename chunk_type::element_type element_type
The type of the elements in the fields.
Definition: derivative_field_common.hpp:65
KOKKOS_FUNCTION std::pair< int, index_type > get_index(DElem elem) const
An internal function which provides the index of an element inside the internal_fields.
Definition: derivative_field_common.hpp:172
constexpr KOKKOS_FUNCTION auto get_slicer_for(Idx< ODDims... > const &slice_idx, int array_idx) const
Get an object which can be used to slice an mdspan.
Definition: derivative_field_common.hpp:216
typename FieldType::span_type chunk_span
The type of a modifiable span of this field. This is a DDC keyword used to make this class interchang...
Definition: derivative_field_common.hpp:101
typename physical_idx_range_type::discrete_element_type physical_index_type
The Idx which describes the physical position where values are defined.
Definition: derivative_field_common.hpp:111
constexpr KOKKOS_FUNCTION auto operator[](IdxRange< QueryDDims... > const &oidx_range) const
Get a ConstField describing a subset of the data.
Definition: derivative_field_common.hpp:514
discrete_domain_type index_range_type
The IdxRange on which the fields in this object are defined.
Definition: derivative_field_common.hpp:75
constexpr KOKKOS_FUNCTION auto get_slicer_for(IdxRange< ODDims... > const &slice_idx_range, int array_idx) const
Get an object which can be used to slice an mdspan.
Definition: derivative_field_common.hpp:262
typename discrete_deriv_idx_range_type::discrete_element_type discrete_deriv_index_type
The Idx which describes the order of the derivatives in each dimension.
Definition: derivative_field_common.hpp:120
KOKKOS_FUNCTION auto get_internal_field(IdxRange< ODims... > idx_range) const
Get a Field from a subset of one of the mdspans in internal_fields.
Definition: derivative_field_common.hpp:319
KOKKOS_FUNCTION auto get_internal_field(Idx< ODims... > elem) const
Get a Field from a subset of one of the mdspans in internal_fields.
Definition: derivative_field_common.hpp:377
typename ddc::detail::convert_type_seq_to_discrete_domain_t< physical_grids > physical_idx_range_type
The index range for the field excluding derivatives.
Definition: derivative_field_common.hpp:108
auto get_values_field() const
Get the Field which holds the values of the function.
Definition: derivative_field_common.hpp:589
KOKKOS_FUNCTION DerivFieldCommon(physical_idx_range_type physical_idx_range, discrete_deriv_idx_range_type deriv_idx_range, to_subidx_range_collection< physical_deriv_grids > cross_derivative_idx_range)
Protected constructor to be used by subclasses to initialise index ranges.
Definition: derivative_field_common.hpp:442
constexpr auto operator[](Idx< QueryDDims... > const &slice_spec) const
Get a ConstField describing a subset of the data.
Definition: derivative_field_common.hpp:465
auto get_values_field()
Get the Field which holds the values of the function.
Definition: derivative_field_common.hpp:576
constexpr auto operator[](Idx< QueryDDims... > const &slice_spec)
Get a Field describing a subset of the data.
Definition: derivative_field_common.hpp:480
auto get_mdspan(IdxRange< ODims... > provided_deriv_idx_range)
Get one of the mdspans from the internal array internal_fields.
Definition: derivative_field_common.hpp:531
Definition: derivative_field_common.hpp:31
See DerivFieldMemImplementation.
Definition: derivative_field.hpp:10
See DerivFieldImplementation.
Definition: derivative_field.hpp:20