Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
amrex::FFT::R2C< T, D, C > Class Template Reference

Parallel Discrete Fourier Transform. More...

#include <AMReX_FFT_R2C.H>

Public Types

using cMF = FabArray< BaseFab< GpuComplex< T > > >
 
using MF = std::conditional_t< C, cMF, std::conditional_t< std::is_same_v< T, Real >, MultiFab, FabArray< BaseFab< T > > > >
 

Public Member Functions

 R2C (Box const &domain, Info const &info=Info{})
 Constructor.
 
 R2C (std::array< int, 3 > const &domain_size, Info const &info=Info{})
 Constructor.
 
 ~R2C ()
 
 R2C (R2C const &)=delete
 
 R2C (R2C &&)=delete
 
R2Coperator= (R2C const &)=delete
 
R2Coperator= (R2C &&)=delete
 
void setLocalDomain (std::array< int, 3 > const &local_start, std::array< int, 3 > const &local_size)
 Set local domain.
 
std::pair< std::array< int, 3 >, std::array< int, 3 > > getLocalDomain () const
 Get local domain.
 
void setLocalSpectralDomain (std::array< int, 3 > const &local_start, std::array< int, 3 > const &local_size)
 Set local spectral domain.
 
std::pair< std::array< int, 3 >, std::array< int, 3 > > getLocalSpectralDomain () const
 Get local spectral domain.
 
template<typename F , Direction DIR = D, std::enable_if_t< DIR==Direction::both, int > = 0>
void forwardThenBackward (MF const &inmf, MF &outmf, F const &post_forward, int incomp=0, int outcomp=0)
 Forward and then backward transform.
 
template<Direction DIR = D, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > = 0>
void forward (MF const &inmf, int incomp=0)
 Forward transform.
 
template<Direction DIR = D, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > = 0>
void forward (MF const &inmf, cMF &outmf, int incomp=0, int outcomp=0)
 Forward transform.
 
template<typename RT , typename CT , Direction DIR = D, bool CP = C, std::enable_if_t<(DIR==Direction::forward||DIR==Direction::both) &&((sizeof(RT) *2==sizeof(CT) &&!CP)||(sizeof(RT)==sizeof(CT) &&CP)), int > = 0>
void forward (RT const *in, CT *out)
 Forward transform.
 
template<Direction DIR = D, std::enable_if_t< DIR==Direction::both, int > = 0>
void backward (MF &outmf, int outcomp=0)
 Backward transform.
 
template<Direction DIR = D, std::enable_if_t< DIR==Direction::backward||DIR==Direction::both, int > = 0>
void backward (cMF const &inmf, MF &outmf, int incomp=0, int outcomp=0)
 Backward transform.
 
template<typename CT , typename RT , Direction DIR = D, bool CP = C, std::enable_if_t<(DIR==Direction::backward||DIR==Direction::both) &&((sizeof(RT) *2==sizeof(CT) &&!CP)||(sizeof(RT)==sizeof(CT) &&CP)), int > = 0>
void backward (CT const *in, RT *out)
 Backward transform.
 
scalingFactor () const
 
template<Direction DIR = D, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > = 0>
std::pair< cMF *, IntVectgetSpectralData () const
 Get the internal spectral data.
 
std::pair< BoxArray, DistributionMappinggetSpectralDataLayout () const
 Get BoxArray and DistributionMapping for spectral data.
 
template<typename F >
void post_forward_doit_0 (F const &post_forward)
 
template<typename F >
void post_forward_doit_1 (F const &post_forward)
 
template<Direction DIR, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > >
std::pair< typename R2C< T, D, C >::cMF *, IntVectgetSpectralData () const
 

Friends

template<typename U >
class OpenBCSolver
 
template<typename U >
class Poisson
 
template<typename U >
class PoissonHybrid
 

Detailed Description

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
class amrex::FFT::R2C< T, D, C >

Parallel Discrete Fourier Transform.

This class supports Fourier transforms between real and complex data. The name R2C indicates that the forward transform converts real data to complex data, while the backward transform converts complex data to real data. It should be noted that both directions of transformation are supported, not just from real to complex. The scaling follows the FFTW convention, where applying the forward transform followed by the backward transform scales the original data by the size of the input array.

