23 const std::string FFT_3d_local::class_name =
"FFT_3d_local";
25 #ifdef USE_FACTORY_AUTOREGISTER
27 bool init = FFT_3d_local::register_factory();
32 FFT_3d_local::FFT_3d_local()
49 FFT_3d_local::~FFT_3d_local()
56 void FFT_3d_local::set_parameters(
const Parameters& params)
59 this->FFT::set_parameters(params);
61 std::string direction;
63 if (params.
fetch_string(
"FFT_direction", direction) == 0) {
64 set_parameters(direction);
70 void FFT_3d_local::set_parameters(
const std::string& direction)
72 if (direction ==
"Forward") {
73 m_direction = FORWARD;
74 }
else if (direction ==
"Backward") {
75 m_direction = BACKWARD;
79 vout.
crucial(m_vl,
"Error at %s: unsupported FFT direction \"%s\"\n", class_name.c_str(), direction.c_str());
86 bool FFT_3d_local::check_ok()
91 vout.
crucial(m_vl,
"%s: incompatible with xyz parallelization.\n", class_name.c_str());
100 void FFT_3d_local::initialize()
103 int thread_ok = fftw_init_threads();
113 void FFT_3d_local::initialize_plan(
const Field& src)
116 vout.
detailed(m_vl,
"%s: plan recycled.\n", class_name.c_str());
119 vout.
detailed(m_vl,
"%s: create plan.\n", class_name.c_str());
134 for (
int i = 0; i < m_ndim; ++i) {
139 m_nv = src.
nin() / 2;
141 m_buf_in = fftw_alloc_complex(m_nv * m_vol);
142 m_buf_out = fftw_alloc_complex(m_nv * m_vol);
144 if ((!m_buf_in) || (!m_buf_out)) {
145 vout.
crucial(m_vl,
"%s: memory allocation failed.\n", class_name.c_str());
149 m_plan_fw = fftw_plan_many_dft(m_ndim, m_nsize, m_nv,
150 m_buf_in, m_nsize, m_nv, 1,
151 m_buf_out, m_nsize, m_nv, 1,
152 FFTW_FORWARD, FFTW_ESTIMATE);
154 m_plan_bw = fftw_plan_many_dft(m_ndim, m_nsize, m_nv,
155 m_buf_in, m_nsize, m_nv, 1,
156 m_buf_out, m_nsize, m_nv, 1,
157 FFTW_BACKWARD, FFTW_ESTIMATE);
159 if ((!m_plan_fw) || (!m_plan_bw)) {
160 vout.
crucial(m_vl,
"%s: create plan failed.\n", class_name.c_str());
167 void FFT_3d_local::clear_plan()
169 if (m_buf_in) fftw_free(m_buf_in);
170 if (m_buf_out) fftw_free(m_buf_out);
172 if (m_plan_fw) fftw_destroy_plan(m_plan_fw);
173 if (m_plan_bw) fftw_destroy_plan(m_plan_bw);
178 void FFT_3d_local::finalize()
187 if (not ((dir == FORWARD) || (dir == BACKWARD))) {
188 vout.
crucial(m_vl,
"%s: unsupported direction. %d\n", class_name.c_str(), dir);
192 initialize_plan(src);
199 size_t count = m_nv * m_vol;
201 for (
int iex = 0; iex < nex; ++iex) {
202 for (
int it = 0; it < nt; ++it) {
203 memcpy(m_buf_in, src.
ptr(0, index.
site(0, 0, 0, it), iex),
sizeof(
double) * count * 2);
205 if (dir == FORWARD) {
206 fftw_execute(m_plan_fw);
207 }
else if (dir == BACKWARD) {
208 fftw_execute(m_plan_bw);
210 vout.
crucial(m_vl,
"%s: unsupported direction. %d\n", class_name.c_str(), dir);
214 memcpy(dst.
ptr(0, index.
site(0, 0, 0, it), iex), m_buf_out,
sizeof(
double) * count * 2);
218 if (dir == BACKWARD) {
219 scal(dst, 1.0 / m_vol);
225 void FFT_3d_local::fft(
Field& dst,
const Field& src)
227 return fft(dst, src, m_direction);
232 void FFT_3d_local::fft(
Field& field)
235 vout.
crucial(m_vl,
"Error at %s: fft on-the-fly unsupported.\n", class_name.c_str());
void scal(Field &x, const double a)
scal(x, a): x = a * x
void detailed(const char *format,...)
static int get_num_threads()
returns available number of threads.
static int npe(const int dir)
logical grid extent
const double * ptr(const int jin, const int site, const int jex) const
int site(const int &x, const int &y, const int &z, const int &t) const
Container of Field-type object.
int fetch_string(const string &key, string &value) const
void crucial(const char *format,...)