1 #ifndef AMREX_FFT_R2C_H_
2 #define AMREX_FFT_R2C_H_
3 #include <AMReX_Config.H>
14 template <
typename T>
class OpenBCSolver;
36 using MF = std::conditional_t<std::is_same_v<T,Real>,
77 std::enable_if_t<DIR == Direction::both, int> = 0>
120 template <Direction DIR=D, std::enable_if_t<DIR == Direction::both,
int> = 0>
164 template <
typename F>
217 template <
typename T, Direction D, DomainStrategy S>
219 : m_real_domain(domain),
224 #
if (AMREX_SPACEDIM >= 2)
229 #
if (AMREX_SPACEDIM == 3)
240 static_assert(std::is_same_v<float,T> || std::is_same_v<double,T>);
242 #if (AMREX_SPACEDIM == 3)
252 #if (AMREX_SPACEDIM == 3)
265 m_rx.define(bax, dmx, 1, 0,
MFInfo().SetAlloc(
false));
269 for (
auto &
b : bl) {
277 #if (AMREX_SPACEDIM >= 2)
282 if (cbay.size() == dmx.size()) {
291 #if (AMREX_SPACEDIM == 3)
296 {
false,
true,
true},
true);
298 if (cbaz.size() == dmx.size()) {
300 }
else if (cbaz.size() == cdmy.
size()) {
321 #if (AMREX_SPACEDIM >= 2)
324 m_cmd_x2y = std::make_unique<MultiBlockCommMetaData>
326 m_cmd_y2x = std::make_unique<MultiBlockCommMetaData>
330 #if (AMREX_SPACEDIM == 3)
334 m_cmd_x2z = std::make_unique<MultiBlockCommMetaData>
336 m_cmd_z2x = std::make_unique<MultiBlockCommMetaData>
340 m_cmd_y2z = std::make_unique<MultiBlockCommMetaData>
342 m_cmd_z2y = std::make_unique<MultiBlockCommMetaData>
352 if (myproc <
m_rx.size())
354 Box const& box =
m_rx.box(myproc);
355 auto* pr =
m_rx[myproc].dataPtr();
357 #ifdef AMREX_USE_SYCL
370 #if (AMREX_SPACEDIM >= 2)
375 #if (AMREX_SPACEDIM == 3)
382 template <
typename T, Direction D, DomainStrategy S>
385 if (m_fft_bwd_x.plan != m_fft_fwd_x.plan) {
386 m_fft_bwd_x.destroy();
388 if (m_fft_bwd_y.plan != m_fft_fwd_y.plan) {
389 m_fft_bwd_y.destroy();
391 if (m_fft_bwd_z.plan != m_fft_fwd_z.plan) {
392 m_fft_bwd_z.destroy();
394 m_fft_fwd_x.destroy();
395 m_fft_fwd_y.destroy();
396 m_fft_fwd_z.destroy();
399 template <
typename T, Direction D, DomainStrategy S>
406 if (&m_rx != &inmf) {
407 m_rx.ParallelCopy(inmf, 0, 0, 1);
409 m_fft_fwd_x.template compute_r2c<Direction::forward>();
412 ParallelCopy(m_cy, m_cx, *m_cmd_x2y, 0, 0, 1, m_dtos_x2y);
414 m_fft_fwd_y.template compute_c2c<Direction::forward>();
417 ParallelCopy(m_cz, m_cy, *m_cmd_y2z, 0, 0, 1, m_dtos_y2z);
419 #if (AMREX_SPACEDIM == 3)
420 else if ( m_cmd_x2z) {
422 Box upper_half = m_spectral_domain_z;
424 upper_half.
growLo (0,-m_spectral_domain_z.length(0)/2);
425 if (! m_cmd_x2z_half) {
426 Box bottom_half = m_spectral_domain_z;
427 bottom_half.
growHi(0,-m_spectral_domain_z.length(0)/2);
428 m_cmd_x2z_half = std::make_unique<MultiBlockCommMetaData>
429 (m_cz, bottom_half, m_cx,
IntVect(0), m_dtos_x2z);
434 m_cz.setVal(0, upper_half, 0, 1);
437 ParallelCopy(m_cz, m_cx, *m_cmd_x2z, 0, 0, 1, m_dtos_x2z);
441 m_fft_fwd_z.template compute_c2c<Direction::forward>();
444 template <
typename T, Direction D, DomainStrategy S>
445 template <Direction DIR, std::enable_if_t<DIR == Direction::both,
int> >
448 backward_doit(outmf);
451 template <
typename T, Direction D, DomainStrategy S>
456 m_fft_bwd_z.template compute_c2c<Direction::backward>();
458 ParallelCopy(m_cy, m_cz, *m_cmd_z2y, 0, 0, 1, m_dtos_z2y);
460 #if (AMREX_SPACEDIM == 3)
461 else if ( m_cmd_z2x) {
463 Box upper_half = m_spectral_domain_x;
464 upper_half.
growLo (2,-m_spectral_domain_x.length(2)/2);
465 if (! m_cmd_z2x_half) {
466 Box bottom_half = m_spectral_domain_x;
467 bottom_half.
growHi(2,-m_spectral_domain_x.length(2)/2);
468 m_cmd_z2x_half = std::make_unique<MultiBlockCommMetaData>
469 (m_cx, bottom_half, m_cz,
IntVect(0), m_dtos_z2x);
476 ParallelCopy(m_cx, m_cz, *m_cmd_z2x, 0, 0, 1, m_dtos_z2x);
481 m_fft_bwd_y.template compute_c2c<Direction::backward>();
483 ParallelCopy(m_cx, m_cy, *m_cmd_y2x, 0, 0, 1, m_dtos_y2x);
486 m_fft_bwd_x.template compute_r2c<Direction::backward>();
487 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0), ngout);
490 template <
typename T, Direction D, DomainStrategy S>
498 if (!fab) {
return {fwd, bwd};}
500 Box const& box = fab->box();
503 #ifdef AMREX_USE_SYCL
504 fwd.template init_c2c<Direction::forward>(box, pio);
508 fwd.template init_c2c<Direction::forward>(box, pio);
511 bwd.template init_c2c<Direction::backward>(box, pio);
518 template <
typename T, Direction D, DomainStrategy S>
519 template <
typename F>
522 if (m_info.batch_mode) {
525 if ( ! m_cz.empty()) {
528 auto const& a = spectral_fab->array();
532 post_forward(jx,ky,
iz,a(
iz,jx,ky));
535 }
else if ( ! m_cy.empty()) {
538 auto const& a = spectral_fab->array();
542 post_forward(jx,
iy,k,a(
iy,jx,k));
548 auto const& a = spectral_fab->array();
552 post_forward(i,j,k,a(i,j,k));
559 template <
typename T, Direction D, DomainStrategy S>
562 #if (AMREX_SPACEDIM == 3)
563 if (m_info.batch_mode) {
564 return T(1)/T(Long(m_real_domain.length(0)) *
565 Long(m_real_domain.length(1)));
569 return T(1)/T(m_real_domain.numPts());
573 template <
typename T, Direction D, DomainStrategy S>
576 std::pair<typename R2C<T,D,S>::cMF *,
IntVect>
581 }
else if (!m_cy.empty()) {
588 template <
typename T, Direction D, DomainStrategy S>
599 (outmf, m_spectral_domain_x, m_cz,
IntVect(0), dtos);
601 }
else if (!m_cy.empty()) {
603 (outmf, m_spectral_domain_x, m_cy,
IntVect(0), m_dtos_y2x);
610 template <
typename T, Direction D, DomainStrategy S>
620 (m_cz, m_spectral_domain_z, inmf,
IntVect(0), dtos);
622 }
else if (!m_cy.empty()) {
624 (m_cy, m_spectral_domain_y, inmf,
IntVect(0), m_dtos_x2y);
627 m_cx.ParallelCopy(inmf, 0, 0, 1);
629 backward_doit(outmf);
632 template <
typename T, Direction D, DomainStrategy S>
633 std::pair<BoxArray,DistributionMapping>
636 #if (AMREX_SPACEDIM == 3)
638 BoxList bl = m_cz.boxArray().boxList();
640 auto lo =
b.smallEnd();
641 auto hi =
b.bigEnd();
649 return std::make_pair(
BoxArray(std::move(bl)), m_cz.DistributionMap());
652 #if (AMREX_SPACEDIM >= 2)
653 if (!!m_cy.empty()) {
654 BoxList bl = m_cy.boxArray().boxList();
656 auto lo =
b.smallEnd();
657 auto hi =
b.bigEnd();
663 return std::make_pair(
BoxArray(std::move(bl)), m_cy.DistributionMap());
667 return std::make_pair(m_cx.boxArray(), m_cx.DistributionMap());
#define BL_PROFILE(a)
Definition: AMReX_BLProfiler.H:551
#define AMREX_ALWAYS_ASSERT(EX)
Definition: AMReX_BLassert.H:50
#define AMREX_GPU_DEVICE
Definition: AMReX_GpuQualifiers.H:18
#define AMREX_D_DECL(a, b, c)
Definition: AMReX_SPACE.H:104
if(!(yy_init))
Definition: amrex_iparser.lex.nolint.H:935
A collection of Boxes stored in an Array.
Definition: AMReX_BoxArray.H:549
A class for managing a List of Boxes that share a common IndexType. This class implements operations ...
Definition: AMReX_BoxList.H:52
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition: AMReX_Box.H:105
AMREX_GPU_HOST_DEVICE const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition: AMReX_Box.H:116
AMREX_GPU_HOST_DEVICE IntVectND< dim > length() const noexcept
Return the length of the BoxND.
Definition: AMReX_Box.H:146
AMREX_GPU_HOST_DEVICE BoxND & growHi(int idir, int n_cell=1) noexcept
Grow the BoxND on the high end by n_cell cells in direction idir. NOTE: n_cell negative shrinks the B...
Definition: AMReX_Box.H:659
AMREX_GPU_HOST_DEVICE BoxND & growLo(int idir, int n_cell=1) noexcept
Grow the BoxND on the low end by n_cell cells in direction idir. NOTE: n_cell negative shrinks the Bo...
Definition: AMReX_Box.H:648
Calculates the distribution of FABs to MPI processes.
Definition: AMReX_DistributionMapping.H:41
Long size() const noexcept
Length of the underlying processor map.
Definition: AMReX_DistributionMapping.H:104
Definition: AMReX_FFT_OpenBCSolver.H:11
Parallel Discrete Fourier Transform.
Definition: AMReX_FFT_R2C.H:34
T scalingFactor() const
Definition: AMReX_FFT_R2C.H:560
std::pair< cMF *, IntVect > getSpectralData()
Get the internal spectral data.
RotateFwd m_dtos_x2z
Definition: AMReX_FFT_R2C.H:195
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2z_half
Definition: AMReX_FFT_R2C.H:189
Swap01 m_dtos_x2y
Definition: AMReX_FFT_R2C.H:191
Plan< T > m_fft_bwd_y
Definition: AMReX_FFT_R2C.H:176
static std::pair< Plan< T >, Plan< T > > make_c2c_plans(cMF &inout)
Definition: AMReX_FFT_R2C.H:492
Box m_real_domain
Definition: AMReX_FFT_R2C.H:206
Plan< T > m_fft_fwd_x
Definition: AMReX_FFT_R2C.H:173
Swap02 m_dtos_y2z
Definition: AMReX_FFT_R2C.H:193
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2y
Definition: AMReX_FFT_R2C.H:183
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2y
Definition: AMReX_FFT_R2C.H:186
Plan< T > m_fft_bwd_x
Definition: AMReX_FFT_R2C.H:174
void forward(MF const &inmf, cMF &outmf)
Forward transform.
Definition: AMReX_FFT_R2C.H:591
cMF m_cz
Definition: AMReX_FFT_R2C.H:201
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2x_half
Definition: AMReX_FFT_R2C.H:190
Plan< T > m_fft_bwd_z
Definition: AMReX_FFT_R2C.H:178
bool m_slab_decomp
Definition: AMReX_FFT_R2C.H:213
cMF m_cx
Definition: AMReX_FFT_R2C.H:199
void backward(MF &outmf)
Backward transform.
Definition: AMReX_FFT_R2C.H:446
Box m_spectral_domain_y
Definition: AMReX_FFT_R2C.H:208
RotateBwd m_dtos_z2x
Definition: AMReX_FFT_R2C.H:196
std::pair< BoxArray, DistributionMapping > getSpectralDataLayout() const
Get BoxArray and DistributionMapping for spectral data.
Definition: AMReX_FFT_R2C.H:634
Info m_info
Definition: AMReX_FFT_R2C.H:211
std::unique_ptr< MultiBlockCommMetaData > m_cmd_y2z
Definition: AMReX_FFT_R2C.H:185
Box m_spectral_domain_z
Definition: AMReX_FFT_R2C.H:209
std::unique_ptr< MultiBlockCommMetaData > m_cmd_z2x
Definition: AMReX_FFT_R2C.H:188
std::conditional_t< std::is_same_v< T, Real >, MultiFab, FabArray< BaseFab< T > > > MF
Definition: AMReX_FFT_R2C.H:37
Plan< T > m_fft_fwd_y
Definition: AMReX_FFT_R2C.H:175
R2C(Box const &domain, Info const &info=Info{})
Constructor.
Definition: AMReX_FFT_R2C.H:218
std::unique_ptr< MultiBlockCommMetaData > m_cmd_y2x
Definition: AMReX_FFT_R2C.H:184
bool m_openbc_half
Definition: AMReX_FFT_R2C.H:214
void post_forward_doit(F const &post_forward)
Definition: AMReX_FFT_R2C.H:520
Plan< T > m_fft_fwd_z
Definition: AMReX_FFT_R2C.H:177
std::unique_ptr< char, DataDeleter > m_data_2
Definition: AMReX_FFT_R2C.H:204
Swap02 m_dtos_z2y
Definition: AMReX_FFT_R2C.H:194
R2C & operator=(R2C const &)=delete
MF m_rx
Definition: AMReX_FFT_R2C.H:198
void backward_doit(MF &outmf, IntVect const &ngout=IntVect(0))
Definition: AMReX_FFT_R2C.H:452
Box m_spectral_domain_x
Definition: AMReX_FFT_R2C.H:207
Swap01 m_dtos_y2x
Definition: AMReX_FFT_R2C.H:192
std::unique_ptr< char, DataDeleter > m_data_1
Definition: AMReX_FFT_R2C.H:203
cMF m_cy
Definition: AMReX_FFT_R2C.H:200
~R2C()
Definition: AMReX_FFT_R2C.H:383
void backward(cMF const &inmf, MF &outmf)
Backward transform.
Definition: AMReX_FFT_R2C.H:613
void forward(MF const &inmf)
Forward transform.
Definition: AMReX_FFT_R2C.H:402
std::unique_ptr< MultiBlockCommMetaData > m_cmd_x2z
Definition: AMReX_FFT_R2C.H:187
void forwardThenBackward(MF const &inmf, MF &outmf, F const &post_forward)
Forward and then backward transform.
Definition: AMReX_FFT_R2C.H:78
bool empty() const noexcept
Definition: AMReX_FabArrayBase.H:88
An Array of FortranArrayBox(FAB)-like Objects.
Definition: AMReX_FabArray.H:344
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition: AMReX_FabArray.H:778
void define(const BoxArray &bxs, const DistributionMapping &dm, int nvar, int ngrow, const MFInfo &info=MFInfo(), const FabFactory< FAB > &factory=DefaultFabFactory< FAB >())
Define this FabArray identically to that performed by the constructor having an analogous function si...
Definition: AMReX_FabArray.H:2027
A collection (stored as an array) of FArrayBox objects.
Definition: AMReX_MultiFab.H:38
FA::FABType::value_type * get_fab(FA &fa)
Definition: AMReX_FFT_Helper.H:1303
std::unique_ptr< char, DataDeleter > make_mfs_share(FA1 &fa1, FA2 &fa2)
Definition: AMReX_FFT_Helper.H:1314
DistributionMapping make_iota_distromap(Long n)
Definition: AMReX_FFT.cpp:88
Definition: AMReX_FFT.cpp:7
Direction
Definition: AMReX_FFT_Helper.H:46
DomainStrategy
Definition: AMReX_FFT_Helper.H:48
std::enable_if_t< IsBaseFab< FAB >) &&IsDataPacking< DataPacking, FAB >)> ParallelCopy_finish(FabArray< FAB > &dest, CommHandler handler, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition: AMReX_NonLocalBC.H:793
AMREX_NODISCARD CommHandler ParallelCopy_nowait(NoLocalCopy, FabArray< FAB > &dest, const FabArray< FAB > &src, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition: AMReX_NonLocalBC.H:701
int MyProcSub() noexcept
my sub-rank in current frame
Definition: AMReX_ParallelContext.H:76
int NProcsSub() noexcept
number of ranks in current frame
Definition: AMReX_ParallelContext.H:74
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition: AMReX_algoim_K.H:113
@ min
Definition: AMReX_ParallelReduce.H:18
constexpr int iz
Definition: AMReX_Interp_3D_C.H:37
constexpr int iy
Definition: AMReX_Interp_2D_C.H:33
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition: AMReX_CTOParallelForImpl.H:200
IntVectND< AMREX_SPACEDIM > IntVect
Definition: AMReX_BaseFwd.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 length(Array4< T > const &a) noexcept
Definition: AMReX_Array4.H:322
BoxArray decompose(Box const &domain, int nboxes, Array< bool, AMREX_SPACEDIM > const &decomp={AMREX_D_DECL(true, true, true)}, bool no_overlap=false)
Decompose domain box into BoxArray.
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition: AMReX.cpp:225
void ParallelCopy(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &ng_src=IntVect(0), IntVect const &ng_dst=IntVect(0), Periodicity const &period=Periodicity::NonPeriodic())
dst = src w/ MPI communication
Definition: AMReX_FabArrayUtility.H:1672
Definition: AMReX_FFT_Helper.H:56
bool batch_mode
Definition: AMReX_FFT_Helper.H:60
int nprocs
Max number of processes to use.
Definition: AMReX_FFT_Helper.H:63
Definition: AMReX_FFT_Helper.H:111
std::conditional_t< std::is_same_v< float, T >, cuComplex, cuDoubleComplex > VendorComplex
Definition: AMReX_FFT_Helper.H:115
Definition: AMReX_FFT_Helper.H:1426
Definition: AMReX_FFT_Helper.H:1401
Definition: AMReX_FFT_Helper.H:1355
Definition: AMReX_FFT_Helper.H:1378
FabArray memory allocation information.
Definition: AMReX_FabArray.H:66
This class specializes behaviour on local copies and unpacking receive buffers.
Definition: AMReX_NonLocalBC.H:615
Contains information about which components take part of the data transaction.
Definition: AMReX_NonLocalBC.H:528