Gyselalib++
 
Loading...
Searching...
No Matches
neumann_spline_quadrature.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2
8#pragma once
9
10#include <cassert>
11
12#include <ddc/ddc.hpp>
13#include <ddc/kernels/splines.hpp>
14
15#include <sll/matrix.hpp>
16
17#include "ddc_aliases.hpp"
18
19
20
21namespace {
22template <class ExecSpace, class Grid1D>
23using CoefficientFieldMem1D = DFieldMem<IdxRange<Grid1D>, typename ExecSpace::memory_space>;
24template <class ExecSpace, class Grid1D>
25using CoefficientField1D = DField<IdxRange<Grid1D>, typename ExecSpace::memory_space>;
26
27} // namespace
28
29
30
49template <class ExecSpace, class Grid1D, class SplineBuilder>
50DFieldMem<IdxRange<Grid1D>, typename ExecSpace::memory_space>
52 IdxRange<Grid1D> const& idx_range,
53 SplineBuilder const& builder)
54{
55 constexpr int nbc_xmin = SplineBuilder::s_nbc_xmin;
56 constexpr int nbc_xmax = SplineBuilder::s_nbc_xmax;
57 static_assert(
58 SplineBuilder::s_bc_xmin == ddc::BoundCond::HERMITE,
59 "The neumann spline quadrature requires a builder which uses Hermite boundary "
60 "conditions.");
61 static_assert(
62 SplineBuilder::s_bc_xmax == ddc::BoundCond::HERMITE,
63 "The neumann spline quadrature requires a builder which uses Hermite boundary "
64 "conditions.");
65 static_assert(
66 nbc_xmin == 1,
67 "The neumann spline quadrature requires a builder which uses the value of the "
68 "derivative.");
69 static_assert(
70 nbc_xmax == 1,
71 "The neumann spline quadrature requires a builder which uses the value of the "
72 "derivative.");
73 assert(idx_range.size()
74 == ddc::discrete_space<typename SplineBuilder::bsplines_type>().nbasis() - nbc_xmin
75 - nbc_xmax);
76
77 DFieldMem<IdxRange<Grid1D>, typename SplineBuilder::memory_space> quadrature_coefficients(
78 builder.interpolation_domain());
79 // Even if derivatives coefficients on boundaries are eventually non-zero,
80 // they are ignored for 0-flux Neumann boundary condition because
81 // they would always be multiplied by f'(x)=0
82 std::tie(std::ignore, quadrature_coefficients, std::ignore) = builder.quadrature_coefficients();
83 DFieldMem<IdxRange<Grid1D>, typename ExecSpace::memory_space> output_quad_coefficients(
84 idx_range);
85 ddc::parallel_deepcopy(output_quad_coefficients, quadrature_coefficients[idx_range]);
86 return output_quad_coefficients;
87}
88
89
90
105template <class ExecSpace, class... DDims, class... SplineBuilders>
106DFieldMem<IdxRange<DDims...>, typename ExecSpace::memory_space>
108 IdxRange<DDims...> const& idx_range,
109 SplineBuilders const&... builders)
110{
111 assert((std::is_same_v<
112 typename DDims::continuous_dimension_type,
113 typename SplineBuilders::continuous_dimension_type> and ...));
114
115 // Get coefficients for each dimension
116 std::tuple<CoefficientFieldMem1D<Kokkos::DefaultHostExecutionSpace, DDims>...>
117 current_dim_coeffs_alloc(
119 Kokkos::DefaultHostExecutionSpace>(ddc::select<DDims>(idx_range), builders)...);
120 std::tuple<CoefficientField1D<Kokkos::DefaultHostExecutionSpace, DDims>...> current_dim_coeffs(
121 get_field(std::get<CoefficientFieldMem1D<Kokkos::DefaultHostExecutionSpace, DDims>>(
122 current_dim_coeffs_alloc))...);
123 // Allocate ND coefficients
124 DFieldMem<IdxRange<DDims...>, typename ExecSpace::memory_space> coefficients_alloc(idx_range);
125 auto coefficients_alloc_host = ddc::create_mirror(get_field(coefficients_alloc));
126 host_t<DField<IdxRange<DDims...>>> coefficients(get_field(coefficients_alloc_host));
127 // Serial loop is used due to nvcc bug concerning functions with variadic template arguments
128 // (see https://github.com/kokkos/kokkos/pull/7059)
129 ddc::for_each(idx_range, [&](Idx<DDims...> const idim) {
130 // multiply the 1D coefficients by one another
131 coefficients(idim)
132 = (std::get<CoefficientField1D<Kokkos::DefaultHostExecutionSpace, DDims>>(
133 current_dim_coeffs)(ddc::select<DDims>(idim))
134 * ... * 1);
135 });
136 ddc::parallel_deepcopy(coefficients_alloc, coefficients_alloc_host);
137 return coefficients_alloc;
138}
DFieldMem< IdxRange< Grid1D >, typename ExecSpace::memory_space > neumann_spline_quadrature_coefficients_1d(IdxRange< Grid1D > const &idx_range, SplineBuilder const &builder)
Get the spline quadrature coefficients in 1D.
Definition neumann_spline_quadrature.hpp:51
DFieldMem< IdxRange< DDims... >, typename ExecSpace::memory_space > neumann_spline_quadrature_coefficients(IdxRange< DDims... > const &idx_range, SplineBuilders const &... builders)
Get the spline quadrature coefficients in ND from N 1D quadrature coefficient.
Definition neumann_spline_quadrature.hpp:107