12#include <pspg/math/GpuResources.h>
65 setup(rField, kField);
83 for (
int i = 0; i < D; ++i) {
85 meshDimensions_[i] = rDimensions[i];
86 rSize_ *= rDimensions[i];
88 kSize_ *= rDimensions[i];
90 kSize_ *= (rDimensions[i]/2 + 1);
99 makePlans(rField, kField);
102 if (!rFieldCopy_.isAllocated()) {
103 rFieldCopy_.allocate(rDimensions);
105 if (rFieldCopy_.capacity() != rSize_) {
106 rFieldCopy_.deallocate();
107 rFieldCopy_.allocate(rDimensions);
113 if (!kFieldCopy_.isAllocated()) {
114 kFieldCopy_.allocate(kDimensions);
116 if (kFieldCopy_.capacity() != rSize_) {
117 kFieldCopy_.deallocate();
118 kFieldCopy_.allocate(kDimensions);
134 int nBlocks, nThreads;
143 cudaReal scale = 1.0/cudaReal(rSize_);
144 scaleRealData<<<nBlocks, nThreads>>>(rField.
cDField(), scale, rSize_);
147 #ifdef SINGLE_PRECISION
148 if(cufftExecR2C(fPlan_, rField.
cDField(), kField.
cDField()) != CUFFT_SUCCESS) {
149 std::cout <<
"CUFFT error: forward" << std::endl;
153 if(cufftExecD2Z(fPlan_, rField.
cDField(), kField.
cDField()) != CUFFT_SUCCESS) {
154 std::cout <<
"CUFFT error: forward" << std::endl;
170 rFieldCopy_ = rField;
171 forwardTransform(rFieldCopy_, kField);
187 #ifdef SINGLE_PRECISION
188 if(cufftExecC2R(iPlan_, kField.
cDField(), rField.
cDField()) != CUFFT_SUCCESS) {
189 std::cout <<
"CUFFT error: inverse" << std::endl;
193 if(cufftExecZ2D(iPlan_, kField.
cDField(), rField.
cDField()) != CUFFT_SUCCESS) {
194 std::cout <<
"CUFFT error: inverse" << std::endl;
210 kFieldCopy_ = kField;
211 inverseTransform(kFieldCopy_, rField);
218static __global__
void scaleRealData(cudaReal* data, cudaReal scale,
int size) {
221 int nThreads = blockDim.x * gridDim.x;
222 int startId = blockIdx.x * blockDim.x + threadIdx.x;
223 for(
int i = startId; i < size; i += nThreads ) {
An IntVec<D, T> is a D-component vector of elements of integer type T.
Data * cDField()
Return pointer to underlying C array.
int capacity() const
Return allocated size.
void forwardTransformSafe(RDField< D > const &rField, RDFieldDft< D > &kField) const
Compute forward Fourier transform without destroying input.
void forwardTransform(RDField< D > &rField, RDFieldDft< D > &kField) const
Compute forward (real-to-complex) discrete Fourier transform.
void setup(IntVec< D > const &meshDimensions)
Setup grid dimensions, plans and work space.
void inverseTransform(RDFieldDft< D > &kField, RDField< D > &rField) const
Compute inverse (complex-to-real) discrete Fourier transform.
virtual ~FFT()
Destructor.
FFT()
Default constructor.
void inverseTransformSafe(RDFieldDft< D > const &kField, RDField< D > &rField) const
Compute inverse (complex to real) DFT without destroying input.
Discrete Fourier Transform (DFT) of a real field on an FFT mesh.
void allocate(const IntVec< D > &meshDimensions)
Allocate the underlying C array for an FFT grid.
const IntVec< D > & meshDimensions() const
Return vector of mesh dimensions by constant reference.
Field of real single precision values on an FFT mesh on a device.
void allocate(const IntVec< D > &meshDimensions)
Allocate the underlying C array for an FFT grid.
const IntVec< D > & meshDimensions() const
Return mesh dimensions by constant reference.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
void setThreadsLogical(int nThreadsLogical)
Set the total number of threads required for execution.
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.