Long Term Dynamics of the Di-Block Copolymer Model on ...
Transcript of Long Term Dynamics of the Di-Block Copolymer Model on ...
Long Term Dynamics of the Di-Block Copolymer Model on Higher Dimensional Domains
A thesis submitted in partial fulfillment of the requirements for the degree ofMaster of Science at George Mason University
By
Michael R. AtkinsBachelor of Science
George Mason University, 2010
Director: Thomas Wanner, ProfessorDepartment of Mathematical Sciences
Spring Semester 2011George Mason University
Fairfax, VA
Acknowledgments
I would like to thank the following people who made this possible.
• Thomas Wanner
• Evelyn Sander
• Ian Johnson
• Jeff Snider
• Pearu Peterson
• The developers of matplotlib, Python and numpy
• Dept. of Mathematical Sciences
• Anyone who feels their name should be here instead of this sentence.
iv
Table of Contents
Page
List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii
Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Galerkin’s Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3 Fourier Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1 A Basis of Eigenfunctions . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.2 A Fact About Fourier Coefficients . . . . . . . . . . . . . . . . . . . 11
1.4 Semi Implicit Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2 Numerical Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1 Derivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2 Implementation in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2.1 Fast Fourier Transform . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.2 Zero Padding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Implementation in Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3 Results and Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1 Creating a Double Gyroid . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2 Examining a Phase Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
A Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
B AISE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
B.0.1 util.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
B.0.2 plotters.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
B.0.3 transFunc.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
B.1 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
B.1.1 CMWcheck.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
B.1.2 dg.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
C Solvers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
v
C.1 2D per.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
C.2 3D per.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
vi
List of Tables
Table Page
3.1 The Predicted Lamellae column represents simulations that took place with
µ, σ and λ which should have generated lamellae as predicted by Choksi et al.
whereas the Predicted Circles column represents simulations that took place
with µ, σ and λ which should have generated hexagonally packed circles as
predicted by Choksi et al. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
vii
List of Figures
Figure Page
3.1 A Double Gyroid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 µ, λ and σ as in (3.1), t = 15. The simulation was carried out with a step-size
of h = 10−5 for t ∈ [0, 14] and a step-size of h = 10−6 for t ∈ (14, 15]. N was
set to 64 for the simulation. Due to memory constraints, the nonlinearity
was approximated using 2N Fourier coefficients instead of the 3N required
to compute it exactly. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3 A typical energy decay for the 3D case with µ, λ and σ as in (3.1). . . . . . 30
3.4 Hexagonally packed circles in the 2D case. . . . . . . . . . . . . . . . . . . . 31
3.5 Lamellae in the 2D case. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
viii
Abstract
LONG TERM DYNAMICS OF THE DI-BLOCK COPOLYMER MODEL ON HIGHERDIMENSIONAL DOMAINS
Michael R. Atkins, M.S.
George Mason University, 2011
Thesis Director: Dr. Thomas Wanner
In this thesis, we examine the di-block copolymer model as proposed by Ohta and
Kawasaki. We derive a nonlinear evolution equation from the Ohta-Kawasaki functional.
We then find an approximation to this equation via Galerkin’s method. A semi-implicit
scheme is then applied to the Galerkin system. This solver is then implemented in C with
a python user interface. This implementation is then used to investigate the long term
dynamics of the model in 2D and 3D.
Specifically, we arrive at a solution to the 3D case which partially reproduces the results
of Teramoto and Nishiura which describe the existence of a Double Gyroid equilibrium state.
In the 2D case, we find a long term solution for many different parameter configurations. In
fact, our results in the 2D case call in to question the efficacy of a nonstandard numerical
method introduced by Choksi et al.
ix
Chapter 1: Introduction
In this work, we examine a differential equation which is often used to model diblock
copolymers. Block copolymers are molecules which are made up of two or more blocks
of chemically distinct monomers each of which are either a small molecule or an atom[1].
Since we have restricted ourselves to diblock copolymers, the copolymers we will investigate
only have two blocks, or monomers, per molecule. This class of copolymers exhibits phase
separation when each monomer is viewed as a phase [1]. This phase separation is commonly
modeled via the minimization of a free energy functional introduced by Ohta & Kawasaki
which we will introduce more formally later [11].
Using this model, the phase diagram for this phenomenon has been partially constructed
[2,14]. Moreover, in attempting to describe the phase diagram, some new structures which
have not been observed in experiment were observed in numerical simulations, namely,
the double gyroid [14]. However, in spite of the promise of these results, a nonstandard
numerical technique was used, and as a result, these results have not been independently
reproduced. It is our goal to reproduce these results using a more standard numerical
scheme. In order to achieve this aim, we will introduce a model for this phase separation,
construct a numerical scheme for solving this model, discuss the implementation of this
scheme and provide examples of solutions generated by this scheme.
1.1 Model
Let Ω ⊂ R3 be the unit cube, and u ∈ H1per(Ω, [0,∞)) describe the ratio of monomers at a
given point. The functional proposed by Ohta & Kawasaki which we will use is given by
Eλ,σ[u] =
ˆΩ
[1
2|∇u|2 + λW (u) +
λσ
2|∇v|2
]dx. (1.1)
1
where λ is the reciprocal of the Flory–Huggins parameter [11],
W (u) :=(1− u2)2
4, −1 < µ < 1, σ > 0 and λ > 0, (1.2)
u satisfies the average mass constraint
µ :=
ˆΩu dx (1.3)
and v ∈f ∈ H1
per(Ω) |´
Ω f dx = 0
such that
−∆v = u− µ (1.4)
describes the long range interactions with σ scaling the strength of these interactions [3,11].
It is our aim to find an evolution equation for u(x, t). In order to do so, we apply a
similar approach to that given in [3] and [5]. First, define the Hilbert space
H :=
f ∈ L2(Ω)
∣∣∣ ˆΩf dx = 0
equipped with the inner product
(f, g)H :=
ˆΩ∇u∇v dx (1.5)
where f = −∆u and g = −∆v on Ω.
Second, define gradHEλ,σ[u] ∈ H using the weak formulation of the H−1 norm, i.e., for
all δ > 0 and
B(t) : [0, δ)→ H
2
such that B is differentiable at t = 0, B(0) = u and B satisfies
d
dtEλ,σ[B(t)]
∣∣∣t=0
=
(gradHEλσ[u],
∂B
∂t
∣∣∣t=0
).
Third, assume that u evolves along the path of steepest descent, i.e.,
∂u
∂t= −gradHEλ,σ[u]. (1.6)
Let u be as in (1.1) and −∆w ∈ H. Set −∆v = u− µ− t∆w. We now compute
d
dtEλ,σ[u− t∆w]
∣∣∣t=0
=
[d
dt
ˆΩ
1
2|∇(u− t∆w)|2 dx
+d
dt
ˆΩλW (u− t∆w) dx
+d
dt
ˆΩ
λσ
2|∇v|2 dx
]t=0
. (1.7)
First, we find
d
dt
ˆΩ
1
2|∇(u− t∆w)|2 dx =
d
dt
ˆΩ
1
2∇(u− t∆w) · ∇(u− t∆w) dx
=d
dt
ˆΩ
1
2
d∑k=1
(∂
∂xk(u− t∆w)
)2
dx
=
ˆΩ
d∑k=1
(∂
∂xk(u− t∆w)
)(d
dt
∂
∂xk(u− t∆w)
)dx
=
ˆΩ
d∑k=1
(∂
∂xk(u− t∆w)
)(− ∂
∂xk∆w
)dx.
3
Evaluating at t = 0 yields
d
dt
ˆΩ
1
2|∇(u− t∆w)|2 dx
∣∣∣t=0
=
ˆΩ
d∑k=1
(∂
∂xku
)(− ∂
∂xk∆w
)dx
= −ˆ
Ω∇u · ∇(∆w) dx
= −(ˆ
∂Ω∆w∇u · ν ds−
ˆΩ
∆w∆u dx
)(1.8)
=
ˆΩ
∆w∆u dx (1.9)
where (1.8) comes from Green’s first identity and the equality in (1.9) comes from the
periodic boundary conditions.
Now, we find
d
dt
ˆΩλW (u− t∆w) dx
∣∣∣t=0
= λ
ˆΩ−∆w W ′(u− t∆w) dx
∣∣∣t=0
= −λˆ
ΩW ′(u)∆w dx. (1.10)
4
Finally, we find
d
dt
ˆΩ
λσ
2|∇v|2 dx =
d
dt
λσ
2
ˆΩ∇v · ∇v dx
=λσ
2
ˆΩ
d
dt
d∑k=1
(∂
∂xkv
)2
dx
= λσ
ˆΩ
d∑k=1
(∂
∂xkv
)(∂
∂xk
d
dtv
)dx
= λσ
ˆΩ
d∑k=1
(∂
∂xkv
)(∂
∂xkw
)dx
= λσ
ˆΩ∇v · ∇w dx.
Evaluating at t = 0 yields
d
dt
ˆΩ
λσ
2|∇v|2 dx
∣∣∣t=0
=
ˆΩλσ∇v · ∇w dx. (1.11)
Combining (1.9), (1.10) and (1.11) with (1.7) yields
d
dtEλ,σ[u− t∆w]
∣∣∣t=0
=
ˆΩ
[(λW ′(u)−∆u)(−∆w) + σλ∇u · ∇w dx
]=
ˆΩ
[∇(λW ′(u)−∆u+ λσv) · ∇w dx
](1.12)
=(−∆(λW ′(u)−∆u+ λσv),−∆w
)H
(1.13)
where (1.12) follows from applying integration by parts and the boundary conditions, and
5
(1.13) comes from (1.5). Hence,
gradHEλ,σ[u] = −∆(λW ′(u)−∆u+ λσv)
= −∆(λW ′(u))−∆u+ λσ(u− µ). (1.14)
Combining this fact with our assumption in (1.6) yields
∂u
∂t= −∆2u− λ∆(u− u3)− λσ(u− µ). (1.15)
1.2 Galerkin’s Method
In this section, we introduce Galerkin’s method. We will use this to approximate the
solution of (1.15), by finding an exact solution in a finite dimensional subspace of H1per(Ω).
It will be necessary to approximate the solution, since in general, even for linear PDE, only
statements about existence of solutions can be made. First however, we must define what
it means to solve (1.15).
Definition 1. We say a function u ∈ H1per(Ω) is a solution to (1.15) provided that
(−∆2u− λ∆(u− u3)− λσ(u− µ)− ∂u
∂t, v
)L2(Ω)
= 0
for all v ∈ H1per with u(0) = u0.
With this definition for solutions in mind, we now provide Galerkin’s method. Let wk(x)
be a set of smooth functions which is a complete orthogonal set in H1per(Ω) and a complete
orthonormal set in L2(Ω). For any N , we can construct uN such that
uN (x, t) :=
N∑k=0
ak(t)wk(x) (1.16)
6
for ak(t) ∈ H1([0,∞)) satisfy
ak(0) = (u0, wk)L2(Ω) for all k ≤ N (1.17)
and
(−∆2uN + λ∆W ′(uN )− λσ(uN − µ)− ∂uN
∂t, wk
)L2(Ω)
= 0 for all k ≤ N. (1.18)
The existence and uniqueness of these ak(t) is guaranteed by the following theorem.
Theorem 1. Provided that wk is complete and orthogonal in H1per(Ω) and is complete
and orthonormal in L2(Ω), for any N ∈ N0, there exists a unique uN in the form of (1.16)
which satisfies (1.17) and (1.18).
Proof. Assume uN as in (1.16). For simplicity, assume µ = 0. Since the inner product is
linear in the first argument, for all k ≤ N
(−∆2uN − λ∆(uN − u3
N )− λσ(uN )− ∂uN∂t
, wk
)L2(Ω)
= −(∆2uN , wk
)L2(Ω)
+(λ∆W ′(uN ), wk
)L2(Ω)
− (λσ(uN ), wk)L2(Ω)
−(∂uN∂t
, wk
)L2(Ω)
Note that for some bk(t), W′(uN ) =
∑∞k=0 bk(t)wk(x). Let PM (W ′(uN )) :=
∑Mk=0 bk(t)wk(x).
Assume that for some M ∈ N, W ′(uN ) = PM (W ′(uN )). Also, set c` = (∆2w`, wk)L2(Ω) and
7
d` = (∆w`, wk).
−(∆2uN , wk
)L2(Ω)
= −N∑`=0
a`(t)c`
(λ∆W ′(uN ), wk
)L2(Ω)
= λM∑`=0
b`(t)d`
− (λσ(uN ), wk)L2(Ω) = −λσak(t)
−(∂uN∂t
, wk
)L2(Ω)
= −a′k(t).
If we construct uN so that it satisfies (1.17), elementary ordinary differential equations
theory tells us that there are unique ak(t) which satisfy
0 = −N∑`=0
a`(t)c` + λ
M∑`=0
b`(t)d` − λσak(t)− a′k(t)
given the initial condition u0 and setting ak(0) as in (1.17).
1.3 Fourier Analysis
In the previous section we saw that finite linear combinations of orthonormal basis functions
will solve (1.15). In this section we will choose our orthonormal basis as well as prove some
facts about the Fourier coefficients of a function over this basis.
1.3.1 A Basis of Eigenfunctions
Since we are working with periodic boundary conditions on the unit cube, the set of functions
we will choose is
wk(x) = e2πi∑d
j=1 kjxj (1.19)
8
where (x1, x2, . . . , xd) = x ∈ Rd and (k1, k2, . . . , kd) = k ∈ Nd0. We have chosen these
functions because they are the eigenfunctions of the Laplacian over the unit cube with
periodic boundary conditions. This will allow us to turn differentiation into multiplication
by an eigenvalue which will make implementation of a solver in software possible. We prove
this fact in the following theorem.
Theorem 2. Let −∆ denote the Laplacian over the unit cube in Rd with periodic boundary
conditions. The functions wk are eigenfunctions of −∆.
Proof. In order to show that wk are eigenfunctions of −∆, we must show for all k ∈ Nd0 that
−∆wk = akwk for ak ∈ R and that wk ∈ H1per(Ω). First, we show the former statement.
To proceed, we compute the partial derivative
∂2
∂x2`
wk =∂
∂x`
[∂
∂x`e2πi
∑dj=1 kjxj
]
=∂
∂x`
[2πik`e
2πi∑d
j=1 kjxj]
= −4π2k2` e
2πi∑d
j=1 kjxj (1.20)
Now the computation of the Laplacian becomes straightforward.
−∆wk = −d∑`=1
∂2
∂x2`
wk
= −d∑`=1
−4π2k2` e
2πi∑d
j=1 kjxj (1.21)
= 4π2d∑`=1
k2` e
2πi∑d
j=1 kjxj (1.22)
where the equality in (1.21) comes from (1.20).
It remains to be shown that for all k ∈ Nd0, wk ∈ H1per(Ω). We saw in (1.20) that wk
9
has a continuous derivative, so wk ∈ H1(Ω). Therefore, all that we need to show is that wk
satisfies the periodic boundary conditions. Let c ∈ Zd.
wk(x+ c) = e2πi∑d
j=1 kj(xj+cj)
= e2πi∑d
j=1 kjxje2πi∑d
j=1 kjcj
= e2πi∑d
j=1 kjxj (1.23)
where the equality in (1.23) comes from Euler’s identity.
In addition to proving the theorem, the above proof also gives us that the eigenvalue
corresponding to wk is
κk = 4π2d∑`=1
k2` . (1.24)
As well as being the eigenfunctions of −∆, wk is a complete orthonormal set in L2(Ω)
and a complete orthogonal set in H1per(Ω) which we show in the next theorem.
Theorem 3. wk is a complete orthonormal set in L2(Ω) and a complete orthogonal set
in H1per(Ω).
Proof. From Theorem 2, we know that for all k ∈ Nd0, wk ∈ H1per(Ω) ⊂ L2(Ω). First we
show that wk is orthonormal in L2(Ω). From the definition of the L2(Ω) inner product,
we have
(wk, w`)L2(Ω) =
ˆΩwkw` dx
=
ˆΩe2πi
∑dj=1 kjxje2πi
∑dj=1 `jxj dx
=
ˆΩe2πi
∑dj=1(kj−`j)xj dx. (1.25)
10
If k = j, we have (wj , wk)L2(Ω) = 1; otherwise, (wj , wk)L2(Ω) = 0.
We now show that wk is orthogonal in H1per(Ω). Let j 6= k. From the definition of the
H1per(Ω) inner product,
(wk, w`)H1per(Ω) = (wk, w`)L2(Ω) +
d∑m=1
(∂
∂xmwk,
∂
∂xmw`
)L2(Ω)
=d∑
m=1
(2πikme
2πi∑d
j=1 kjxj , 2πi`me2πi
∑dj=1 `jxj
)L2(Ω)
(1.26)
=
d∑m=1
−4π2km`m
ˆΩe2πi
∑dj=1(kj−`j)xj dx (1.27)
= 0
where the equality in (1.26) comes from (1.25) and the equality in (1.27) comes from the
definition of the inner product in L2(Ω).
It remains to show that wk is complete in H1per(Ω) and L2(Ω). This part of the proof
is outside of the scope of this thesis, so we will simply cite [4] to complete the proof.
We have now established that wk satisfies the conditions for Theorem 1; hence, for any
N ∈ N0, there is a unique uN which approximates (1.15) such that
uN (x, t) =∑|k|∞≤N
ak(t)wk(x). (1.28)
1.3.2 A Fact About Fourier Coefficients
One fact that we take advantage of in Section 2.2 pertains to the nonlinear term in (1.15),
u− u3.
11
Theorem 4.
u3N (x, t) =
∑|k|∞≤3N
bk(t)wk(x)
for some bk : [0,∞)→ R.
Proof. From (1.28), we have
u3N (x, t) =
∑|k|∞≤N
ak(t)wk(x)
3
=
∑|k|∞≤N
ak(t)e2πi
∑dj=1 kjxj
3
(1.29)
=∑|k|∞≤N
∑|`|∞≤N
∑|m|∞≤N
ak(t)a`(t)am(t)e2πi∑d
j=1 kjxje2πi∑d
`=1 kjxje2πi∑d
m=1 kjxj
=∑|k|∞≤N
∑|`|∞≤N
∑|m|∞≤N
ak(t)a`(t)am(t)e2πi∑d
j=1(kj+`j+mj)xj . (1.30)
Setting
bn :=∑
k+`+m=n
ak(t) + a`(t) + am(t) (1.31)
yields
∑|k|∞≤N
∑|`|∞≤N
∑|m|∞≤N
ak(t)a`(t)am(t)e2πi∑d
j=1(kj+`j+mj)xj =∑
|n|∞≤3N
bn(t)e2πi∑d
j=1 njxj .
(1.32)
12
1.4 Semi Implicit Method
An important feature of (1.15) which was omitted in the preceding two sections is that of
time. In this section, we will introduce a time stepping method for approximating a solution
of an autonomous ODE and show that this method is convergent and is order 1. Of course,
we must first define what we mean by convergent and order 1.
Let u : [0,∞)→ Rd and f : Rd → Rd such that for all t ≥ 0,
u′(t) = f(u(t)) (1.33)
where f is Lipschitz. We approximate u over [0, t∗] by first choosing a discretization width
h > 0 and using it to define tn,h via tn+1,h = tn,h + h, where t0,h = 0. A time stepping
method, F seeks to approximate u(tn,h) ≈ un,h via un,h = F (un,h, un−1,h, f)1.
Definition 2. A time stepping method for the ODE (1.33) is convergent provided that for
all t∗ > 0,
limh→0+
maxn∈[0,bt∗/hc]∩Z
||un,h − u(tn,h)|| = 0. (1.34)
Definition 3. A time stepping method F for the ODE (1.33) is order p ≥ 1 provided for
h > 0, n ∈ N,
u(tn,h)− F (u(tn,h), u(tn−1,h), f)) = O(hp+1). (1.35)
The time stepping method we will use requires a further constraint on f . Namely, that
f = f1 + f2, for some f1 and f2 where f1 is linear and f2 is Lipschitz. This method is
defined by
F (un,h, un−1,h, f) := un−1,h + hf1(un,h) + hf2(un−1,h). (1.36)
1This definition is overly specialized for simplicity here; for a more general context, see [7].
13
In order for this method to be useful, it will need to be convergent and at least order p = 1
[7].
Theorem 5. The time stepping method given in (1.36) is order 1.
Proof. Let h > 0, n ∈ N. Substituting (1.36) into the left side of (1.35) yields
u(tn,h)− F (u(tn,h), u(tn−1,h), f)) = u(tn,h)− u(tn−1,h)
− hf1(u(tn,h))− hf2(u(tn−1,h))
= u(tn−1,h) + hu′(tn−1,h) +O(h2)− u(tn−1,h) (1.37)
− hf1 (u(tn−1,h) +O(h))
− hf2(u(tn−1,h))
= hu′(tn−1,h) +O(h2) (1.38)
− hf1(u(tn−1,h))− hf1(O(h))
− hf2(u(tn−1,h))
= h(u′(tn−1,h)− f(u(tn−1,h))) +O(h2) (1.39)
= O(h2), (1.40)
where the equality in step (1.37) comes from the Taylor series expansion of u(tn,h) centered
at tn−1,h, the equality in step (1.38) comes from the linearity of f1 and the equality in (1.40)
comes from (1.33).
Theorem 6. The time stepping method given in (1.36) is convergent.
Proof. We assume without loss of generality that f2 is globally Lipschitz. Due to our choice
of W in (1.2), given sufficient initial conditions, |u|∞ ≤ M for some M ∈ R, so f2 can be
14
extended linearly on (−∞,−M) ∪ (M,∞) to satisfy globally Lipschitz.
Let t∗, h > 0. Define the en,h := yn,h − y(tn,h). From (1.36) we have
un,h = un−1,h + hf1(un,h) + hf2(un−1,h).
combining this with Theorem 5 yields
en,h = en−1,h + h(f1(un,h)− f1(u(tn,h))) + h(f2(un−1,h)− f2(u(tn−1,h))) +O(h2). (1.41)
By the triangle inequality and the fact that O(h2) ≤ ch2 for some c ∈ R,
||en,h|| ≤ ||en−1,h||+ h||(f1(un,h)− f1(u(tn,h)))||+ h||(f2(un−1,h)− f2(u(tn−1,h)))||+ ch2
(1.42)
Since f1 is linear and f2 is globally Lipschitz, there exist λ1, λ2 > 0 such that for all
u1, u2 ∈ Rd,
||f1(u1)− f1(u2)|| ≤ λ1||u1 − u2|| and ||f2(u1)− f2(u2)|| ≤ λ2||u1 − u2||.
If λ2 is a Lipschitz coefficient for f2, λ2 + ε where ε > 0 is a Lipschitz coefficient for f2 as
well. Therefore, we can assume without loss of generality that λ1 6= λ2. Applying this fact
to (1.42) yields
||en,h|| ≤ ||en−1,h||+ hλ1||en,h||+ hλ2||en−1,h||+ ch2.
Since we will be taking a limit as h→ 0+, we can assume without loss of generality 1 > hλ1.
This gives us
||en,h|| ≤ 1 + hλ2
1− hλ1||en−1,h||+ ch2
1− hλ1. (1.43)
15
To proceed any further, we need to show that
||en,h|| ≤ ch2
1− hλ1
11+hλ21−hλ1 − 1
[(1 + hλ2
1− hλ1
)n− 1
]for n = 0, 1, . . . . (1.44)
We show this by induction. For n = 0, u0,h = u(0), so ||e0,h|| = 0 ≤ 0; hence, the base
case is true. Assume (1.44) for n. By (1.43),
||en+1,h|| ≤ 1 + hλ2
1− hλ1
ch2
1− hλ1
11+hλ21−hλ1 − 1
[(1 + hλ2
1− hλ1
)n− 1
]+
ch2
1− hλ1
=ch2
1− hλ1
11+hλ21−hλ1 − 1
[(1 + hλ2
1− hλ1
)n+1
− 1 + hλ2
1− hλ1+
1 + hλ2
1− hλ1− 1
]
=ch2
1− hλ1
11+hλ21−hλ1 − 1
[(1 + hλ2
1− hλ1
)n+1
− 1
]. (1.45)
Hence, (1.44) is indeed the case for all n.
Moreover, we have that
(1 + hλ2
1− hλ1
)n=
(1− hλ1 + hλ1 + hλ2
1− hλ1
)n
=
(1 +
hλ1 + hλ2
1− hλ1
)n
≤ exp
(hλ1 + hλ2
1− hλ1
)n
= exp
(nhλ1 + nhλ2
1− hλ1
). (1.46)
Since n ∈ [0, bt∗/hc] ∩ Z, for all such n,
exp
(nhλ1 + nhλ2
1− hλ1
)≤ exp
(t∗λ1 + t∗λ2
1− hλ1
). (1.47)
16
To complete the proof, we must show that
limh→0
ch2
1− hλ1
11+hλ21−hλ1 − 1
[exp
(t∗λ1 + t∗λ2
1− hλ1
)− 1
]= 0. (1.48)
First, we note that
limh→0
exp
(t∗λ1 + t∗λ2
1− hλ1
)− 1 = exp (t∗λ1 + t∗λ2)− 1. (1.49)
Now we must handle the other term in (1.48).
limh→0
ch2
(1− hλ1)(
1+hλ21−hλ1 − 1
) = limh→0
ch2
(1 + hλ2)− (1− hλ1)
= limh→0
ch2
h(λ2 − λ1)
= limh→0
ch
λ2 − λ1
= 0 (1.50)
where (1.50) comes from choosing λ1 and λ2 so that λ2 6= λ1.
17
Chapter 2: Numerical Scheme
In this chapter, we will use the results built in the previous chapter to derive a numerical
scheme for solving (1.15) numerically. Once we have developed a scheme, we will discuss
how the scheme was implemented in software as well as a software package developed to
ease the use of the solvers which implement the scheme.
2.1 Derivation
Let κ` and w` denote the eigenvalues and eigenfunctions of the Laplacian operator over
the unit cube in R3 with periodic boundary conditions. In Section 1.3.1 we saw that these
functions satisfied the hypothesis of Theorem 1 which yielded an approximate solution to
(1.15), (1.28). This approximation is still exact in t, so here we apply the time stepping
method (1.36) to approximate in t as well.
To this end, we must first discretize t. Pick h to be the discretization width. We
discretize the interval [0, T ] by DT,h := [0, dT/he] ∩ Z. Given N ∈ N0, k ∈ DT,h, let
ukN ≈ uN (kh) via some time stepping method.
In order to use the time stepping method (1.36), we must first split the right side of
(1.15) into a linear part f1 and a Lipschitz part f2. Define
f1(uk+1N ) = −∆(∆uk+1
N )− λσ(uk+1N − µ)
f2(ukN ) = λ∆((ukN )3 − ukN )
From the definition of ukN , (1.28) and Theorem 4, for all k ∈ N0, there exist ak` and bk` such
18
that
ukN =∑|`|∞≤N
ak`w`, and (ukN )3 − ukN ≈∑|`|∞≤N
bk`w`. (2.1)
The fact that the w` are eigenfunctions couples with (2.1) to yield
f1(uk+1N ) = −∆
∆∑|`|∞≤N
ak+1` w`
− λσ ∑|`|∞≤N
ak+1` w` − µ
= −∑|`|∞≤N
κ2`ak+1` w` − λσ
∑|`|∞≤N
ak+1` w` − µ
(2.2)
f2(ukN ) = λ∆((ukN )3 − ukN )
= λ∆
∑|`|∞≤N
bk`w`
= λ
∑|`|∞≤N
κkbk`w`. (2.3)
We now apply the semi-implicit method (1.36) to ukN .
uk+1N = ukN + hf1(uk+1
N ) + hf2(ukN )
∑|`|∞≤N
ak+1` w` =
∑|`|∞≤N
ak`w` − h
∑|`|∞≤N
κ2`ak+1` w` + λσ
∑|`|∞≤N
ak+1` w` − µ
+ h
λ ∑|`|∞≤N
κ`bk`w`
(2.4)
where (2.4) comes from substituting (2.1), (2.2) and (2.3). Since the w` are orthonormal,
19
we can look at each term within the summation individually. For ` 6= 0, we have
ak+1` = ak` − h
[κ2`ak+1` + λσak+1
`
]+ hλκ`b
k`
ak+1` =
ak` + hλκ`bk`
1 + hκ2` + hλσ
. (2.5)
In the case that ` = 0, we must refer back to the integral constraint (1.3). For all k ∈ N0,
we have
µ =
ˆΩukN
=
ˆΩ
∑|`|∞≤N
ak`w` (2.6)
=∑|`|∞≤N
ak`
ˆΩw`
= ak0 (2.7)
where the equality in (2.6) comes from (2.1) and the equality in (2.7) comes from the fact
that
ˆΩw` =
1 for ` = 0
0 otherwise.
2.2 Implementation in C
In this section we discuss how the numerical scheme in section 2.1 was implemented in
software. We chose the C programming language to accomplish this as C allows one to write
code that is both efficient and readable. Below is the algorithm which was implemented.
1. Compute a random initial condition via the Mersenne Twister [10].
20
2. Compute the fast Fourier transform of this initial condition and store it as a0` .
3. Compute bk` from ak` for each ` via the fast Fourier transform.
4. Compute ak+1` for each ` via (2.5).
5. Goto Step 3 until k is sufficiently large.
In order to use the fast Fourier transform, we must first discretize our domain. Given N ,
we discretize the d-dimensional unit cube by X = x` where, for all ` ∈ 0, 1, . . . , N − 1d,
x` =
(`0N,`1N, . . . ,
`dN
). (2.8)
This will allow us to describe what we mean when we say compute the fast Fourier transform
in the next section. To see how this algorithm was implemented, see Appendix C.
2.2.1 Fast Fourier Transform
Here we describe how we use the fast Fourier transform to compute the bk` in part 3 of
the above algorithm. The data we store are the Fourier coefficients of ukN , i.e., ak` . In
order to compute (ukN )3 − ukN , we must first transform the ak` to ukN (x`). Which we do for
` ∈ 0, 1, . . . , 3N − 1 as it will allow us to compute (ukN )3 exactly due to Theorem 4. This
is done using the Fastest Fourier Transform in the West library (FFTW) which computes
the inverse Fourier transform, i.e., for m ∈ 0, 1, . . . , 3N − 1d [6]
Ym =∑
|`|∞<3N
ak` e2πi/3N
∑dj=1mj`j
=∑
|`|∞<3N
ak` e2πi
∑dj=1 xmj `j
= ukN (xm). (2.9)
21
We then use FFTW to compute the Fourier transform of (ukN (xm))3−ukN (xm) to obtain bk`
[6].
X` =∑
|m|∞<3N
((ukN (xm))3 − ukN (xm))e−2πi/3N∑d
j=1mj`j
=∑
|m|∞<3N
bk`w`(xm)e−2πi/3N∑d
j=1mj`j (2.10)
=∑
|m|∞<3N
bk` e2πi
∑dj=1(xmj `j)−2πi/3N
∑dj=1mj`j
=∑
|m|∞<3N
bk`
= (3N)dbk` (2.11)
where the equality in (2.10) comes from Theorem 4.
In this way we are able to leverage FFTW to compute our nonlinearity. However, we
have glossed over how we managed to sum ak` over ` ∈ 0, 1, . . . , 3N − 1d when we have
only defined ak` for ` ∈ 0, 1, . . . , N − 1d. Unfortunately, due to a symmetry condition
given for the fast Fourier transform of real data, we can’t simply append zeros to the places
where ak` is not defined [6]. That would break the symmetry condition, so we need to pad
ak` more carefully which is discussed in section 2.2.2.
2.2.2 Zero Padding
In this section we describe how the C array which contained the ak` was padded with zeros
so to preserve symmetry. However, we must first describe how data is input and output in
FFTW for transforms of real data.
For the inverse Fourier transform, FFTW is given an array of Nd−1(N/2 + 1) complex
numbers and an array of Nd double precision numbers. The inverse Fourier transform of
the array of complex numbers is then computed and stored in the array of double precision
22
numbers. For the Fourier transform, the same arrays are given, but the Fourier transform
of the array of double precision numbers is computed and stored in the array of complex
numbers. The reason FFTW only needs an array of Nd−1(N/2 + 1) complex numbers
instead of Nd is because FFTW uses the symmetry condition to determine the missing
entries [6].
The symmetry condition can be thought of as each element of the array has an element
in the opposite corner which is its conjugate, and is a result of the fact that u must be real
[6]. More precisely, define
f(n) :=
0 if n = 0
N − n otherwise
The symmetry condition is given by
a(`1,`2,...,`d) = a(f(`1),f(`2),...,f(`d)). (2.12)
If (2.12) is broken, then the result of the transform will no longer be real, so in order to
guarantee that this condition is not broken, we map corners to corners and place zeros
everywhere else. To see this stated more precisely, please see Appendix C, specifically, the
function a_copy.
2.3 Implementation in Python
Here we describe a Python software package which was developed to provide an easy to use
interface to the C solver discussed in section 2.2. The goal was to have an interface which
would provide the following features.
1. Automated plotting of results
2. Save Run to disk
23
3. Restart runs
4. Start multiple runs at once and take advantage of all available processors
Python was chosen since features 2 and 4 could easily be accomplished using the Python
standard library, and feature 1 could be achieved via the matplotlib and pyvtk libraries
[8, 12, 13]. Also, by choosing Python, we are able to easily document and test the code by
using doctests to see this, please look to appendix B [13].
In order to achieve features 2 and 3, a Path class was created with attributes which
would contain all the data generated by a solver such as the Fourier coefficients, energies
and norms. This class also contains a save method which uses pickling, a part of the
Python standard library, to save the entire object. In order to restart a run, this object is
simply reloaded, has its timeEnd attribute increased and the run continued via the evolve
method. Feature 1 was accomplished by looping through the data saved in the Path object
and using either matplotlib or pyvtk to save images or vtk files of the plots generated by the
data, respectively. To achieve feature 4, the runBuilder method was created. This method
essentially takes a list of python dictionaries which contain parameters for runs which should
be performed. Then, the program uses the multiprocessing library to divide these runs over
several processes. Each of these processes then creates a subprocess which runs the solver
with the desired parameters, saves the created Path object and plots the results. In this
way, one is able to give the computer a large amount of instructions for performing runs
with very short scripts. To see examples of such scripts, please see appendix B.1.
24
Chapter 3: Results and Conclusions
Now that we have implemented the scheme derived in section 2.1, we can use it to examine
some previously obtained results from the literature. Specifically, we will attempt to create
a double gyroid in the 3D case as in Teramoto and Nishiura, and examine the phase diagram
for the 2D case presented by Choksi et al. [2, 14].
3.1 Creating a Double Gyroid
In their 2002 paper, Teramoto and Nishiura present results which confirm the existence
of a double gyroid (see Figure 3.1) structure as an equilibrium phase configuration under
certain choices of µ, λ, σ [14]. Unfortunately, the numerical scheme used to generate these
results was a nonstandard technique they were not independently reproduced using standard
numerical techniques. We have attempted to reproduce the double gyroid structure with
the following parameters taken from [15].
µ = 0.2, λ =2
(0.03)2and σ = 0.03 · 211(1− µ2)−2. (3.1)
Unfortunately, due to stability constraints and the inherently long runtime (approximately
24 hours per simulation time unit) necessary to obtain solutions to 3D questions, we are only
able to produce the intermediate structure, Figure 3.2 which looks close enough to a double
gyroid that we can hope that this simulation will result in a double gyroid equilibrium state.
The runtime issue was compounded by the fact that in this model, suboptimal states have
energy which is very close to the energy of optimal states [3], so a long simulation time is
necessary to reach the stable equilibrium state. This fact can be seen in the energy decay,
Figure 3.3, which after a very rapid initial decay, flattens out dramatically. However, it is
25
Figure 3.1: A Double Gyroid
also possible that the approximation created by the Galerkin system we use is leading our
solution into an equilibrium for our approximate system that is not an equilibrium for the
physical system. Future work would need to verify that this is not the case.
3.2 Examining a Phase Diagram
In the 2D case of the model, given µ, λ and σ = 1, there is either one of two stable equilibrium
solutions or no stable solution. These two stable states are hexagonally packed circles and
lamellae (see Figures 3.4 and 3.5). In a paper recently submitted by Choksi, et al., they
26
make the following statement about the phase diagram for the 2D problem [2].
Define γ :=√λ, and set σ = 1. If
γ =2
1− 3µ2
β2
, (3.2)
the lamellae state is stable provided
0 ≤ β < 1
29
√551− 174
√6 (3.3)
and the hexagonally packed circular state is stable provided
1
29
√551− 174
√6 < β < 3
√5
37. (3.4)
This result is accompanied by some numerical simulations which verify the result; how-
ever, these numerical simulations were done with a nonstandard scheme where noise was
added to coerce solutions away from unstable equilibria [2].
In order to evaluate the efficacy of this scheme, we performed simulations using randomly
chosen λ and µ which satisfied either
β = −.001 +1
29
√551− 174
√6,
β = .001 +1
29
√551− 174
√6,
or β = −.001 + 3
√5
37, (3.5)
as well as (3.2). σ was set to 1 and N was set to 40 with 3N Fourier coefficients used to
compute the nonlinearity. In order to recreate the results of Choksi et al., we changed our
27
Predicted Lamellae Predicted Circles
Actual Lamellae 8 9
Actual Circles 4 5
Table 3.1: The Predicted Lamellae column represents simulations that took place with µ, σand λ which should have generated lamellae as predicted by Choksi et al. whereasthe Predicted Circles column represents simulations that took place with µ, σ andλ which should have generated hexagonally packed circles as predicted by Choksiet al.
domain from the unit square to the L-square with L = 4π for√
2 ≤ λ <√
10, L = 2π for
√10 ≤ λ < 5 and L = π for λ > 5. This was accomplished by rescaling λ, σ and t. Since the
solver discussed in section 2.2 is relatively efficient, we were able to compute solutions at
t = 100000λ with a step size of h = 0.1
λ(1+λ34 )
which removed the need for using a nonstandard
scheme to find stable solutions. The results of these simulations are summarized in Table
3.1. Based on these results, it seems as if the numerical scheme used in Choksi et al. had
some effect on the results presented there in the sense that the scheme coerced solutions
into unstable equilibria.
3.3 Conclusion
In this thesis, we introduced the Ohta-Kawasaki functional, used a gradient flow argument
to derive an evolution equation for this functional, developed a numerical scheme for solving
this evolution equation, implemented this scheme in software and used this implementation
to examine a pair of previous results. The results of Teramoto and Nishiura were partially
verified, but due to the shallow energy decay could not be completely verified, while the
results of Choksi et al. were shown to have some dependence on the numerical scheme used.
In future work, it would be interesting to see the results of Teramoto and Nishiura fully
verified as well as the results of Choksi et al. more fully explored.
28
Figure 3.2: µ, λ and σ as in (3.1), t = 15. The simulation was carried out with a step-size
of h = 10−5 for t ∈ [0, 14] and a step-size of h = 10−6 for t ∈ (14, 15]. Nwas set to 64 for the simulation. Due to memory constraints, the nonlinearitywas approximated using 2N Fourier coefficients instead of the 3N required tocompute it exactly.
29
0.000 0.002 0.004 0.006 0.008 0.010time
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
6.0
6.5
Ene
rgy
Figure 3.3: A typical energy decay for the 3D case with µ, λ and σ as in (3.1).
30
Appendix A: Notation
• N0 The set 0, 1, 2, . . . .
• | · | The Euclidean norm in Rd
• | · |∞ The max norm in Rd.
• || · ||B The norm in the Banach space B.
• L2(Ω) The space of functions which are square integrable in the Lebeguse sense.
• H1per(Ω) The space of functions which are weakly differentiable and periodic over Ω.
• ∆ The Laplacian operator.
• x The complex conjugate of x.
• (·, ·)H The inner product in the Hilbert space H.
• 0 The zero vector in some space (the space should be clear from the context).
33
Appendix B: AISE
B.0.1 util.py
1 import numpy , transFunc , p l o t t e r s
2 import sys , subprocess , cPick le , gzip , os , copy , mu l t ip roce s s ing ,
f u n c t o o l s
3 from math import sqrt , p i
4 from i t e r t o o l s import product
5
6 # These d i c t i o n a r i e s map the BCs s p e c i f i e d to the f u n c t i o n s which
are p e r t i e n t
7 BC funcs = ’ neu1 ’ : transFunc . matlab dct ,
8 ’ neu2 ’ : transFunc . dct2 ,
9 ’ neu3 ’ : transFunc . dct3 ,
10 ’ per1 ’ : numpy . f f t . r f f t ,
11 ’ per2 ’ : numpy . f f t . r f f t 2 ,
12 ’ per3 ’ : numpy . f f t . r f f t n ,
13 ’ d i r 1 ’ : transFunc . matlab dst ,
14 ’ d i r 2 ’ : transFunc . dst2
15
16 BC ifuncs = ’ neu1 ’ : transFunc . mat lab idct ,
17 ’ neu2 ’ : transFunc . idct2 ,
18 ’ neu3 ’ : transFunc . idct3 ,
19 ’ per1 ’ : numpy . f f t . i r f f t ,
20 ’ per2 ’ : numpy . f f t . i r f f t 2 ,
34
21 ’ per3 ’ : numpy . f f t . i r f f t n ,
22 ’ d i r 1 ’ : transFunc . mat lab idst ,
23 ’ d i r 2 ’ : transFunc . i d s t 2
24
25
26 class EqSoln ( ob j e c t ) :
27 ”””A c l a s s which r e p r e s e n t s an e q u i l i b r i u m s o l u t i o n to the
d i b l o c k
28 copolymer model . When i n s t a n t i a t e d , the e i g e n f u n c t i o n s w i l l
a u t o m a t i c a l l y
29 be computed and s t o r e d .
30
31 The i n i t i a l p e r t u r b e d s o l u t i o n s shou ld be mass p r e s e r v i n g
32 >>> eqn = EqSoln (numpy . array ( [ 0 , 0 ] ) , lambd =400. , sigma =0. ,mu
=0.)
33 >>> cons tant = 0 .
34 >>> f o r path in eqn . paths :
35 . . . cons tant += numpy . abs ( path . i n i t i a l [ 0 ] )
36 >>> cons tant == 0.
37 True
38 ”””
39
40 def i n i t ( s e l f , so ln , lambd , sigma , mu, BCs=’ neu1 ’ ,
41 perturb =.001 , s o l v e r=’ neu1 ’ , paths = False ) :
42 s e l f . s o l n = so ln
35
43 s e l f . lambda = lambd
44 s e l f . s igma = sigma
45 s e l f . mu = mu
46 s e l f . pe r turb = perturb
47 s e l f . s o l v e r = s o l v e r
48 s e l f . BCs = BCs
49
50 i f not paths :
51 s e l f . computeEigenfunct ions ( )
52 else : s e l f . paths = copy . deepcopy ( paths )
53
54 @property
55 def so ln ( s e l f ) :
56 ”””The e q u i l i b r i u m s o l u t i o n ”””
57 return s e l f . s o l n . copy ( )
58
59 @property
60 def lambd ( s e l f ) :
61 ”””The lambda v a l u e f o r t h i s e q u i l i b r i u m s o l u t i o n ”””
62 return s e l f . lambda
63
64 @property
65 def sigma ( s e l f ) :
66 ”””The sigma v a l u e f o r t h i s e q u i l i b r i u m s o l u t i o n ”””
67 return s e l f . s igma
36
68
69 @property
70 def mu( s e l f ) :
71 ”””The mu v a l u e f o r t h i s e q u i l i b r i u m s o l u t i o n ”””
72 return s e l f . mu
73
74 @property
75 def perturb ( s e l f ) :
76 ”””The p e r t u b a t i o n f a c t o r f o r computing the p e r t u r b e d
e q u i l i b r i u m
77 s o l u t i o n s ”””
78 return s e l f . pe r turb
79
80 @property
81 def s o l v e r ( s e l f ) :
82 ”””The path to the t i m e s t e p p e r ”””
83 return s e l f . s o l v e r
84
85 @solver . s e t t e r
86 def s o l v e r ( s e l f , va lue ) :
87 s e l f . s o l v e r = value
88 for evo lu t i on in s e l f . e i g e n f u n c t i o n s :
89 evo lu t i on . s o l v e r = value
90
91 @property
37
92 def paths ( s e l f ) :
93 ”””A l i s t c o n t a i n i n g the u n s t a b l e paths c r e a t e d by the
94 e i g e n v a l u e s / f u n c t i o n s o f the e q u i l i b r i u m s o l u t i o n . ”””
95
96 return copy . copy ( s e l f . paths )
97
98 @property
99 def BCs( s e l f ) :
100 ”””The Boundary c o n d i t i o n s . A v a i l a b l e c h o i c e s :
101 ’ neu1 ’
102 ’ neu2 ’
103 ’ neu3 ’
104 ’ per1 ’
105 ’ per2 ’
106 ’ per3 ’
107 ’ d i r 1 ’
108 ’ d i r 2 ’ ”””
109 return s e l f . BCs
110
111 def computeEigenfunct ions ( s e l f ) :
112
113 s e l f . paths = [ ]
114 dot = numpy . dot
115 diag = numpy . diag
116 e i g = numpy . l i n a l g . e i g
38
117 so ln = s e l f . s o ln
118 sigma = s e l f . sigma
119 lambd = s e l f . lambd
120
121 N = so ln . shape [ 0 ]
122 v = numpy . eye (N)
123 A = numpy . z e r o s ( [N,N] , numpy . complex128 )
124
125 f t = BC funcs [ s e l f . BCs ]
126 r t = BC ifuncs [ s e l f . BCs ]
127
128 for j in range (N) :
129 A[ : , j ] = 3∗N∗ f t ( ( ( r t ( s o ln ) ) ∗∗2) \
130 ∗( r t ( v [ : , j ] ) ) )
131
132 kappa = pi ∗∗2 ∗ numpy . l i n s p a c e (1 ,N,N) ∗∗2
133 mat = −diag ( kappa ∗∗2 ,0) + lambd ∗ diag ( kappa , 0 ) \
134 −lambd∗dot ( diag ( kappa , 0 ) ,A) \
135 −sigma ∗ v
136 D,V = e i g (mat)
137
138 for i in range ( l en (D) ) :
139 #Only examine u n s t a b l e e q u i l i b r i a
140 i f D[ i ] <= 0 : continue
141
39
142 e i g f u n c = V[ : , i ]
143 e i g f u n c [ 0 ] = 0 .0
144 e i g v a l = D[ i ]
145 perturbedEig func = s e l f . pe r turb ∗ e i g f u n c + s e l f .
s o l n
146 s e l f . paths . append ( Path ( i n i t i a l=perturbedEigfunc ,
147 e i g v a l=e igva l ,
148 BCs=s e l f . BCs) )
149
150 def evo lve ( s e l f , f o r c e=False ) :
151 ””” This f u n c t i o n c a l l s the e v o l v e method f o r the Paths
which have not
152 been p r e v i o u s l y e v o l v e d . The e v o l v e method i s c a l l e d in
p a r a l l e l on as
153 many p r o c e s s o r s t h a t are a v a i l a b l e . I f f o r c e i s True , a l l
Paths in
154 s e l f . pa ths are e v o l v e d . ”””
155
156 paths = s e l f . paths
157
158 unsolved = [ ]
159 for path in paths :
160 i f f o r c e :
161 path . so lved = False
162 i f not path . so lved :
40
163 unsolved . append ( path )
164
165 for path in unsolved :
166 paths . remove ( path )
167
168 ncpus = mu l t i p ro c e s s i ng . cpu count ( )
169 pool = mu l t i p ro c e s s i ng . Pool ( p r o c e s s e s=ncpus )
170 evo lv e r = lambda path : path . evo lve ( )
171 so lved = pool . map( evo lver , unsolved )
172 paths += so lved
173
174 def p lo t ( s e l f , r o o t d i r ) :
175 ””” R e c u r s i v e l y p l o t the paths o f t h i s e q u i l i b r i u m
s o l u t i o n in the g iven
176 roo t d i r e c t o r y . ”””
177
178 paths = s e l f . paths
179
180 for i in range ( l en ( paths ) ) :
181 f i l e p a t h = r o o t d i r + ’/%d ’ % i
182 paths [ i ] . p l o t ( f i l e p a t h )
183
184 def save ( s e l f , f i l ename ) :
185 ””” Save t h i s EqSoln to a f i l e . ”””
186 o u t f i l e = gz ip . open ( f i l ename + ’ . gz ’ , ’w ’ )
41
187 cP i ck l e . dump( s e l f , o u t f i l e )
188 o u t f i l e . c l o s e ( )
189
190 class Path ( ob j e c t ) :
191 ”””A c l a s s which w i l l s t o r e the in format ion about the
e v o l u t i o n o f some
192 i n i t i a l c o n d i t i o n .
193
194 An example o f path c r e a t i o n wi th 2D p e r i o d i c boundary
c o n d i t i o n s . Note t h a t
195 numPlots s p e c i f i e s the number o f snapshot s to genera te o t her
than the f i n a l
196 c o n f i g u r a t i o n . In t h i s case , the two snapshots generated are
the i n i t i a l
197 c o n d i t i o n and the f i n a l s o l u t i o n .
198 >>> path = Path ( s o l v e r = ’ per2 ’ ,
199 . . . lambd = 1 .0 ,
200 . . . sigma = 1 .0 ,
201 . . . mu = . 1 ,
202 . . . s t e p S i z e = 1e−2,
203 . . . BCs = ’ per2 ’ ,
204 . . . numPlots = 1 ,
205 . . . timeEnd = .1
206 . . . )
207 >>> path . e v o l v e ( ) #d o c t e s t : +ELLIPSIS
42
208 < main . Path o b j e c t a t 0x . . . >
209 >>> l e n ( path . e v o l u t i o n )
210 2
211
212 Another example ; t h i s time with 3D p e r i o d i c boundary
c o n d i t i o n s .
213 >>> path = Path ( s o l v e r = ’ per3 ’ ,
214 . . . lambd = 1 .0 ,
215 . . . sigma = 1 .0 ,
216 . . . mu = . 1 ,
217 . . . s t e p S i z e = 1e−2,
218 . . . BCs = ’ per3 ’ ,
219 . . . numPlots = 1 ,
220 . . . timeEnd = .1
221 . . . )
222 >>> path . e v o l v e ( ) #d o c t e s t : +ELLIPSIS
223 < main . Path o b j e c t a t 0x . . . >
224 >>> l e n ( path . e v o l u t i o n )
225 2
226
227 The e n e r g i e s are computed the f i r s t time they are needed , and
t h e r e w i l l be
228 the same amount o f e n e r g i e s as t h e r e w i l l snapshots in
e v o l u t i o n
229 >>> path . computeEnergies ( )
43
230 >>> l e n ( path . e n e r g i e s ) == l e n ( path . e v o l u t i o n )
231 True
232
233 Also , the t imes are computed when the e n e r g i e s are computed ,
f o r ease when
234 p l o t t i n g e n e r g i e s .
235 >>> l e n ( path . e n e r g i e s ) == l e n ( path . t imes )
236 True
237
238 Also , i f the number o f p l o t s exceeds the amount o f time s t e p s
t h a t w i l l
239 occur , the number o f time s t e p s shou ld be used i n s t e a d .
240 >>> path = Path ( s o l v e r = ’ per2 ’ ,
241 . . . lambd = 1 .0 ,
242 . . . sigma = 1 .0 ,
243 . . . mu = . 1 ,
244 . . . s t e p S i z e = 1e−2,
245 . . . BCs = ’ per2 ’ ,
246 . . . numPlots = 100 ,
247 . . . timeEnd = .1
248 . . . )
249 >>> path . e v o l v e ( ) #d o c t e s t : +ELLIPSIS
250 < main . Path o b j e c t a t 0x . . . >
251 >>> l e n ( path . e v o l u t i o n )
252 11
44
253 ”””
254
255 def i n i t ( s e l f ,
256 i n i t i a l = None ,
257 e i g v a l = None ,
258 s o l v e r = ’ per2 ’ ,
259 evo lu t i on = None ,
260 so lved = False ,
261 norms = None ,
262 e n e r g i e s = None ,
263 BCs = ’ per2 ’ ,
264 lambd = 500 .0 ,
265 sigma = 0 . 0 ,
266 mu = 0 . 0 ,
267 s t e p S i z e = 1e−5,
268 timeEnd = 0 . 1 ,
269 numPlots = 100 ,
270 cache = None ) :
271
272 s e l f . i n i t i a l = i n i t i a l
273 s e l f . lambda = lambd
274 s e l f . s igma = sigma
275 s e l f . mu = mu
276 s e l f . e i g v a l = e i g v a l
277 s e l f . s o l v e r = s o l v e r
45
278 s e l f . s o l v e d = so lved
279 s e l f . BCs = BCs
280 s e l f . s t e p S i z e = s t e p S i z e
281 s e l f . timeEnd = timeEnd
282 s e l f . numPlots = numPlots
283 s e l f . cache = cache
284 s e l f . t imes = None
285
286 i f norms == None :
287 s e l f . norms = [ ]
288 else :
289 s e l f . norms = norms
290
291 i f e n e r g i e s == None :
292 s e l f . e n e r g i e s = [ ]
293 else :
294 s e l f . e n e r g i e s = e n e r g i e s
295
296 i f evo lu t i on == None :
297 s e l f . e v o l u t i o n = [ ]
298 else :
299 s e l f . e v o l u t i o n = evo lu t i on
300
301 @property
302 def i n i t i a l ( s e l f ) :
46
303 ”””The i n i t i a l c o n d i t i o n ”””
304
305 i f s e l f . i n i t i a l != None :
306 return s e l f . i n i t i a l . copy ( )
307 else : return None
308
309 @property
310 def e i g v a l ( s e l f ) :
311 ”””The e i g e n v a l u e which corresponds to t h i s path . ”””
312
313 return s e l f . e i g v a l
314
315 @property
316 def s o l v e r ( s e l f ) :
317 ”””The path to the t imes tepper , s o l v e r . ”””
318
319 return s e l f . s o l v e r
320
321 @property
322 def evo lu t i on ( s e l f ) :
323 ”””The e v o l u t i o n as c a l c u l a t e d by s o l v e r ”””
324
325 return copy . copy ( s e l f . e v o l u t i o n )
326
327 @property
47
328 def so lved ( s e l f ) :
329 ”””True i f the e v o l u t i o n has been c a l c u l a t e d . ”””
330
331 return s e l f . s o l v e d
332
333 @solved . s e t t e r
334 def so lved ( s e l f , va lue ) :
335 s e l f . s o l v e d = value
336
337 @property
338 def norms ( s e l f ) :
339 ”””A l i s t o f the norms o f the f o u r i e r c o e f f i c i e n t s as
computed by
340 s o l v e r . ”””
341
342 return copy . copy ( s e l f . norms )
343
344 @property
345 def e n e r g i e s ( s e l f ) :
346 ”””A l i s t o f the e n e r g i e s computed by the s o l v e r ten
t imes per p l o t
347 s t e p . ”””
348 return copy . copy ( s e l f . e n e r g i e s )
349
350 @property
48
351 def t imes ( s e l f ) :
352 ”””A l i s t o f t imes at which the e v o l u t i o n s and e n e r g i e s
were
353 recorded . ”””
354
355 return copy . copy ( s e l f . t imes )
356
357 @property
358 def BCs( s e l f ) :
359 ”””The Boundary c o n d i t i o n s . A v a i l a b l e c h o i c e s :
360 ’ neu1 ’
361 ’ neu2 ’
362 ’ neu3 ’
363 ’ per1 ’
364 ’ per2 ’
365 ’ per3 ’
366 ’ d i r 1 ’
367 ’ d i r 2 ’ ”””
368 return s e l f . BCs
369
370 @property
371 def lambd ( s e l f ) :
372 ””” lambda ”””
373 return s e l f . lambda
374
49
375 @property
376 def sigma ( s e l f ) :
377 ””” sigma ”””
378 return s e l f . s igma
379
380 @property
381 def mu( s e l f ) :
382 ”””mu”””
383 return s e l f . mu
384
385 @property
386 def timeEnd ( s e l f ) :
387 ”””End time o f s i m u l a t i o n . This w i l l be s h i f t e d i f
co n t in u in g a run so
388 t h a t the e n t i r e s i m u l a t i o n time i s timeEnd . ”””
389 return s e l f . timeEnd
390
391 @timeEnd . s e t t e r
392 def timeEnd ( s e l f , va lue ) :
393 s e l f . timeEnd = value
394
395 @property
396 def numPlots ( s e l f ) :
397 ”””The number o f p l o t s to be generated during t h i s
e v o l u t i o n . I f
50
398 co nt in u ing a run , t h i s number o f p l o t s w i l l be genera ted
f o r the
399 c o n t i n u a t i o n . ”””
400 return s e l f . numPlots
401
402 @numPlots . s e t t e r
403 def numPlots ( s e l f , va lue ) :
404 s e l f . numPlots = value
405
406 @property
407 def cache ( s e l f ) :
408 ”””The l o c a t i o n o f the cache d i r e c t o r y f o r the e v o l u t i o n .
I f s e t to
409 none , the e v o l u t i o n i s not cached . An a b s o l u t e path i s
necessary i f you
410 plan on opening the same e v o l u t i o n from d i f f e r e n t working
d i r e c t o r i e s . ”””
411 return s e l f . cache
412
413 @cache . s e t t e r
414 def cache ( s e l f , va lue ) :
415 s e l f . cache = value
416
417 @property
418 def s t e p S i z e ( s e l f ) :
51
419 ”””The s t e p S i z e i s the s i z e o f the time s t e p used by the
s o l v e r . The
420 d e f a u l t , 1e−5 shou ld g i v e s t a b i l i t y f o r most c o n d i t i o n s
on the DBCP
421 model . ”””
422 return s e l f . s t e p S i z e
423
424 @stepSize . s e t t e r
425 def s t e p S i z e ( s e l f , va lue ) :
426 s e l f . s t e p S i z e = value
427
428 def evo lve ( s e l f ) :
429 ””” Uses s o l v e r to e v o l v e . The path i s re turned a f t e r
e v o l u t i o n . I f
430 so l ved , the l a s t snapshot o f the e v o l u t i o n i s used as the
i n i t i a l
431 c o n d i t i o n . ”””
432
433 i f s e l f . cache != None and not os . path . e x i s t s ( s e l f . cache ) :
434 os . mkdir ( s e l f . cache )
435
436 a s s e r t not ( s e l f . e vo lu t i on == [ ] and s e l f . s o lved )
437
438 i f s e l f . s o lved :
439 i f s e l f . cache != None :
52
440 cacheLoc = len ( s e l f . e vo lu t i on )
441 snap = loadCache ( cacheLoc−1, s e l f . cache )
442 i n i t i a l = snap . so ln
443 t imeSh i f t = snap . time
444 else :
445 i n i t i a l = s e l f . e vo lu t i on [ −1 ] . s o ln
446 t imeSh i f t = s e l f . e vo lu t i on [ −1 ] . time
447 else :
448 i n i t i a l = s e l f . i n i t i a l
449 s e l f . e v o l u t i o n = [ ]
450 t imeSh i f t = 0
451 cacheLoc = 0
452
453 a s s e r t ( s e l f . timeEnd − t imeSh i f t ) > 0
454 i f s e l f . timeEnd − t imeSh i f t == 0 :
455 return s e l f
456
457 proce s s = subproces s . Popen ( [ s e l f . s o l v e r ] ,
458 s h e l l=False ,
459 s td in=subproces s . PIPE ,
460 stdout=subproces s . PIPE)
461
462 s td in = s t r ( s e l f .mu) + ’ ’ \
463 + s t r ( s e l f . lambd ) + ’ ’ \
464 + s t r ( s e l f . sigma ) + ’ ’ \
53
465 + s t r ( s e l f . s t e p S i z e ) + ’ ’ \
466 + s t r ( s e l f . timeEnd − t imeSh i f t ) + ’ ’ \
467 + s t r ( s e l f . numPlots )
468
469 i f i n i t i a l != None :
470 s td in += ’ \n1\n ’
471 for element in i n i t i a l . f l a t t e n ( ) :
472 s td in += ’%g %g\n ’ % ( element . r ea l , e lement . imag )
473 else :
474 s td in += ’ \n0 ’ ;
475
476 message = proce s s . communicate ( s td in ) [ 0 ]
477 l i n e s = message . s p l i t ( ’ \n ’ )
478
479 for l i n e in l i n e s :
480
481 l i n e = l i n e . lower ( )
482 data = l i n e . s p l i t ( )
483
484 # There needs to be a meaning when t h e s e are e v a l e d
485 nan = numpy . nan
486 i n f = numpy . i n f t y
487 nannanj = numpy . nan
488
489 i f l en ( data ) == 0 :
54
490 pass
491 e l i f data [ 0 ] == ’norm ’ :
492 s e l f . norms . append ( eva l ( data [ 1 ] ) )
493
494 e l i f data [ 0 ] == ’ begin ’ and data [ 1 ] == ’ p l o t ’ :
495 snap = [ ]
496
497 e l i f data [ 0 ] == ’ time ’ :
498 time = eva l ( data [ 1 ] ) + t imeSh i f t
499
500 e l i f data [ 0 ] == ’ end ’ and data [ 1 ] == ’ p l o t ’ :
501 snap = numpy . array ( snap )
502 snapshot = Snapshot ( time , snap )
503 i f s e l f . cache != None :
504 saveCache ( snapshot , cacheLoc , s e l f . cache )
505 s e l f . e v o l u t i o n . append ( cacheLoc )
506 cacheLoc += 1
507 else :
508 s e l f . e v o l u t i o n . append ( snapshot )
509
510 else :
511 snap . append ( eva l ( l i n e ) )
512
513 s e l f . s o lved = True
514
55
515 return s e l f
516
517 def p lo t ( s e l f , f i l e p a t h ) :
518 ””” P l o t s each snapshot us ing m a t p l o t l i b f o r 1D and 2D
p l o t s and v t k f o r
519 3D p l o t s . in the g iven d i r e c t o r y . ”””
520
521 i f not os . path . e x i s t s ( f i l e p a t h ) :
522 os . mkdir ( f i l e p a t h )
523 else :
524 print >> sys . s tde r r , ”Warning : Plot d i r e c t o r i e s e x i s t
”
525
526 i f l en ( s e l f . e vo lu t i on ) > 0 :
527 i f s e l f . cache == None :
528 dim = len ( s e l f . e vo lu t i on [ 0 ] . s o ln . shape )
529 else :
530 snap = loadCache ( s e l f . e vo lu t i on [ 0 ] , s e l f . cache )
531 dim = len ( snap . s o ln . shape )
532 i f dim == 1 :
533 p l o t t e r = p l o t t e r s . p l o t
534 i f dim == 2 :
535 p l o t t e r = p l o t t e r s . pco l o r
536 else :
537 p l o t t e r = p l o t t e r s . plotVTK
56
538
539 for snapshot in s e l f . e vo lu t i on :
540 i f s e l f . cache != None :
541 snapshot = loadCache ( snapshot , s e l f . cache )
542
543 so ln = snapshot . s o ln
544 time = snapshot . time
545 u = prePlot ( so ln , s e l f . BCs)
546 p l o t t e r (u , f i l e p a t h + ’ /%.08 f ’ % time )
547
548 def computeEnergies ( s e l f ) :
549 ”””Compute the energy f o r each snapshot in e v o l u t i o n .
Current ly , t h i s
550 doesn ’ t work f o r c e r t a i n boundar ies or dimensions ! . ”””
551
552 i f not s e l f . s o lved :
553 return
554 else :
555 s e l f . e n e r g i e s = [ ]
556 s e l f . t imes = [ ]
557 i f s e l f . BCs [ : 3 ] == ’ per ’ :
558 i f s e l f . cache != None :
559 f i r s t P l o t = loadCache ( s e l f . e vo lu t i on [ 0 ] ,
s e l f . cache )
560 else :
57
561 f i r s t P l o t = s e l f . e vo lu t i on [ 0 ]
562 shape = f i r s t P l o t . s o ln . shape
563 kappa = genEigenva lues ( shape , s e l f . BCs)
564
565 for snap in s e l f . e vo lu t i on :
566
567 #FIXME none o f t h i s works f o r 1D due to the cho ice f o r N
568 #FIXME none o f t h i s works f o r neumann boundar ies
569 i f s e l f . cache != None :
570 snap = loadCache ( snap , s e l f . cache )
571
572 a = snap . so ln
573 d = a . ndim
574 N = a . shape [ 0 ]
575
576 u = prePlot ( a ,
577 BCs=s e l f . BCs ,
578 r e s o l u t i o n =3∗N
579 )
580 w = (1 − u∗∗2) ∗∗2 / 4 .
581 b = BC funcs [ s e l f . BCs ] (w) / N∗∗d
582
583 energy = 0
584 coords = [ range ( i ) for i in shape ]
585 coords = product (∗ coords )
58
586 for coord in coords :
587 i f any ( coord ) == 0 :
588 energy += b [ coord ]
589 e l i f coord [−1] == shape [−1]−1:
590 energy += a [ coord ] ∗ numpy . conj ( a [
coord ] ) \
591 ∗( kappa [ coord ] / s e l f . lambd\
592 + s e l f . sigma ∗ . 5 / kappa [
coord ] )
593 else :
594 energy += 2 ∗ a [ coord ] ∗ numpy . conj ( a
[ coord ] ) \
595 ∗( kappa [ coord ] / s e l f . lambd\
596 + s e l f . sigma ∗ . 5 / kappa [
coord ] )
597
598 s e l f . e n e r g i e s . append ( energy )
599 s e l f . t imes . append ( snap . time )
600 else :
601 raise NotImplementedError
602
603
604
605 def save ( s e l f , f i l ename ) :
606 ””” Save t h i s Path to a f i l e . ”””
59
607 o u t f i l e = gz ip . open ( f i l ename + ’ . gz ’ , ’w ’ )
608 cP i ck l e . dump( s e l f , o u t f i l e )
609 o u t f i l e . c l o s e ( )
610
611 class Snapshot ( ob j e c t ) :
612 ””” This c l a s s w i l l conta in two a t t r i b u t e s . Namely , time and
s o l u t i o n . They
613 correspond to the time at which s o l v e r has re turned v a l u e s
f o r a g iven
614 e v o l u t i o n ”””
615
616 def i n i t ( s e l f , time , so ln ) :
617 s e l f . t ime = time
618 s e l f . s o l n = so ln
619
620 @property
621 def time ( s e l f ) :
622 ”””The time at which s o l v e r computed t h i s s o l u t i o n
snapshot ”””
623 return s e l f . t ime
624
625 @property
626 def so ln ( s e l f ) :
627 ”””The s o l u t i o n which s o l v e r computed f o r t h i s snapshot
”””
60
628 return s e l f . s o l n . copy ( )
629
630 def prePlot ( a , BCs=’ neu ’ , r e s o l u t i o n =256) :
631 ””” Computes the i n v e r s e transform of an array o f f o u r i e r
c o e f f i c i e n t s , a ,
632 a f t e r padding the array so t h a t the array l e n g t h i s a t l e a s t
the s p e c i f i e d
633 r e s o l u t i o n . This padded array i s then re turned .
634
635 >>> [ x , y ] = numpy . mgrid [ 0 : 1 : 1 . / 6 4 , 0 : 1 : 1 . / 6 4 ]
636 >>> u = numpy . s i n (2∗ p i ∗( x+y ) )
637 >>> a = BC funcs [ ’ per2 ’ ] ( u) / 64∗∗2
638 >>> u0 = p r e P l o t (a , ’ per2 ’ ,64)
639 >>> u1 = p r e P l o t (a , ’ per2 ’ ,128)
640
641 u shou ld be c l o s e to the i f f t ( f f t (u) )
642 >>> numpy . a l l c l o s e (u , u0 )
643 True
644
645 max/min shou ld s t a y the same r e g a r d l e s s o f r e s o l u t i o n
646 >>> numpy . a l l c l o s e ( [ u1 . max ( ) , u1 . min () ] , [ u . max () , u . min () ] )
647 True
648
649 The same shou ld be t r u e in 3D.
650
61
651 >>> [ x , y , z ] = numpy . mgrid [ 0 : 1 : 1 . / 6 4 , 0 : 1 : 1 . / 6 4 , 0 : 1 : 1 . / 6 4 ]
652 >>> u = numpy . s i n (2∗ p i ∗( x+y+z ) )
653 >>> a = BC funcs [ ’ per3 ’ ] ( u) / 64∗∗3
654 >>> u0 = p r e P l o t (a , ’ per3 ’ ,64)
655 >>> u1 = p r e P l o t (a , ’ per3 ’ ,128)
656
657 u shou ld be c l o s e to the i f f t ( f f t (u) )
658 >>> numpy . a l l c l o s e (u , u0 )
659 True
660
661 max/min shou ld s t a y the same r e g a r d l e s s o f r e s o l u t i o n
662 >>> numpy . a l l c l o s e ( [ u1 . max ( ) , u1 . min () ] , [ u . max () , u . min () ] )
663 True
664
665 I t would be nice i f the d e f a u l t r e s o l u t i o n does not throw a
MemoryError .
666 >>> u2 = p r e P l o t (a , ’ per3 ’ )
667 ”””
668 a = a . copy ( )
669
670 r t = BC ifuncs [ BCs ]
671
672 for s i z e in a . shape :
673 i f r e s o l u t i o n < s i z e :
674 r e s o l u t i o n = s i z e
62
675 print >> sys . s tde r r , ”Warning : array s i z e used
in s t ead o f ”\
676 +” s p e c i f i e d r e s o l u t i o n . ”
677
678 i f l en ( a . shape ) == 1 :
679 s i z e = a . shape [ 0 ]
680
681 i f BCs == ’ per ’ :
682 r e s o l u t i o n = r e s o l u t i o n /2 + 1
683
684 pads i z e = r e s o l u t i o n−s i z e
685
686 padding = numpy . z e r o s ( pads i z e )
687 aext = numpy . concatenate ( ( a , padding ) )
688
689 aext ∗= s q r t ( r e s o l u t i o n )
690
691 e l i f l en ( a . shape ) == 2 :
692
693 i f BCs == ’ per2 ’ :
694 i f a . shape [ 0 ] == r e s o l u t i o n :
695 aext = a
696 else :
697 n2 = a . shape [ 0 ] / 2
698 nh = a . shape [1]−1
63
699
700 aext = numpy . z e r o s ( [ r e s o l u t i o n , r e s o l u t i o n /2 + 1 ]
701 ,numpy . complex128 )
702 aext [ : n2 , : nh ] = a [ : n2 , : nh ]
703 aext [ : n2 , nh ] = . 5 ∗ a [ : n2 , nh ]
704 aext [−n2 +1: , : nh ] = a[−n2 +1: , : nh ]
705 aext [−n2 +1: ,nh ] = . 5 ∗ a[−n2 +1: ,nh ]
706
707 i f a . shape [ 0 ] % 2 == 0 :
708 aext [−n2 , : nh ] = . 5 ∗ a [ n2 , : nh ]
709 aext [ n2 , : nh ] = . 5 ∗ a [ n2 , : nh ]
710 aext [−n2 , nh ] = .25 ∗ a [ n2 , nh ]
711 aext [ n2 , nh ] = .25 ∗ a [ n2 , nh ]
712
713 aext ∗= r e s o l u t i o n ∗∗2
714
715 else :
716 aext = numpy . z e r o s ( [ r e s o l u t i o n , r e s o l u t i o n ] )
717 aext [ : a . shape [ 0 ] , : a . shape [ 1 ] ] = a
718 aext ∗= r e s o l u t i o n
719
720 e l i f l en ( a . shape ) == 3 :
721 i f BCs == ’ per3 ’ :
722 a s s e r t a . shape [ 0 ] == a . shape [ 1 ]
723 i f a . shape [ 0 ] == r e s o l u t i o n :
64
724 aext = a
725 else :
726 n2 = a . shape [ 0 ] / 2
727 nh = a . shape [−1]−1
728
729 aext = numpy . z e r o s ( [ r e s o l u t i o n , r e s o l u t i o n ,
r e s o l u t i o n /2 +1]
730 ,numpy . complex128 )
731
732 aext [ : n2 , : n2 , : nh ] = a [ : n2 , : n2 , : nh ]
733 aext [−n2 +1: , : n2 , : nh ] = a[−n2 +1: , : n2 , : nh ]
734 aext [ : n2,−n2 +1: , : nh ] = a [ : n2,−n2 +1: , : nh ]
735 aext [−n2+1:,−n2 +1: , : nh ] = a[−n2+1:,−n2 +1: , : nh ]
736
737 aext [ : n2 , : n2 , nh ] = . 5 ∗ a [ : n2 , : n2 , nh ]
738 aext [−n2 +1: , : n2 , nh ] = . 5 ∗ a[−n2 +1: , : n2 , nh ]
739 aext [ : n2,−n2 +1: ,nh ] = . 5 ∗ a [ : n2,−n2 +1: ,nh ]
740 aext [−n2+1:,−n2 +1: ,nh ] = . 5 ∗ a[−n2+1:,−n2 +1: ,nh ]
741
742 i f a . shape [ 0 ] %2 == 0 :
743 aext [−n2 , : n2 , : nh ] = . 5 ∗ a [ n2 , : n2 , : nh ]
744 aext [ n2 , : n2 , : nh ] = . 5 ∗ a [ n2 , : n2 , : nh ]
745 aext [ : n2,−n2 , : nh ] = . 5 ∗ a [ : n2 , n2 , : nh ]
746 aext [ : n2 , n2 , : nh ] = . 5 ∗ a [ : n2 , n2 , : nh ]
747
65
748 aext [−n2,−n2 +1: , : nh ] = . 5 ∗ a [ n2,−n2 +1: , : nh ]
749 aext [ n2,−n2 +1: , : nh ] = . 5 ∗ a [ n2,−n2 +1: , : nh ]
750 aext [−n2+1:,−n2 , : nh ] = . 5 ∗ a[−n2 +1: ,n2 , : nh ]
751 aext [−n2 +1: ,n2 , : nh ] = . 5 ∗ a[−n2 +1: ,n2 , : nh ]
752
753 aext [−n2 , : n2 , nh ] = .25 ∗ a [ n2 , : n2 , nh ]
754 aext [ n2 , : n2 , nh ] = .25 ∗ a [ n2 , : n2 , nh ]
755 aext [ : n2,−n2 , nh ] = .25 ∗ a [ : n2 , n2 , nh ]
756 aext [ : n2 , n2 , nh ] = .25 ∗ a [ : n2 , n2 , nh ]
757
758 aext [−n2,−n2 +1: ,nh ] = .25 ∗ a [ n2,−n2 +1: ,nh ]
759 aext [ n2,−n2 +1: ,nh ] = .25 ∗ a [ n2,−n2 +1: ,nh ]
760 aext [−n2+1:,−n2 , nh ] = .25 ∗ a[−n2 +1: ,n2 , nh ]
761 aext [−n2 +1: ,n2 , nh ] = .25 ∗ a[−n2 +1: ,n2 , nh ]
762
763 aext [−n2 , n2 , : nh ] = .25 ∗ a [ n2 , n2 , : nh ]
764 aext [ n2 , n2 , : nh ] = .25 ∗ a [ n2 , n2 , : nh ]
765 aext [ n2,−n2 , : nh ] = .25 ∗ a [ n2 , n2 , : nh ]
766 aext [−n2,−n2 , : nh ] = .25 ∗ a [ n2 , n2 , : nh ]
767
768 aext [−n2 , n2 , nh ] = .125 ∗ a [ n2 , n2 , nh ]
769 aext [ n2 , n2 , nh ] = .125 ∗ a [ n2 , n2 , nh ]
770 aext [ n2,−n2 , nh ] = .125 ∗ a [ n2 , n2 , nh ]
771 aext [−n2,−n2 , nh ] = .125 ∗ a [ n2 , n2 , nh ]
772
66
773 aext ∗= r e s o l u t i o n ∗∗3
774
775 else :
776 aext = numpy . z e r o s ( [ r e s o l u t i o n , r e s o l u t i o n , r e s o l u t i o n
] )
777 aext [ : a . shape [ 0 ] , : a . shape [ 1 ] , : a . shape [ 2 ] ] = a
778 aext ∗= r e s o l u t i o n ∗∗ ( 1 . 5 )
779 else :
780 raise NotImplementedError
781
782 u = r t ( aext )
783
784 return u
785
786 def runBui lder ( cond i t i ons , baseDir=’ . ’ , ncpus=None ) :
787 ””” This f u n c t i o n t a k e s a l i s t o f l i s t s o f the form
788 [ paramdict , number ] or [ paramdict , Path , dirname ] ,
789 where paramdict i s a d i c t i o n a r y o f parameters f o r the
c r e a t i o n o f a path
790 o b j e c t and number i s the number o f runs to perform with t h e s e
parameters .
791 After the path o b j e t s have been created , they are evo lved ,
p i c k l e d and
792 saved w i t h i n the baseDir in p a r a l l e l wi th ncpus workers .
793
67
794 The second format i s f o r c ont inu i ng a run . Path i s a Path
o b j e c t , dirname
795 i s where you ’ d l i k e the p l o t s and p i c k l e s tored , and
paramdict i s the same
796 as be fore , but can only conta in a t t r i b u t e s in the p u b l i c
i n t e r f a c e o f Path
797 ( so l ved , numPlots and ’ timeEnd ’) .
798
799 The f o l l o w i n g r a i s e s an Asser t ionError s i n c e timeEnd i s s e t
to 0 .
800 Otherwise , i t i s a good example .
801
802 >>> c o n d i t i o n s = [ [ ’ s o l v e r ’ : ’ per2 ’ ,
803 . . . ’BCs ’ : ’ per2 ’ ,
804 . . . ’ lambd ’ : 500.0 ,
805 . . . ’ sigma ’ : 0 . 0 ,
806 . . . ’mu ’ : 0 . 0 ,
807 . . . ’ numPlots ’ : 100 ,
808 . . . ’ timeEnd ’ : 0 .0 ,
809 . . . 1 ] ]
810 >>> t r y :
811 . . . runBui lder ( c o n d i t i o n s )
812 . . . e x c e p t Asser t ionError :
813 . . . pass
814 ”””
68
815
816 paths = [ ]
817 for cond i t i on in c o n d i t i o n s :
818 i f type ( cond i t i on [ 1 ] ) == i n t :
819 for i in range ( cond i t i on [ 1 ] ) :
820 path = ( Path (∗∗ cond i t i on [ 0 ] ) ,
821 i )
822 paths . append ( path )
823 else :
824 for key in cond i t i on [ 0 ] :
825 i f key == ’ numPlots ’ :
826 cond i t i on [ 1 ] . numPlots = cond i t i on [ 0 ] [ key ]
827 e l i f key == ’ timeEnd ’ :
828 cond i t i on [ 1 ] . timeEnd = cond i t i on [ 0 ] [ key ]
829 e l i f key == ’ so lved ’ :
830 cond i t i on [ 1 ] . s o lved = cond i t i on [ 0 ] [ key ]
831 e l i f key == ’ s t e p S i z e ’ :
832 cond i t i on [ 1 ] . s t e p S i z e = cond i t i on [ 0 ] [ key ]
833 else :
834 raise Exception ( ’ I n v a l i d paramdict f o r run
r e s t a r t ’ )
835 paths . append ( ( cond i t i on [ 1 ] , c ond i t i on [ 2 ] ) )
836
837 i f ncpus == None :
838 ncpus = mu l t i p ro c e s s i ng . cpu count ( )
69
839
840 pool = mu l t i p ro c e s s i ng . Pool ( p r o c e s s e s=ncpus )
841 runner = f u n c t o o l s . p a r t i a l ( runner , dirname=baseDir )
842
843 pool . map( runner , paths )
844
845 def runner ( path , dirname ) :
846 i = path [ 1 ]
847 path = path [ 0 ]
848 sigma = path . sigma
849 lambd = path . lambd
850 mu = path .mu
851
852 i f dirname [−1] != ’ / ’ :
853 dirname += ’ / ’
854
855 i f type ( i ) == s t r :
856 dirname += i
857 else :
858 dirname += s t r (mu) + ’ ’ \
859 + s t r ( sigma ) + ’ ’ \
860 + s t r ( lambd ) + ’ / ’ \
861 + s t r ( i ) + ’ / ’
862
863 i f not os . path . e x i s t s ( dirname ) :
70
864 os . makedirs ( dirname )
865
866 i f path . cache == ’ ’ :
867 path . cache = dirname + ’ evocache ’
868 path . evo lve ( )
869 path . save ( dirname + ’ evo ’ )
870 path . p l o t ( dirname )
871
872 def loadCache ( cacheLoc , cache ) :
873 l o a d F i l e = open ( cache + ’ / ’ + s t r ( cacheLoc ) , ’ r ’ )
874 snapshot = cP i ck l e . load ( l o a d F i l e )
875 l o a d F i l e . c l o s e ( )
876 return snapshot
877
878 def saveCache ( obj , cacheLoc , cache ) :
879 dumpFile = open ( cache + ’ / ’ + s t r ( cacheLoc ) , ’w ’ )
880 cP i ck l e . dump( obj , dumpFile )
881 dumpFile . c l o s e ( )
882
883 def genEigenva lues ( shape , BCs) :
884 N = shape [ 0 ]
885 i f BCs [ : 3 ] == ’ per ’ :
886 kappap = [ 4 ∗ pi ∗∗2 ∗ i ∗∗2 for i in range (N/2) + range (N
/2 ,0 ,−1) ]
887 kappa = numpy . z e r o s ( shape )
71
888 coords = [ range ( i ) for i in shape ]
889 coords = product (∗ coords )
890 for coord in coords :
891 e i g v a l = [ kappap [ i ] for i in coord ]
892 kappa [ coord ] = sum( e i g v a l )
893 return kappa
894 else :
895 raise NotImplementedError
896
897 i f name == ” main ” :
898 import doc t e s t
899 doc t e s t . testmod ( )
B.0.2 plotters.py
1 import numpy , sys
2 import matp lo t l i b . pyplot as pyplt
3 from pyvtk import VtkData , StructuredPoints , PointData , S c a l a r s
4
5 def p lo t (u , f i l ename ) :
6 ””” P l o t s the g iven array and saves i t to the g iven f i l ename .
”””
7
8 N = u . shape [ 0 ]
9 x = numpy . l i n s p a c e (0 , 1 ,N)
10
11 pyplt . f i g u r e ( )
72
12 pyplt . p l o t (x , u )
13 pyplt . s a v e f i g ( f i l ename + ’ . png ’ )
14 pyplt . c l o s e ( )
15
16 def pco lo r (u , f i l ename ) :
17 ””” P l o t s the g iven array and saves i t to the g iven f i l ename .
”””
18
19 i f u . max( ) > 1 or u . min ( ) <−1:
20 print >> sys . s tde r r , ” p l o t out o f bounds”
21
22 pyplt . f i g u r e ( )
23 pyplt . axes ( [ 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 ] )
24 try :
25 pyplt . imsave ( a r r=u , fname=f i l ename + ’ . png ’ , o r i g i n=’ lower ’
, vmin=−1,vmax=1)
26 except Attr ibuteError :
27 # Older v e r s i o n s o f m a t p l o t l i b do not have imsave , so i t i s
implemented
28 # below .
29 from matp lo t l i b . backends . backend agg import
FigureCanvasAgg
30 from matp lo t l i b . f i g u r e import Figure
31
32 f i g = Figure ( f i g s i z e=u . shape [ : : − 1 ] , dpi =1, frameon=False )
73
33 canvas = FigureCanvasAgg ( f i g )
34 f i g . f i g image (u , vmin=−1,vmax=1, o r i g i n=’ lower ’ )
35 f i g . s a v e f i g ( f i l ename + ’ . png ’ , dpi=1)
36
37 pyplt . c l o s e ( )
38
39 def plotVTK(u , f i l ename ) :
40 ””” Saves a g iven array in a v t k f i l e wi th the g iven f i l ename .
”””
41
42 shape = u . shape
43 VtkData ( StructuredPo int s ( shape ) ,
44 PointData ( S c a l a r s (u . f l a t t e n ( ) ) )
45 ) . t o f i l e ( f i l ename + ’ . vtk ’ )
B.0.3 transFunc.py
1 import numpy
2 from math import s q r t
3
4 #TODO add d o c t e s t s f o r t h i s module
5
6 def matlab dct (v , a x i s=−1) :
7 ””” Implements the Matlab v e r s i o n o f the dct , i . e . , the
nonsca led v e r s i o n o f
8 the dc t implemented in dc t i s s c a l e d to normal ize i t and make
i t
74
9 o r t h o g o n a l . ”””
10
11 N = v . shape [ a x i s ]
12
13 vhat = dct (v , a x i s )
14
15 i f a x i s == 0 :
16 vhat [ 0 , . . . ] = vhat [ 0 , . . . ] ∗ 1 . 0 / ( 2 . 0 ∗ s q r t (N) )
17 vhat [ 1 : , . . . ] = vhat [ 1 : , . . . ] ∗ 1 .0/ s q r t ( 2 . 0 ∗ N)
18 e l i f a x i s == −1:
19 vhat [ . . . , 0 ] = vhat [ . . . , 0 ] ∗ 1 . 0 / ( 2 . 0 ∗ s q r t (N) )
20 vhat [ . . . , 1 : ] = vhat [ . . . , 1 : ] ∗ 1 .0/ s q r t ( 2 . 0 ∗ N)
21 e l i f a x i s == −2:
22 vhat [ . . . , 0 , : ] = vhat [ . . . , 0 , : ] ∗ 1 . 0 / ( 2 . 0 ∗ s q r t (N) )
23 vhat [ . . . , 1 : , : ] = vhat [ . . . , 1 : , : ] ∗ 1 .0/ s q r t ( 2 . 0 ∗ N)
24
25 return vhat
26
27
28 def dct (v , a x i s=−1) :
29 ””” Implements the d i s c r e t e co s in e transform by computing a
f o u r i e r
30 transform o f an array o f l e n g t h 4N. ”””
31
32 N = v . shape [ a x i s ]
75
33 vp = numpy . z e r o s (4∗N)
34
35 s l i c e s = [ None ]∗2
36 s l i c e s [ 0 ] = s l i c e (1 ,2∗N+1 ,2)
37 s l i c e s [ 1 ] = s l i c e (4∗N+1,2∗N,−2)
38
39 vp [ s l i c e s [ 0 ] ] = v
40 vp [ s l i c e s [ 1 ] ] = v
41
42 vhat = numpy . f f t . r f f t ( vp )
43
44 return vhat [ : N]
45
46 def dct2 (v , axes =(−1 ,0) ) :
47 ””” Implements Matlab ’ s dct2 r o u t i n e . ”””
48
49 return matlab dct ( matlab dct (v , a x i s=axes [ 0 ] ) , a x i s=axes [ 1 ] )
50
51 def dct3 (v , axes =(−1,−2,0) ) :
52 ””” Implements Matlab ’ s dct3 r o u t i n e . ”””
53
54 return matlab dct ( matlab dct ( matlab dct ( v
55 , a x i s=axes [ 0 ] )
56 , a x i s=axes [ 1 ] )
57 , a x i s=axes [ 2 ] )
76
58
59 def mat lab idct (v , a x i s=−1) :
60 ”””
61 Implememnts the Matlab v e r s i o n o f i d c t , i . e . , i t uses
62 the b a s i s s c a l i n g s as in Matlab ’ s dc t / i d c t p a i r .
63 ”””
64
65 N = v . shape [ a x i s ]
66 v=v . copy ( )
67 i f a x i s == 0 :
68 v [ 0 , . . . ] = v [ 0 , . . . ] ∗ 2 .0∗ s q r t ( 1 . 0 /N)
69 v [ 1 : , . . . ] = v [ 1 : , . . . ] ∗ s q r t ( 2 . 0 /N)
70 e l i f a x i s == −2:
71 v [ . . . , 0 , : ] = v [ . . . , 0 , : ] ∗ 2 .0∗ s q r t ( 1 . 0 /N)
72 v [ . . . , 1 : , : ] = v [ . . . , 1 : , : ] ∗ s q r t ( 2 . 0 /N)
73 e l i f a x i s == −1:
74 v [ . . . , 0 ] = v [ . . . , 0 ] ∗ 2 .0∗ s q r t ( 1 . 0 /N)
75 v [ . . . , 1 : ] = v [ . . . , 1 : ] ∗ s q r t ( 2 . 0 /N)
76 return i d c t (v , a x i s ) / ( 2 . 0 / N)
77
78 def i d c t (v , a x i s=−1) :
79 ”””
80 Implements the i n v e r s e d i s c r e t e co s in e transform ,
81 with a s l i g h t l y nonstandard s c a l i n g .
82 ”””
77
83 p i = numpy . p i
84 n = len ( v . shape )
85 N = v . shape [ a x i s ]
86 even = (N%2 == 0)
87 s l i c e s = [ None ]∗4
88 for k in range (4 ) :
89 s l i c e s [ k ] = [ ]
90 for j in range (n) :
91 s l i c e s [ k ] . append ( s l i c e (None ) )
92 k = numpy . arange (N)
93 i f even :
94 ak = numpy . r [ 1 . 0 , [ 2 ] ∗ (N−1) ]∗numpy . exp (1 j ∗ pi ∗k/(2∗N) )
95 newshape = numpy . ones (n)
96 newshape [ a x i s ] = N
97 ak . shape = newshape
98 xhat = numpy . r e a l (numpy . f f t . i f f t ( v∗ak , a x i s=a x i s ) )
99 x = 0.0∗ v
100 s l i c e s [ 0 ] [ a x i s ] = s l i c e (None , None , 2 )
101 s l i c e s [ 1 ] [ a x i s ] = s l i c e (None ,N/2)
102 s l i c e s [ 2 ] [ a x i s ] = s l i c e (N, None ,−2)
103 s l i c e s [ 3 ] [ a x i s ] = s l i c e (N/2 ,None )
104 for k in range (4 ) :
105 s l i c e s [ k ] = tup l e ( s l i c e s [ k ] )
106 x [ s l i c e s [ 0 ] ] = xhat [ s l i c e s [ 1 ] ]
107 x [ s l i c e s [ 2 ] ] = xhat [ s l i c e s [ 3 ] ]
78
108 return x
109 else :
110 ak = 2∗numpy . exp (1 j ∗ pi ∗k/(2∗N) )
111 newshape = numpy . ones (n)
112 newshape [ a x i s ] = N
113 ak . shape = newshape
114 newshape = l i s t ( v . shape )
115 newshape [ a x i s ] = 2∗N
116 Y = numpy . z e r o s ( newshape , numpy . complex )
117 #Y[ :N] = ak∗v
118 #Y[ (N+1) : ] = conj (Y[N:0 : −1])
119 s l i c e s [ 0 ] [ a x i s ] = s l i c e (None ,N)
120 s l i c e s [ 1 ] [ a x i s ] = s l i c e (None , None )
121 s l i c e s [ 2 ] [ a x i s ] = s l i c e (N+1,None )
122 s l i c e s [ 3 ] [ a x i s ] = s l i c e ( (N−1) ,0 ,−1)
123 Y[ s l i c e s [ 0 ] ] = ak∗v
124 Y[ s l i c e s [ 2 ] ] = numpy . conj (Y[ s l i c e s [ 3 ] ] )
125 x = numpy . r e a l (numpy . f f t . i f f t (Y, a x i s=a x i s ) ) [ s l i c e s [ 0 ] ]
126 return x
127
128 def i d c t 2 (v , axes =(−1,−2) ) :
129 ”””
130 Matlab ’ s i d c t 2 r o u t i n e .
131 ”””
132 return mat lab idct ( mat lab idct (v , a x i s=axes [ 0 ] ) , a x i s=axes [ 1 ] )
79
133
134 def i d c t 3 (v , axes =(−1,−2,0) ) :
135 ””” Implements Matlab ’ s i d c t 3 r o u t i n e . ”””
136
137 return mat lab idct ( mat lab idct ( mat lab idct ( v
138 , a x i s=axes [ 0 ] )
139 , a x i s=axes [ 1 ] )
140 , a x i s=axes [ 2 ] )
141
142 def matlab dst (v , a x i s=−1) :
143 ””” Matlab ’ s d s t r o u t i n e . ”””
144 #TODO implement d s t
145 raise NotImplementedError ( )
146
147
148 def mat lab ids t (v , a x i s=−1) :
149 ””” Matlab ’ s i d s t r o u t i n e . ”””
150 #TODO implement i d s t
151 raise NotImplementedError ( )
152
153 def dst2 (v , axes =(−1,−2) ) :
154 ””” Matlab ’ s ds t 2 r o u t i n e . ”””
155 #TODO implement d s t2
156 raise NotImplementedError ( )
157
80
158 def i d s t 2 (v , axes =(−1,−2) ) :
159 ””” Matlab ’ s i d s t 2 r o u t i n e . ”””
160 #TODO implement i d s t 2
161 raise NotImplementedError ( )
B.1 Examples
B.1.1 CMWcheck.py
1 #!/ Users / matkins / b in / python
2 import numpy , u t i l
3
4 # Number o f cores to use
5 ncpus = 3
6
7 # Number o f parameter p o s s i b i l i t i e s t h i s t r a n s l a t e s to N ∗ 4 runs
, so be c a r e f u l
8 N = 3
9
10 # Amount o f time to run f o r .
11 time = 100000
12
13 # Amount o f p e r t u r b a t i o n away from the asymptot ic regime boundary
14 per turbat i on = .001
15
16 # Domain s i z e s
17 L = [ 4 ∗ numpy . pi ,
81
18 2 ∗ numpy . pi ,
19 numpy . p i
20 ]
21
22 # Base d i r e c t o r y to s t o r e the p l o t s in
23 baseDir = ’ / Users / matkins / s c ra t ch /CMWCheck ’
24
25 mu1 = numpy . random . uniform ( 0 , . 2 ,N)
26 mu2 = numpy . random . uniform ( 0 , . 6 ,N)
27
28 # Use the be low f u n c t i o n to g e t gamma from be t a and mu
29 f = lambda beta , mu : ( 2 . /\
30 (1 − 3∗(mu/ beta ) ∗∗2) ,
31 mu)
32
33 # Use the be low f u n c t i o n to g e t mu from be ta and gamma
34 #f = lambda beta , gamma : be ta ∗ numpy . s q r t ( 1 . / 3 . − 2 . / ( 3 .∗gamma)
)
35
36 # Lamellae c o n d i t i o n i s b e ta l e s s than the f o l l o w i n g
37 beta1 = ( 1 . / 2 9 . ) ∗ numpy . s q r t (551−174∗numpy . s q r t (6 ) )
38
39 # Hex−c i r c c o n d i t i o n i s be ta l e s s than the f o l l o w i n g
40 beta2 = 3∗numpy . s q r t ( 5 . / 3 7 . )
41
82
42 gammal = [ f ( beta1 − perturbat ion , m) for m in mu1 ]
43 print gammal
44 gammac = [ f ( beta1 + perturbat ion , m) for m in mu1]\
45 + [ f ( beta2 − perturbat ion , m) for m in mu2 ]
46 print gammac
47 gammad = [ f ( beta2 + perturbat ion , m) for m in mu2 ]
48
49 # In the CMW paper , sigma = 1
50 sigma = 1
51
52 def domSz(gamma) :
53 i f gamma < 10 :
54 return L [ 0 ]
55 e l i f gamma < 25 :
56 return L [ 1 ]
57 else :
58 return L [ 2 ]
59
60 parmsl = [ ( g∗∗2∗domSz( g ) ∗∗2 ,
61 m,
62 sigma∗domSz( g ) ∗∗2 ,
63 ( .1/(1+ g ∗∗1 . 5 ) ) /domSz( g ) ∗∗4/g ∗∗2 ,
64 time /domSz( g ) ∗∗4/g ∗∗2)
65 for ( g ,m) in gammal ]
66
83
67 parmsc = [ ( g∗∗2∗domSz( g ) ∗∗2 ,
68 m,
69 sigma∗domSz( g ) ∗∗2 ,
70 ( .1/(1+ g ∗∗1 . 5 ) ) /domSz( g ) ∗∗4/g ∗∗2 ,
71 time /domSz( g ) ∗∗4/g ∗∗2)
72 for ( g ,m) in gammac ]
73
74 parmsd = [ ( g∗∗2∗domSz( g ) ∗∗2 ,
75 m,
76 sigma∗domSz( g ) ∗∗2 ,
77 ( .1/(1+ g ∗∗1 . 5 ) ) /domSz( g ) ∗∗4/g ∗∗2 ,
78 time /domSz( g ) ∗∗4/g ∗∗2)
79 for ( g ,m) in gammad ]
80
81 mkrun = lambda parm : ( ’ s o l v e r ’ : ’ per2 ’ ,
82 ’BCs ’ : ’ per2 ’ ,
83 ’ lambd ’ : parm [ 0 ] ,
84 ’ sigma ’ : parm [ 2 ] ,
85 ’mu ’ : parm [ 1 ] ,
86 ’ numPlots ’ : 100 ,
87 ’ timeEnd ’ : parm [ 4 ] ,
88 ’ s t e p S i z e ’ : parm [ 3 ]
89 ,
90 1)
91
84
92 lamel laeRuns = [ mkrun(parm) for parm in parmsl ]
93 u t i l . runBui lder ( lamellaeRuns , baseDir+’ / l ame l l a e ’ , ncpus )
94
95 c i r cu la rRuns = [ mkrun(parm) for parm in parmsc ]
96 u t i l . runBui lder ( c i rcu larRuns , baseDir+’ / c i r c u l a r ’ , ncpus )
97
98 disorderRuns = [ mkrun(parm) for parm in parmsd ]
99 u t i l . runBui lder ( disorderRuns , baseDir+’ / d i s o r d e r ’ , ncpus )
B.1.2 dg.py
1 #!/ Users / matkins / b in / python
2
3 import u t i l
4
5 e p s i l o n = .03
6 mu = . 2
7 lambd = 2 / e p s i l o n ∗∗2
8 sigma = e p s i l o n ∗ 2∗∗11 ∗ (1 − mu∗∗2)∗∗−2
9
10 c o n d i t i o n s = [ [ ’mu ’ : mu,
11 ’ lambd ’ : lambd ,
12 ’ sigma ’ : sigma ,
13 ’BCs ’ : ’ per3 ’ ,
14 ’ s o l v e r ’ : ’ per3 ’ ,
15 ’ numPlots ’ : 10 ,
16 ’ timeEnd ’ : 1 ,
85
17 ’ cache ’ : ’ ’ ,
18 ’ s t e p S i z e ’ : 1e−5 ,
19 4 ] ]
20
21 u t i l . runBui lder ( cond i t i ons , baseDir=’ / Users / matkins / s c ra t ch / ra id /
dgc ’ )
86
Appendix C: Solvers
C.1 2D per.c
1 #include <s t d i o . h>
2 #include <math . h>
3 #include <complex . h>
4 #include <f f tw3 . h>
5 #include <time . h>
6 #include ”mt . h”
7
8 #define DEBUG (0)
9
10 #define NORMOUT (1)
11
12 #define N (40)
13 #define NH ( (N) / 2 + 1)
14 #define NLONG (3 ∗ N)
15 #define NLONGH ( (NLONG) / 2 + 1)
16
17 #define PI (3 .141592653589793)
18
19 #define sq ( x ) ( ( x ) ∗( x ) )
20 #define cu ( x ) ( ( x ) ∗ sq ( x ) )
21
22 #define coordh ( i , j ) ( ( j ) + NH ∗ ( i ) )
87
23 #define coordlongh ( i , j ) ( ( j ) + NLONGH ∗ ( i ) )
24 #define coord long ( i , j ) ( ( j ) + NLONG ∗ ( i ) )
25
26 void s c a l e ( f f tw complex ∗b , f f tw complex ∗bext )
27 //Copys data from the array the transform was c a l c u l a t e d on
and s c a l e s the
28 // data s i m u l t a n a e o u s l y .
29
30 register int i , j ;
31
32 for ( i =0; i<N/2 ; i++)
33 for ( j =0; j<NH−1; j++)
34 b [ coordh ( i , j ) ] = bext [ coordlongh ( i , j ) ] / sq (NLONG) ;
35 i f ( i != 0)
36 b [ coordh (N−i , j ) ] = bext [ coordlongh (NLONG−i , j ) ] /
sq (NLONG) ;
37
38
39
40
41
42 void pr int complex ( f f tw complex ∗a , int n , int nh)
43 // Pr in t s an n x nh array o f complex numbers to s t d o u t in a
way t h a t
44 // u t i l w i l l be a b l e to read
88
45 register int i , j ;
46
47 for ( i =0; i<n ; i++)
48 p r i n t f ( ” [ ” ) ;
49 for ( j =0; j<nh ; j++)
50 switch (nh)
51 case NH:
52 p r i n t f ( ”%l g%+l g j ” ,
53 c r e a l ( a [ coordh ( i , j ) ] ) ,
54 cimag ( a [ coordh ( i , j ) ] ) ) ;
55 break ;
56 case NLONGH:
57 p r i n t f ( ”%l g%+l g j ” ,
58 c r e a l ( a [ coordlongh ( i , j ) ] ) ,
59 cimag ( a [ coordlongh ( i , j ) ] ) ) ;
60 break ;
61
62 i f ( j < nh−1)
63 p r i n t f ( ” , ” ) ;
64
65
66 p r i n t f ( ” ]\n” ) ;
67
68
69
89
70 void pr in t doub l e (double ∗a , int n)
71 // Pr in t s an n x n array o f doub le to s t d o u t in a way t h a t
u t i l can
72 // d e c i p h e r .
73 register int i , j ;
74
75 for ( i =0; i<n ; i++)
76 p r i n t f ( ” [ ” ) ;
77 for ( j =0; j<n ; j++)
78 p r i n t f ( ”%l g ” , a [ coordlongh ( i , j ) ] ) ;
79 i f ( j < n−1)
80 p r i n t f ( ” , ” ) ;
81
82
83 p r i n t f ( ” ]\n” ) ;
84
85
86
87 double norm( f f tw complex ∗a )
88 // computes the two−norm in f o u r i e r space
89
90 register int i ;
91 double value ;
92
93 value = 0 . 0 ;
90
94 for ( i =0; i<N∗NH; i++)
95 value += (double ) ( a [ i ] ∗ conj ( a [ i ] ) ) ;
96
97 return s q r t ( va lue ) ;
98
99
100 void b update (double ∗u , double ∗ f , f f t w p l a n f f t , f f t w p l a n i f f t
)
101 // computes the non− l i n e a r i t y by computing the i f f t , computing
the
102 //non− l i n e a r i t y and computing the f f t o f t h a t .
103
104 register int i ;
105
106 f f t w e x e c u t e ( i f f t ) ;
107
108 for ( i =0; i<sq (NLONG) ; i++)
109 f [ i ] = u [ i ] − cu (u [ i ] ) ;
110
111
112 f f t w e x e c u t e ( f f t ) ;
113
114
115 void a copy ( f f tw complex ∗a , f f tw complex ∗ aext )
116
91
117 register int i , j ;
118
119 // Zero the array (FFTW w i l l d e s t r o y i t , so i t needs to be
re zero ed at
120 // everyt ime s t e p ) .
121 for ( i =0; i<NLONG∗NLONGH; i++)
122 aext [ i ] = 0 ;
123
124
125 // Copy the s m a l l e r array i n t o the padded one so t h a t
symmetry i s
126 // p r e s e r v e d .
127 for ( i =0; i<N/2 ; i++)
128 for ( j =0; j<NH−1; j++)
129 aext [ coordlongh ( i , j ) ] = a [ coordh ( i , j ) ] ;
130 i f ( i != 0)
131 aext [ coordlongh (NLONG−i , j ) ] = a [ coordh (N−i , j ) ] ;
132
133
134
135
136
137 main ( )
138
139 register int i , j , k ;
92
140 int i n i t i a l , numplots , p lo t s t ep , normstep ;
141 double ∗u , ∗ f , ∗kappa , ∗kappap , mu, sigma , lambda , tmp real ,
tmp imag ,
142 h , timeend ;
143 f f tw complex ∗a , ∗b , ∗aext , ∗bext ;
144 f f t w p l a n f f t , i f f t ;
145
146 kappa = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ N ∗ NH) ;
147 kappap= (double∗) f f t w m a l l o c ( s izeof (double ) ∗ N) ;
148 a = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ N
∗ NH) ;
149 b = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ N
∗ NH) ;
150 aext = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗
NLONG ∗ NLONGH) ;
151 bext = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗
NLONG ∗ NLONGH) ;
152 u = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ sq (NLONG) ) ;
153 f = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ sq (NLONG) ) ;
154
155 f f tw import system wisdom ( ) ;
156 f f t = f f t w p l a n d f t r 2 c 2 d (NLONG,NLONG, f , bext ,
FFTW EXHAUSTIVE) ;
157 i f f t = f f t w p l a n d f t c 2 r 2 d (NLONG,NLONG, aext , u ,
FFTW EXHAUSTIVE) ;
93
158
159 // Read c o e f f i c i e n t s and o th er parameters from s t d i n
160 scan f ( ”%l f %l f %l f %l f %l f %d” ,
161 &mu, &lambda , &sigma , &h , &timeend , &numplots ) ;
162 p l o t s t e p = ( int ) c e i l ( timeend / h / numplots ) ;
163 normstep = ( int ) c e i l ( timeend / h / ( numplots ∗10) ) ;
164
165
166 // See i f s t d i n t e l l s us to use an i n i t i a l c o n d i t i o n
167 // 0 means no , 1 means yes
168 scan f ( ”%d” , &i n i t i a l ) ;
169
170 // I n i t i a l i z t i o n o f e i g e n v a l u e array
171
172 for ( i =0; i<N/2 ; i++)
173 kappap [ i ] = 4 .0 ∗ sq ( i ) ∗ sq ( PI ) ;
174 kappap [ i+N/2 ] = 4 .0 ∗ sq (N/2− i ) ∗ sq ( PI ) ;
175
176
177 for ( i =0; i<N; i++)
178 for ( j =0; j<NH; j++)
179 kappa [ coordh ( i , j ) ] = kappap [ i ] + kappap [ j ] ;
180
181
182
94
183 i f ( i n i t i a l )
184 for ( i =0; i<N∗NH; i++)
185 scan f ( ”%l f %l f ” , &tmp real , &tmp imag ) ;
186 a [ i ] = tmp rea l + I ∗tmp imag ;
187
188
189
190 // Use random i n i t i a l c o n d i t i o n s o t h e r w i s e
191 else
192 // I n i t i a l i z a t i o n o f the c o e f f i c i e n t array
193 // ( f i r s t we need a seed )
194 i n i t g e n r a n d ( time (NULL) ) ;
195
196 // Random c o e f f i c i e n t s in r e a l space
197 for ( i =0; i<NLONG; i++)
198 for ( j =0; j<NLONG; j++)
199 f [ coord long ( i , j ) ] = genrand rea l c ( ) ;
200
201
202
203 f f t w e x e c u t e ( f f t ) ;
204
205 // Zero a b e f o r e copy
206 for ( i =0; i<N∗NH; i++)
207 a [ i ] = 0 . 0 ;
95
208
209
210 s c a l e ( a , bext ) ;
211 a [ 0 ] = mu;
212
213
214 // I n i t i a l i z e b to z e r o s
215 for ( i =0; i<N∗NH; i++)
216 b [ i ] = 0 . 0 ;
217
218
219 #i f DEBUG
220 p r i n t f ( ”a\n” ) ;
221 pr int complex ( a ,N,NH) ;
222
223 a copy (a , aext ) ;
224
225 p r i n t f ( ”\naext\n” ) ;
226 pr int complex ( aext ,NLONG,NLONGH) ;
227
228 f f t w e x e c u t e ( i f f t ) ;
229
230 // p r i n t d o u b l e (u ,NLONG) ;
231
232 for ( i =0; i<cu (NLONG) ; i++)
96
233 f [ i ] = u [ i ] ;
234
235
236 // p r i n t d o u b l e ( f ,NLONG) ;
237
238 f f t w e x e c u t e ( f f t ) ;
239
240 p r i n t f ( ”\nbext\n” ) ;
241 pr int complex ( bext ,NLONG,NLONGH) ;
242
243 s c a l e (b , bext ) ;
244
245 p r i n t f ( ”\nb\n” ) ; pr int complex (b ,N,NH) ;
246
247 int works = 1 ;
248 for ( i =0; i<N; i++)
249 for ( j =0; j<NH; j++)
250 i f ( ( double ) ( ( a [ coordh ( i , j ) ]−b [ coordh ( i , j ) ] )
251 ∗ conj ( a [ coordh ( i , j ) ]−b [ coordh ( i , j ) ] ) )
252 > 1e−16)
253 works = 0 ;
254 p r i n t f ( ”\nTransform not i n v e r t i b l e , at (%d,%d) ,\
255 %l f%+l f i != %l f%+l f i \n” ,
256 i , j ,
97
257 c r e a l ( a [ coordh ( i , j ) ] ) , cimag ( a [ coordh ( i , j )
] ) ,
258 c r e a l (b [ coordh ( i , j ) ] ) , cimag (b [ coordh ( i , j )
] ) ) ;
259
260
261
262 i f ( works )
263 p r i n t f ( ”\nTransform i s i n v e r t i b l e !\n” ) ;
264
265
266 #else
267 for ( k=0;k∗h<timeend ; k++)
268
269 i f ( k % p l o t s t e p == 0)
270 p r i n t f ( ” begin p l o t \n” ) ;
271 p r i n t f ( ” time %l g \n” , k∗h) ;
272 pr int complex ( a ,N,NH) ;
273 p r i n t f ( ”end p lo t \n” ) ;
274
275 #i f NORMOUT
276 i f ( k % normstep == 0)
277 p r i n t f ( ”norm %l g \n” ,norm( a ) ) ;
278
279 #endif
98
280 a copy (a , aext ) ;
281 b update (u , f , f f t , i f f t ) ;
282 s c a l e (b , bext ) ;
283
284 for ( i =0; i<N; i++)
285 for ( j =0; j<NH−1; j++)
286 i f ( ! ( i == N/2 && N%2 == 0) && ! ( i == 0 && j ==
0) )
287 a [ coordh ( i , j ) ] = ( a [ coordh ( i , j ) ]
288 + h ∗ lambda ∗ b [ coordh ( i , j ) ] ∗ kappa [
coordh ( i , j ) ] )
289 / (1 + h ∗ sq ( kappa [ coordh ( i , j ) ] ) + h ∗
lambda ∗ sigma ) ;
290
291
292
293
294 p r i n t f ( ” begin p l o t \n” ) ;
295 p r i n t f ( ” time %l f \n” , timeend ) ;
296 pr int complex ( a ,N,NH) ;
297 p r i n t f ( ”end p lo t \n” ) ;
298 #endif
299
C.2 3D per.c
99
1 #include <s t d i o . h>
2 #include <math . h>
3 #include <complex . h>
4 #include <f f tw3 . h>
5 #include <time . h>
6 #include ”mt . h”
7
8 #define DEBUG (0)
9
10 #define NORMOUT (1)
11
12 #define N (64)
13 #define NH ( (N) / 2 + 1)
14 #define NLONG (128)
15 #define NLONGH ( (NLONG) / 2 + 1)
16
17 #define PI (3 .141592653589793)
18
19 #define sq ( x ) ( ( x ) ∗( x ) )
20 #define cu ( x ) ( ( x ) ∗ sq ( x ) )
21
22 #define coordh ( i , j , k ) ( ( k ) + NH ∗ ( ( j ) + N ∗ ( i ) ) )
23 #define coordlongh ( i , j , k ) ( ( k ) + NLONGH ∗ ( ( j ) + NLONG ∗ ( i ) ) )
24 #define coord long ( i , j , k ) ( ( k ) + NLONG ∗ ( ( j ) + NLONG ∗ ( i ) ) )
25
100
26 void s c a l e ( f f tw complex ∗b , f f tw complex ∗bext )
27 //Copys data from the array the transform was c a l c u l a t e d on
and s c a l e s the
28 // data s i m u l t a n a e o u s l y .
29 register int i , j , k ;
30
31 for ( i =0; i<N/2 ; i++)
32 for ( j =0; j<N/2 ; j++)
33 for ( k=0;k<NH−1;k++)
34 b [ coordh ( i , j , k ) ] = bext [ coordlongh ( i , j , k ) ]
35 / cu (NLONG) ;
36 i f ( i != 0)
37 b [ coordh (N−i , j , k ) ] = bext [ coordlongh (NLONG−i ,
j , k ) ]
38 / cu (NLONG) ;
39
40 i f ( j != 0)
41 b [ coordh ( i ,N−j , k ) ] = bext [ coordlongh ( i ,NLONG−
j , k ) ]
42 / cu (NLONG) ;
43
44 i f ( i != 0 && j != 0)
45 b [ coordh (N−i ,N−j , k ) ] = bext [ coordlongh (NLONG−
i ,NLONG−j , k ) ]
46 / cu (NLONG) ;
101
47
48
49
50
51
52
53 void pr int complex ( f f tw complex ∗a , int n , int nh)
54 // Pr in t s an n x n x nh array o f complex numbers to s t d o u t in
a way t h a t
55 // u t i l w i l l be a b l e to read
56 register int i , j , k ;
57
58 for ( i =0; i<n ; i++)
59 p r i n t f ( ” [ ” ) ;
60 for ( j =0; j<n ; j++)
61 p r i n t f ( ” [ ” ) ;
62 for ( k=0;k<nh ; k++)
63 switch (nh)
64 case NH:
65 p r i n t f ( ”%l g%+l g j ” ,
66 c r e a l ( a [ coordh ( i , j , k ) ] ) ,
67 cimag ( a [ coordh ( i , j , k ) ] ) ) ;
68 break ;
69 case NLONGH:
70 p r i n t f ( ”%l g%+l g j ” ,
102
71 c r e a l ( a [ coordlongh ( i , j , k ) ] ) ,
72 cimag ( a [ coordlongh ( i , j , k ) ] ) ) ;
73 break ;
74
75 i f ( k < nh−1)
76 p r i n t f ( ” , ” ) ;
77
78
79 p r i n t f ( ” ] ” ) ;
80 i f ( j < n−1)
81 p r i n t f ( ” , ” ) ;
82
83
84 p r i n t f ( ” ]\n” ) ;
85
86
87
88 void pr in t doub l e (double ∗a , int n)
89 // Pr in t s an n x n x n array o f doub le to s t d o u t in a way t h a t
u t i l can
90 // d e c i p h e r .
91 register int i , j , k ;
92
93 for ( i =0; i<n ; i++)
94 p r i n t f ( ” [ ” ) ;
103
95 for ( j =0; j<n ; j++)
96 p r i n t f ( ” [ ” ) ;
97 for ( k=0;k<n ; k++)
98 p r i n t f ( ”%l g ” , a [ coordlongh ( i , j , k ) ] ) ;
99 i f ( k < n−1)
100 p r i n t f ( ” , ” ) ;
101
102
103 p r i n t f ( ” ] ” ) ;
104 i f ( j < n−1)
105 p r i n t f ( ” , ” ) ;
106
107
108 p r i n t f ( ” ]\n” ) ;
109
110
111
112 double norm( f f tw complex ∗a )
113 // computes the two−norm in f o u r i e r space
114
115 register int i ;
116 double value ;
117
118 value = 0 . 0 ;
119 for ( i =0; i<sq (N) ∗NH; i++)
104
120 value += (double ) ( a [ i ] ∗ conj ( a [ i ] ) ) ;
121
122 return s q r t ( va lue ) ;
123
124
125 void b update (double ∗u , double ∗ f , f f t w p l a n f f t , f f t w p l a n i f f t
)
126 // computes the non− l i n e a r i t y by computing the i f f t , computing
the
127 //non− l i n e a r i t y and computing the f f t o f t h a t .
128
129 register int i ;
130
131 f f t w e x e c u t e ( i f f t ) ;
132
133 for ( i =0; i<cu (NLONG) ; i++)
134 f [ i ] = u [ i ] − cu (u [ i ] ) ;
135
136
137 f f t w e x e c u t e ( f f t ) ;
138
139
140 void a copy ( f f tw complex ∗a , f f tw complex ∗ aext )
141
142 register int i , j , k ;
105
143
144 // Zero the array (FFTW w i l l d e s t r o y i t , so i t needs to be
re zero ed at
145 // everyt ime s t e p ) .
146 for ( i =0; i<sq (NLONG) ∗NLONGH; i++)
147 aext [ i ] = 0 ;
148
149
150 // Copy the s m a l l e r array i n t o the padded one so t h a t
symmetry i s
151 // p r e s e r v e d .
152 for ( i =0; i<N/2 ; i++)
153 for ( j =0; j<N/2 ; j++)
154 for ( k=0;k<NH−1;k++)
155 aext [ coordlongh ( i , j , k ) ] = a [ coordh ( i , j , k ) ] ;
156 i f ( i != 0)
157 aext [ coordlongh (NLONG−i , j , k ) ] = a [ coordh (N−i ,
j , k ) ] ;
158
159 i f ( j != 0)
160 aext [ coordlongh ( i ,NLONG−j , k ) ] = a [ coordh ( i ,N−
j , k ) ] ;
161
162 i f ( i != 0 && j != 0)
106
163 aext [ coordlongh (NLONG−i ,NLONG−j , k ) ] = a [
coordh (N−i ,N−j , k ) ] ;
164
165
166
167
168
169
170 main ( )
171
172 register int i , j , k , l ;
173 int i n i t i a l , numplots , p lo t s t ep , normstep ;
174 double ∗u , ∗ f , ∗kappa , ∗kappap , mu, sigma , lambda , tmp real ,
tmp imag ,
175 h , timeend ;
176 f f tw complex ∗a , ∗b , ∗aext , ∗bext ;
177 f f t w p l a n f f t , i f f t ;
178
179 kappa = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ sq (N) ∗ NH) ;
180 kappap= (double∗) f f t w m a l l o c ( s izeof (double ) ∗ N) ;
181 a = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ sq
(N) ∗ NH) ;
182 b = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ sq
(N) ∗ NH) ;
107
183 aext = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ sq
(NLONG) ∗ NLONGH) ;
184 bext = ( f f tw complex ∗) f f t w m a l l o c ( s izeof ( f f tw complex ) ∗ sq
(NLONG) ∗ NLONGH) ;
185 u = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ cu (NLONG) ) ;
186 f = (double∗) f f t w m a l l o c ( s izeof (double ) ∗ cu (NLONG) ) ;
187
188 f f tw import system wisdom ( ) ;
189 f f t = f f t w p l a n d f t r 2 c 3 d (NLONG,NLONG,NLONG, f , bext ,
FFTW EXHAUSTIVE) ;
190 i f f t = f f t w p l a n d f t c 2 r 3 d (NLONG,NLONG,NLONG, aext , u ,
FFTW EXHAUSTIVE) ;
191
192 // Read c o e f f i c i e n t s from s t d i n
193 scan f ( ”%l f %l f %l f %l f %l f %d” ,
194 &mu, &lambda , &sigma , &h , &timeend , &numplots ) ;
195 p l o t s t e p = ( int ) c e i l ( timeend / h / numplots ) ;
196 normstep = ( int ) c e i l ( timeend / h / ( numplots ∗10) ) ;
197
198 // See i f s t d i n t e l l s us to use an i n i t i a l c o n d i t i o n
199 // 0 means no , 1 means yes
200 scan f ( ”%d” , &i n i t i a l ) ;
201
202 // I n i t i a l i z t i o n o f e i g e n v a l u e array
203
108
204 for ( i =0; i<N/2 ; i++)
205 kappap [ i ] = 4 .0 ∗ sq ( i ) ∗ sq ( PI ) ;
206 kappap [ i+N/2 ] = 4 .0 ∗ sq (N/2− i ) ∗ sq ( PI ) ;
207
208
209 for ( i =0; i<N; i++)
210 for ( j =0; j<N; j++)
211 for ( k=0;k<NH; k++)
212 kappa [ coordh ( i , j , k ) ] = kappap [ i ] + kappap [ j ] +
kappap [ k ] ;
213
214
215
216
217 i f ( i n i t i a l )
218 for ( i =0; i<sq (N) ∗NH; i++)
219 scan f ( ”%l f %l f ” , &tmp real , &tmp imag ) ;
220 a [ i ] = tmp rea l + I ∗tmp imag ;
221
222
223
224 // Use random i n i t i a l c o n d i t i o n s o t h e r w i s e
225 else
226 // I n i t i a l i z a t i o n o f the c o e f f i c i e n t array
227 // ( f i r s t we need a seed )
109
228 i n i t g e n r a n d ( time (NULL) ) ;
229
230 // Random c o e f f i c i e n t s in r e a l space
231 for ( i =0; i<NLONG; i++)
232 for ( j =0; j<NLONG; j++)
233 for ( k=0;k<NLONG; k++)
234 f [ coord long ( i , j , k ) ] = . 1 ∗ genrand rea l c ( ) ;
235
236
237
238
239 f f t w e x e c u t e ( f f t ) ;
240
241 // Zero a b e f o r e copy
242 for ( i =0; i<sq (N) ∗NH; i++)
243 a [ i ] = 0 . 0 ;
244
245
246 s c a l e ( a , bext ) ;
247 a [ 0 ] = mu;
248
249
250 // I n i t i a l i z e b to z e r o s
251 for ( i =0; i<sq (N) ∗NH; i++)
252 b [ i ] = 0 . 0 ;
110
253
254
255 #i f DEBUG
256 p r i n t f ( ”a\n” ) ;
257 pr int complex ( a ,N,NH) ;
258
259 a copy (a , aext ) ;
260
261 p r i n t f ( ”\naext\n” ) ;
262 pr int complex ( aext ,NLONG,NLONGH) ;
263
264 f f t w e x e c u t e ( i f f t ) ;
265
266 // p r i n t d o u b l e (u ,NLONG) ;
267
268 for ( i =0; i<cu (NLONG) ; i++)
269 f [ i ] = u [ i ] ;
270
271
272 // p r i n t d o u b l e ( f ,NLONG) ;
273
274 f f t w e x e c u t e ( f f t ) ;
275
276 p r i n t f ( ”\nbext\n” ) ;
277 pr int complex ( bext ,NLONG,NLONGH) ;
111
278
279 s c a l e (b , bext ) ;
280
281 p r i n t f ( ”\nb\n” ) ; pr int complex (b ,N,NH) ;
282
283 int works = 1 ;
284 for ( i =0; i<N; i++)
285 for ( j =0; j<N; j++)
286 for ( k=0;k<NH; k++)
287 i f ( ( double ) ( ( a [ coordh ( i , j , k ) ]−b [ coordh ( i , j , k ) ] )
288 ∗ conj ( a [ coordh ( i , j , k ) ]−b [ coordh ( i , j ,
k ) ] ) )
289 > 1e−16)
290 works = 0 ;
291 p r i n t f ( ”\nTransform not i n v e r t i b l e , at (%d,%d
,%d) ,\
292 %l f%+l f i != %l f%+l f i \n” ,
293 i , j , k ,
294 c r e a l ( a [ coordh ( i , j , k ) ] ) , cimag ( a [ coordh
( i , j , k ) ] ) ,
295 c r e a l (b [ coordh ( i , j , k ) ] ) , cimag (b [ coordh
( i , j , k ) ] ) ) ;
296
297
298
112
299
300 i f ( works )
301 p r i n t f ( ”\nTransform i s i n v e r t i b l e !\n” ) ;
302
303
304 #else
305 for ( l =0; l ∗h<timeend ; l++)
306
307 i f ( l % p l o t s t e p == 0)
308 p r i n t f ( ” begin p l o t \n” ) ;
309 p r i n t f ( ” time %l g \n” , l ∗h) ;
310 pr int complex ( a ,N,NH) ;
311 p r i n t f ( ”end p lo t \n” ) ;
312
313 #i f NORMOUT
314 i f ( l % normstep == 0)
315 p r i n t f ( ”norm %l g \n” ,norm( a ) ) ;
316
317 #endif
318 a copy (a , aext ) ;
319 b update (u , f , f f t , i f f t ) ;
320 s c a l e (b , bext ) ;
321
322 for ( i =0; i<N; i++)
323 for ( j =0; j<N; j++)
113
324 for ( k=0;k<NH−1;k++)
325 i f ( (N%2 != 0 | | ( i != N/2 && j != N/2) ) &&
326 ! ( i == 0 && j == 0 && k == 0) )
327 a [ coordh ( i , j , k ) ] = ( a [ coordh ( i , j , k ) ]
328 + h ∗ lambda ∗ b [ coordh ( i , j , k ) ] ∗
kappa [ coordh ( i , j , k ) ] )
329 / (1 + h ∗ sq ( kappa [ coordh ( i , j , k ) ] ) +
h ∗ sigma ∗ lambda ) ;
330
331
332
333
334
335 p r i n t f ( ” begin p l o t \n” ) ;
336 p r i n t f ( ” time %l f \n” , timeend ) ;
337 pr int complex ( a ,N,NH) ;
338 p r i n t f ( ”end p lo t \n” ) ;
339 #endif
340
114
Bibliography
[1] Frank S. Bates and Glenn H. Fredrickson. Block copolymer thermodynamics: Theoryand experiment. Annu. Rev. Phys. Chem., 41:525–57, 1990.
[2] Rustum Choksi, Mirjana Maras, and J. F. Williams. 2d phase diagram for minimzersof a nonlocal cahn-hilliard functional. SIAM J. Appl. Dynamical Systems, 2010.
[3] Rustum Choksi, Mark A. Peletier, and J. F. Williams. On the phase diagram for mi-crophase separation of diblock copolymers: An approach via a nonlocal Cahn-Hilliardfunctional. SIAM J. Appl. Math., 69(6):1712–1738, 2009.
[4] Lawrence C. Evans. Partial Differential Equations. American Mathematical Society,1998.
[5] Paul C. Fife. Models for phase separation and their mathematics. Electronic Journalof Differential Equations, 2000(48):1–26, 2000.
[6] Matteo Frigo and Steven G. Johnson. The Design and Implementation of FFTW3,2005.
[7] Arieh Iserles. A First Course in the Numerical Analysis of Differential Equations.Cambridge University Press, 2 edition, 2009.
[8] Michael Droettboom John Hunter, Darren Dale. matplotlib User’s Guide.
[9] A.N. Kolmogorov and S.V. Fomin. Introductory Real Analysis. Dover, 1975.
[10] M. Matsumoto and T. Nishimura. Mersenne twister: A 623-dimensionally equidis-tributed uniform pseudorandom number generator. ACM Trans. on Modeling andComputer Simulation, 8(1):3–30, 1998.
[11] Takao Ohta and Kyozi Kawasaki. Equilibrium morphology of block copolymer melts.Macromolecules, 19(10):2621–2632, 1986.
[12] Pearu Peterson. PyVTK – Tools for manipulating VTK files in Python.
[13] Python Software Foundation. Python v2.7.1 documentation.
[14] Takashi Teramoto and Yasumasa Nishiura. Double gyroid morphology in a gradientsystem with nonlocal effects. Journal of the Physical Society of Japan, 71(7):1611–1614,2002.
[15] Takashi Teramoto and Yasumasa Nishiura. Double gyroid morphology of the diblockcopolymer problem. RIMS Kokyuroku, 1356:116–121, 2004.
116
Curriculum Vitae
Michael Atkins graduated from McLean High School, McLean, Virginia in 2006. He receivedhis Bachelor of Science in Mathematics from George Mason University in 2010. During thistime, he was employed by the Department of State as a Computer technician and theNational Institute of Standards and Technology as a researcher.
117