//////////////////////////////////////////////////////////////////////////////// // // FourierTransform.h // //////////////////////////////////////////////////////////////////////////////// // $Id: FourierTransform.h,v 1.10 2007-03-17 01:14:00 fgygi Exp $ #ifndef FOURIERTRANSFORM_H #define FOURIERTRANSFORM_H #include #include #if USE_FFTW #include "fftw.h" #endif #include "Timer.h" class Basis; class Context; class FourierTransform { private: const Context& ctxt_; const Basis& basis_; int nprocs_, myproc_; int np0_,np1_,np2_; int ntrans0_,ntrans1_,ntrans2_; int nvec_; std::vector np2_loc_; // np2_loc_[iproc], iproc=0, nprocs_-1 std::vector np2_first_; // np2_first_[iproc], iproc=0, nprocs_-1 std::vector > zvec_; std::vector scounts, sdispl, rcounts, rdispl; std::vector > sbuf, rbuf; std::vector ifftp_, ifftm_; std::vector ipack_, iunpack_; void init_lib(void); #if USE_ESSL #if USE_ESSL_2DFFT std::vector aux1xyf; std::vector aux1xyb; int naux1xy; #else std::vector aux1xf, aux1yf, aux1zf; std::vector aux1xb, aux1yb, aux1zb; std::vector aux2; int naux1x,naux1y,naux1z,naux2; #endif #elif USE_FFTW || USE_FFTW3 fftw_plan fwplan0,fwplan1,fwplan2,bwplan0,bwplan1,bwplan2; #else // no library #endif void vector_to_zvec(const std::complex* c); void zvec_to_vector(std::complex* c); void doublevector_to_zvec(const std::complex* c1, const std::complex *c2); void zvec_to_doublevector(std::complex* c1, std::complex* c2); void fwd(std::complex* val); void bwd(std::complex* val); public: FourierTransform (const Basis &basis, int np0, int np1, int np2); ~FourierTransform (); const Context& context(void) const { return ctxt_; } // backward: Fourier synthesis, compute real-space function // forward: Fourier analysis, compute Fourier coefficients // forward transform includes scaling by 1/np012 // single transforms: c -> f, f -> c void backward (const std::complex* c, std::complex* f); // Note: forward transforms overwrite the array f void forward(std::complex* f, std::complex* c); // double transforms: c1 + i*c2 -> f, f -> c1 + i*c2 void backward (const std::complex* c1, const std::complex* c2, std::complex* f); // Note: forward transforms overwrite the array f void forward(std::complex* f, std::complex* c1, std::complex* c2); int np0() const { return np0_; } int np1() const { return np1_; } int np2() const { return np2_; } int np2_loc() const { return np2_loc_[myproc_]; } int np2_loc(int iproc) const { return np2_loc_[iproc]; } int np2_first() const { return np2_first_[myproc_]; } int np2_first(int iproc) const { return np2_first_[iproc]; } int np012() const { return np0_ * np1_ * np2_; } int np012loc(int iproc) const { return np0_ * np1_ * np2_loc_[iproc]; } int np012loc() const { return np0_ * np1_ * np2_loc_[myproc_]; } int index(int i, int j, int k) const { return i + np0_ * ( j + np1_ * k ); } void reset_timers(void); Timer tm_f_map, tm_f_fft, tm_f_pack, tm_f_mpi, tm_f_zero, tm_f_unpack, tm_b_map, tm_b_fft, tm_b_pack, tm_b_mpi, tm_b_zero, tm_b_unpack; }; #endif