The arrays are assumed to be in column-major, which is different from FFTW's row-major layout. Because the complex domain data have the Hermitian symmetry, only half of the data in the complex domain are stored. If the real domain size is nx * ny * nz, the complex domain's size will be (nx/2+1) * ny * nz.

For more details, we refer the users to https://amrex-codes.github.io/amrex/docs_html/FFT_Chapter.html.

Member Typedef Documentation

◆ cMF

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
using amrex::FFT::R2C< T, D, C >::cMF = FabArray<BaseFab<GpuComplex<T> > >

◆ MF

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
using amrex::FFT::R2C< T, D, C >::MF = std::conditional_t <C, cMF, std::conditional_t<std::is_same_v<T,Real>, MultiFab, FabArray<BaseFab<T> > > >

Constructor & Destructor Documentation

◆ R2C() [1/4]

template<typename T , Direction D, bool C>
amrex::FFT::R2C< T, D, C >::R2C ( Box const &  domain,
Info const &  info = Info{} 
)
explicit

Constructor.

Parameters
domainthe forward domain (i.e., the domain of the real data)
infooptional information

◆ R2C() [2/4]

template<typename T , Direction D, bool C>
amrex::FFT::R2C< T, D, C >::R2C ( std::array< int, 3 > const &  domain_size,
Info const &  info = Info{} 
)
explicit

Constructor.

If AMREX_SPACEDIM is 3 and you want to do 2D FFT, you just need to set the size of one of the dimensions to 1.

Parameters
domain_sizesize of the forward domain (i.e., the real data domain)
infooptional information

◆ ~R2C()

template<typename T , Direction D, bool C>
amrex::FFT::R2C< T, D, C >::~R2C ( )

◆ R2C() [3/4]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
amrex::FFT::R2C< T, D, C >::R2C ( R2C< T, D, C > const &  )
delete

◆ R2C() [4/4]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
amrex::FFT::R2C< T, D, C >::R2C ( R2C< T, D, C > &&  )
delete

Member Function Documentation

◆ backward() [1/3]

template<typename T , Direction D, bool C>
template<Direction DIR, std::enable_if_t< DIR==Direction::backward||DIR==Direction::both, int > >
void amrex::FFT::R2C< T, D, C >::backward ( cMF const &  inmf,
MF outmf,
int  incomp = 0,
int  outcomp = 0 
)

Backward transform.

This function is not available when this class template is instantiated for forward-only transform.

Parameters
inmfinput data in FabArray<BaseFab<GpuComplex<T>>>
outmfoutput data in MultiFab or FabArray<BaseFab<float>>
incompcomponent index of input data
outcompcomponent index of output data

◆ backward() [2/3]

template<typename T , Direction D, bool C>
template<typename CT , typename RT , Direction DIR, bool CP, std::enable_if_t<(DIR==Direction::backward||DIR==Direction::both) &&((sizeof(RT) *2==sizeof(CT) &&!CP)||(sizeof(RT)==sizeof(CT) &&CP)), int > >
void amrex::FFT::R2C< T, D, C >::backward ( CT const *  in,
RT *  out 
)

Backward transform.

This raw pointer version of backward requires setLocalDomain/getLocalDomain and setLocalSpectralDomain/getLocalSpectralDomain have been called already. Note that one is allowed to call this function multiple times after the set/get domain functions are called only once unless the domain decomposition changes. In fact, that is the preferred way because it has better performance. All processes need to call this function even if their local size is zero. If the local size is zero, one can pass nullptrs.

◆ backward() [3/3]

template<typename T , Direction D, bool C>
template<Direction DIR, std::enable_if_t< DIR==Direction::both, int > >
void amrex::FFT::R2C< T, D, C >::backward ( MF outmf,
int  outcomp = 0 
)

Backward transform.

This function is available only when this class template is instantiated for transforms in both directions.

Parameters
outmfoutput data in MultiFab or FabArray<BaseFab<float>>
outcompcomponent index of output data

◆ forward() [1/3]

template<typename T , Direction D, bool C>
template<Direction DIR, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > >
void amrex::FFT::R2C< T, D, C >::forward ( MF const &  inmf,
cMF outmf,
int  incomp = 0,
int  outcomp = 0 
)

Forward transform.

This function is not available when this class template is instantiated for backward-only transform.

