PSCF v1.4.0
cpu/FFT.h
1#ifndef PRDC_CPU_FFT_H
2#define PRDC_CPU_FFT_H
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <prdc/cpu/RFieldDft.h> // member
12#include <pscf/math/IntVec.h> // member
13
14#include <fftw3.h>
15
16namespace Pscf {
17namespace Prdc {
18namespace Cpu {
19
20 // Forward declarations
21 template <int D> class RField;
22 template <int D> class CField;
23
24 using namespace Util;
25 using namespace Pscf;
26
37 template <int D>
38 class FFT
39 {
40
41 public:
42
46 FFT();
47
51 virtual ~FFT();
52
58 void setup(IntVec<D> const & meshDimensions);
59
60 // Real Data (Real <-> Complex Transforms)
61
76 void forwardTransform(RField<D> const & in, RFieldDft<D>& out) const;
77
95 void inverseTransformUnsafe(RFieldDft<D>& in, RField<D>& out) const;
96
109 void inverseTransformSafe(RFieldDft<D> const & in, RField<D>& out)
110 const;
111
112 // Complex Data (Complex <-> Complex Transforms)
113
132 void forwardTransform(CField<D> const & in, CField<D>& out) const;
133
147 void inverseTransform(CField<D> const & in, CField<D>& out) const;
148
149 // Accessors
150
154 IntVec<D> const & meshDimensions() const;
155
159 bool isSetup() const;
160
161 // Static function
162
174 static
175 void computeKMesh(IntVec<D> const & rMeshDimensions,
176 IntVec<D> & kMeshDimensions,
177 int & kSize );
178
196 static
197 bool hasImplicitInverse(IntVec<D> const & wavevector,
198 IntVec<D> const & meshDimensions);
199
200 private:
201
203 mutable RFieldDft<D> kFieldCopy_;
204
206 IntVec<D> meshDimensions_;
207
209 int rSize_;
210
212 int kSize_;
213
215 fftw_plan rcfPlan_;
216
218 fftw_plan criPlan_;
219
221 fftw_plan ccfPlan_;
222
224 fftw_plan cciPlan_;
225
227 bool isSetup_;
228
232 void makePlans(RField<D>& rField, RFieldDft<D>& kField,
233 CField<D>& cFieldIn, CField<D>& cFieldOut);
234
235 };
236
237 // Declarations of explicit specializations
238
239 template <>
240 void FFT<1>::makePlans(RField<1>& rField, RFieldDft<1>& kField,
241 CField<1>& cFieldIn, CField<1>& cFieldOut);
242
243 template <>
244 void FFT<2>::makePlans(RField<2>& rField, RFieldDft<2>& kField,
245 CField<2>& cFieldIn, CField<2>& cFieldOut);
246
247 template <>
248 void FFT<3>::makePlans(RField<3>& rField, RFieldDft<3>& kField,
249 CField<3>& cFieldIn, CField<3>& cFieldOut);
250
251 // Inline member functions
252
253 /*
254 * Has this object been setup?
255 */
256 template <int D>
257 inline bool FFT<D>::isSetup() const
258 { return isSetup_; }
259
260 /*
261 * Return the dimensions of the grid for which this was allocated.
262 */
263 template <int D>
264 inline IntVec<D> const & FFT<D>::meshDimensions() const
265 { return meshDimensions_; }
266
267 /*
268 * Does this wavevector have an implicit inverse?
269 */
270 template <int D>
271 inline
272 bool FFT<D>::hasImplicitInverse(IntVec<D> const & wavevector,
274 {
275 int i = wavevector[D-1];
276 int d = meshDimensions[D-1];
277 UTIL_CHECK(i >= 0 && i < d);
278 if ((i != 0) && (d - i > d/2)) {
279 return true;
280 } else {
281 return false;
282 }
283 }
284
285 // Explicit instantiation declarations
286 extern template class FFT<1>;
287 extern template class FFT<2>;
288 extern template class FFT<3>;
289
290} // namespace Pscf::Prdc::Cpu
291} // namespace Pscf::Prdc
292} // namespace Pscf
293#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition IntVec.h:27
Field of complex double precision values on an FFT mesh.
Definition cpu/CField.h:29
Fourier transform wrapper.
Definition cpu/FFT.h:39
bool isSetup() const
Has this FFT object been setup?
Definition cpu/FFT.h:257
FFT()
Default constructor.
Definition cpu/FFT.tpp:59
static bool hasImplicitInverse(IntVec< D > const &wavevector, IntVec< D > const &meshDimensions)
Does this wavevector have implicit inverse in DFT or real data?
Definition cpu/FFT.h:272
IntVec< D > const & meshDimensions() const
Return the dimensions of the grid for which this was setup.
Definition cpu/FFT.h:264
static void computeKMesh(IntVec< D > const &rMeshDimensions, IntVec< D > &kMeshDimensions, int &kSize)
Compute dimensions and size of k-space mesh for DFT of real data.
Definition cpu/FFT.tpp:264
void forwardTransform(RField< D > const &in, RFieldDft< D > &out) const
Compute forward (real-to-complex) discrete Fourier transform (DFT).
Definition cpu/FFT.tpp:153
void setup(IntVec< D > const &meshDimensions)
Setup grid dimensions, FFT plans and work space.
Definition cpu/FFT.tpp:94
void inverseTransformSafe(RFieldDft< D > const &in, RField< D > &out) const
Compute inverse (complex-to-real) DFT without overwriting input.
Definition cpu/FFT.tpp:199
void inverseTransform(CField< D > const &in, CField< D > &out) const
Compute complex-to-complex inverse Fourier transform.
Definition cpu/FFT.tpp:243
virtual ~FFT()
Destructor.
Definition cpu/FFT.tpp:74
void inverseTransformUnsafe(RFieldDft< D > &in, RField< D > &out) const
Compute inverse (complex-to-real) DFT, overwriting the input.
Definition cpu/FFT.tpp:181
Fourier transform of a real field on an FFT mesh.
Field of real double precision values on an FFT mesh.
Definition cpu/RField.h:27
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
Fields and FFTs for periodic boundary conditions (CPU)
Definition complex.cpp:12
Periodic fields and crystallography.
Definition complex.cpp:11
PSCF package top-level namespace.