#include #include #include using namespace amrex; using namespace Gpu; SpectralKSpace::SpectralKSpace( const BoxArray& realspace_ba, const DistributionMapping& dm, const RealVect realspace_dx ) { // Store the cell size dx = realspace_dx; // Create the box array that corresponds to spectral space BoxList spectral_bl; // Create empty box list // Loop over boxes and fill the box list for (int i=0; i < realspace_ba.size(); i++ ) { // For local FFTs, each box in spectral space starts at 0 in each direction // and has the same number of points as the real space box (including guard cells) Box realspace_bx = realspace_ba[i]; Box bx = Box( IntVect::TheZeroVector(), realspace_bx.bigEnd() - realspace_bx.smallEnd() ); spectral_bl.push_back( bx ); } spectralspace_ba.define( spectral_bl ); // Allocate the components of the k vector: kx, ky (only in 3D), kz for (int i_dim=0; i_dim& k = k_comp[mfi]; // Allocate k to the right size int N = bx.length( i_dim ); k.resize( N ); // Fill the k vector const Real dk = 2*MathConst::pi/(N*dx[i_dim]); AMREX_ALWAYS_ASSERT_WITH_MESSAGE( bx.smallEnd(i_dim) == 0, "Expected box to start at 0, in spectral space."); AMREX_ALWAYS_ASSERT_WITH_MESSAGE( bx.bigEnd(i_dim) == N-1, "Expected different box end index in spectral space."); // Fill positive values of k (FFT conventions: first half is positive) for (int i=0; i<(N+1)/2; i++ ){ k[i] = i*dk; } // Fill negative values of k (FFT conventions: second half is negative) for (int i=(N+1)/2; i& k = k_vec[i_dim][mfi]; ManagedVector& modified_k = modified_k_comp[mfi]; // Allocate modified_k to the same size as k modified_k.resize( k.size() ); // Fill the modified k vector for (int i=0; i& k = k_vec[i_dim][mfi]; ManagedVector& shift = shift_factor[mfi]; // Allocate shift coefficients shift.resize( k.size() ); // Fill the shift coefficients Real sign = 0; switch (shift_type){ case ShiftType::CenteredToNodal: sign = -1.; break; case ShiftType::NodalToCentered: sign = 1.; } constexpr Complex I{0,1}; for (int i=0; i