24 const std::string FFT_3d_local::class_name =
"FFT_3d_local";
26 #ifdef USE_FACTORY_AUTOREGISTER
28 bool init = FFT_3d_local::register_factory();
33 FFT_3d_local::FFT_3d_local()
50 FFT_3d_local::~FFT_3d_local()
57 void FFT_3d_local::set_parameters(
const Parameters& params)
60 this->FFT::set_parameters(params);
62 std::string direction;
64 if (params.
fetch_string(
"FFT_direction", direction) == 0) {
65 set_parameters(direction);
71 void FFT_3d_local::set_parameters(
const std::string& direction)
73 if (direction ==
"Forward") {
74 m_direction = FORWARD;
75 }
else if (direction ==
"Backward") {
76 m_direction = BACKWARD;
80 vout.
crucial(m_vl,
"Error at %s: unsupported FFT direction \"%s\"\n", class_name.c_str(), direction.c_str());
87 bool FFT_3d_local::check_ok()
92 vout.
crucial(m_vl,
"%s: incompatible with xyz parallelization.\n", class_name.c_str());
101 void FFT_3d_local::initialize()
104 int thread_ok = fftw_init_threads();
114 void FFT_3d_local::initialize_plan(
const Field& src)
117 vout.
detailed(m_vl,
"%s: plan recycled.\n", class_name.c_str());
120 vout.
detailed(m_vl,
"%s: create plan.\n", class_name.c_str());
135 for (
int i = 0; i < m_ndim; ++i) {
140 m_nv = src.
nin() / 2;
142 m_buf_in = fftw_alloc_complex(m_nv * m_vol);
143 m_buf_out = fftw_alloc_complex(m_nv * m_vol);
145 if ((!m_buf_in) || (!m_buf_out)) {
146 vout.
crucial(m_vl,
"%s: memory allocation failed.\n", class_name.c_str());
150 m_plan_fw = fftw_plan_many_dft(m_ndim, m_nsize, m_nv,
151 m_buf_in, m_nsize, m_nv, 1,
152 m_buf_out, m_nsize, m_nv, 1,
153 FFTW_FORWARD, FFTW_ESTIMATE);
155 m_plan_bw = fftw_plan_many_dft(m_ndim, m_nsize, m_nv,
156 m_buf_in, m_nsize, m_nv, 1,
157 m_buf_out, m_nsize, m_nv, 1,
158 FFTW_BACKWARD, FFTW_ESTIMATE);
160 if ((!m_plan_fw) || (!m_plan_bw)) {
161 vout.
crucial(m_vl,
"%s: create plan failed.\n", class_name.c_str());
168 void FFT_3d_local::clear_plan()
170 if (m_buf_in) fftw_free(m_buf_in);
171 if (m_buf_out) fftw_free(m_buf_out);
173 if (m_plan_fw) fftw_destroy_plan(m_plan_fw);
174 if (m_plan_bw) fftw_destroy_plan(m_plan_bw);
179 void FFT_3d_local::finalize()
188 if (not ((dir == FORWARD) || (dir == BACKWARD))) {
189 vout.
crucial(m_vl,
"%s: unsupported direction. %d\n", class_name.c_str(), dir);
193 initialize_plan(src);
200 size_t count = m_nv * m_vol;
202 for (
int iex = 0; iex < nex; ++iex) {
203 for (
int it = 0; it < nt; ++it) {
204 memcpy(m_buf_in, src.
ptr(0, index.
site(0, 0, 0, it), iex),
sizeof(
double) * count * 2);
206 if (dir == FORWARD) {
207 fftw_execute(m_plan_fw);
208 }
else if (dir == BACKWARD) {
209 fftw_execute(m_plan_bw);
211 vout.
crucial(m_vl,
"%s: unsupported direction. %d\n", class_name.c_str(), dir);
215 memcpy(dst.
ptr(0, index.
site(0, 0, 0, it), iex), m_buf_out,
sizeof(
double) * count * 2);
219 if (dir == BACKWARD) {
220 scal(dst, 1.0 / m_vol);
226 void FFT_3d_local::fft(
Field& dst,
const Field& src)
228 return fft(dst, src, m_direction);
233 void FFT_3d_local::fft(
Field& field)
236 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,...)