Parameters
inmfinput data in MultiFab or FabArray<BaseFab<float>>
outmfoutput data in FabArray<BaseFab<GpuComplex<T>>>
incompcomponent index of input data
outcompcomponent index of output data

◆ forward() [2/3]

template<typename T , Direction D, bool C>
template<Direction DIR, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > >
void amrex::FFT::R2C< T, D, C >::forward ( MF const &  inmf,
int  incomp = 0 
)

Forward transform.

The output is stored in this object's internal data. This function is not available when this class template is instantiated for backward-only transform.

Parameters
inmfinput data in MultiFab or FabArray<BaseFab<float>>
incompcomponent index of input data

◆ forward() [3/3]

template<typename T , Direction D, bool C>
template<typename RT , typename CT , Direction DIR, bool CP, std::enable_if_t<(DIR==Direction::forward||DIR==Direction::both) &&((sizeof(RT) *2==sizeof(CT) &&!CP)||(sizeof(RT)==sizeof(CT) &&CP)), int > >
void amrex::FFT::R2C< T, D, C >::forward ( RT const *  in,
CT *  out 
)

Forward transform.

This raw pointer version of forward requires setLocalDomain/getLocalDomain and setLocalSpectralDomain/getLocalSpectralDomain have been called already. Note that one is allowed to call this function multiple times after the set/get domain functions are called only once, unless the domain decomposition changes. In fact, that is the preferred way because it has better performance. All processes need to call this function even if their local size is zero. If the local size is zero, one can pass nullptrs.

◆ forwardThenBackward()

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<typename F , Direction DIR = D, std::enable_if_t< DIR==Direction::both, int > = 0>
void amrex::FFT::R2C< T, D, C >::forwardThenBackward ( MF const &  inmf,
MF outmf,
F const &  post_forward,
int  incomp = 0,
int  outcomp = 0 
)
inline

Forward and then backward transform.

This function is available only when this class template is instantiated for transforms in both directions. It's more efficient than calling the forward function that stores the spectral data in a caller provided container followed by the backward function, because this can avoid parallel communication between the internal data and the caller's data container.

Parameters
inmfinput data in MultiFab or FabArray<BaseFab<float>>
outmfoutput data in MultiFab or FabArray<BaseFab<float>>
post_forwarda callable object for processing the post-forward data before the backward transform. Its interface is (int,int,int,GpuComplex<T>&), where the integers are indices in the spectral space, and the reference to the complex number allows for the modification of the spectral data at that location.
incompcomponent index of input data
outcompcomponent index of output data

◆ getLocalDomain()

template<typename T , Direction D, bool C>
std::pair< std::array< int, 3 >, std::array< int, 3 > > amrex::FFT::R2C< T, D, C >::getLocalDomain ( ) const

Get local domain.

This function returns the domain decomposition chosen by AMReX. The first part of the pair is the local starting indices, and the second part is the local domain size.

This is needed, only if one uses the raw pointer interfaces, not the amrex::MulitFab interfaces. Only one of the functions, setLocalDomain and getLocalDomain, should be called.

◆ getLocalSpectralDomain()

template<typename T , Direction D, bool C>
std::pair< std::array< int, 3 >, std::array< int, 3 > > amrex::FFT::R2C< T, D, C >::getLocalSpectralDomain ( ) const

Get local spectral domain.

This function returns the domain decomposition chosen by AMReX for the complex data spectral domain. The returned pair contains the local starting indices and the local domain size.

This is needed, only if one uses the raw pointer interfaces, not the amrex::MulitFab interfaces. Only one of the functions, setLocalSpectralDomain and getLocalSpectralDomain, should be called. Note that one could use this function together with setLocalDomain. That is the user is allowed to choose their own real domain decomposition, while let AMReX choose the spectral data domain decomposition. Also note that the entire spectral domain has the size of (nx+1)/2 * ny * nz, if the real domain is nx * ny * nz.

◆ getSpectralData() [1/2]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<Direction DIR = D, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > = 0>
std::pair< cMF *, IntVect > amrex::FFT::R2C< T, D, C >::getSpectralData ( ) const

Get the internal spectral data.

This function is not available when this class template is instantiated for backward-only transform. For performance reasons, the returned data array does not have the usual ordering of (x,y,z). The order is specified in the second part of the return value.

