Long Term Dynamics of the Di-Block Copolymer Model on ...

127

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

Copyright c© 2011 by Michael R. AtkinsAll Rights Reserved

ii

Dedication

This thesis is dedicated to the memory of Ann Atkins.

iii

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

Figure 3.4: Hexagonally packed circles in the 2D case.

31

Figure 3.5: Lamellae in the 2D case.

32

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

115

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