* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download A program for calculating photonic band structures, Green`s
Superconductivity wikipedia , lookup
Magnetohydrodynamics wikipedia , lookup
Magnetochemistry wikipedia , lookup
Multiferroics wikipedia , lookup
Magnetoreception 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
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).