-
Notifications
You must be signed in to change notification settings - Fork 1
/
fft.h
285 lines (244 loc) · 10.1 KB
/
fft.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
// This file is part of the ESPResSo distribution (http://www.espresso.mpg.de).
// It is therefore subject to the ESPResSo license agreement which you accepted upon receiving the distribution
// and by which you are legally bound while utilizing this file in any form or way.
// There is NO WARRANTY, not even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// You should have received a copy of that license along with this program;
// if not, refer to http://www.espresso.mpg.de/license.html where its current version can be found, or
// write to Max-Planck-Institute for Polymer Research, Theory Group, PO Box 3148, 55021 Mainz, Germany.
// Copyright (c) 2002-2009; all rights reserved unless otherwise stated.
#ifndef FFT_H
#define FFT_H
/** \file fft.h
*
* Routines, row decomposition, data structures and communication for the 3D-FFT.
*
* The 3D-FFT is split into 3 ond dimensional FFTs. The data is
* distributed in such a way, that for the actual direction of the
* FFT each node has a certain number of rows for which it performs a
* 1D-FFT. After performing the FFT on theat direction the data is
* redistributed.
*
* For simplicity at the moment I have implemented a full complex to
* complex FFT (even though a real to complex FFT would be
* sufficient)
*
* \todo Combine the forward and backward structures.
* \todo The packing routines could be moved to utils.h when they are needed elsewhere.
*
* For more information about FFT usage, see \ref fft.c "fft.c".
*/
#include "utils.h"
#ifdef ELP3M
/************************************************
* data types
************************************************/
/** Structure for performing a 1D FFT.
*
* This includes the information about the redistribution of the 3D
* FFT *grid before the actual FFT.
*/
typedef struct {
/** plan direction: 0 = Forward FFT, 1 = Backward FFT. */
int dir;
/** row direction of that FFT. */
int row_dir;
/** permutations from normal coordinate system. */
int n_permute;
/** number of 1D FFTs. */
int n_ffts;
/** plan for fft. */
void *fft_plan;
/** function for fft. */
void (*fft_function)();
/** size of local mesh before communication. */
int old_mesh[3];
/** size of local mesh after communication, also used for actual FFT. */
int new_mesh[3];
/** lower left point of local FFT mesh in global FFT mesh coordinates. */
int start[3];
/** size of new mesh (number of mesh points). */
int new_size;
/** number of nodes which have to communicate with each other. */
int g_size;
/** group of nodes which have to communicate with each other. */
int *group;
/** packing function for send blocks. */
void (*pack_function)();
/** Send block specification. 6 integers for each node: start[3], size[3]. */
int *send_block;
/** Send block communication sizes. */
int *send_size;
/** Recv block specification. 6 integers for each node: start[3], size[3]. */
int *recv_block;
/** Recv block communication sizes. */
int *recv_size;
/** size of send block elements. */
int element;
} fft_forw_plan;
/** Additional information for backwards FFT.*/
typedef struct {
/** plan direction. (e.g. fftw makro)*/
int dir;
/** plan for fft. */
void *fft_plan;
/** function for fft. */
void (*fft_function)();
/** packing function for send blocks. */
void (*pack_function)();
} fft_back_plan;
/** \name Exported Variables */
/************************************************************/
/*@{*/
/** Information about the three one dimensional FFTs and how the nodes
* have to communicate in between.
*
* NOTE: FFT numbering starts with 1 for technical reasons (because we
* have 4 node grids, the index 0 is used for the real space
* charge assignment grid). */
#ifdef ELECTROSTATICS
extern fft_forw_plan fft_plan[4];
#endif
#ifdef MAGNETOSTATICS
extern fft_forw_plan Dfft_plan[4];
#endif
/*@}*/
/** \name Exported Functions */
/************************************************************/
/*@{*/
/** Initialize some arrays connected to the 3D-FFT. */
void fft_pre_init();
#ifdef ELECTROSTATICS
/** Initialize everything connected to the 3D-FFT.
* \return Maximal size of local fft mesh (needed for allocation of ca_mesh).
* \param data Pointer Pounter to data array.
* \param ca_mesh_dim Pointer to CA mesh dimensions.
* \param ca_mesh_margin Pointer to CA mesh margins.
* \param ks_pnum Pointer to number of permutations in k-space.
*/
int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, int *ks_pnum);
/** perform the forward 3D FFT.
The assigned charges are in \a data. The result is also stored in \a data.
\warning The content of \a data is overwritten.
\param data Mesh.
*/
void fft_perform_forw(double *data);
/** perform the backward 3D FFT.
\warning The content of \a data is overwritten.
\param data Mesh.
*/
void fft_perform_back(double *data);
#endif
#ifdef MAGNETOSTATICS
/** Initialize everything connected to the 3D-FFT related to the dipole-dipole.
* \return Maximal size of local fft mesh (needed for allocation of ca_mesh).
* \param data Pointer Pounter to data array.
* \param ca_mesh_dim Pointer to CA mesh dimensions.
* \param ca_mesh_margin Pointer to CA mesh margins.
* \param ks_pnum Pointer to number of permutations in k-space.
*/
int Dfft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, int *ks_pnum);
/** perform the forward 3D FFT for meshes related to the magnetic dipole-dipole interaction.
The assigned charges are in \a data. The result is also stored in \a data.
\warning The content of \a data is overwritten.
\param data DMesh.
*/
void Dfft_perform_forw(double *data);
/** perform the backward 3D FFT for meshes related to the magnetic dipole-dipole interaction.
\warning The content of \a data is overwritten.
\param data DMesh.
*/
void Dfft_perform_back(double *data);
#endif
/** pack a block (size[3] starting at start[3]) of an input 3d-grid
* with dimension dim[3] into an output 3d-block with dimension size[3].
*
* The block with dimensions (size[0], size[1], size[2]) is stored
* in 'row-major-order' or 'C-order', that means the first index is
* changing slowest when running through the linear array. The
* element (i0 (slow), i1 (mid), i2 (fast)) has the linear index
* li = i2 + size[2] * (i1 + (size[1]*i0))
*
* \param in pointer to input 3d-grid.
* \param out pointer to output 3d-grid (block).
* \param start start index of the block in the in-grid.
* \param size size of the block (=dimension of the out-grid).
* \param dim size of the in-grid.
* \param element size of a grid element (e.g. 1 for Real, 2 for Complex).
*/
void pack_block(double *in, double *out, int start[3], int size[3],
int dim[3], int element);
/** pack a block with dimensions (size[0] * size[1] * aize[2]) starting
* at start[3] of an input 3d-grid with dimension dim[3] into an
* output 3d-grid with dimensions (size[2] * size[0] * size[1]) with
* a simulatanous one-fold permutation of the indices.
*
* The permutation is defined as:
* slow_in -> fast_out, mid_in ->slow_out, fast_in -> mid_out
*
* An element (i0_in , i1_in , i2_in ) is then
* (i0_out = i1_in-start[1], i1_out = i2_in-start[2], i2_out = i0_in-start[0]) and
* for the linear indices we have: <br>
* li_in = i2_in + size[2] * (i1_in + (size[1]*i0_in)) <br>
* li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out))
*
* For index definition see \ref pack_block.
*
* \param in pointer to input 3d-grid.
* \param out pointer to output 3d-grid (block).
* \param start start index of the block in the in-grid.
* \param size size of the block (=dimension of the out-grid).
* \param dim size of the in-grid.
* \param element size of a grid element (e.g. 1 for Real, 2 for Complex).
*/
void pack_block_permute1(double *in, double *out, int start[3], int size[3],
int dim[3], int element);
/** pack a block with dimensions (size[0] * size[1] * aize[2]) starting
* at start[3] of an input 3d-grid with dimension dim[3] into an
* output 3d-grid with dimensions (size[2] * size[0] * size[1]), this
* is a simulatanous two-fold permutation of the indices.
*
* The permutation is defined as:
* slow_in -> mid_out, mid_in ->fast_out, fast_in -> slow_out
*
* An element (i0_in , i1_in , i2_in ) is then
* (i0_out = i2_in-start[2], i1_out = i0_in-start[0], i2_out = i1_in-start[1]) and
* for the linear indices we have: <br>
* li_in = i2_in + size[2] * (i1_in + (size[1]*i0_in)) <br>
* li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out))
*
* For index definition see \ref pack_block.
*
* \param in pointer to input 3d-grid.
* \param out pointer to output 3d-grid (block).
* \param start start index of the block in the in-grid.
* \param size size of the block (=dimension of the out-grid).
* \param dim size of the in-grid.
* \param element size of a grid element (e.g. 1 for Real, 2 for Complex).
*/
void pack_block_permute2(double *in, double *out, int start[3], int size[3],
int dim[3],int element);
/** unpack a 3d-grid input block (size[3]) into an output 3d-grid
* with dimension dim[3] at start position start[3].
*
* see also \ref pack_block.
*
* \param in pointer to input 3d-grid.
* \param out pointer to output 3d-grid (block).
* \param start start index of the block in the in-grid.
* \param size size of the block (=dimension of the out-grid).
* \param dim size of the in-grid.
* \param element size of a grid element (e.g. 1 for Real, 2 for Complex).
*/
void unpack_block(double *in, double *out, int start[3], int size[3],
int dim[3], int element);
/** Debug function to print global fft mesh.
Print a globaly distributed mesh contained in data. Element size is element.
* \param plan fft/communication plan (see \ref fft_forw_plan).
* \param data mesh data.
* \param element element size.
* \param num element index to print.
*/
void print_global_fft_mesh(fft_forw_plan plan, double *data, int element, int num);
/*@}*/
#endif
#endif