1 #ifndef COSMO_UTILS_FOURIER_H 2 #define COSMO_UTILS_FOURIER_H 5 #define FFT_INDEX(i,j,k) ((NZ/2+1)*NY*((i+NX)%NX) + (NZ/2+1)*((j+NY)%NY) + ((k+NZ)%NZ)) 7 #define FFT_NP_INDEX(i,j,k) ((NZ/2+1)*NY*(i) + (NZ/2+1)*(j) + (k)) 14 #include "../cosmo_macros.h" 15 #include "../cosmo_types.h" 16 #include "../cosmo_globals.h" 25 typedef long double fft_rt;
26 typedef fftwl_complex fft_ct;
28 typedef double fft_rt;
29 typedef fftw_complex fft_ct;
52 void Initialize_1D(IT n);
55 void execute_f_r2c() { fftwl_execute(p_r2c); }
56 void execute_f_c2r() { fftwl_execute(p_c2r); }
58 void execute_f_r2c() { fftw_execute(p_r2c); }
59 void execute_f_c2r() { fftw_execute(p_c2r); }
62 template<
typename RT,
typename IOT>
65 template<
typename IT,
typename RT>
66 void inverseLaplacian(RT *field);
84 f_field = (fft_ct *) fftwl_malloc(nx*ny*(nz/2+1)
85 *((
long long)
sizeof(fft_ct)));
86 double_field =
new fft_rt[nx*ny*nz];
88 p_r2c = fftwl_plan_dft_r2c_3d(nx, ny, nz,
89 double_field, f_field,
91 p_c2r = fftwl_plan_dft_c2r_3d(nx, ny, nz,
92 f_field, double_field,
96 f_field = (fft_ct *) fftw_malloc(nx*ny*(nz/2+1)
97 *((
long long)
sizeof(fft_ct)));
98 double_field =
new fft_rt[nx*ny*nz];
100 p_r2c = fftw_plan_dft_r2c_3d(nx, ny, nz,
101 double_field, f_field,
103 p_c2r = fftw_plan_dft_c2r_3d(nx, ny, nz,
104 f_field, double_field,
109 template<
typename IT>
110 void Fourier::Initialize_1D(IT n)
115 f_field = (fft_ct *) fftwl_malloc((n/2 +1)*((
long long)
sizeof(fft_ct)));
116 double_field =
new fft_rt[n];
118 p_r2c = fftwl_plan_dft_r2c_1d(n,
119 double_field, f_field,FFTW_ESTIMATE
121 p_c2r = fftwl_plan_dft_c2r_1d(n,
122 f_field, double_field,FFTW_ESTIMATE
126 f_field = (fft_ct *) fftw_malloc((n/2 +1)*((
long long)
sizeof(fft_ct)));
127 double_field =
new fft_rt[n];
129 p_r2c = fftw_plan_dft_r2c_1d(n,
130 double_field, f_field,FFTW_ESTIMATE
132 p_c2r = fftw_plan_dft_c2r_1d(n,
133 f_field, double_field,FFTW_ESTIMATE
146 template<
typename RT,
typename IOT>
150 for(
long int i=0; i<POINTS; ++i)
151 double_field[i] = (fft_rt) in[i];
154 fftwl_execute_dft_r2c(p_r2c, double_field, f_field);
156 fftw_execute_dft_r2c(p_r2c, double_field, f_field);
160 const int numbins = (int) (sqrt(NX*NX + NY*NY + NZ*NZ)/2.0) + 1;
161 RT * array_out =
new RT[numbins];
162 int * numpoints =
new int[numbins];
163 RT * p =
new RT[numbins];
164 RT * f2 =
new RT[numbins];
169 int i, j, k, px, py, pz;
172 for(i=0; i<numbins; i++) {
180 px = (i<=NX/2 ? i : i-NX);
183 py = (j<=NY/2 ? j : j-NY);
184 for(k=1; k<NZ/2; k++)
187 pmagnitude = sqrt((RT) (pw2(px) + pw2(py) + pw2(pz)));
188 fp2 = pw2(C_RE((f_field)[FFT_NP_INDEX(i,j,k)])) + pw2(C_IM((f_field)[FFT_NP_INDEX(i,j,k)]));
189 numpoints[(int)pmagnitude] += 2;
190 f2[(int)pmagnitude] += 2.*fp2;
195 pmagnitude = sqrt((RT) (pw2(px) + pw2(py) + pw2( pz)));
196 fp2 = pw2(C_RE((f_field)[FFT_NP_INDEX(i,j,k)])) + pw2(C_IM((f_field)[FFT_NP_INDEX(i,j,k)]));
197 numpoints[(int)pmagnitude] += 1;
198 f2[(int)pmagnitude] += fp2;
202 pmagnitude = sqrt((RT) (pw2(px) + pw2(py) + pw2(pz)));
203 fp2 = pw2(C_RE((f_field)[FFT_NP_INDEX(i,j,k)])) + pw2(C_IM((f_field)[FFT_NP_INDEX(i,j,k)]));
204 numpoints[(int)pmagnitude] += 1;
205 f2[(int)pmagnitude] += fp2;
209 for(i=0; i<numbins; i++)
214 array_out[i] = f2[i]/((fft_rt) numpoints[i]);
223 std::string filename = iodata->dir() +
"spec.dat.gz";
226 gzFile datafile = gzopen(filename.c_str(),
"ab");
227 if(datafile == Z_NULL) {
228 printf(
"Error opening file: %s\n", filename.c_str());
232 for(i=0; i<numbins; i++)
235 sprintf(data,
"%g\t", (fft_rt) array_out[i]);
236 gzwrite(datafile, data, std::char_traits<char>::length(data));
238 gzwrite(datafile,
"\n", std::char_traits<char>::length(
"\n"));
251 template<
typename IT,
typename RT>
252 void Fourier::inverseLaplacian(RT *field)
257 for(
long int i=0; i<POINTS; ++i)
258 double_field[i] = (fft_rt) field[i];
261 fftwl_execute_dft_r2c(p_r2c, double_field, f_field);
263 fftw_execute_dft_r2c(p_r2c, double_field, f_field);
268 px = (RT) (i<=NX/2 ? i : i-NX);
271 py = (RT) (j<=NY/2 ? j : j-NY);
272 for(k=0; k<NZ/2+1; k++)
276 IT fft_index = FFT_NP_INDEX(i,j,k);
278 pmag = sqrt( pw2(px) + pw2(py) + pw2(pz) )*2.0*PI/H_LEN_FRAC;
280 f_field[fft_index][0] /= -pmag*pmag*POINTS;
281 f_field[fft_index][1] /= -pmag*pmag*POINTS;
290 fftwl_execute_dft_c2r(p_c2r, f_field, double_field);
292 fftw_execute_dft_c2r(p_c2r, f_field, double_field);
296 for(
long int i=0; i<POINTS; ++i)
297 field[i] = (RT) double_field[i];
void powerDump(RT *in, IOT *iodata)
Compute a power spectrum and write to file.
Definition: Fourier.h:147
void Initialize(IT nx, IT ny, IT nz)
Initialize a fourier class instance.
Definition: Fourier.h:79