src/FFT/FFTBase.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 //--------------------------------------------------------------------------
00012 // Class FFTBase
00013 //--------------------------------------------------------------------------
00014 
00015 #ifndef IPPL_FFT_FFTBASE_H
00016 #define IPPL_FFT_FFTBASE_H
00017 
00018 // include files
00019 #include "Utility/PAssert.h"
00020 #include "Index/NDIndex.h"
00021 #include "Field/GuardCellSizes.h"
00022 
00023 #if defined(IPPL_USE_SCSL_FFT)
00024 #include "FFT/SCSL_FFT.h"
00025 #else
00026 #include "FFT/fftpack_FFT.h"
00027 #endif
00028 
00029 #ifdef IPPL_STDSTL
00030 #include <map>
00031 using std::map;
00032 #else
00033 #include <map.h>
00034 #endif
00035 
00036 #ifdef IPPL_USE_STANDARD_HEADERS
00037 #include <iostream>
00038 using namespace std;
00039 #else
00040 #include <iostream.h>
00041 #endif
00042 
00043 // forward declarations
00044 template <unsigned Dim, class T> class FFTBase;
00045 template <unsigned Dim, class T>
00046 ostream& operator<<(ostream&, const FFTBase<Dim,T>&);
00047 
00049 static char* transformTypeString_g[3] = { "complex-to-complex FFT",
00050                                           "real-to-complex FFT",
00051                                           "sine transform" };
00060 template <unsigned Dim, class T>
00061 class FFTBase {
00062 
00063 public: 
00064 
00065     // Some externally visible typedefs and enums.
00066     enum { dimensions = Dim };               // dimension
00067     typedef T Precision_t;                   // precision
00068     typedef NDIndex<Dim> Domain_t;           // domain type
00069 
00070     // Enumeration of transform types, used by derived FFT classes
00071     enum FFT_e { ccFFT, rcFFT, sineFFT };
00072 
00073     // Type used for performing 1D FFTs
00074 #if defined(IPPL_USE_SCSL_FFT)
00075     typedef SCSL<T> InternalFFT_t;
00076 #else
00077     typedef FFTPACK<T> InternalFFT_t;
00078 #endif
00079 
00080     FFTBase() {}  
00081   
00093     FFTBase(FFT_e transform, const Domain_t& domain,
00094             const bool transformTheseDims[Dim], bool compressTemps);
00095     
00104     FFTBase(FFT_e transform, const Domain_t& domain, bool compressTemps);
00105     
00106     // destructor
00107     virtual ~FFTBase(void) { delete [] activeDims_m; }
00108   
00114     void write(ostream& out) const;
00115 
00122     void setDirectionName(int direction, const char* directionName);
00123 
00129     void setNormFact(Precision_t nf) { normFact_m = nf; }
00130 
00137     int transVnodes() const {
00138         if (Ippl::maxFFTNodes() > 0 && Ippl::maxFFTNodes() <= Ippl::getNodes())
00139             return Ippl::maxFFTNodes();
00140         else
00141             return (-1);
00142     }
00143 
00144 protected:
00145 
00150 
00151     static GuardCellSizes<Dim> nullGC;
00152 
00154     int getDirection(const char* directionName) const;
00155 
00157     bool transformDim(unsigned d) const;
00158 
00160     unsigned numTransformDims(void) const { return nTransformDims_m; }
00161 
00163     unsigned activeDimension(unsigned d) const;
00164 
00166     InternalFFT_t& getEngine(void) { return FFTEngine_m; }
00167 
00169     Precision_t& getNormFact(void) { return normFact_m; }
00170 
00172     const Domain_t& getDomain(void) const { return Domain_m; }
00173 
00175     bool checkDomain(const Domain_t& dom1, const Domain_t& dom2) const;
00176 
00178     bool compressTemps(void) const { return compressTempFields_m; }
00179 
00180 private: 
00181 
00183     map<const char*,int> directions_m;
00184 
00185     FFT_e transformType_m;     
00186     bool transformDims_m[Dim]; 
00187     unsigned nTransformDims_m; 
00188     unsigned* activeDims_m;    
00189 
00191     InternalFFT_t FFTEngine_m;
00192 
00194     Precision_t normFact_m;
00195 
00197     Domain_t Domain_m;
00198 
00200     bool compressTempFields_m;
00201 };
00202 
00203 
00204 // Inline function definitions
00205 
00207 template <unsigned Dim, class T>
00208 inline ostream&
00209 operator<<(ostream& out, const FFTBase<Dim,T>& fft)
00210 {
00211     fft.write(out);
00212     return out;
00213 }
00214 
00219 template <unsigned Dim, class T>
00220 inline void
00221 FFTBase<Dim,T>::setDirectionName(int direction,
00222                                  const char* directionName) {
00223     PAssert(direction==+1 || direction==-1);
00224     directions_m[directionName] = direction;
00225     return;
00226 }
00227 
00235 template <unsigned Dim, class T>
00236 inline int
00237 FFTBase<Dim,T>::getDirection(const char* directionName) const {
00238     return (*(directions_m.find(directionName))).second;
00239 }
00240 
00248 template <unsigned Dim, class T>
00249 inline bool
00250 FFTBase<Dim,T>::transformDim(unsigned d) const {
00251     PAssert(d<Dim);
00252     return transformDims_m[d];
00253 }
00254 
00262 template <unsigned Dim, class T>
00263 inline unsigned
00264 FFTBase<Dim,T>::activeDimension(unsigned d) const {
00265     PAssert(d<nTransformDims_m);
00266     return activeDims_m[d];
00267 }
00268 
00279 template <unsigned Dim, class T>
00280 inline bool
00281 FFTBase<Dim,T>::checkDomain(const FFTBase<Dim,T>::Domain_t& dom1,
00282                             const FFTBase<Dim,T>::Domain_t& dom2) const {
00283     // check whether domains are equivalent
00284     // we require that some permutation of the axes gives a matching domain.
00285     static bool matched[Dim];
00286     bool found;
00287     unsigned d, d1;
00288     // initialize matched array to false
00289     for (d=0; d<Dim; ++d) matched[d] = false;
00290     d=0;
00291     while (d<Dim) {
00292         d1=0;
00293         found = false;
00294         while (!found && d1<Dim) {
00295             // if we have not yet found a match for this dimension,
00296             // compare length and base of Index objects
00297             if (!matched[d1]) {
00298                 found = ( dom1[d].length()==dom2[d1].length() &&
00299                           dom1[d].sameBase(dom2[d1]) );
00300                 // if equivalent, mark this dimension as matched
00301                 if (found) matched[d1] = true;
00302             }
00303             ++d1;
00304         }
00305         if (!found) return false;
00306         ++d;
00307     }
00308     return true;
00309 }
00310 
00311 #include "FFT/FFTBase.cpp"
00312 
00313 #endif // IPPL_FFT_FFTBASE_H
00314 
00315 /***************************************************************************
00316  * $RCSfile: FFTBase.h,v $   $Author: adelmann $
00317  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:25 $
00318  * IPPL_VERSION_ID: $Id: FFTBase.h,v 1.1.1.1 2003/01/23 07:40:25 adelmann Exp $ 
00319  ***************************************************************************/
00320 

Generated on Mon Jan 16 13:23:42 2006 for IPPL by  doxygen 1.4.6