Download A program for calculating photonic band structures, Green`s

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Superconductivity wikipedia , lookup

Magnetohydrodynamics wikipedia , lookup

Magnetochemistry wikipedia , lookup

Multiferroics wikipedia , lookup

Magnetoreception wikipedia , lookup

Dielectric wikipedia , lookup

Scanning SQUID microscope wikipedia , lookup

Lorentz force wikipedia , lookup

Electromagnetism wikipedia , lookup

Maxwell's equations wikipedia , lookup

Galvanometer wikipedia , lookup

Immunity-aware programming wikipedia , lookup

Computational electromagnetics wikipedia , lookup

Mathematics of radio engineering wikipedia , lookup

Transcript
Computer Physics Communications 128 (2000) 590–621
www.elsevier.nl/locate/cpc
A program for calculating photonic band structures,
Green’s functions and transmission/reflection coefficients
using a non-orthogonal FDTD method
A.J. Ward 1 , J.B. Pendry ∗
Condensed Matter Theory Group, The Blackett Laboratory, Imperial College, Prince Consort Road, London, SW7 2BZ, UK
Received 31 August 1999
Abstract
In this paper we present an updated version of our ONYX program for calculating photonic band structures using a nonorthogonal finite difference time domain method. This new version employs the same transparent formalism as the first
version with the same capabilities for calculating photonic band structures or causal Green’s functions but also includes extra
subroutines for the calculation of transmission and reflection coefficients. Both the electric and magnetic fields are placed onto
a discrete lattice by approximating the spacial and temporal derivatives with finite differences. This results in discrete versions
of Maxwell’s equations which can be used to integrate the fields forwards in time. The time required for a calculation using
this method scales linearly with the number of real space points used in the discretization so the technique is ideally suited to
handling systems with large and complicated unit cells.  2000 Elsevier Science B.V. All rights reserved.
PACS: 42.70Qs; 02.70.Bf; 02.70.-c
PROGRAM SUMMARY
Catalogue identifier for previous version: ADIJ
Authors of previous version: A.J. Ward, J.B. Pendry
Title of program: ONYX; Version 2.1
Catalogue identifier: ADLU
Program Summary URL: http://cpc.cs.qub.ac.uk/summaries/ADLU
Program obtainable from: CPC Program Library, Queen’s University of Belfast, N. Ireland
Reference in CPC to previous version: 112 (1998) 23–41
Does the new version supersede the original program?: Yes
Computers for which the new version is designed and others on
which it has been tested: Digital Alpha 250
Operating Systems or monitors under which the new version has
been tested: Digital UNIX V3.2D-1 (Rev. 41)
Programming language of new version: Fortran 90
Memory required to execute with typical data: 23 MB
∗ Corresponding author; E-mail: [email protected].
1 Current address: Marconi Materials Technology, Caswell, Towcester, Northants.
0010-4655/00/$ – see front matter  2000 Elsevier Science B.V. All rights reserved.
PII: S 0 0 1 0 - 4 6 5 5 ( 9 9 ) 0 0 5 4 3 - 3
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
No. of bits in a word: 32
No. of processors used: 1
Has the code been vectorized or parallelized?: No
No. of bytes in distributed program, including test data, etc.:
375 166 bytes
Distribution format: uuencoded compressed tar file
Keywords: Discretized Maxwell’s equations, Order(N ) method, finite difference time domain (FDTD) method, photonic band structure, Green’s function, density of states, transmission and reflection
coefficients
Nature of physical problem
Efficient calculation of either photonic dispersion relationships,
Green’s functions or transmission and reflection coefficients for
photons in complex dielectric structures.
Method of solution
A discretization of Maxwell’s equations in both the space and time
domains which leads to finite difference equations connecting the
electric and magnetic fields at one time step to those at the next.
591
After using these equations to find the response in the time domain
to a particular initial set of fields, we perform a Fourier transform
to obtain the response in the frequency domain. From this we can
easily extract dispersion relationship information, or alternatively,
by setting the initial fields to be a delta function, we can obtain the
Green’s function for the system under consideration. In addition, by
projecting onto a complete basis set of plane waves we can find the
transmission and reflection matrices for the scattering system.
Restrictions on complexity of the problem
The complexity of the dielectric structure that the method can be
applied to is limited only the computer time and memory available.
Both time and memory requirements scale linearly with the system
size. One restriction on the method is that the dielectric permittivity
and magnetic permeability must both be independent of frequency.
This means it cannot treat some problems, typically those involving
metals.
Typical running time
Highly dependent on the system under consideration. For the test
transmission calculation given, 120 seconds on a Digital Alpha 250
workstation.
Unusual features of the program
Option to work with non-orthogonal co-ordinate systems.
1. Introduction
Over recent years the interest in using artificially structured dielectrics, or photonic crystals, to radically
manipulate the optical properties of materials has continued and expanded. In order to keep pace, theorists have
developed tools of increasing sophistication to model and predict the behaviour of these artificial dielectrics. The
simplest method involves expanding the electric and magnetic fields in terms of a basis set of plane waves [1–3].
This allows Maxwell’s equations to be recast in the form of an eigenvalue problem, the eigenvalues corresponding
to the allowed frequencies of modes which can propagate in the system. Though simple to implement and use, this
method has the draw back that the time taken for the calculation scales as the cube of the number of plane waves
used and so rapidly becomes impractical as the complexity of the problem increases.
The second method to be developed involves not expanding the wavefield as a sum of plane waves in reciprocal
space, but rather expanding the fields on a discrete real-space lattice [4,5]. The resulting equations can be rearranged
into the form of a transfer matrix which relates the fields in one layer of the lattice to the fields in the next. This
method is far more efficient and calculations based on this method scale not as the cube of the number of real space
points, but rather as the square. Moreover, this method is also able to calculate the transmission and reflection
coefficients of a scatterer.
The optimum scaling, however, is a linear scaling with the system size. It is possible to achieve this by
discretizing Maxwell’s equations not only in spatially but also in the time domain. This technique is known as
either the finite difference time domain method (FDTD) [6] or the Order(N ) method [7] The details of this method
will be considered in the next section, and will formed the basis for our ONYX computer program [8].
In this new version of the ONYX program [9] we have extended its capabilities in an important way by adding
the necessary subroutines for performing in calculation of the transmission and reflection coefficients of a given
scattering structure. This type of calculation would normally be performed using a transfer matrix technique (our
program PHOTON, for example, [10]) but now can be performed with the advantageous linear scaling that the
592
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Order(N ) method gives. These transmission and reflection calculations are, in practice, often very important as
they are most closely related to the quantities measured in an experiment.
2. Background theory
2.1. Deriving the discrete Maxwell’s equations
We wish to derive discrete versions of Maxwell’s equations which can be used as the basis for a finite difference
time domain calculation of a form similar to that of Yee [6]. This derivation is exactly the same as was given in detail
in our previous paper [9] so here we shall simply reproduce the central results. We start from Maxwell’s equations
and after replacing the frequency ω and wavevector k by approximations we rearrange and use the generalized
co-ordinate transformation which we have previously derived [11]. This results in the discrete equations which we
require.
0
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b1 (r, t) + ε̂ −1 (r) 11 H
b3 (r, t) − H
b1 (r, t + δt) = 1 − σ̂ E
E
12 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
H
+ ε̂ −1 (r)
13 0
b20 (r − a, t) − H
b10 (r, t) + H
b10 (r − b, t) ,
b2 (r, t) − H
(1)
H
+ ε̂ −1 (r)
−1 21 0
b2 (r, t) + ε̂ (r)
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b3 (r, t) − H
b2 (r, t + δt) = 1 − σ̂ E
H
E
22 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
H
+ ε̂ −1 (r)
23 0
b20 (r − a, t) − H
b10 (r, t) + H
b10 (r − b, t) ,
b2 (r, t) − H
(2)
H
+ ε̂ −1 (r)
−1 31 0
b3 (r, t) + ε̂ (r)
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b3 (r, t) − H
b3 (r, t + δt) = 1 − σ̂ E
H
E
−1 32 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
H
+ ε̂ (r)
33 0
b20 (r − a, t) − H
b10 (r, t) + H
b10 (r − b, t) ,
b2 (r, t) − H
(3)
H
+ ε̂ −1 (r)
b10 (r, t + δt) = 1 + σ̂m −1 H
b10 (r, t)
H
−
−
δt c0
Q0
δt c0
Q0
2
2
µ̂ −1 (r)
11 b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
b3 (r + b, t) − E
E
µ̂ −1 (r)
12 b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
b1 (r + c, t) − E
E
δt c0 2 −1 13 b
b
b
b
µ̂ (r)
E2 (r + a, t) − E2 (r, t) − E1 (r + b, t) + E1 (r, t) ,
−
Q0
b20 (r, t)
b20 (r, t + δt) = 1 + σ̂m −1 H
H
−
−
−
δt c0
Q0
δt c0
Q0
δt c0
Q0
2
2
2
µ̂ −1 (r)
21 b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
b3 (r + b, t) − E
E
µ̂ −1 (r)
22 b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
b1 (r + c, t) − E
E
µ̂ −1 (r)
23 b2 (r, t) − E
b1 (r + b, t) + E
b1 (r, t) ,
b2 (r + a, t) − E
E
(4)
(5)
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
593
b30 (r, t + δt) = 1 + σ̂m −1 H
b30 (r, t)t
H
−
−
−
δt c0
Q0
δt c0
Q0
δt c0
Q0
2
2
2
µ̂ −1 (r)
31 b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
b3 (r + b, t) − E
E
µ̂ −1 (r)
32 b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
b1 (r + c, t) − E
E
µ̂
−1
33 b
b
b
b
(r)
E2 (r + a, t) − E2 (r, t) − E1 (r + b, t) + E1 (r, t) ,
(6)
where the effective permittivity ε̂ and permeability µ̂ are tensors of the following form,
Q1 Q2 Q3
,
Qi Qj Q0
Q1 Q2 Q3
.
µ̂ ij (r) = µ(r)g ij |u1 · u2 × u3 |
Qi Qj Q0
ε̂ ij (r) = ε(r)g ij |u1 · u2 × u3 |
(7)
(8)
In addition the electrical conductivity, and a fictitious magnetic conductivity, are defined as follows,
Q1 Q2 Q3
,
Qi Qj Q0
Q1 Q2 Q3
,
σ̂m ij (r) = σm (r)g ij |u1 · u2 × u3 |
Qi Qj Q0
σ̂ ij (r) = σ (r)g ij |u1 · u2 × u3 |
where,
Qi =
s
∂x
∂qi
2
+
∂y
∂qi
2
+
∂z
∂qi
(9)
2
(10)
and the vectors ui are unit vectors pointing along the axes of the generalized co-ordinate system. The constant
Q0 is arbitrary and is usually defined to be Q0 = Q3 . The electric and magnetic fields have been renormalized as
follows,
bi = Qi Hi ,
bi = Qi Ei ,
H
(11)
E
δt
b
b0 =
H.
(12)
H
ε0 Q0
Together these are the update equations for the fields that we require. They give a stable updating procedure for the
fields if the time step is kept sufficiently small. The criterion is,
2
c0
c02
c02 −1
+
+
.
(13)
(δt)2 <
Q21 Q22 Q23
2.2. The real-space, discrete frequency transfer matrix
The transfer matrix [4,5] is an operator which given the electric and magnetic fields in one layer of a discrete
lattice allows us to find the fields in the adjacent layer. It is normally defined on a lattice which is discrete in space
but continuous in the frequency domain, that is to say no approximations are made to the frequency ω. However,
for our purposes it is useful to re-derive the transfer matrix for the finite difference time-domain case where the
frequency ω is also discrete. This is simply achieved by replacing the frequency ω in Maxwell’s equations with the
relevant approximations and then deriving the transfer matrix as before. Note that we will only be concerned with
the transfer matrix in a uniform dielectric with dielectric constant εr .
594
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
We begin, as usual, from Maxwell’s equations,
k × E = +µ0 ωH;
k × H = −ε0 εr ωE;
(14)
then we make approximations for k and ω.
k+ × E = +µ0 ω− H;
k− × H = −ε0 εr ω+ E;
(15)
where, as before, for the electric field terms,
kj 7→ kj+ =
exp [ikj Qj ] − 1
;
iQj
ω 7→ ω+ =
exp [−iωδt] − 1
.
−iδt
(16)
1 − exp [iωδt]
.
−iδt
(17)
And for the magnetic field terms,
kj 7→ kj− =
1 − exp [−ikj Qj ]
;
iQj
ω 7→ ω− =
Next we rescale the magnetic field,
H0 =
δt
H;
ε0 Q0
(18)
so that,
k+ × E = +
Q0
c02 δt
ω − H0 ;
k− × H0 = −
δtεr +
ω E.
Q0
(19)
If we now write out component by component,
Q0 −ky− Hx0 + kx− Hy0 ;
+
δt εr ω
Q0
kz+ Ex = kx+ Ez + 2 ω− Hy0 ;
c0 δt
Q0
kz+ Ey = ky+ Ez − 2 ω− Hx0 ;
c0 δt
Ez = −
c02 δt −ky+ Ex + kx+ Ey ;
−
Q0 ω
δt εr +
kz− Hx0 = kx− Hz0 −
ω Ey ;
Q0
Hz0 =
kz− Hy0 = ky− Hz0 +
δt εr +
ω Ex .
Q0
We eliminate the z-components to leave us with a set of four equations,
Q0
Q0 +
+
− 0
− 0
−ky Hx + kx Hy + 2 ω− Hy0 ,
k z Ex = k x −
δt εr ω+
c0 δt
Q
Q0
0
−ky− Hx0 + kx− Hy0 − 2 ω− Hx0 ,
kz+ Ey = ky+ −
+
δt εr ω
c0 δt
2
c0 δt δt εr +
ω Ey ,
−ky+ Ex + kx+ Ey −
kz− Hx0 = kx−
−
Q0 ω
Q0
2
c0 δt δt εr +
+
+
E
+
k
E
ω Ex .
−k
+
kz− Hy0 = ky−
y x
x y
Q0 ω−
Q0
(20)
(21)
(22)
(23)
(24)
(25)
(26)
Expanding the brackets and simplifying gives,
Ex (kk , z + c, ω) = Ex (kk , z, ω)
iQ20
iQ20
iQ20 ω−
+ −
0
+ −
k k Hx (kk , z, ω) −
k k − 2
Hy0 (kk , z, ω),
+
δt εr ω+ x y
δt εr ω+ x x
c0 δt
(27)
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Ey (kk , z + c, ω) = Ey (kk , z, ω)
iQ20
iQ20 ω−
iQ20
+ −
0
+ −
Hx (kk , z, ω) −
k k − 2
k k Hy0 (kk , z, ω),
+
δt εr ω+ y y
δt εr ω+ y x
c0 δt
Hx0 (kk , z + c, ω) = Hx0 (kk , z, ω)
2
2
ic0 δt + −
ic0 δt − +
+
k
k
(k
,
z
+
c,
ω)
+
k
k
−
iδt
ε
ω
−
E
Ey (kk , z + c, ω),
x k
r
ω− x y
ω− x x
Hy0 (kk , z + c, ω) = Hy0 (kk , z, ω)
2
ic0 δt + −
ic02 δt + −
+
k k Ey (kk , z + c, ω).
+ iδt εr ω − − ky ky Ex (kk , z + c, ω) +
ω
ω− x y
595
(28)
(29)
(30)
These equations define the transfer matrix for a system which is discrete in the frequency domain as well as
spatially.
2.3. Defining a plane wave basis set
A vital element of any transmission and reflection calculation, if we wish to be able to calculate the elements
of the transmission matrix rather than just the transmitted intensity at some point, is the ability to project the
transmitted/reflected wavefield onto a complete basis set of plane waves. Fortunately, we can use the transfer
matrix to define just such a basis set.
A plane wave solution to Maxwell’s equations has the following form,
H(r, t) = H0 exp i(k · r − ωt) .
(31)
E(r, t) = E0 exp i(k · r − ωt) ,
So if we substitute into Maxwell’s equations on the lattice,
k− × H0 = −ε0 ω+ E0 ,
k+ × E0 = µ0 ω− H0 .
(32)
The second equation allows us to generate the components of H given E. For a given k there are two polarization
states which we must consider. For the s-polarization,
Es ∝ k− × n,
(33)
and for the p-polarization,
Ep ∝ k− × k+ × n,
(34)
where n is an arbitrary unit vector. Once we have E, finding H is a straight-forward application of our discrete
Maxwell’s equations. At a given frequency ω we loop over all kk to generate the complete set.
The next task is to properly normalize this basis set. This is done by ensuring the current carried by each mode
is normalized to unity. The z-component of the current can be shown to be,
∗
∗
(35)
Sz = eikz c Ex Hy0∗ − eikz c Ey Hx0∗ + eiwδt Hy0 eikz c Ex − eiwδt Hx0 eikz c Ey .
It is very easy to show that the plane waves which we have just defined are the right eigenvectors of the transfer
matrix for a homogeneous dielectric. By definition the effect of the transfer matrix on an arbitrary set of fields is,
TbFr (r) = Fr (r + c),
where,
(36)


Ex
E 
Fr =  y0  .
Hx
Hy0
(37)
596
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
But for plane waves,
exp [ikz c]Fr (r) = Fr (r + c),
(38)
hence,
TbFr (r) = exp [ikz c]Fr (r).
(39)
Unfortunately for us, the right eigenvectors of the transfer matrix do not in general form an orthonormal set. So
if we are to project out the components of particular plane waves from an arbitrary set of fields, we need a set of
vectors which are the reciprocal set to the right eigenvectors. We could generate the set by inverting the matrix
formed by the right eigenvectors but fortunately there is a simpler way of doing this. The transfer matrix also has
a distinct set of left eigenvectors and these are the reciprocal set which we need.
Fl (r)Tb = exp [ikz c]Fl (r)
(40)
and
j
Fli · Fr = δ ij .
(41)
By examining the elements of the transfer matrix (which we derived in Section 2.2) we can show how to generate
the left vectors from the elements of the right ones.
p+
p+
0p+
0p+ (42)
Fls+ = −Ey , +Ex , +αHy , −αHx ,
p+
(43)
Fl = −Eys+ , +Exs+ , +αHy0s+ , −αHx0s+ ,
p−
p−
0p−
0p− s−
(44)
Fl = −Ey , +Ex , +αHy , −αHx ,
p−
s−
s−
0s−
0s−
(45)
Fl = −Ey , +Ex , +αHy , −αHx ,
where,
α=
Q0
c0 δt
2
ω−
.
εr ω +
(46)
Note that s+ denotes an s-polarized wave coming from +∞, p− denotes a p-polarized wave coming from −∞,
etc. This left eigenvector set can now be used to project out the individual modes from an arbitrary set of fields. If
we write the arbitrary fields as a sum over modes,
X
αi Fri ,
(47)
F=
i
then,
j
αj = Fl · F.
(48)
2.4. Defining an absorbing boundary condition
In this section we will derive formulae for an absorbing boundary region which we can use to pad ends of our
real-space lattice and absorb any spurious reflections. This absorbing layer is essential if we are to successfully
perform a transmission/reflection calculation where even small reflections from the ends of the system could cause
serious errors. Fig. 1 gives a schematic to illustrate the set-up for performing a transmission/reflection calculation.
On one side of the system some incident field is set up, probably a Gaussian pulse but certainly something which
contains all of the frequencies which we are interested in. The fields are then time evolved and at every time step
the fields are stored on the planes indicated with the dashed lines in the figure. At the end of the integration time the
stored fields are Fourier transformed into the frequency domain and projected onto a complete basis set of plane
waves to give the amplitude of each mode present in the scattered fields.
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
597
Fig. 1. Diagram showing the typical arrangement for a transmission/reflection coefficient calculation. Some incident wave field is set up and
allowed to time evolve to give reflected and transmitted fields. Absorbing regions (PML’s) minimize any unphysical reflections from the ends
of the system. The fields are stored at each time step on the planes shown with dashed lines and analyzed to give the transmission and reflection
coefficients as functions of frequency.
However, all this relies critically on the minimization of spurious reflections from the ends of the computational
domain if it to work effectively. To this end we will implement a Berenger type of perfectly matched layer
(PML) [12] as our absorbing layer and our derivation will closely follow the work of Zhao and Cangellaris [13].
We begin from Maxwell’s equations in an arbitrary co-ordinate system,
b
∇q+ × b
E
∇q− × H
b
E,
(49)
= −iε0 ε̂(r)ω+b
= iµ0 µ̂(r)ω− H,
Q0
Q0
where the renormalized fields are,
bi = Qi Hi ,
bi = Qi Ei ,
H
(50)
E
with,
s
∂x
∂qi
2
∂z 2
,
∂qi
Q1 Q2 Q3
,
ε̂ ij (r) = ε(r)g ij |u1 · u2 × u3 |
Qi Qj Q0
Q1 Q2 Q3
.
µ̂ ij (r) = µ(r)g ij |u1 · u2 × u3 |
Qi Qj Q0
Qi =
+
∂y
∂qi
2
+
(51)
(52)
(53)
To make a layer which is absorbing we simply make Q3 complex and keep the co-ordinate axis orthogonal.
Typically, if in the free-space region,
Q1 = Q2 = Q3 = Q0 ,
(54)
then in the absorbing region,
Q1 = Q2 = Q0 ;
iωz
Q3 = Q0 1 + − ,
ω
(55)
where ωz is an arbitrary parameter which we can use to control the strength of the absorption. Note that the
absorption in Q3 must be odd with respect to frequency so that it changes sign at ω = 0. This ensures that all
solutions are absorbed, even non-physical negative frequency solutions. Note also that we could equally well have
chosen to use ω+ in the above equation just as long as we were consistent. Substituting into ε̂ and µ̂ this gives in
the free space region,
ε̂ ii = εr ;
µ̂ ii = 1
(56)
598
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
and in the absorber,
iωz
ε̂ = ε̂ = εr 1 + − ;
ω
iωz
µ̂ 11 = µ̂ 22 = 1 + − ;
ω
11
22
iωz −1
;
ε̂ = εr 1 + −
ω
iωz −1
.
µ̂ 33 = 1 + −
ω
33
(57)
(58)
Because the co-ordinate system remains orthogonal, the off-diagonal elements remain zero. When we substitute
into Maxwell’s equations we obtain the following,
iωz
b = −iε0 εr 1 + iωz ω+ E
b
bx ;
bx ;
∇
×
E
=
iµ
(59)
1
+
ω− H
∇q × H
q
0
x
x
ω−
ω−
iωz
b = −iε0 εr 1 + iωz ω+ E
b
by ;
by ;
∇
×
E
=
iµ
(60)
1
+
ω− H
∇q × H
q
0
y
y
ω−
ω−
iωz −1 + b
iωz −1 − b
b
b
ω Ez ;
∇q × E z = iµ0 1 + −
ω Hz .
(61)
∇q × H z = −iε0 εr 1 + −
ω
ω
These can be rearranged to give,
1
bx (r, t) +
E
1 + ωz δt
1
by (r, t) +
b
E
Ey (r, t + δt) =
1 + ωz δt
1
0
b
∇q × H (r, t) x ,
(62)
εr
1
b0 (r, t) ,
∇q × H
(63)
y
εr
∞
1
ωz δt X 0
b
b0 (r, t − nδt) ,
b
b
(64)
∇q × H (r, t) z +
∇q × H
Ez (r, t + δt) = Ez (r, t) +
z
εr
εr
n=0
2
1
bx0 (r, t − δt) − c0 δt
bx0 (r, t) =
H
E(r, t) x ,
∇q × b
(65)
H
1 + ωz δt
Q0
1
c0 δt 2 0
0
b
b
b
Hy (r, t − δt) −
(66)
∇q × E(r, t) y ,
Hy (r, t) =
1 + ωz δt
Q0
(
)
2
∞
X
bz0 (r, t − δt) − c0 δt
bz0 (r, t) = H
E(r, t) z + ωz δt
E(r, t − nδt) z ,
∇q × b
∇q × b
(67)
H
Q0
n=0
P
n
−
where we have made use of the fact that 1/(1 − x) = ∞
n=0 x to transform 1/ω into a sum over previous fields.
These six equations can now be used to update the electric and magnetic fields in the absorbing region and will
cause any waves within to be attenuated. The strength of the attenuation is determined by the parameter ωz .
bx (r, t + δt) =
E
3. The ONYX program
The ONYX program has been written and structured along a kit of parts philosophy. That is to say that
since it is almost impossible to write a single program which could perform every calculation which one might
want to do, the program has been constructed out of a number of largely self-contained subroutines which can
be bolted together in different ways to perform different tasks. The subroutines loosely divide up into four
groups: initialization routines for setting the problem up, time integration routines which make up the core
of the calculation, post-processing routines for making sense of the results and service routines for providing
primitive matrix operations, error trapping, etc. In the following sections we will consider each subroutine in
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
599
Fig. 2. Schematic to show the general structure of the ONYX program.
turn in the order in which they appear in the program. For each routine we will give a table of all the variables
used by that routine, identifying which are used for the input/output of the routine and which are purely internal
variables. We will also try to give a description of the routine; what it does and how it works. In order to see how
each subroutine fits into the overall program scheme, Fig. 2 gives an overview of the organization of the whole
program.
3.1. Preamble – Table 1
The Order N program begins with a block of comments. Most important are the lines which identify the
version number and the date of that version. Following the comments are a series of modules. Most of these
contain interface blocks which serve two purposes. Firstly, they allow the Fortran 90 compiler to perform proper
type-checking to help prevent errors caused by passing the wrong type or number of arguments to a subroutine.
Secondly, this explicit interface syntax is required by Fortran 90 if any of the parameters passed to a subroutine are
the new style Fortran 90 pointers. Apart from the interfaces there are three other important modules; files
which puts the unit numbers for the various input and output files used by the program into sensibly named
variables, parameters which contains variables for all the constants read in by the program at execution time
and physconsts which defines variables for the physical constants needed by the program. Notice that the
parameters bclayer1, bclayer2 and epsref are not defined in the input file but are set in the subroutine
defcell.
3.2. Program onyx – Table 2
The main program itself does very little, other than setting the calculation up and passing control to other
subroutines which do the hard work. The main program does contain some important loops however. There is
600
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Table 1
Variables in modules physconsts, files and parameters
Variables in modules physconsts, files and parameters
physconsts
files
parameters
real
pi
Value for π
real
c0
Speed of light in free space (atomic units)
real
eps0
Free space permittivity (atomic units)
real
mu0
Free space permeability (atomic units)
real
abohr
Bohr radius (metres)
real
x
Dummy parameter
real
emach
complex
ci
Machine accuracy
√
−1
integer
logfile
Unit number for log.dat
integer
infile
Unit number for infile.dat
integer
outfile
Unit number for out.dat
integer
fields
Unit number for fields.dat
integer
ixmax
Number of mesh points in the x-direction
integer
iymax
Number of mesh points in the y-direction
integer
izmax
Number of mesh points in the z-direction
integer
itmax
Total number of time steps=n_block.block_size
integer
ikmax
Number of k points
integer
n_block
Number of blocks for time integration
integer
block_size
Size of each block
integer
n_pts_store
Number of points where we store the fields
real
Q0
Scale factor equal to typical mesh spacing
real
Q(3)
Array holding mesh spacing in each direction
real
dt
Size of the time step
real
akx
Rescaled x-component of k. akx=(Q(1)*ixmax)*kx
real
aky
Rescaled y-component of k. aky=(Q(2)*iymax)*ky
real
akz
Rescaled z-component of k. akz=(Q(3)*izmax)*kz
integer
n_segment
Number of segments for the FFT (leave as 1)
logical
overlap
True if segments are to overlap (leave as false)
integer
fft_size
If overlap=true then itmax=fft_size*(n_segment+1)
If overlap=false then itmax=fft_size*(2*n_segment)
real
damping
Controls amount fields are damped when stored
integer
bclayer1
Thickness of absorbing layer on left-hand side
integer
bclayer2
Thickness of absorbing layer on right-hand side
complex
epsref
Dielectric constant of host material
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
601
Table 2
Variables for program onyx
Variables for program onyx
integer
ios
Input/output status
integer
ik,ik2,ik3
Loop counters for k
integer
ix_cur,iy_cur,iz_cur
x, y, z co-ordinates
integer
i_pol
Field component label
integer,pointer
store_pts(:,:)
Positions at which we store the fields
complex,pointer
e(:,:,:,:)
Electric field at the current time
complex,pointer
h(:,:,:,:)
Magnetic field at the current time
complex,pointer
eps(:,:,:)
Physical permittivity
complex,pointer
mu(:,:,:)
Physical permeability
complex,pointer
eps_inv(:,:,:,:,:)
Inverse of renormalized permittivity
complex,pointer
mu_inv(:,:,:,:,:)
Inverse of renormalized permeability
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
complex,pointer
fft_data(:,:)
Array for storing the fields
real,pointer
sigma(:,:,:)
Electric conductivity
real,pointer
sigma_m(:,:,:)
Magnetic conductivity
real,pointer
spectrum(:)
Array to store the power spectrum or the DOS
real
u1(3),u2(3),u3(3)
Unit lattice vectors
real
g1(3),g2(3),g3(3)
Reciprocal lattice vectors
real
g(3,3)
Metric tensor
real
omega
|u1 · u2 × u3 |
the possibility to loop over akx, aky and akz which are the variables that control the values of kx , ky and kz .
Remember that akx, etc. are defined such akx=(Q(1)*ixmax)*kx. If one is calculating a Green’s function
there is the possibility to loop over ipol, the variable which determines which field component contains the initial
delta function. Depending on whether one is performing a band structure calculation, a density of states calculation
or a transmission calculation separate versions of some subroutines are provided. Whilst this does result in a certain
amount of code duplication it does mean that switching from one type can be done entirely by changing subroutine
calls in the main program and removes the error prone process of searching through the whole program trying to
find all the places where changes must be made.
3.3. Subroutine driver – Table 3
This subroutine handles the main part of the calculation which steps the electromagnetic fields forward in time.
The total number of time steps itmax is divided up into n_blocks blocks each of block_size time steps each
(n_blocks and block_size are parameters set from the input file). The subroutine int performs the actual
time integration for the block_size time steps in each block and at the end of each block there is the option to
perform several tests on the fields, charge conservation, energy conservation in order to make sure nothing is going
wrong.
602
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Table 3
Variables for subroutine driver
Variables for subroutine driver
input
complex,pointer
e_cur(:,:,:,:)
Electric field at the current time
input
complex,pointer
h_cur(:,:,:,:)
Magnetic field at the current time
input
complex,pointer
eps_inv(:,:,:,:,:)
Inverse of renormalized permittivity
input
complex,pointer
mu_inv(:,:,:,:,:)
Inverse of renormalized permeability
input
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
input
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
input
real,pointer
sigma(:,:,:)
Renormalized electric conductivity
input
real,pointer
sigma_m(:,:,:)
Renormalized magnetic conductivity
output
complex,pointer
fft_data(:,:)
Array for storing the fields
input
integer,pointer
store_pts(:,:)
Positions at which we store the fields
internal
complex,pointer
e_prev(:,:,:,:)
Electric field at the previous time
internal
complex,pointer
h_prev(:,:,:,:)
Electric field at the previous time
internal
complex,pointer
div(:,:,:)
Divergence of the field
internal
real,pointer
rho(:,:,:)
Energy density
internal
integer
i
Loop counter
internal
integer
iblock
Loop counter
internal
complex,pointer
intcurle_1(:,:,:)
Integral of (∇ × E)z on left side of system
internal
complex,pointer
intcurlh_1(:,:,:)
Integral of (∇ × H)z on left side of system
internal
complex,pointer
intcurle_2(:,:,:)
Integral of (∇ × E)z on right side of system
internal
complex,pointer
intcurlh_2(:,:,:)
Integral of (∇ × H)z on right side of system
internal
real,pointer
wz_1(:)
Strength of absorber on left side of system
internal
real,pointer
wz_2(:)
Strength of absorber on right side of system
The routine also does a few other odds and ends; it allocates storage to the arrays to store the fields at the
previous time-step, and various arrays used to store the divergence of the fields and the energy density when testing
the calculation. It also sets up various arrays required by the absorbing boundary layers including making a call
to the subroutine set_wz which defines the strengths of the absorbing layers. All these arrays are defined here
because they are only required during the time integration loop and are not needed by the rest of the program.
3.4. Subroutine int – Table 4
The subroutine forms the heart of the finite difference time domain calculation. It advances the electric and
magnetic fields forward in time by nt time-steps. The equations used to advance the fields are the finite difference
time dependent Maxwell equations that we derived earlier.
0
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b1 (r, t) + ε̂ −1 (r) 11 H
b3 (r, t) − H
b1 (r, t + δt) = 1 − σ̂ E
E
12 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
+ ε̂ −1 (r)
H
13 0
b0 (r − a, t) − H
b0 (r, t) + H
b0 (r − b, t) ,
b (r, t) − H
(68)
H
+ ε̂ −1 (r)
2
2
1
1
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
603
Table 4
Variables for subroutine int
Variables for subroutine int
in/out
complex,pointer
e_cur(:,:,:,:)
Electric field at the current time
in/out
complex,pointer
e_prev(:,:,:,:)
Electric field at the previous time
in/out
complex,pointer
h_cur(:,:,:,:)
Magnetic field at the current time
in/out
complex,pointer
h_prev(:,:,:,:)
Magnetic field at the previous time
input
complex,pointer
eps_inv(:,:,:,:,:)
Inverse of renormalized permittivity
input
complex,pointer
mu_inv(:,:,:,:,:)
Inverse of renormalized permeability
input
real,pointer
sigma(:,:,:)
Renormalized electric conductivity
input
real,pointer
sigma_m(:,:,:)
Renormalized magnetic conductivity
input
integer
nt
Number of time steps to integrate for
input
integer
iblock
Current time step block
output
complex,pointer
fft_data(:,:)
Array for storing the fields
input
integer
store_pts(:,:)
Positions at which we store the fields
in/out
complex,pointer
intcurle_1(:,:,:)
Integral of (∇ × E)z on left side of system
in/out
complex,pointer
intcurlh_1(:,:,:)
Integral of (∇ × H)z on left side of system
in/out
complex,pointer
intcurle_2(:,:,:)
Integral of (∇ × E)z on right side of system
in/out
complex,pointer
intcurlh_2(:,:,:)
Integral of (∇ × H)z on right side of system
input
real,pointer
wz_1(:)
Strength of absorber on left side of system
input
real,pointer
wz_2(:)
Strength of absorber on right side of system
internal
integer
ix,iy,iz,it,i_pts
Loop counters
internal
complex
curl(3)
Work space for the curl
internal
real
dtcq2
(δt c0 /Q0 )2
internal
complex,pointer
temp(:,:,:,:)
Temporary pointer
0
b2 (r, t) + ε̂ −1 (r) 21 H
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b2 (r, t + δt) = 1 − σ̂ E
b3 (r, t) − H
E
22 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
+ ε̂ −1 (r)
H
23 0
b20 (r − a, t) − H
b10 (r, t) + H
b10 (r − b, t) ,
b2 (r, t) − H
H
+ ε̂ −1 (r)
0
b3 (r, t) + ε̂ −1 (r) 31 H
b30 (r − b, t) − H
b20 (r, t) + H
b20 (r − c, t)
b3 (r, t) − H
b3 (r, t + δt) = 1 − σ̂ E
E
32 0
b10 (r − c, t) − H
b30 (r, t) + H
b30 (r − a, t)
b1 (r, t) − H
H
+ ε̂ −1 (r)
33 0
b20 (r − a, t) − H
b10 (r, t) + H
b10 (r − b, t) ,
b2 (r, t) − H
H
+ ε̂ −1 (r)
−1
0
b
b10 (r, t)
H1 (r, t + δt) = 1 + σ̂m
H
−
δt c0
Q0
2
µ̂ −1 (r)
11 b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
b3 (r + b, t) − E
E
(69)
(70)
604
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
δt c0 2 −1 12 b
b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
−
µ̂ (r)
E1 (r + c, t) − E
Q0
δt c0 2 −1 13 b
b2 (r, t) − E
b1 (r + b, t) + E
b1 (r, t) ,
µ̂ (r)
E2 (r + a, t) − E
−
Q0
b20 (r, t)
b20 (r, t + δt) = 1 + σ̂m −1 H
H
δt c0 2 −1 21 b
b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
µ̂ (r)
E3 (r + b, t) − E
−
Q0
δt c0 2 −1 22 b
b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
µ̂ (r)
E1 (r + c, t) − E
−
Q0
δt c0 2 −1 23 b
b
b
b
µ̂ (r)
E2 (r + a, t) − E2 (r, t) − E1 (r + b, t) + E1 (r, t) ,
−
Q0
b30 (r, t)
b30 (r, t + δt) = 1 + σ̂m −1 H
H
(71)
−
δt c0
Q0
2
µ̂ −1 (r)
31 b3 (r, t) − E
b2 (r + c, t) + E
b2 (r, t)
b3 (r + b, t) − E
E
δt c0 2 −1 32 b
b1 (r, t) − E
b3 (r + a, t) + E
b3 (r, t)
µ̂ (r)
E1 (r + c, t) − E
−
Q0
δt c0 2 −1 33 b
b2 (r, t) − E
b1 (r + b, t) + E
b1 (r, t) .
µ̂ (r)
E2 (r + a, t) − E
−
Q0
(72)
(73)
There are a few other points that should be mentioned about the int subroutine. Two sets of fields are stored
e_cur and h_cur, which refer to the fields at the current time step, and e_prev and h_prev which refer to
the previous time step. The first thing the routine does at each time step is to switch round the current and previous
fields so that the current fields become the previous ones and vice versa. This can be done very efficiently because
the arrays in which the fields are stored are accessed as Fortran 90 pointers so all you have to do is switch over
which pointer points to which array.
temp=>e_cur
e_cur=>e_prev
e_prev=>temp
temp=>h_cur
h_cur=>h_prev
h_prev=>temp
This means the arrays e_cur and h_cur can now be used to hold the updated fields at the next time step as they
are calculated using the equations given earlier. By doing this we are able to hold on to the fields at two successive
time steps which as we shall see later we need when we want to calculate the energy density.
Normal Bloch boundary conditions or perfect metal boundary conditions are provided by the set subroutines
bc_xmax_bloch or bc_xmax_metal, etc. Notice that the equations given above are only used to update the
fields in the region of the system which is not part of any absorbing layer. Calls are made to the subroutines PML_e
and PML_h to update the fields in the absorbing layers.
At the end of each time step some components of the fields are stored in the array fft_data. The array
store_pts determines which components are to be sampled and the parameter n_pts_store fixes the
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
605
number of fields components to be stored. The array store_pts works as follows; for the ith point to be
stored store_pts(i,2), store_pts(i,3) and store_pts(i,4) contain the x, y and z co-ordinates
of the mesh point at which the fields are to be sampled. store_pts(i,1) determines which of the six fields
components is to be stored; 1 corresponding to Ex , 2 is Ey , etc. up to 6 being Hz . The stored field can also be
damped by an exponential term corresponding to adding a small imaginary part to the energy. This comes in handy
when calculating a Green’s function as it ensures the sum in the Fourier transform converges to give us the causal
Green’s function. The size of this damping is set by the run-time parameter damping. Another technical detail –
it turns out that in order to correctly calculate the Green’s function we must store the current value for any electric
field, but the previous value for the magnetic field. This arises from the fact that we took the forward time difference
for the electric field and the backwards one for the magnetic field.
4. Subroutines to initialize the calculation
4.1. Subroutine setparam – Table 5
This subroutine reads in the run-time parameters from an input file called infile.dat which it assumes has
already been opened and connected to unit number infile. The parameters are then written out to make up the
header blocks for the output files, log.dat, out.dat and fields.dat. If the subroutine can not make sense
of the input file it calls the subroutine err. The parameters read in from the input file are read into the variables in
the module parameters and are described in Section 9.
4.2. Subroutine initfields – Table 6
The initfields subroutine defines the initial values of the electric and magnetic fields at the first time step
and returns them in the arrays e and h. Code is supplied for several possible initial fields; a Gaussian pulse, a delta
function pulse and a sum of plane waves similar to the starting conditions used by Chan et al. [7]. The delta function
is centered on the point (ix_cur,iy_cur,iz_cur) and the parameter i_pol determines which component
of the fields contains the delta function. The subroutine also takes as arguments eps_hat and mu_hat in order
that tests on the divergence of the initial fields can be made if required.
A version of this subroutine initfields_dos is provided, and should be used when calculating the
density of states, since it sets the starting fields to be the required delta function. In addition, another version,
initfields_trans is provided for the transmission/reflection calculation and sets the initial fields to be some
Gaussian pulse. Notice that it is important for a successful transmission/reflection calculation that the initial fields
contain only one mode at each frequency. If the initial fields were to contain more than one mode then it would
become impossible to work out which part of the scattered field corresponded to which incident mode. It is only
by virtue of the system being linear that we can calculate transmission and reflection for all frequencies at once.
If the system were non-linear then frequency mixing could occur and it would be impossible to determine which
scattered waves corresponded to which incident frequency.
Table 5
Variables for subroutine setparam
Variables for subroutine setparam
internal
integer
nbits
Bit size of an integer
internal
integer
set_bits
Counter for number of set bits
internal
integer
i
Loop counter
606
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Table 6
Variables for subroutines initfields and initfields_dos
Variables for subroutines initfields and initfields_dos
input
real
g1(3),g2(3),g3(3)
Reciprocal lattice vectors
output
complex,pointer
e(:,:,:,:)
Electric field
output
complex,pointer
h(:,:,:,:)
Magnetic field
input
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
input
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
input
integer
ix_cur,iy_cur,iz_cur
x, y, z co-ordinates
input
integer
i_pol
Field component label
internal
integer
ix,iy,iz,jx,jy,jz,i
Loop counters
internal
real
G(3)
General reciprocal lattice vector
internal
real
k(3)
General wavevector
internal
real
v(3)
Arbitrary vector with components ≈ 1
internal
real
k_plus_G(3)
k+G
internal
complex
vec(3)
Temporary vector
internal
complex
h0(3)
Temporary magnetic field
internal
complex
expo
exp [i(k + G) · r]
internal
complex,pointer
div(:,:,:)
Array to store divergence
internal
real
dtcq2
(δt c0 /Q0 )2
Table 7
Variables for subroutine defcell
Variables for subroutine defcell
output
complex,pointer
eps(:,:,:)
Physical permittivity
output
complex,pointer
mu(:,:,:)
Physical permeability
output
real,pointer
sigma(:,:,:)
Electric conductivity
output
real,pointer
sigma_m(:,:,:)
Magnetic conductivity
input
real
u1(3),u2(3),u3(3)
Unit lattice vectors
Whilst it is hoped that the subroutines given here will serve as some sort of guide, it is clear that, in general, the
user will have to write his own subroutine to set the initial conditions appropriately for the calculation he has in
mind.
4.3. Subroutine defcell – Table 7
This subroutine defines the physical properties of the unit cell by setting the values of εµ and the conductivity σ
at each point on the discrete mesh. For historical reasons a magnetic conductivity σm is also defined. When defining
a new unit cell this is the subroutine which must be replaced.
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
607
4.4. Subroutines init_store_pts_band, init_store_pts_dos, init_store_pts_trans –
Table 8
These subroutines initializes the array store_pts to hold information about which field components
are to be stored during the time integration into the array fft_data for later post-processing. The array
store_pts works as follows; for the ith point to be stored store_pts(i,2), store_pts(i,3) and
store_pts(i,4) contain the x, y and z co-ordinates of the mesh point at which the fields are to be
sampled. store_pts(i,1) determines which of the six fields components is to be stored; 1 corresponding
to Ex , 2 is Ey , etc. up to 6 being Hz . The parameter n_pts_store controls how many field components
are to be stored. For a band structure calculation subroutine init_store_pts_band fills the array
store_pts randomly while for a Green’s function calculation subroutine init_store_pts_dos sets
up store_pts such that only the i_pol’th component of the fields at the position ix_cur, iy_cur, iz_cur
is stored. For the transmission/reflection coefficient calculation the storage requirements are rather greater as
we must store all the x and y components of both E and H fields on two planes, one at either end of the
system. This is necessary if we want to decompose the transmitted and reflected fields into their constituent plane
waves.
4.5. Subroutine defmetric – Table 9
The subroutine defmetric takes the three unit vectors u1, u2 and u3 and defines some of the quantities
required when setting up the generalized co-ordinate system. The three vectors g1, g2 and g3 are defined to be
the set of vectors reciprocal to the u’s so that g1 = (u2 × u3 )/(|u1 · u2 × u3 |). Therefore uα · gβ = δαβ . The routine
also defines the metric tensor for the co-ordinate system, Gαβ = gα · gβ . Finally the subroutine defines an extra
constant Q0 which has the dimensions of a length and a magnitude roughly the same as the spacing between mesh
points Q(1),Q(2),Q(3). In fact the routine simply sets Q0=Q(1).
Table 8
Variables for init_store_pts_band, init_store_pts_dos and init_store_pts_trans
Variables for init_store_pts_band, init_store_pts_dos and init_store_pts_trans
output
integer,pointer
store_pts(:,:)
Positions at which we store the fields
input
integer
ix_cur,iy_cur,iz_cur
x, y, z co-ordinates
input
integer
i_pol
Field component label
internal
integer
i,ix,iy,ip
Loop counters
internal
real
x
Random number
Table 9
Variables for subroutine defmetric
Variables for subroutine defmetric
input
real
u1(3),u2(3),u3(3)
Unit lattice vectors
output
real
g1(3),g2(3),g3(3)
Reciprocal lattice vectors
output
real
g(3,3)
Metric tensor
output
real
omega
|u1 · u2 × u3 |
internal
real
tmp(3)
Temporary vector
608
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Table 10
Variables for subroutine renorm
Variables for subroutine renorm
input
complex,pointer
eps(:,:,:)
Physical permittivity
input
complex,pointer
mu(:,:,:)
Physical permeability
in/out
real,pointer
sigma(:,:,:)
Electric conductivity
in/out
real,pointer
sigma_m(:,:,:)
Magnetic conductivity
output
complex,pointer
eps_inv(:,:,:,:,:)
Inverse of renormalized permittivity
output
complex,pointer
mu_inv(:,:,:,:,:)
Inverse of renormalized permeability
output
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
output
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
input
real
g(3,3)
Metric tensor
input
real
omega
|u1 · u2 × u3 |
internal
complex, dimension(3,3)
eps_tmp,mu_tmp
Temporary arrays
internal
integer
i,j,ix,iy,iz
Loop counters
internal
logical
fail
Flag for matrix inversion failure
4.6. Subroutine renorm – Table 10
The subroutine renorm takes the real, physical quantities ε, µ, σ and σm and returns the renormalized ε̂, µ̂, σ̂
and σ̂m according to the formulae we gave previously,
ε̂ ij (r) = ε(r)g ij |u1 · u2 × u3 |
σ̂ =
δt σ
;
ε0 ε(r)
σ̂m =
Q1 Q2 Q3
;
Qi Qj Q0
µ̂ ij (r) = µ(r)g ij |u1 · u2 × u3 |
δt σm
.
µ0 µ(r)
Q1 Q2 Q3
;
Qi Qj Q0
(74)
(75)
The routine then calculates ε̂ −1 and µ̂ −1 as it is these quantities which are needed in the equations which update
the fields.
5. Subroutines for post-processing
5.1. Subroutines postproc_band and postproc_dos – Table 11
The postproc_band subroutine provides any necessary post-processing on the time-dependent fields that
have been stored in the array fft_data. For the band structure calculation this involves a Fourier transform by
means of the subroutine power_spec after which the band structure is written out analyzing the derivative of
the spectrum and identifying the peaks. If ikmax is set to one the routine does not write out the band structure
but instead writes the power spectrum as returned by power_spec. This was originally done to serve as a test to
make sure the spectrum makes physical sense.
For a calculation of the density of states the subroutine postproc_dos provides post-processing by calling
the subroutine FFT to perform a simple Fourier transform and then adding minus the imaginary part of the result
to the cumulative density of states stored in the array spectrum.
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
609
Table 11
Variables for subroutines postproc_band and postproc_dos
Variables for subroutines postproc_band and postproc_dos
input
complex,pointer
fft_data(:,:)
Array for storing the fields
output
real,pointer
spectrum(:)
Array for the power spectrum
or the density of states
internal
integer
i
Loop counter
5.2. Subroutine finalproc_dos – Table 12
The subroutine finalproc_dos performs the final post-process step to write out the complete density of
states to the output file.
5.3. Subroutine postproc_trans – Table 13
This subroutine takes the fields which have been stored at both ends of the system and first Fourier transforms
them into the frequency domain by calling the subroutine fft. At each frequency it then uses subroutine defpw to
generate a complete basis set of plane waves. Next this basis set is used to project out the amplitude of each mode
present at either end of the system. By summing the squares of the amplitudes of the waves traveling to the left or
right at either end we can find the total incident, reflected and transmitted photon currents. Finally, the transmitted
Table 12
Variables for subroutine finalproc_dos
Variables for subroutine finalproc_dos
input
real,pointer
spectrum(:)
Array for the density of states
internal
integer
i
Loop counter
Table 13
Variables for subroutine postproc_trans
Variables for subroutine postproc_trans
input
complex,pointer
fft_data(:,:)
Array for storing the fields
internal
complex,pointer
rvec(:,:)
Right eigenvectors
internal
complex,pointer
lvec(:,:)
Left eigenvectors
internal
complex,pointer
kz(:)
Values of kz
internal
integer
i,j,k
Labels for different modes
internal
integer
isign
+1 for transform, −1 for inverse transform
internal
integer
iw,ikx,iky,ipol,ix,iy,ijpol
Loop counter
internal
complex
ave
Average
internal
real
w
Current frequency in Hartrees
internal
real
wp
wp = ω+ = (exp [−iωδt] − 1)/δt
internal
logical
ifail
Flag indicating failure in basis set
610
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
and reflected currents are divided by the incident current and are written out as the transmission and reflection
coefficients for that frequency. Current conservation checks are also possible here by summing the transmitted and
reflected currents and comparing with the incident current. Notice that there are many reasons why current may
not be exactly conserved. Firstly, imperfections in the absorbing layers will mean that there will be some small,
spurious reflections from the ends of the system which will interfere with the genuine transmitted and reflected
beams. More seriously, any kind of resonance in the scattering region will result in energy becoming trapped for a
time in the scatterer. Since we only integrate for a finite time it is possible that some energy will still be trapped in
the scattering region at the end of the calculation and this will disrupt current conservation. By using the subroutine
calc_energy_density it is possible to measure how energy remains trapped at any given time and also to
find where in the scattering region the energy is localized. This should make it possible to estimate how long one
needs to continue the time integration to minimize these problems. Note that many physical effects can give rise
to a small group velocity and hence to trapped energy; Anderson localization, Van Hove singularities or single
scatterer resonances, for example.
5.4. Subroutine defpw – Table 14
This subroutine uses the results derived in Section 2.3 to generate a complete basis set of plane waves at the
frequency iw. It returns both the right and left eigenvectors, in the arrays rvec and lvec, respectively, as well as
the corresponding values of kz in the array kz.
Table 14
Variables for subroutine defpw
Variables for subroutine defpw
input
integer
iw
Current frequency
output
complex,pointer
rvec(:,:)
Right eigenvectors
output
complex,pointer
lvec(:,:)
Left eigenvectors
output
complex,pointer
kz(:)
Values of kz
internal
integer
i,j,ipol,jpol,ikx,iky
Loop counter
internal
integer
imode
Mode label
internal
real
w
Frequency in Hartrees
internal
real
dtcq2
(δt c0 /Q0 )2
internal
real
kx,ky
x and y components of k
internal
real
wpp
Dimensionless frequency
internal
complex
e(3)
Electric field
internal
complex
h(3)
Magnetic field
internal
complex
kp(3),km(3)
k + and k −
internal
complex
wp,wm
ω+ and ω−
internal
complex
u(3)
Arbitrary unit vector
internal
complex
mag
Storage for magnitude of vector
internal
complex
temp1,temp2
Temporary storage
internal
complex
const
−(ω− /ω+ )/(εr (δt c0 /Q0 )2 )
internal
logical
fail
Indicates failure in basis set
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
611
The routine begins by generating the right eigenvector set. It loops over kk and generates the corresponding
values for kz from the free space dispersion relation. Once k is fully defined the electric and magnetic fields
for both s and p polarized waves are generated using Maxwell’s equations including the special case of normal
incidence. Each mode is then normalized such that it carries unit photon current. This is achieved by dividing by
the z-component of the Poynting vector as defined in Section 7.3. The x and y components of the electric and
magnetic fields are then copied into the array rvec. The array is organized such that the first index labels the
mode while the second labels the components the the fields for that mode in the order Ex , Ey , Hx and Hy . The
modes are arranged in groups of four for each value of kk in the order s + , p+ , s − then p− where s + represents
in s-polarized wave coming from +∞, p− a p-polarized wave coming from −∞, etc. The array kz stores the
corresponding values of kz in the same order as rvec.
The left eigenvectors are then generated analytically from the right eigenvectors as described in Section 2.3. The
left eigenvectors also need to be properly normalized and this is done by ensuring that,
j
Fli · Fr = δ ij .
(76)
Arrangements for storing the left-vectors in the array lvec are rather complex but are maintained for historical
reasons and for computability with our transfer matrix program PHOTON [10]. The second index labels the
polarization and direction of the mode as before, s + , p+ , s − then p− . The first index labels both kk and the
four components of the mode. So elements 1–4 correspond to Ex , Ey , Hx and Hy for first value of kk while
elements 5–8 give Ex to Hy for the next kk , etc.
Before returning the routine checks that the left-vector set is indeed orthonormal to the right-vectors and gives
an error if it is not.
6. Boundary conditions
6.1. Simple boundary conditions – Table 15
Two sets of simple boundary condition routines a provided. The first set, bc_*_bloch, use Bloch’s law,
F (r + R) = exp (ik · R)F (r) to correctly set the fields along the planes ix=0, iy=0, iz=0, ix=ixmax+1,
iy=iymax+1 and iz=izmax+1, respectively. The values for the normalized k-vector components akx,
aky,akz are made available by using the module parameters. The second set of subroutines, bc_*_metal,
set the fields to be zero along those planes.
Table 15
Variables for subroutines bc_*_bloch and bc_*_metal
Variables for subroutines bc_*_bloch and bc_*_metal
in/out
complex,pointer
e(:,:,:,:)
Electric field at the current time
in/out
complex,pointer
h(:,:,:,:)
Magnetic field at the current time
internal
integer
ix,iy,iz,i
Loop counters
internal
complex
fxm1
Bloch phase – exp [−ik · a]
internal
complex
fxp1
Bloch phase – exp [ik · a]
internal
complex
fym1
Bloch phase – exp [−ik · b]
internal
complex
fyp1
Bloch phase – exp [ik · b]
internal
complex
fzm1
Bloch phase – exp [−ik · c]
internal
complex
fzp1
Bloch phase – exp [ik · c]
612
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
Table 16
Variables for subroutines PML_e and PML_h
Variables for subroutines PML_e and PML_h
in/out
complex,pointer
e_cur(:,:,:,:)
Electric field at the current time
in/out
complex,pointer
e_prev(:,:,:,:)
Electric field at the previous time
in/out
complex,pointer
h_cur(:,:,:,:)
Magnetic field at the current time
in/out
complex,pointer
h_prev(:,:,:,:)
Magnetic field at the previous time
in/out
complex,pointer
intcurle_1(:,:,:)
Integral of (∇ × E)z on left side of system
in/out
complex,pointer
intcurlh_1(:,:,:)
Integral of (∇ × H)z on left side of system
in/out
complex,pointer
intcurle_2(:,:,:)
Integral of (∇ × E)z on right side of system
in/out
complex,pointer
intcurlh_2(:,:,:)
Integral of (∇ × H)z on right side of system
input
real,pointer
wz_1(:)
Strength of absorber on left side of system
input
real,pointer
wz_2(:)
Strength of absorber on right side of system
internal
integer
ix,iy,iz,iz1
Loop counters
internal
complex
curl(3)
Curl of E or H
Table 17
Variables for subroutine set_wz
Variables for subroutine set_wz
output
real,pointer
wz_1(:)
Strength of absorber on left side of system
output
real,pointer
wz_2(:)
Strength of absorber on right side of system
internal
integer
i
Loop counter
6.2. Absorbing boundary conditions – Tables 16 and 17
The two subroutines PML_e and PML_h implement the absorbing layer equations which we derived in
Section 2.4. PML_e updates the electric field inside the absorbing layers while PML_h updates the magnetic fields.
Notice that the absorber at the left and right ends of the systems are handled independently and can be of different
thicknesses and absorption strengths.
The subroutine set_wz defines the strength of the absorbing layers on both the left (wz_1) and right (wz_2)
sides of the system. The absorption strength is in general a function of position and for most purposes it is
convenient to to define some smooth, for example, quadratic, switching on of the absorption.
7. Subroutines to calculate physical quantities
7.1. Subroutines calc_div_D and calc_div_B – Table 18
b but we can easily work out what those
E(r) and ∇ + · µ̂(r)H(r)
In fact our program actually calculates ∇ − · ε̂(r)b
quantities correspond to. Start from,
∇ · D = ρ.
(77)
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
613
Table 18
Variables for subroutines calc_div_D and calc_div_B
Variables for subroutines calc_div_D and calc_div_B
input
complex,pointer
e(:,:,:,:)
Electric field at the current time
input
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
output
complex,pointer
div_D(:,:,:)
Array to store ∇ · D
input
complex,pointer
h(:,:,:,:)
Magnetic field at the current time
input
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
output
complex,pointer
div_B(:,:,:)
Array to store ∇ · B
internal
integer
ix,iy,iz,i
Loop counters
internal
integer
ixm1
ix-1
internal
integer
iym1
iy-1
internal
integer
izm1
iz-1
internal
integer
ixp1
ix+1
internal
integer
iyp1
iy+1
internal
integer
izp1
iz+1
So in integral form,
Z
∇ · D dV = Q,
(78)
Vol
where Q is the charge in volume V . Using the divergence theorem,
Z
D · dS = Q.
(79)
Surface
So integrating over the surface of the cell surrounding one of our discrete mesh points. . .
Q/ε0 = ε(r)E 3 (r)u3 · Q1 Q2 (u1 × u2 ) − ε(r − c)E 3 (r − c)u3 · Q1 Q2 (u1 × u2 )
+ ε(r)E 1 (r)u1 · Q2 Q3 (u2 × u3 ) − ε(r − a)E 1 (r − a)u1 · Q2 Q3 (u2 × u3 )
+ ε(r)E 2 (r)u2 · Q3 Q1 (u3 × u1 ) − ε(r − b)E 2 (r − b)u2 · Q3 Q1 (u3 × u1 )
bi (r) − ε(r − c)g 3i E
bi (r − c) Q1 Q2 Q3
= Q0 |u1 · u2 × u3 | ε(r)g 3i E
Q0 Qi Q3
bi (r) − ε(r − a)g 1i E
bi (r − a) Q1 Q2 Q3
+ ε(r)g 1i E
Q0 Qi Q1
Q1 Q2 Q3
2i b
2i b
+ ε(r)g Ei (r) − ε(r − b)g Ei (r − b)
,
Q0 Qi Q2
bi (r) − ε̂ 3i (r − c)E
bi (r − c)
Q/(Q0 ε0 ) = ε̂ 3i (r)E
1i
1i
bi (r) − ε̂ (r − a)E
bi (r − a) + ε̂ 2i (r)E
bi (r) − ε̂ 2i (r − b)E
bi (r − b)
+ ε̂ (r)E
E(r).
= ∇ − · ε̂(r)b
(80)
(81)
So instead of returning Q the subroutine calc_div_D actually returns Q/(Q0 ε0 ) but that only differs from Q
by a constant. The same follows for calculating ∇ · B.
614
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
7.2. Subroutine calc_energy_density – Table 19
The correct discrete form for the energy density is. . .
U = 12 ε0 ε(r)Eα∗ (t)E α (t − δt) + µ0 µ(r)Hα∗ (t − δt)H α (t − δt) .
(82)
This has the correct form for the energy density in the limit δt → 0 and can be shown to be an exactly conserved
quantity on the lattice. Substituting the usual expressions for the generalized co-ordinates you get. . .
Q0 2 αβ 0 ∗
U0 αβ b∗ b
ε̂ Eα (t)Eβ (t − δt) +
µ̂ Ĥ α (t − δt)Ĥ 0 β (t − δt) ,
(83)
U=
2
c0 δt
where U0 = Q0 ε0 /(Q1 Q2 Q3 |u1 · u2 × u3 |). The subroutine calc_energy_density calculates the total
electromagnetic energy stored in the system at a given time. Notice though that any energy in the absorbing layers
is excluded from this calculation.
7.3. Subroutine calc_current – Table 20
The exact Poynting vector on the lattice can be obtained fairly simply by considering 1t U (t) = (U (t + δt) −
U (t))/δt. This gives. . .
U0 n b0∗
b30∗ (r − b, t) E
b1 (r, t)
U
(t)
=
H2 (r − c, t) − H
1+
t
2
b10∗ (r − c, t) E
b2 (r, t)
b30∗ (r − a, t) − H
+ H
Table 19
Variables for subroutine calc_energy_density
Variables for subroutine calc_energy_density
input
complex,pointer
e_cur(:,:,:,:)
Electric field at the current time
input
complex,pointer
e_prev(:,:,:,:)
Electric field at the previous time
input
complex,pointer
h_prev(:,:,:,:)
Magnetic field at the previous time
output
real,pointer
rho(:,:,:)
Energy density
input
complex,pointer
eps_hat(:,:,:,:,:)
Renormalized permittivity
input
complex,pointer
mu_hat(:,:,:,:,:)
Renormalized permeability
internal
integer
ix,iy,iz,i,j
Loop counters
internal
real
dtcq2
(δt c0 /Q0 )2
Table 20
Variables for subroutine calc_current
Variables for subroutine calc_current
output
complex
J(3)
Energy current away from mesh point
input
complex,pointer
e_cur(:,:,:,:)
Electric field at the current time
input
complex,pointer
h_cur(:,:,:,:)
Magnetic field at the current time
input
complex,pointer
h_prev(:,:,:,:)
Magnetic field at the previous time
input
integer
ix,iy,iz
Position co-ordinates
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
0∗
b1 (r − b, t) − H
b20∗ (r − a, t) E
b3 (r, t)
+ H
∗
0
b30 (r − b, t − δt) E
b1 (r, t)
b2 (r − c, t − δt) − H
+ H
0
b10 (r − c, t − δt) E
b2∗ (r, t)
b3 (r − a, t − δt) − H
+ H
0
b20 (r − a, t − δt) E
b3∗ (r, t)
b1 (r − b, t − δt) − H
+ H
0∗
b3 (r + b, t) H
b1 (r, t)
b2 (r + c, t) − E
+ E
0∗
b1 (r + c, t) H
b2 (r, t)
b3 (r + a, t) − E
+ E
0∗
b2 (r + a, t) H
b3 (r, t)
b1 (r + b, t) − E
+ E
0
∗
∗
b3 (r + b, t) H
b1 (r, t)
b2 (r + c, t) − E
+ E
0
∗
∗
b1 (r + c, t) H
b2 (r, t)
b3 (r + a, t) − E
+ E
o
∗
b2∗ (r + a, t) H
b30 (r, t) .
b1 (r + b, t) − E
+ E
615
(84)
These terms can be divided up into those which carry energy into a given mesh point and those which carry energy
away from it. The subroutine calc_current returns the three components of the energy flow away from the
given mesh point.
8. Miscellaneous subroutines
8.1. Subroutine err – Table 21
This is a very simple subroutine which takes as its argument the integer ierr and depending on its value writes
a relevant error message to the log file and then stops execution of the program. This allows other subroutines to
halt the calculation when they encounter a problem and leave the user with some clue as to what has gone wrong.
8.2. Function matinv3 – Table 22
The function matinv3 returns the inverse of the three by three matrix A. If A has no inverse then fail is set
to true else fail is false. emach is the machine accuracy.
Table 21
Variables for subroutine err
Variables for subroutine err
input
integer
ierr
Error number
Table 22
Variables for function matinv3
Variables for function matinv3
output
complex
matinv3(3,3)
A−1
input
complex
A(3,3)
3 × 3 matrix
input
real
emach
Machine accuracy
output
logical
fail
True if A has no inverse
internal
complex
det
|A|
internal
complex
B(3,3)
Work space
616
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
8.3. General matrix inversion – Table 23
Although not actually used by the program as it stands, this set of three routines provides facilities for inversion
of a general square matrix. The algorithm used is an LU decomposition followed by back-substitution as presented
in Numerical Recipes pages 33 and following [14]. The user is referred there for further details. Notice that the
original matrix A is destroyed by the inversion process and that any failure of the inversion procedure is indicated
by the flag fail.
8.4. Functions cross_prod and c_cross_prod – Table 24
The function cross_prod returns the cross-product of the two real three-vectors that the function takes as
arguments.
Similarly, the function c_cross_prod returns the cross-product of the two complex three-vectors that the
function takes as arguments.
8.5. Subroutines power_spec, FFT and FT – Tables 25 and 26
The subroutines FFT and power_spec are standard routines for performing a fast Fourier transform and using
that to obtain a power spectrum. The code follows directly from Numerical Recipes page 425 and following [14].
The only substantial alteration is the inclusion of the loop after the fast Fourier transform has been completed,
Table 23
Variables for functions matinv, lu_decomp and lu_bksub
Variables for function matinv, lu_decomp and lu_bksub
output
complex
matinv(:,:)
A−1
input
complex,pointer
A(:,:)
N × N matrix
input
real
emach
Machine accuracy
output
logical
fail
True if A has no inverse
internal
integer
D
Work space
internal
integer
i,j,k
Loop counter
internal
integer
imax
Index of largest pivot
internal
integer
N
Rank of A
internal
integer,pointer
indx(:)
Work space
internal
complex,pointer
B(:)
Work space
internal
complex
sum,dum,vv(:)
Work space
internal
real
aamax
Largest pivot
internal
integer
ii,ll
Work space
Table 24
Variables for function cross_prod
Variables for function cross_prod
output
real
cross_prod(3)
a×b
input
real
a(3),b(3)
Two 3-vectors
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
do i=1,nmax/2
w=2.0*pi*(i-1)/real(nmax)
f(1,i)=f(1,i)*cexp(+isign*ci*w*0.50)
enddo
Table 25
Variables for subroutines power_spec, FFT
Variables for subroutine power_spec
input
complex,pointer
f(:,:)
Array of functions to be transformed
output
real,pointer
spectrum(:)
Power spectrum
internal
integer
j,k
Loop counters
internal
integer
mm,m2,offset
Internal variables
internal
real
den,facm,facp,sumw
Internal variables
internal
real
window
Window function
internal
complex,pointer
w1(:,:),w2(:,:)
Work space
in/out
complex,pointer
f(:,:)
Array of functions to be transformed
input
integer
isign
+1 for transform, −1 for inverse transform
internal
complex
tmp,w,wp
Internal variables
internal
real
theta
Frequency
Variables for subroutine FFT
internal
integer
n
Number of functions to be transformed
internal
integer
nmax
Length of each function
internal
integer
nbits
Bit size of an integer
internal
integer
set_bits
Counter for number of set bits
internal
integer
i,j,k,m,mmax,istep
Internal variables
Table 26
Variables for subroutine FT
Variables for subroutine FT
in/out
complex,pointer
f(:,:)
Array of functions to be transformed
input
integer
isign
+1 for transform, −1 for inverse transform
internal
complex,pointer
ft_f(:)
Temporary array to hold the transforms
internal
complex
tmp
Temporary variable
internal
real
w
Frequency
internal
integer
n
Number of functions to be transformed
internal
integer
nmax
Length of each function
internal
integer
iw,i,it
Loop counters
617
618
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
This multiplies each frequency component by a factor exp [iω/2] which ensures that the Fourier transform we have
calculated corresponds to,
F (ω) =
Nt
X
f (n δt) exp iω(n − 0.5)δt
(85)
f (n δt) exp iω(n − 1)δt .
(86)
n=1
rather than,
F (ω) =
Nt
X
n=1
The half time step offset was found to be necessary in order to correctly calculate the Green’s function and avoid
negatives in the density of states.
The subroutine FT performs a straight-forward slow Fourier transform except for the half a time step offset in
the exponential part. So what we are calculating is,
F (ω) =
Nt
X
f (n δt) exp iω(n − 0.5)δt .
(87)
n=1
The array f(n,nmax) contains n separate functions of length nmax each of which is Fourier transformed
separately. The parameter isign determines whether a inverse transform is performed. If isign=1 it calculates
the transform, if isign=-1 it calculates inverse transform, except for the normalization factor.
Table 27
Parameters read in from infile.dat
Parameters read in from infile.dat
integer
ixmax
Number of mesh points in the x-direction
integer
iymax
Number of mesh points in the y-direction
integer
izmax
Number of mesh points in the z-direction
real
dx
Mesh spacing in x-direction in atomic units
real
dy
Mesh spacing in y-direction in atomic units
real
dz
Mesh spacing in z-direction in atomic units
real
dt
Size of the time step in atomic units
real
akx
Rescaled x-component of k. akx=(Q(1)*ixmax)*kx
real
aky
Rescaled y-component of k. aky=(Q(2)*iymax)*ky
real
akz
Rescaled z-component of k. akz=(Q(3)*izmax)*kz
integer
ikmax
Number of k points
integer
n_block
Number of blocks for time integration
integer
block_size
Size of each block
integer
n_pts_store
Number of points where we store the fields
integer
n_segment
Number of segments for the FFT (leave as 1)
logical
overlap
True if segments are to overlap (leave as false)
real
damping
Controls amount fields are damped when stored
integer
nw
The number of frequencies written to the output files
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
619
9. Input/output
Table 27 describes the parameters the program expects to be able to read in from a file called infile.dat
located in the current directory. The input routine is rather unsophisticated so the parameters must be supplied
in the order above, with no additional lines or blank lines. An example infile.dat is included in the standard
distribution. All program output is sent to one of five files. The first is out.dat which contains the principle output
from the program, so either a band structure, frequency spectrum or density of states. For the transmission/reflection
calculation out.dat contains the magnitude of the current reflected from the PML absorbing layer on the
right hand side of the system to give some indication as to how efficiently the PML’s are working. The second,
fields.dat is available for dumping out the electric and magnetic fields at various stages in the calculation. The
files ref.dat and trans.dat contain the reflection and transmission coefficients respectively as the principle
output from a transmission/reflection calculation. The final file log.dat contains a record of the calculation’s
progress subroutine by subroutine and it is here that the program will write any error message it generates. The
idea is that should a problem occur in a given calculation, this file should give some indication of where the problem
lies and what the nature of the problem might be.
Fig. 3. A triangular lattice of air holes in dielectric.
Fig. 4. The transmission coefficient for a triangular lattice of air holes in dielectric as produced by the ONYX program.
620
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
10. Example calculation
For a suitable test run we choose a two-dimensional array of dielectric cylinders placed in a triangular lattice
(Fig. 3). The dielectric constant of the cylinders is set to be 1, while for the host medium the dielectric constant is
9.0. The lattice
√ constant is 16a0 , the radius of each cylinder is 0.46 × 16a0 and the total length of the scattering
region is 4 3 lattice constants. The ONYX source code, and the infile.dat file supplied are set up to perform
a transmission and reflection coefficient calculation for this system. The transmission and reflection coefficients
as a function of frequency are sent to the files trans.dat ref.dat respectively with the frequencies in
dimensionless units of (ω a)/(2π c0 ). Results for both s and p polarizations can be found by altering the value
Fig. 5. The reflection coefficient for a triangular lattice of air holes in dielectric as produced by the ONYX program.
Fig. 6. Partial band structure for a triangular lattice of air holes in dielectric as produced by the ONYX program.
A.J. Ward, J.B. Pendry / Computer Physics Communications 128 (2000) 590–621
621
of i_pol in the main program and are shown in Figs. 4 and 5. For each calculation the electromagnetic fields
are integrated for 16 blocks of 1024 time steps each. The time steps themselves are each 0.004 × (me a02 /h̄)s.
Also given for comparison is a partial band structure for the same system in Fig. 6. Clearly the gaps in the band
structure correspond to minima in the transmission and corresponding maxima in the reflected power. The file
log.dat contains details of energy conservation as the calculation progresses. It lists the total transmitted and
reflected intensity as a function of frequency. Another test is included in the file out.dat which measures the
total reflected power from one of the PML absorbing layers. By inspecting this file the performance of the PML
can be assessed.
References
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
K.M. Leung, Y.F. Liu, Phys. Rev. Lett. 65 (1990) 2646.
Z. Zhang, S. Satpathy, Phys. Rev. Lett. 65 (1990) 2650.
K.M. Ho, C.T. Chan, C.M. Soukoulis, Phys. Rev. Lett. 65 (1990) 3152.
J.B. Pendry, A. MacKinnon, Phys. Rev. Lett. 69 (1992) 2772.
J.B. Pendry, J. Mod. Optics 41 (1994) 209.
K.S. Yee, IEEE Trans. on Antennas and Propagation 14 (1966) 302.
C.T. Chan, Q.L. Yu, K.M. Ho, Phys. Rev. B 51 (1995) 16635.
A.J. Ward, J.B. Pendry, Phys. Rev. B 58 (1998) 7252.
A.J. Ward, J.B. Pendry, Comput. Phys. Commun. 112 (1998) 23.
P.M. Bell, J.B. Pendry, L. Martín-Moreno, A.J. Ward, Comput. Phys. Commun. 85 (1995) 306.
A.J. Ward, J.B. Pendry, J. Modern Optics 43 (1995) 773.
J.P. Berenger, J. Comput. Phys. 114 (1994) 185.
L. Zhao, A.C. Cangellaris, IEEE Trans. on Microwave Theory Techniques 44 (1996) 2555.
W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling, Numerical Recipies: The Art of Scientific Computing (Cambridge University
Press, Cambridge, 1989).