◆ getSpectralData() [2/2]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<Direction DIR, std::enable_if_t< DIR==Direction::forward||DIR==Direction::both, int > >
std::pair< typename R2C< T, D, C >::cMF *, IntVect > amrex::FFT::R2C< T, D, C >::getSpectralData ( ) const

◆ getSpectralDataLayout()

template<typename T , Direction D, bool C>
std::pair< BoxArray, DistributionMapping > amrex::FFT::R2C< T, D, C >::getSpectralDataLayout ( ) const

Get BoxArray and DistributionMapping for spectral data.

The returned BoxArray and DistributionMapping can be used to build FabArray<BaseFab<GpuComplex<T>>> for spectral data. The returned BoxArray has the usual order of (x,y,z).

◆ operator=() [1/2]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
R2C & amrex::FFT::R2C< T, D, C >::operator= ( R2C< T, D, C > &&  )
delete

◆ operator=() [2/2]

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
R2C & amrex::FFT::R2C< T, D, C >::operator= ( R2C< T, D, C > const &  )
delete

◆ post_forward_doit_0()

template<typename T , Direction D, bool C>
template<typename F >
void amrex::FFT::R2C< T, D, C >::post_forward_doit_0 ( F const &  post_forward)

◆ post_forward_doit_1()

template<typename T , Direction D, bool C>
template<typename F >
void amrex::FFT::R2C< T, D, C >::post_forward_doit_1 ( F const &  post_forward)

◆ scalingFactor()

template<typename T , Direction D, bool C>
T amrex::FFT::R2C< T, D, C >::scalingFactor ( ) const

Scaling factor. If the data goes through forward and then backward, the result multiplied by the scaling factor is equal to the original data.

◆ setLocalDomain()

template<typename T , Direction D, bool C>
void amrex::FFT::R2C< T, D, C >::setLocalDomain ( std::array< int, 3 > const &  local_start,
std::array< int, 3 > const &  local_size 
)

Set local domain.

This is needed, only if one uses the raw pointer interfaces, not the amrex::MulitFab interfaces. This may contain collective MPI calls. So all processes even if their local size is zero should call. This function informs AMReX the domain decomposition chosen by the user for the forward domain (i.e., real data domain). There is no constraint on the domain decomposition strategy. One can do 1D, 2D or 3D domain decomposition. Alternatively, one could also let AMReX choose for you by calling getLocalDomain. The latter could potentially reduce data communication.

Again, this is needed, only if one uses the raw pointer interfaces. Only one of the functions, setLocalDomain and getLocalDomain, should be called.

This should only be called once unless the domain decomposition changes.

local_start starting indices of the local domain local_size size of the local domain

◆ setLocalSpectralDomain()

template<typename T , Direction D, bool C>
void amrex::FFT::R2C< T, D, C >::setLocalSpectralDomain ( std::array< int, 3 > const &  local_start,
std::array< int, 3 > const &  local_size 
)

Set local spectral domain.

This is needed, only if one uses the raw pointer interfaces, not the amrex::MulitFab interfaces. This may contain collective MPI calls. So all processes even if their local size is zero should call. This function informs AMReX the domain decomposition chosen by the user for the complex data domain. There is no constraint on the domain decomposition strategy. One can do 1D, 2D or 3D domain decomposition. Alternatively, one could also let AMReX choose for you by calling getLocalSpectralDomain. The latter could potentially reduce data communication.

Again, this is needed, only if one uses the raw pointer interfaces. Only one of the functions, setLocalSpectralDomain and getLocalSpectralDomain, should be called. Note that one could use this function together with getLocalDomain. That is the user is allowed to choose their own spectral domain decomposition, while let AMReX choose the real data domain decomposition. Also note that the entire spectral domain has the size of (nx+1)/2 * ny * nz, if the real domain is nx * ny * nz.

This should only be called once unless the domain decomposition changes.

local_start starting indices of the local domain local_size size of the local domain

Friends And Related Symbol Documentation

◆ OpenBCSolver

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<typename U >
friend class OpenBCSolver
friend

◆ Poisson

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<typename U >
friend class Poisson
friend

◆ PoissonHybrid

template<typename T = Real, FFT::Direction D = FFT::Direction::both, bool C = false>
template<typename U >
friend class PoissonHybrid
friend

The documentation for this class was generated from the following file: