Professional Documents
Culture Documents
Lecture 2
1
(x) =
2
g(k)eikx dk ,
(k)eikx dk .
g(k) =
(k) ikx
e dk .
k2
(k)
.
k2
We need to impose appropriate boundary conditions, and also specify how to treat the singularity at k = 0 in the integral.
Boundary conditions and types of transforms
The boundary conditions determine the appropriate type of Fourier transform to solve the problem. Some problems, like
conduction of heat through a rod which Fourier studied, require a sine transform. Others require a cosine or exponential
transform.
PHY 410-505 Computational Physics I
Chapter 6
Lecture 2
Consider a domain 0 x L in one dimension. Choose a lattice of N equally spaced points xn = nL/N, n =
0, . . . , N 1.
The complex Fourier transform coefficients of f (x) are
N 1
1 X kn
gk =
W fn ,
N n=0
W = e2i/N .
N 1
1 X nk
W
gk ,
fn =
N k=0
will be periodic in xn with period L. This complex Fourier transform is therefore appropriate for problems which satisfy
periodic boundary conditions.
If the problem involves Dirichlet boundary conditions, for example, f (0) = f (L) = 0, then it would be appropriate to use
a sine Fourier transform
r N 1
2 X
nk
fn =
sin
gk .
N
N
k=1
If the problem involves Neumann boundary conditions it is appropriate to use is the cosine Fourier transform. One discrete
version on N + 1 points given in Numerical Recipes is
1
[g0 + (1)n gN ] +
fn =
2N
N 1
2 X
nk
cos
gk .
N
N
k=1
Note that the cosine and sine transforms are not just the real and imaginary parts of the complex exponential transform.
This is because the sine, cosine, and exponential functions separately form complete sets, albeit with different boundary
conditions. The basic phase factor for the sine and cosine transforms is /N compared with 2/N for the exponential:
PHY 410-505 Computational Physics I
Chapter 6
Lecture 2
the sine and cosine transforms require twice as many lattice points because they are real, compared with the exponential
transform which is complex.
Fast Sine and Cosine transforms can be defined similarly to the FFT of Chapter 5. Details and programs are given in
Section 12.3 of Numerical Recipes.
Poissons equation in two dimensions
Lets consider the discrete form of Poissons equation
2
2
1
[j+1,k + j1,k + j,k+1 + j,k1 4j,k ] = j,k
+
(x,
y)
'
x2
y 2
h2
on an N N grid of points in the region 0 x, y 1 with a given charge density, say a single point charge located at
the center of the square.
For simplicity, we will impose periodic boundary conditions so that the exponential FFT can be used to obtain the solution.
The discrete Fourier transform is a linear operation, so we can apply it separately in the x and y directions, and it does
not matter in which order the transforms are done.
The two-dimensional Fourier coefficients are given by
N 1 N 1
1 X X mj+nk
m,n =
W
j,k ,
N j=0
k=0
m,n
N 1 N 1
1 X X mj+nk
W
j,k .
=
N j=0
k=0
N 1 N 1
1 X X jmkn
=
W
m,n ,
N m=0 n=0
Chapter 6
Lecture 2
N 1 N 1
1 X X jmkn
=
W
m,n .
N m=0 n=0
Plugging these expressions into the discretized equation and equating coefficients of W mjnk gives
1 m
m
n
n
W
+
W
+
W
+
W
4
m,n =
m,n ,
2
h
which is easily solved for
m,n =
h2 m,n
.
4 W m W m W n W n
<cmath>
<complex>
<cstdlib>
<ctime>
<iostream>
<fstream>
1
2
3
4
5
6
#include "Vector.hpp"
int main() {
10
12
13
14
15
Friday, November 5, 2004
Chapter 6
Lecture 2
std::cin >> N;
int n = 1;
while (n < N)
n *= 2;
if (n != N)
std::cout << " must be a power of 2, using " << (N=n) << std::endl;
16
17
18
19
20
21
23
std::clock_t t0 = std::clock();
25
double q = 10;
// point charge
std::complex<double> rho[N][N];
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
if (j == N/2 && k == N/2)
// at center of lattice
rho[j][k] = q / (h * h);
else
rho[j][k] = 0.0;
}
}
27
28
29
30
31
32
33
34
35
36
cpl::ComplexVector f(N);
cpl::FFT fft;
38
39
41
42
43
44
5
Chapter 6
Lecture 2
}
// FFT columns of rho
for (int k = 0; k < N; k++) {
for (int j = 0; j < N; j++)
f[j] = rho[j][k];
fft.transform(f);
for (int j = 0; j < N; j++)
rho[j][k] = f[j];
}
45
46
47
48
49
50
51
52
53
54
55
56
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Chapter 6
Lecture 2
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
std::clock_t t1 = std::clock();
std::cout << " CPU time = " << double(t1 - t0) / CLOCKS_PER_SEC
<< " sec" << std::endl;
91
92
93
95
96
97
98
99
100
101
102
Chapter 6
Lecture 2
}
dataFile << \n;
103
104
105
106
107
}
dataFile.close();
}
Running the program
> a.out
FFT solution of Poissons equation
---------------------------------Enter number points in x or y: 64
CPU time = 0.06 sec
Potential in file PoissonFFT.data
gives the potential in the figure on the next page, which was obtained using the following Gnuplot commands:
gnuplot>
gnuplot>
gnuplot>
gnuplot>
gnuplot>
Chapter 6
Lecture 2
17
16
15
14
13
12
11
10
9
1
0.8
0
0.6
0.2
0.4
0.4
0.6
0.2
0.8
1 0