diff --git a/include/ddc/kernels/fft.hpp b/include/ddc/kernels/fft.hpp index 74a01083d..884581968 100644 --- a/include/ddc/kernels/fft.hpp +++ b/include/ddc/kernels/fft.hpp @@ -332,29 +332,7 @@ int N(ddc::DiscreteDomain x_mesh) static_assert( (is_uniform_point_sampling_v && ...), "DDimX dimensions should derive from UniformPointSampling"); - return ddc::get(x_mesh.extents()); -} - -template -double a(ddc::DiscreteDomain x_mesh) -{ - static_assert( - (is_uniform_point_sampling_v && ...), - "DDimX dimensions should derive from UniformPointSampling"); - return ((2 * N(x_mesh) - 1) * coordinate(ddc::select(x_mesh).front()) - - coordinate(ddc::select(x_mesh).back())) - / 2 / (N(x_mesh) - 1); -} - -template -double b(ddc::DiscreteDomain x_mesh) -{ - static_assert( - (is_uniform_point_sampling_v && ...), - "DDimX dimensions should derive from UniformPointSampling"); - return ((2 * N(x_mesh) - 1) * coordinate(ddc::select(x_mesh).back()) - - coordinate(ddc::select(x_mesh).front())) - / 2 / (N(x_mesh) - 1); + return static_cast(x_mesh.template extent()); } // core @@ -595,7 +573,10 @@ typename DDimFx::template Impl init_fourier_space( ddc::Coordinate(0), ddc::Coordinate( 2 * (ddc::detail::fft::N(x_mesh) - 1) - / (ddc::detail::fft::b(x_mesh) - ddc::detail::fft::a(x_mesh)) + * (ddc::detail::fft::N(x_mesh) - 1) + / static_cast( + ddc::detail::fft::N(x_mesh) + * (ddc::coordinate(x_mesh.back()) - ddc::coordinate(x_mesh.front()))) * Kokkos::numbers::pi), ddc::DiscreteVector(ddc::detail::fft::N(x_mesh)), ddc::DiscreteVector(ddc::detail::fft::N(x_mesh))); diff --git a/include/ddc/periodic_sampling.hpp b/include/ddc/periodic_sampling.hpp index 5b73b65ec..b0882a3be 100644 --- a/include/ddc/periodic_sampling.hpp +++ b/include/ddc/periodic_sampling.hpp @@ -127,8 +127,8 @@ class PeriodicSampling : detail::PeriodicSamplingBase { return m_origin + continuous_element_type( - static_cast((icoord.uid() + m_n_period / 2 - 1) % m_n_period) - - static_cast(m_n_period / 2 - 1)) + static_cast((icoord.uid() + m_n_period / 2) % m_n_period) + - static_cast(m_n_period / 2)) * m_step; } }; diff --git a/tests/fft.cpp b/tests/fft.cpp index f2cfd4727..183b4b28b 100644 --- a/tests/fft.cpp +++ b/tests/fft.cpp @@ -29,6 +29,34 @@ struct DFDim : ddc::PeriodicSampling { }; +template +static void test_fourier_mesh(std::size_t Nx) +{ + double const a = -10; + double const b = 10; + + DDom> const x_mesh(ddc::init_discrete_space>(DDim::template init>( + ddc::Coordinate(a + (b - a) / Nx / 2), + ddc::Coordinate(b - (b - a) / Nx / 2), + DVect>(Nx)))); + ddc::init_discrete_space>>( + ddc::init_fourier_space>>(ddc::DiscreteDomain>(x_mesh))); + DDom>> const k_mesh + = ddc::FourierMesh>>(x_mesh, true); + + double const epsilon = 1e-14; + ddc::DiscreteElement>> const k_front = k_mesh.front(); + for (ddc::DiscreteElement>> k : k_mesh) { + double const ka = -Kokkos::numbers::pi * Nx / (b - a); + double const kb = Kokkos::numbers::pi * Nx / (b - a); + double const k_pred = 2 * (k - k_front) * Kokkos::numbers::pi / (b - a); + EXPECT_NEAR( + ddc::coordinate(k), + k_pred - (kb - ka) * Kokkos::floor((k_pred - ka) / (kb - ka)), + epsilon); + } +} + // TODO: // - FFT multidim but according to a subset of dimensions template @@ -199,6 +227,16 @@ struct RDimX; struct RDimY; struct RDimZ; +TEST(FourierMesh, Even) +{ + test_fourier_mesh(16); +} + +TEST(FourierMesh, Odd) +{ + test_fourier_mesh(17); +} + #if fftw_serial_AVAIL TEST(FFTNorm, OFF) {