traping boundary of turbulent magnetic field lines
DESCRIPTION
My Senior ProjectTRANSCRIPT
Trapping Boundary of Turbulent
Magnetic Field Lines
Mr. Jakapan Meechai
Senior Project submitted to the
Department of Physics, Chulalongkorn University
in partial fulfillment of the requirements for the degree of
Bachelor of Science
Academic Year 2003
Project Title: Trapping Boundary of Turbulent Magnetic Field LinesName: Mr. Jakapan MeechaiProject Advisor: Asst. Prof. Dr. Udomsilp PinsookProject Co-Advisor: Assoc. Prof. Dr. David RuffoloDepartment: PhysicsAcademic Year: 2003
Abstract
We use a computer program to simulate turbulent magnetic field lines
in the 2D+slab model of turbulence, which has been shown to provide a good
description of solar wind turbulence. In this model, the magnetic field lines seem
to be temporarily trapped inside or outside of certain boundaries. We develop a
mathematical definition of local trapping boundaries, which are found to coincide
with the edges of the trapping regions of these turbulent magnetic field lines in
computer simulations.
i
Acknowledgements
I am grateful to my Co-Advisor, Assoc. Prof. Dr. David Ruffolo, for many guid-
ance and suggestions, for giving me a chance to use the scientific side of my mind
(by this project) and correcting my English. I am thankful to Asst. Prof. Dr.
Udomsilp Pinsook for being my advisor and giving me some recommendations. I
am also thankful to Asst. Prof. Manit Rujiwarodom, and Dr. Thiti Bovornrata-
naraks for being my senior project examiners.
I would like to thank Miss Piyanate Chuychai, Mr. Peera Pongkitiwanichkul
and everybody in the “Astrophysics Laboratory” for their kind instructions and
recommendations. This work could not be finished without them.
I also would like to thank everybody at the Department of Physics, Chu-
lalongkorn University, everybody at the Gr.3, everybody at the “BaanDork”, and
all other friends from other faculties for everything in my university life. Many
thanks to everybody at the “Music Club”, Faculty of Science, Chulalongkorn
University. They always brighten my days up humorously.
Finally, I wish to thank my family for their love. Special thanks to some-
ONE for her existence in this world.
ii
Table of Contents
Abstract i
Abstract in Thai ii
Acknowledgements iii
Table of Contents iv
List of Figures vi
1 Introduction 1
2 Turbulent Magnetic Field Model and Diffusion Theory 5
2.1 Turbulent Magnetic Field Model . . . . . . . . . . . . . . . . . . . 5
2.2 Diffusion Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Temporary Trapping . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Simulation of Turbulent Magnetic Field Lines 15
3.1 Generating the Magnetic Field . . . . . . . . . . . . . . . . . . . . 15
3.1.1 Generating the Slab Field . . . . . . . . . . . . . . . . . . 16
3.1.2 Generating the 2D Field . . . . . . . . . . . . . . . . . . . 18
3.2 Tracing the Magnetic Field Lines . . . . . . . . . . . . . . . . . . 19
3.2.1 Tracing Slab Trajectories . . . . . . . . . . . . . . . . . . . 19
iii
3.2.2 Tracing 2D Trajectories . . . . . . . . . . . . . . . . . . . 21
3.2.3 Tracing 2D+slab Trajectories . . . . . . . . . . . . . . . . 22
3.3 Local Trapping Boundaries . . . . . . . . . . . . . . . . . . . . . . 23
4 Results and Discussion 25
5 Conclusions 33
References 34
Appendices 35
A Numerical Methods 35
A.1 Interpolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A.1.1 Linear Interpolation . . . . . . . . . . . . . . . . . . . . . 35
A.1.2 Bilinear Interpolation . . . . . . . . . . . . . . . . . . . . . 36
A.2 Simulation Parameters . . . . . . . . . . . . . . . . . . . . . . . . 37
B Source Code 38
iv
List of Figures
1.1 Interplanetary magnetic field . . . . . . . . . . . . . . . . . . . . . 2
1.2 Energy of H-Fe ions (in units of MeV nucleon−1) vs. arrival time
at 1 AU for impulsive flare events of 1999 January 9-10 (Mazur et
al. 2000). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1 Pure slab magnetic field lines . . . . . . . . . . . . . . . . . . . . 7
2.2 Contours of a magnetic potential function for 2D turbulence . . . 8
2.3 A pure 2D magnetic field line . . . . . . . . . . . . . . . . . . . . 9
2.4 A 2D+slab (80:20) magnetic field line . . . . . . . . . . . . . . . . 10
2.5 Interplanetary magnetic field lines (Ruffolo et al. 2003) . . . . . . 12
2.6 Contours of a magnetic potential function with O-points and X-
points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.7 Scatter plot of magnetic field lines with dropouts . . . . . . . . . 14
3.1 Kolmogorov power spectrum . . . . . . . . . . . . . . . . . . . . . 15
4.1 Contours of a magnetic potential function . . . . . . . . . . . . . 26
4.2 Scatter plot of initial magnetic field line locations at z = 0. . . . . 27
4.3 Scatter plot of locations of magnetic field lines at about 0.25 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.4 Scatter plot of locations of magnetic field lines at about 0.50 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
v
4.5 Scatter plot of locations of magnetic field lines at about 0.75 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.6 Scatter plot of locations of magnetic field lines at about 1.00 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.7 Scatter plot of locations of magnetic field lines at about 1.25 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.8 Scatter plot of locations of magnetic field lines at about 1.50 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.9 Scatter plot of locations of magnetic field lines at about 1.75 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.10 Scatter plot of locations of magnetic field lines at about 2.00 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.11 Scatter plot of locations of magnetic field lines at about 2.25 AU
from the Sun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.12 Contour plot of b22D . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A.1 Linear interpolation at point P between two values F (xi) and
F (xi+1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A.2 Bilinear interpolation at point S . . . . . . . . . . . . . . . . . . . 36
vi
Chapter 1
Introduction
The solar wind is a stream of ionized gas flowing outward from the Sun in all
directions at speeds of about 400 km/s (about 1 million miles per hour). It
is caused by the heat of the outermost region of the Sun which is called the
corona. The corona can be seen with the naked eyes during a solar eclipse. The
temperature of the corona is very high, so hot that the coronal gas can expand and
escape gravitational attraction. The solar wind also drags the solar magnetic field
outward from the Sun to be the interplanetary magnetic field (IMF). Although
the solar wind moves out almost radially from the Sun, the rotation of the Sun
gives the magnetic field a spiral form (garden hose effect).
Turbulence is an irregular flow of fluids. Most flows occurring in nature
are turbulent. The turbulent flows must have these following characteristics.
First, the turbulent flows must have irregularity or randomness which makes it
impossible to use a deterministic approach to turbulence problems. Instead, we
rely on statistical methods. Second, the turbulent flows must have diffusivity
which causes a rapid rate of momentum, heat, and mass transfer. Third, turbu-
lent flows occur at high Reynolds number1. Fourth, turbulent flows are always
dissipative. The large scale must feed energy to the smaller scale with some losses,
1The fluid velocity times length scale divided by kinematic viscosity, R = uLν .
1
2
Figure 1.1: Interplanetary magnetic field
so turbulence will decay rapidly if there is no continuous supply of energy.
The solar wind is one example of a turbulent flow. It also drags out the
interplanetary magnetic field, so this is a turbulent magnetic field. As we know
that charged particles generally gyrate and travel along magnetic field lines, this
interplanetary magnetic field will control the path of accelerated charged particles
from solar events (such as solar flares and coronal mass ejections), which are called
solar energetic particles (SEP). The transport of solar energetic particles can be
divided into two different types. One is the transport along the mean magnetic
field. It is called parallel transport. Another is perpendicular transport, the
transport along magnetic field lines as they separate from the mean magnetic
field. Solar energetic particles diffuse away from the mean field by this kind of
transport.
3
The Advanced Composition Explorer (ACE) observed the transport of
solar energetic particles in many solar events. In a large number of impulsive
solar events, “dropouts” can be seen. Dropouts refer to discontinuous data where
the intensity of solar energetic particles repeatedly disappears and reappears (see
Figure 1.2). This observation seems to indicate that solar energetic particles are
Figure 1.2: Energy of H-Fe ions (in units of MeV nucleon−1) vs. arrival time at1 AU for impulsive flare events of 1999 January 9-10 (Mazur et al. 2000).
confined to filaments in space, and therefore have a slow diffusion rate. However,
observations from the IMP-8 and Ulysses spacecraft while they were on opposite
sides of the Sun showed very similar intensity profiles, indicating a fast diffu-
sion rate of solar energetic particles. The contradictory observations have been
explained recently by the idea that the solar energetic particles are trapped by
the small-scale topology of solar wind turbulence [1]. The dropouts reflect that
particles are temporarily trapped in three-dimensional filaments corresponding
to the shapes of magnetic potential islands in the two perpendicular directions.
These are irregular, non-geometric shapes.
This undergraduate senior project will examine the boundary of trapping
by using the turbulence model called the “2D+slab Model” [3], and will study
how the magnetic field lines and the boundary are related. The explanation of the
4
model will appear in the next chapter. Chapter 3 will explain the simulation of
magnetic field lines and the method of finding the trapping boundary of turbulent
magnetic field lines. The fourth and fifth chapters will show the results and
conclusions from the simulations, respectively.
Chapter 2
Turbulent Magnetic Field Modeland Diffusion Theory
2.1 Turbulent Magnetic Field Model
This senior project uses the 2D+slab model of turbulence, which is suited to
the actual solar wind (Matthaeus, Goldstein, and Roberts 1990) and can explain
the parallel transport of solar energetic particles in the solar wind (Bieber et al.
1994). In this model, we assume that the total magnetic field can be separated
into two terms:
B = B0 + b(x, y, z). (2.1)
The mean field B0 is constant, not depending on the position coordinates x, y
and z. The mean field also has the constant direction z, the direction along the
spiral curve of the interplanetary magnetic field (Figure 1.1). Another term is b,
the fluctuating field which is perpendicular to the mean field and depends on x,
y and z:
B0 = B0z, b ⊥ z. (2.2)
We model the fluctuating field by two terms. One is a term depending on x and
y. Another one depends on only z. They are called the 2D term and slab term,
5
6
respectively:
b = b2D(x, y) + bslab(z). (2.3)
From Maxwell’s equations, we know that
∇ ·B = 0, (2.4)
so
∇ ·B = ∇ ·B0 +∇ · b2D(x, y) +∇ · bslab(z) = 0. (2.5)
B0 does not depend on the position coordinates x, y and z, so
∇ ·B0 = 0. (2.6)
In general, we also know that
∇ · bslab(z) =∂bslab
x (z)
∂x+
∂bslaby (z)
∂y= 0, (2.7)
because bslabx (z) and bslab
y (z) do not depend on x and y. Therefore we must have
∇ · b2D(x, y) = 0. (2.8)
This implies that
b2D(x, y) = ∇× [a(x, y)z], (2.9)
where az can be interpreted as a vector potential for the 2D component of tur-
bulence. Here a(x, y) is called the magnetic potential function.
Both 2D and slab terms are random functions that depend on the Kol-
mogorov power spectrum. This spectrum is the natural spectrum of turbulence
phenomena. We generate the power spectrum first, and then transform to the
magnetic field by an inverse Fourier transform. The explanation of the power
spectrum and method of generating field lines will appear in the next chapter.
The 2D and slab fluctuating fields are random functions that average to zero.
7
This makes sense because it leaves the first term in Equation 2.1 as the mean
field. If there is only a slab fluctuating field, the magnetic field lines undergo a
simple random walk in x and y. The shapes of the magnetic field lines are similar
if they have same initial z position (beginning on the same x-y plane). Figure
2.1 shows an example of magnetic field lines with only a slab fluctuating field.
Figure 2.1: Pure slab magnetic field lines
For 2D fluctuations at every z, we have the same contours of the magnetic
potential function. Figure 2.2 is an example showing contours of the magnetic
potential function. The color shows the magnitude of the magnetic potential
function. White coloring is for highly positive values, black coloring is for highly
negative values, and grey coloring is for positive or negative values between those
for white and black. If there is only a 2D fluctuating field, the magnetic field
lines follow equipotential lines of the magnetic potential function (which have the
same color in the contour plot). We must combine slab and 2D components to
complete the turbulence model. Figure 2.4 shows an example of magnetic field
8
Figure 2.2: Contours of a magnetic potential function for 2D turbulence
lines with both 2D and slab fluctuating fields.
2.2 Diffusion Theory
By using the 2D+slab model of turbulence, we can explain the magnetic field
line trajectory as a diffusive random walk. The ensemble average statistics of the
field line random walk were calculated by Matthaeus et al. (1995). A diffusion
coefficient, D, is defined by
〈∆x2〉 = 2D∆z, (2.10)
where ∆x is the change in a perpendicular coordinate and ∆z is the distance
along the mean field. The diffusion coefficient of only the slab fluctuating field is
Dslab ∼〈b2
x〉B2
0
lc, (2.11)
9
Figure 2.3: A pure 2D magnetic field line
where lc is the correlation range
lc ≡∫∞
0〈bx(z0)bx(z0 + ∆z)〉d∆z
〈b2x〉
. (2.12)
Dslab is very small (≈ 5 × 10−4 AU) under the normal solar wind conditions, so
the magnetic field lines diffuse very slowly if we have only the slab fluctuating
field. The diffusion coefficient of the 2D fluctuating field alone is
D2D ∼ λ√2
√〈b2〉B0
, (2.13)
where λ is referred to as the “ultrascale” (Matthaeus et al. 1995),
λ =
√a2
〈b2〉2D. (2.14)
If we have only a 2D fluctuating field, the magnetic field lines are trapped in some
equipotential lines permanently, so we must combine the two types of fluctuating
fields. The overall value of the diffusion coefficient is
D =Dslab
2+
[(Dslab
2
)2
+ (D2D)2
] 12
. (2.15)
10
Figure 2.4: A 2D+slab (80:20) magnetic field line
Under normal solar wind conditions, the 2D component of turbulence
dominates (Matthaeus et al. 1995), and D2D is much greater than Dslab (Ruffolo,
Matthaeus, and Chuychai 2003). Because of the high diffusion coefficient, the
magnetic field lines can diffuse far from the mean field at long distances from the
Sun.
2.3 Temporary Trapping
Ensemble average statistics for the 2D+slab model give a diffusion coefficient in
the long-distance limit. Over shorter distances, the diffusion of a magnetic field
line in the 2D+slab model of solar wind turbulence depends on its starting point.
We call these conditional statistics. There are two interesting types of points in
the contour plot of the magnetic potential function. First are the local maxima
or minima of the magnetic potential function, which are called the O-points.
At these points, 2D fluctuating field is very small, so the slab fluctuating field
11
will dominate. The magnetic field lines that start near the O-points will diffuse
slowly due to the slab fluctuating field and then may be temporarily trapped
within “islands” of 2D turbulence, if the islands are not smaller than the mean
free path of slab trajectories. By an island we mean the enclosed area in which
magnetic fields lines are found to be temporarily trapped. The island boundary
separates the slow and fast diffusion zones. Other points of interest are saddle
points. They are called X-points. The magnetic field lines starting near the
X-points rapidly diffuse away from the initial position.
These two types of diffusion cause dropouts. As described in the introduc-
tion, dropouts refer to discontinuous data where the intensity of solar energetic
particles repeatedly disappears and reappears. When solar energetic particles
undergo transport along the interplanetary magnetic field lines (as we show in
Figure 2.5) which can be temporarily trapped in the islands, they are also trapped
in the islands for some distance. This phenomenon is illustrated in Figure 2.6
which shows O and X-Points, and Figure 2.7, which shows a distribution of field
lines at various z values. We can see that the intensity of solar energetic particles
in the islands is much higher than that outside, so we can observe the dropouts.
This mechanism implies that the size of dropouts corresponds to the size of the
islands and the empty space between the islands. The shapes of dropouts are
similar to the shapes of islands because the magnetic field lines outside the is-
lands have a faster diffusion rate. This leaves the magnetic field lines inside the
islands, which have a slow diffusion rate. The trapping of field lines inside the
islands is temporary.
This senior project introduces the local trapping boundary (LTB) for
describing the edge of trapping. At a local trapping boundary, there is a locally
maximal intensity of the 2D field on that contour, so the 2D field has a strong
12
Figure 2.5: Interplanetary magnetic field lines (Ruffolo et al. 2003)
effect on this boundary. The magnetic field lines are forced to go mainly along the
boundary. The mathematical definition and method of finding the local trapping
boundaries will be presented in the next chapter.
13
Figure 2.6: Contours of a magnetic potential function with O-points and X-points
14
Figure 2.7: Scatter plot of magnetic field lines with dropouts
Chapter 3
Simulation of TurbulentMagnetic Field Lines
This chapter will explain about the method of simulating the magnetic field lines
and about the local trapping boundary, which we use to describe the edge of
magnetic field line trapping.
3.1 Generating the Magnetic Field
As we explained in the previous chapter, we must generate a random function
in the wavenumber domain first and then transform this to the real space do-
main by an inverse Fourier transform. We use the Kolmogorov power spectrum
which is the natural spectrum of turbulent phenomena. Figure 3.1 shows the Kol-
-
log P (k)
P (k) ∝ k−53
log k
6
k0
Figure 3.1: Kolmogorov power spectrum
15
16
mogorov power spectrum in a log-log scale. We can see that the function at small
wavenumbers (very large scales) is constant and after the scale k0 the spectrum
has the slope (power law index) of -5/3. This spectrum arises when large scale
fluctuations feed energy to the smaller scales with some losses. Such spectra are
observed for all turbulent phenomena and can be explained theoretically.
3.1.1 Generating the Slab Field
The slab fluctuating field is a random function for which
〈bslabx 〉 = 0, 〈bslab
y 〉 = 0, (3.1)
and their characteristics depend on the Kolmogorov power spectrum, so we use
these following steps to generate them. Note that the power spectrum is defined
as the Fourier transform of the correlation function:
Pxx(k) ≡ 1
(2π)n2
∫ ∞
−∞Rxx(r) exp[i(r · k)]dnr (3.2)
Pyy(k) ≡ 1
(2π)n2
∫ ∞
−∞Ryy(r) exp[i(r · k)]dnr, (3.3)
where n is the dimensionality of the fluctuations (slab: n = 1, 2D: n = 2) and
the correlation function is defined by
Rxx(r) ≡ 〈bx(r0)bx(r0 + r)〉 (3.4)
Ryy(r) ≡ 〈by(r0)by(r0 + r)〉. (3.5)
Note also that the power spectrum is related to the amplitude of the Fourier
transform of b(x):
Pxx(k) ∝ |bx(k)|2 (3.6)
Pyy(k) ∝ |by(k)|2. (3.7)
17
In the first step, we generate the power spectrum (P slabxx or P slab
yy ). Since
bslab depends only on z, these can be written as a function of the wavenumber
kz, e.g.,
P slabxx (kz) =
C1
[1 + (kzlz)2]56
, (3.8)
where lz is a characteristic length scale related to lc in Equation 2.12, and C1 is
a constant. For the y component, we also have
P slabyy (kz) =
C1
[1 + (kzlz)2]56
. (3.9)
With the proper normalization P slabxx (kz) and P slab
yy (kz) are simply |bslabx (kz)|2 and
|bslaby (kz)|2, respectively. After that, we generate a random phase to split them
into two components of the complex number (the real part and imaginary part):
bslabx (kz) =
√P slab
xx (kz) exp(iφ) (3.10)
=√
P slabxx (kz) cos φ + i
√P slab
xx (kz) sin φ,
where i is√−1 and φ is a random phase for each kz (varying from 0 to 2π). We
also have
bslaby (kz) =
√P slab
yy (kz) exp(iφ) (3.11)
=√
P slabyy (kz) cos φ + i
√P slab
yy (kz) sin φ.
Finally, when we already have both the x-components and y-components of the
magnetic field in the wavenumber domain, we transform them to the real space
domain by the inverse Fourier transform. We can write the two slab fluctuating
components as
bslabx (z) =
1√2π
∫ ∞
−∞bslabx (kz) exp(−ikzz)dkz, (3.12)
bslaby (z) =
1√2π
∫ ∞
−∞bslaby (kz) exp(−ikzz)dkz, (3.13)
bslab(z) = bslabx (z)x + bslab
y (z)y. (3.14)
18
By the way, the numerical method that we use for the inverse Fourier transform
is the “fast Fourier transform” (Press et al. 1992). In the numerical method, we
divided the total length of z into 2n grid points, where we used n = 22.
3.1.2 Generating the 2D Field
The 2D fluctuating field is a function of x and y. It must also have the character-
istics of a Kolmogorov power spectrum and the condition in Equation 2.8, so we
use the following steps to generate them. First, we generate the power spectrum.
A(k⊥) =1
[1 + (k⊥l⊥)2]73
, (3.15)
where A(k⊥), the power spectrum of a(x, y), is defined as the Fourier transform
of correlation function 〈a(r0)a(r0 + r)〉,
k⊥ =√
k2x + k2
y, (3.16)
and l⊥ is related to λ in Equation 2.14. The reason for using the exponent 7/3
will be given below.
First, we assign a random phase to a(k⊥):
a(k⊥) =√
A(k⊥) exp(iφ), (3.17)
Now recall Equation 2.9,
b2D(x, y) = ∇× [a(x, y)z]. (3.18)
After Fourier transforms to the wavenumber domain, we have
b2D(kx, ky) = −ik× [a(kx, ky)z]. (3.19)
Then we have
P 2Dxx (kx, ky) = k2
yA(k⊥) (3.20)
P 2Dyy (kx, ky) = k2
xA(k⊥), (3.21)
19
and
P 2Dxx + P 2D
yy = k2⊥A. (3.22)
The power spectrum which we use for the 2D fluctuating field must be summed
over all directions to obtain the omnidirectional power spectrum (OPS), which
should vary as k−5/3 (following the Kolmogorov law). This gives OPS ∝ k⊥(P 2Dxx +
P 2Dyy ) = k3
⊥A ∝ k−5/3. This is why we use the exponent 7/3 in Equation 3.15.
Now, we can find b2D as a function of wavenumber (kx, ky). Finally, we
perform an inverse Fourier transform of b2D to the space domain:
b2Dx (x, y) =
1
2π
∫ ∞
−∞
∫ ∞
−∞b2Dx (kx, ky) exp[−i(r · k)]dkxdky, (3.23)
b2Dy (x, y) =
1
2π
∫ ∞
−∞
∫ ∞
−∞b2Dy (kx, ky) exp[−i(r · k)]dkxdky, (3.24)
As for the slab field, we divide the total length of x and y into 2n×2m grid points
(n and m are integers), and we use periodic boundary conditions at the edges of
the 2D plane.
3.2 Tracing the Magnetic Field Lines
This section is based on a computer program by Mr. Peera Pongkitiwanichkul.
The author thanks him for kindly providing the program and instructions. After
we generate the magnetic field, we trace the magnetic field lines using the equation
dx
Bx
=dy
By
=dz
Bz
. (3.25)
In this model Bz is always the constant B0, so we can calculate the trajectories
of fluctuating field lines by the following method.
3.2.1 Tracing Slab Trajectories
We create the slab magnetic field lines from the equation
dx
dz=
bslabx
B0
,dy
dz=
bslaby
B0
. (3.26)
20
For the grid points of the Fourier transform, we know bslabx and bslab
y . At interme-
diate z values, bslabx or bslab
y is calculated using linear interpolation (see Appendix
A):
bslabx (z) =
z − iδz
δz(bslab
x )i+1 +(i + 1)δz − z
δz(bslab
x )i, (3.27)
where δz is the total length of z divided by the number of grid points (Lz/Nz),
and i and i + 1 label the grid points surrounding z. We can rewrite that as
bslabx (z) = mxz + cx, (3.28)
where
mx =(bslab
x )i+1 − (bslabx )i
δz, (3.29)
and
cx = (bslabx )i(i + 1)− (bslab
x )i+1i, (3.30)
We can see that cx has the same dimensions as bslabx and bslab
x . Similarly, for the
y component,
bslaby (z) = myz + cy, (3.31)
where
my =(bslab
y )i+1 − (bslaby )i
δz, (3.32)
and
cy = (bslaby )i(i + 1)− (bslab
y )i+1i. (3.33)
Now, we have the equations
dx
dz=
mxz + cx
B0
(3.34)
dy
dz=
myz + cy
B0
. (3.35)
21
The solutions of these equations are
x− x0 =1
B0
[mx(z
2 − z20) + cx(z − z0)
](3.36)
y − y0 =1
B0
[my(z
2 − z20) + cy(z − z0)
]. (3.37)
These solutions are valid if there is only a slab fluctuating field.
3.2.2 Tracing 2D Trajectories
We use bilinear interpolation to find the potential function at any position a(x, y):
a(x, y) =(x− iδx)(y − jδy)
δx δyai+1,j+1 +
[(i + 1)δx− x](y − jδy)
δx δyai,j+1 (3.38)
+(x− iδx)[(j + 1)δy − y]
δx δyai+1,j +
[(i + 1)δx− x][(j + 1)δy − y]
δx δyai,j,
or we can write this as
a(x, y) = a1xy + a2x + a3y + a4 (3.39)
From Chapter 2, we know that
b2D(x, y) = ∇× [a(x, y)z]. (3.40)
This gives
b2Dx =
∂a
∂y= a1x + a3, (3.41)
and
b2Dy =
∂a
∂x= a1y + a2. (3.42)
From Equation 3.25, we get
dx
dz=
a1x + a3
B0
(3.43)
dy
dz=
a1y + a2
B0
. (3.44)
22
The solutions of these equations are
z − z0
B0
=1
a1
ln
(a1x + a3
a1x0 + a3
)(3.45)
z − z0
B0
=1
a1
ln
(a1y + a2
a1y0 + a2
). (3.46)
These solutions are valid if there is only a 2D fluctuating field.
3.2.3 Tracing 2D+slab Trajectories
From Equations 3.25, 3.34 and 3.43, we have
dx
dz=
mxz + a1x + Cx
B0
, (3.47)
where
Cx = cx + a3. (3.48)
For the y component, we have
dy
dz=
myz + a1x + Cy
B0
, (3.49)
with
Cy = cy + a2. (3.50)
The solutions of these 2D+slab trajectories are
x = Ax exp
(a1
B0
z
)− mx
a1
z −[mxB0 + Cxa1
a21
](3.51)
y = Ay exp
(a1
B0
z
)− my
a1
z −[myB0 + Cya1
a21
], (3.52)
where Ax and Ay are integration constants that are determined by the initial
location of the field line.
All the above solutions are only valid in one cell (the cubic space sur-
rounded by 3D grid points of the 2D+slab field which we already generated in
the last section). When a field line reaches the edge of a cell, we have to find the
23
position where the magnetic field line leaves the cell. We take the exit position of
the previous cell as the initial position in the new cell. By this method, we can
trace entire magnetic field lines.
3.3 Local Trapping Boundaries
As can be seen in the scatter plot of magnetic field lines in Figure 2.7, there seem
to be sharp boundaries that can temporarily trap the magnetic field lines inside.
Dropouts occur with these boundaries because there are a lot of magnetic field
lines inside the boundaries and few magnetic field lines outside the boundaries.
In this senior project, we develop the concept of the local trapping boundary
(LTB), which is a mathematical concept and can be interpreted as the boundary
of trapping.
We define the local trapping boundary as an equipotential contour that
has a maximum average 2D fluctuation energy compared with neighboring con-
tours. We know that the 2D magnetic energy at each position depends on the
square of the magnetic field:
E(x, y) ∝ |b(x, y)|2, (3.53)
so we can view the average value of |b|2 along the equipotential line as a average
value of the energy.
As we explained in Chapter 2, there are two special types of points in the
contour plot of the 2D magnetic field. There is slow diffusion (almost slab) near
the O-points and there is fast diffusion (both 2D and slab) near the X-points. At
both O-points and X-points we have b = 0. The local trapping boundary contour
has a maximum 〈b2〉, so it could be the edge that separates near-O-point zones
and near-X-point zones.
24
The magnetic field lines that start inside the local trapping boundary are
always temporarily trapped inside. The magnetic field lines that have starting
points outside the local trapping boundary diffuse away over a short distance
in the z direction. We can find the equipotential contours by tracing the 2D
magnetic field lines, without slab turbulence. While tracing the pure 2D magnetic
field lines we can collect the values of |b(x, y)|2 and calculate their average value:
|b|2av =
∫|b(x, y)|2dl
L, (3.54)
where dl is a small step along the equipotential contour (in the x-y plane) and
L is the total length of the equipotential line. Another method of finding the
average value is integration along the z direction:
|b|2av =
∫|b(x, y)|2dz
Lz
. (3.55)
(In practice, we observe little difference in the results for the two definitions.) We
use a computer for all the steps listed above.
When we already have the average value of the energy along an equipo-
tential line, we print out and compare it with neighboring equipotential contours
by eye. If its average value of energy is greater than those of contours both inside
and outside, it is called a local trapping boundary.
Chapter 4
Results and Discussion
After simulating the magnetic field lines by the methods that we described in
Chapters 2 and 3, and using appropriate parameters for solar wind conditions
(see Appendix A), we obtain the results presented in this chapter.
We set the magnetic field lines to start from random initial locations
inside a circle at z = 0. We can see in Figures 4.2-4.11 that the magnetic field
lines that start outside a local trapping boundary rapidly diffuse away from the
initial position. The magnetic field lines that start inside the local trapping
boundary are temporarily trapped for some distance. This means that inside the
local trapping boundary is the near-O-Point-zone and outside the local trapping
boundary is the near-X-Point-zone. The local trapping boundary not only traps
the magnetic field lines inside, but also inhibits the magnetic field lines from
going inside, as seen for the small island in the upper left corner of these figures.
Generally, regions of high b22D coincide with sharp gradients in the density of field
lines.
We can also see that LTBs, which are equipotential contours that have
a maximum value of 〈b22D〉 compared with neighboring contours, nearly coincide
with sharp gradients in the scatter plots of magnetic field lines, so it can be
interpreted as an boundary of trapping which we draw from the simulation. This
25
26
Figure 4.1: Contours of a magnetic potential function
seems to tell us that trapping of turbulent magnetic field lines depends on the
value of b22D. It seems that the magnetic field lines rarely go through an area or
a contour that has a high amount of 2D fluctuating field. We can see a contour
plot of b22D in Figure 4.12.
From these new results, we know that now we can mathematically predict
the trapping edges of turbulent magnetic field lines, including where to find solar
energetic particles when dropouts occur (as can be seen in Ruffolo, Matthaeus,
and Chuychai 2003).
27
Figure 4.2: Scatter plot of initial magnetic field line locations at z = 0.
28
Figure 4.3: Scatter plot of locations of magnetic field lines at about 0.25 AU fromthe Sun
29
Figure 4.4: Scatter plot of locations of magnetic field lines at about 0.50 AU fromthe Sun
30
Figure 4.5: Scatter plot of locations of magnetic field lines at about 0.75 AU fromthe Sun
31
Figure 4.6: Scatter plot of locations of magnetic field lines at about 1.00 AU fromthe Sun
32
Figure 4.7: Scatter plot of locations of magnetic field lines at about 1.25 AU fromthe Sun
33
Figure 4.8: Scatter plot of locations of magnetic field lines at about 1.50 AU fromthe Sun
34
Figure 4.9: Scatter plot of locations of magnetic field lines at about 1.75 AU fromthe Sun
35
Figure 4.10: Scatter plot of locations of magnetic field lines at about 2.00 AUfrom the Sun
36
Figure 4.11: Scatter plot of locations of magnetic field lines at about 2.25 AUfrom the Sun
37
Figure 4.12: Contour plot of b22D
Chapter 5
Conclusions
We have simulated the turbulent magnetic field lines by the 2D+slab model, and
we also mathematically defined a local trapping boundary(LTB), which is an
equipotential contour that has a maximum average 2D fluctuation energy com-
pared with neighboring contours. We have proven that the LTB really functions
as a boundary of the trapping region. That is, the magnetic field lines that start
inside the local trapping boundary are temporarily trapped inside the local trap-
ping boundary for some distance. The magnetic field lines that start outside the
local trapping boundary rarely go inside the local trapping boundary. We can
conclude that the mathematically defined local trapping boundary can truly be
interpreted as a trapping boundary of turbulent magnetic field lines. This gives
us a way to mathematically express where trapping will take place, based on the
characteristics of the 2D turbulence alone.
38
References
[1] Ruffolo, D., Matthaeus, W. H., and Chuychai, P., Trapping of Solar En-
ergetic Particles by The Small-Scale Topology of Solar Wind Turbulence
(2003), Astrophys. J. 597, L169.
[2] Matthaeus, W. H., Goldstein, M. L., and Roberts, D. A. (1990) J. Geophys.
Res. 95, 20,673.
[3] Matthaeus, W. H., Gray, P. C., Pontius, D. H. Jr., and Bieber, J. W. (1995),
Phys. Rev. Lett. 75, 2136.
[4] Ruffolo, D., Matthaeus, W. H., Separation of Magnetic Field Line in Two-
Component Turbulence, submitted by Astrophys. J..
[5] Mazur, J. E., Mason, G. M., Giacolone, J., Jokipii, J. R., and Stone, E. C.
(2000), Astrophys. J. 532, L79.
[6] Bieber, J. W., Matthaeus, W. H., Smith C. W., Wanner, W., Kallenrode,
M.-B., and Wibberenz, G., (1994), Astrophys. J., 420, 294.
[7] Tennekes, H., and Lumley, J. L., A First Course in Turbulence (1994), The
MIT Press, Messachusetts, United States of America.
[8] Press, W. H., Teukolsky, S. A., Vetterling, W. T., Flannery B. P., Numerical
Recipes in C (1992), Cambridge University Press, Cambridge, England.
39
Appendix A
Numerical Methods
A.1 Interpolation
Often a function, say F, is known for specific values of the independent variable(s),
call “grid points.” When we have to find the value of F at a point between two
1D grid points or at a point surrounded by four 2D grid points, we use the
interpolation method. There are two types of interpolation in this senior project.
They are called linear interpolation and bilinear interpolation which are use for
1D and 2D grid points, respectively.
A.1.1 Linear Interpolation
We use the linear interpolation for slab grid points. The linear interpolation
between two points is illustrated in Figure A.1 below.
FP (x)• •Fxi
×Fxi+1
Figure A.1: Linear interpolation at point P between two values F (xi) and F (xi+1)
The formula for F at point P is
Fp(x) =xi+1 − x
xi+1 − xi
F (xi) +x− xi
xi+1 − xi
F (xi+1) (A.1)
40
41
= (1− fx)F (xi) + fxF (xi+1),
where
fx ≡x− xi
xi+1 − xi
. (A.2)
A.1.2 Bilinear Interpolation
We use linear interpolation in two dimensions between 2D grid points. We can
calculate a function value Fs at S by using bilinear interpolation as follows:
At point P : (A.3)
FP (x, yj) = (1− fx)F (xi, yj) + fxF (xi+1, yj).
At point Q : (A.4)
FQ(x, yj+1) = (1− fx)F (xi, yj+1) + fxF (xi+1, yj+1)
At point S : (A.5)
FS(x, y) = .(1− fy)FP (x, yj) + fyFQ(x, yj+1),
where
fy ≡y − yj
yj+1 − yj
. (A.6)
F (xi, yj) F (xi+1, yj)
F (xi, yj+1) F (xi+1, yj+1)
P
Q
S FS(x, y)
• •
• •
×
×
×
Figure A.2: Bilinear interpolation at point S
42
Now, we can calculate the function value FS(x, y) as follows:
FS(x, y) = (1− fy)(1− fx)F (xi, yj) + (1− fy)fxF (xi+1, yj) (A.7)
+(1− fx)fyF (xi, yj+1) + fxfyF (xi+1, yj+1).
A.2 Simulation Parameters
We use simulation parameters similar to the solar wind conditions [1]. The pa-
rameters are as follow:
mean field B0 = 1
parallel scale length λ‖ = 1
perpendicular scale length λ⊥ = 4
turbulent to mean magnetic field ratiob
B0
=1
2
energy ratio (2D:slab) 80 : 20
grid points Nx = 2048
Ny = 2048
Nz = 4194304
total box lengths Lx = 100
Ly = 100
Lz = 1000
random seed numbers iseed 1(for slab) = 43330176
iseed 2(for slab) = 43330038
iseed 3(for 2D) = 223346
Appendix B
Source Code
c--------------------------------------------------------------------program fline
call inputfldscall makeline
endc--------------------------------------------------------------------
subroutine makelineinclude ’parm.h’integer nx,ny,nzinteger step,datasizeparameter (step=419430)parameter (datasize=10)parameter (twopi=2*3.14159265358979323846d0)real*8 lx,ly,lzcommon /nbox/ nx,ny,nzcommon /lbox/ lx,ly,lzreal*8 eslab,lambda_par,alpha1,phase,rrandomcommon /slab/ eslab,lambda_par,alpha1real*8 bx1,by1,a2dcommon /bslab/ bx1(nzmax+2),by1(nzmax+2)common /aa/ a2d(nxmax,nymax)real*8 xp,yp,zp,radcircommon /xp/ xp(20001),yp(20001),zp(20001)real*8 h,ran1integer noline,check,check2,iireal*8 xx,yy,zz
iseed_4=1627190184iseed_5=708969183iseed_6=13894221call genslab()call gen2d()open(2,FILE=’VXtest5000.dat’)
write(2,*)’ ’close(2)radcir=9.iseed_4=-iseed_4iseed_5=-iseed_5iseed_6=-iseed_6do j=1,10000
rrandom=sqrt((radcir**2)*dble(ran1(iseed_5)))phase=dble(twopi*ran1(iseed_4))xp(1)=(12.5)+(rrandom*cos(phase))yp(1)=(12.5)+(rrandom*sin(phase))
43
44
zp(1)= 0.if (eslab.ne.0) then
call trace(step,datasize)else
call trace2d(step,datasize)endifopen(2,FILE=’VXtest5000.dat’,access=’append’)do s=1,datasize
write(2,*) xp(s),yp(s)enddoclose(2)
enddoend
c--------------------------------------------------------------------subroutine inputflds
integer nx,ny,nzreal*8 lx,ly,lzcommon /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nznamelist /box/ lx,ly,lz,nx,ny,nz,nnreal*8 b0,dbobcommon /field/ b0,dbobnamelist /field/ b0,dbobreal*8 eslab,lambda_par,alpha1common /slab/ eslab,lambda_par,alpha1namelist /slab/ eslab,lambda_par,alpha1real*8 e2d,lambda_per,alpha2common /twod/ e2d,lambda_per,alpha2namelist /twod/ e2d,lambda_per,alpha2integer iseed_1,iseed_2,iseed_3common /seeds/ iseed_1,iseed_2,iseed_3namelist /seeds/ iseed_1,iseed_2,iseed_3character*256 flnminteger fldfile
flnm=’input.nml’fldfile = 9open(fldfile,file=flnm)
read(fldfile,nml=box)read(fldfile,nml=field)read(fldfile,nml=slab)read(fldfile,nml=twod)read(fldfile,nml=seeds)
close(fldfile)return
endc--------------------------------------------------------------------
subroutine genslab()include ’parm.h’real*8 dbob,alpha1real*8 b0,eslab,lambda_parparameter (twopi=2*3.14159265358979323846d0)real*8 ssp1,sp,ssp2,enorm,ewantreal*8 phase1,phase2real*8 ran1,deltax,deltay,deltazinteger iseed_1,iseed_2,iseed_3real*8 rkx,rky,kzinteger loc,kx,kyinteger anz(1)real*8 lx,ly,lzinteger nx,ny,nzcommon /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nz
45
common /field/ b0,dbobcommon /slab/ eslab,lambda_par,alpha1common /seeds/ iseed_1,iseed_2,iseed_3real*8 bx1,by1common /bslab/ bx1(nzmax+2),by1(nzmax+2)
deltax=twopi/lxdeltay=twopi/lydeltaz=twopi/lzanz(1)=nzewant=(dbob**2.)*eslabiseed_1=-iseed_1iseed_2=-iseed_2ssp1=0.d0
c*********************************c generate magnetic fieldc*********************************
bx1(1)=0bx1(2)=0by1(1)=0by1(2)=0do k=3,nz+2,2
kz=deltaz*(k-1)/2sp=dble(1+dble(kz*lambda_par)**2.)**(-alpha1/4.)phase1=twopi*dble(ran1(iseed_1))phase2=twopi*dble(ran1(iseed_2))bx1(k)=dsin(phase1)*spbx1(k+1)=dcos(phase1)*spby1(k)=dsin(phase2)*spby1(k+1)=dcos(phase2)*spssp1=ssp1+bx1(k)**2+by1(k)**2
& +bx1(k+1)**2+by1(k+1)**2enddoenorm=dsqrt(ewant/(2*ssp1))do k=1,nz+2
bx1(k)=bx1(k)*enormby1(k)=by1(k)*enorm
enddocall four2(bx1,anz,1,-1,-1)call four2(by1,anz,1,-1,-1)ssp1=0.d0do i=1,nz
bx1(i)=bx1(i)*2.d0ssp1=ssp1+(bx1(i)**2.)by1(i)=by1(i)*2.d0
enddoreturnend
c--------------------------------------------------------------------subroutine gen2d()
include ’parm.h’real*8 dbob,alpha2real*8 b0,e2d,lambda_perparameter (twopi=2*3.14159265358979323846d0)real*8 ssp1,sp,ssp2,enorm,ewantreal*8 phase3real*8 ran1,deltax,deltay,deltazinteger iseed_1,iseed_2,iseed_3real*8 rkx,rkyinteger loc,kx,ky,i,j,kinteger n(2)real*8 lx,ly,lzinteger nx,ny,nz,nn
46
common /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nzcommon /field/ b0,dbobcommon /twod/ e2d,lambda_per,alpha2common /seeds/ iseed_1,iseed_2,iseed_3real*8 a((nxmax+2)*nymax)real*8 a2d,a1,a2,a3,a4common /aa/ a2d(nxmax,nymax)
nn=(nx+2)*nyn(1)=nxn(2)=nydeltax=twopi/lxdeltay=twopi/lydeltaz=twopi/lzdo i=1,nn
a(i)=0.d0enddoewant=e2d*(dbob**2.)ssp1=0.d0iseed_3=-iseed_3do i=4,nn,2
phase3=twopi*dble(ran1(iseed_3))call kloc(kx,ky,n,i)rkx=kx*deltaxrky=ky*deltaysp=1/(1+dble((rkx**2+rky**2)*(lambda_per**2)))**(alpha2/4.d0)a(i-1)=dcos(phase3)*spa(i)=dsin(phase3)*spssp1=ssp1+((rky**2.+rkx**2.)*(sp**2.))if (kx.eq.0) then
call lloc(0,-ky,n,loc)a(loc-1)=a(i-1)a(loc)=-a(i)
endifenddo
enorm=dsqrt(ewant/(2*ssp1))do k=1,nn
a(k)=a(k)*enormenddocall four2(a,n,2,-1,-1)k=1open(59,FILE=’a.dat’)do j=1,ny
do i=1,nxa(k)=a(k)*2.d0write(59,*)a(k)a2d(i,j)=a(k)k=k+1
enddoenddoclose(59)
returnend
c--------------------------------------------------------------------function ran1(idum)integer idum,ia,im,iq,ir,ntab,ndivdouble precision ran1,am,eps,rnmxparameter (ia=16807,im=2147483647,am=1./im,iq=127773,& ir=2836,ntab=32,ndiv=1+(im-1)/ntab,eps=1.2e-7,& rnmx=1.-eps)integer j,k,iv(ntab),iy/0/SAVE iv,iy
47
DATA iv /ntab*0/,iy/0/if(idum.le.0.or.iy.eq.0) then
idum=max(-idum,1)do j=ntab+8,1,-1
k=idum/IQidum=ia*(idum-k*iq)-ir*kif(idum.lt.0) idum=idum+imif(j.le.ntab) iv(j)=idum
enddoiy=iv(1)
endifk=idum/iqidum=ia*(idum-k*iq)-ir*kif(idum.lt.0) idum=idum+imj=1+iy/ndiviy=iv(j)iv(j)=idumran1=min(am*iy,rnmx)returnend
c--------------------------------------------------------------------
subroutine kloc(KX,KY,N,loc)dimension N(2)
NINROW=N(1)+2NTOP=NINROW*(N(2)/2+1)IF (LOC.GT.(NINROW*N(2)))GO TO 220IF (LOC.GT.NTOP) GO TO 210KY=(LOC-1)/NINROWKX=(LOC-KY*NINROW-1)/2RETURN
210 KY=1-N(2)/2+(LOC-NTOP-1)/NINROWKX=(LOC-NTOP-(KY+N(2)/2-1)*NINROW-1)/2RETURN
220 WRITE (6,230)LOC230 FORMAT(’0’,’ERROR IN KLOC,LOC TOO LARGE’,2X,I10)
RETURNEND
c--------------------------------------------------------------------
subroutine lloc(kx,ky,n,loc)integer n(2)
nadd=0ninrow=n(1)+2if(ky.lt.0) nadd=n(2)
loc=ninrow*(nadd+ky)+2*(kx+1)return
endc--------------------------------------------------------------------
subroutine trace2d(step,datasize)include ’parm.h’real*8 hz,bzinteger step,datasizeparameter (twopi=2*3.14159265358979323846d0)real*8 x,y,z,h,zmax,zzreal*8 px1d,py1d,pzreal*8 ztoy,ztox,app1,app2integer check,pinteger d,x1,x2,y1,y2real*8 px,py,bx,by,ppx,ppyreal*8 exceedzinteger ox,oyreal*8 xzmax,yzmax,zzmax,dz,zroundreal*8 gbx,gby,xpeak,ypeakreal*8 trx,try,trz
48
real*8 xp,yp,zpcommon /xp/ xp(20001),yp(20001),zp(20001)integer nx,ny,nz,check2real*8 lx,ly,lzcommon /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nzreal*8 a2d,bx1,by1real*8 x3,y3,z3,px3,py3common /bslab/ bx1(nzmax+2),by1(nzmax+2)common /aa/ a2d(nxmax,nymax)integer kstep
kstep=int(step/datasize)zmax=2.d0bz=1.d0trx=lx/dble(nx)try=ly/dble(ny)trz=lz/dble(nz)hz=1.d0
c ************************c start gen fieldc ************************
p=2x=xp(1)/trxy=yp(1)/tryz=zp(1)/trzpx=xpy=yppx=xppy=yexceedz=0.d0ox=0oy=0gbx=bx(x,y,px,py)gby=by(x,y,px,py)if (gbx.lt.0) then
px=x+0.1ppx=px
elsepx=x-0.1ppx=px
endif
if (gby.lt.0) thenpy=y+0.1ppy=py
elsepy=y-0.1ppy=py
endifh=hzz=zp(1)/trzzz=dble(int(z/100.d0))z=z-(100.d0*zz)
c*******************************c one linec*******************************
do i=1,stepcheck=0if (z.gt.100) then
z=z-100.zz=zz+1.
endifcall locate(x,y,ox,oy,check)
51 if (abs(x).lt.1.d-11) x=0.if (abs(y).lt.1.d-11) y=0.xpeak=xypeak=y
49
px3=pxpy3=pyx3=xy3=yz3=zpx1d=xpy1d=ypz=zcheck2=0if ((int(x).ne.0).and.(int(y).ne.0)) then
if (z.lt.zmax) goto 71endif
61 call edge(x3,y3,z3,zmax,bz,px3,py3)check2=1
71 px=xpy=yapp1=app(px,py)z=z+hif (check2.eq.1) then
if (z.gt.zmax) thenexceedz=z-zmaxz=zmax
elseexceedz=0.d0endif
endifx=ztox(px,py,pz,z,bz,ppx,ppy)y=ztoy(px,py,pz,z,bz,ppx,ppy)if (integ(x).ne.integ(px)) then
if (abs(x-integ(x)).gt.1.d-8) thenif (abs(px-integ(px)).gt.1.d-8) then
x=pxy=pypx=px3py=py3z=z3goto 61
endifendif
endif
if (integ(y).ne.integ(py)) thenif (abs(y-integ(y)).gt.1.d-8) then
if (abs(py-integ(py)).gt.1.d-8) thenx=pxy=pypx=px3py=py3z=z3goto 61
endifendif
endifapp2=app(x,y)if (i.lt.10) then
if (app1.ne.app2) thenx=xpeaky=ypeakz=pz+h
endifendifppx=pxppy=py
c*******************************************c Small stepsc*******************************************
if ((exceedz.gt.1.d-10).and.(app1.eq.app2)) thenh=exceedz
50
check=check+1if (check.eq.1) then
xzmax=xyzmax=yzzmax=z
endifif (check.ge.5) then
check=0if((abs(xzmax-x).lt.1.d-8)
& .and.(abs(yzmax-y).lt.1.d-8))thendz=z-zzmaxzround=exceedz/dzz=z+int(zround)*dzexceedz=exceedz-(dz*int(zround))if (dz.lt.1.d-8) then
z=z+exceedzexceedz=0.d0
endifh=exceedz
endifendifgoto 51
elseh=hz
endifx=x+(dble(nx)*ox)y=y+(dble(ny)*oy)if(i-kstep*int(i/kstep).eq.0) then
xp(p)=trx*xyp(p)=try*yzp(p)=trz*(z+(100.0*zz))p=p+1
endifenddo
returnend
c-----------------------------------------------------------------
subroutine trace(step,datasize)include ’parm.h’real*8 hz,bzinteger stepinteger datasizeparameter (twopi=2*3.14159265358979323846d0)real*8 xp,yp,zpcommon /xp/ xp(20001),yp(20001),zp(20001)real*8 x,y,zinteger nx,ny,nzreal*8 lx,ly,lzcommon /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nzreal*8 a2d,bx1,by1common /bslab/ bx1(nzmax+2),by1(nzmax+2)common /aa/ a2d(nxmax,nymax)real*8 mx,my,cx,cyreal*8 a1,a2,a3,a4,betax,betayinteger s,i,j,x1,x2,y1,y2integer l,check,zo,integ,ox,oyreal*8 zz,findzx,xx,yy,findzy,x3,y3real*8 bx,by,bxx,byy,px,py,pz,zi,zz1,zz2real*8 eslab,lambda_par,alpha1common /slab/ eslab,lambda_par,alpha1integer checkx,checky,checkz,kstep,p,w
w=69092p=1kstep=int(step/datasize)
51
hz=1.d0trx=lx/dble(nx)try=ly/dble(ny)trz=lz/dble(nz)bz=trx/trzx=xp(1)/trxy=yp(1)/tryz=zp(1)/trzzo=int(z/10.d0)z=z-(zo*10)pz=zox=int(x/dble(nx))oy=int(y/dble(ny))if (x.lt.0) ox=ox-1if (y.lt.0) oy=oy-1x=x-(ox*dble(nx))y=y-(oy*dble(ny))if ((int(x).eq.x).and.(int(y).eq.y)
& .and.(eslab.eq.0)) theni=int(x)j=int(y)if (a2d(i,j).gt.a2d(i-1,j)) then
if (a2d(i,j).gt.a2d(i+1,j)) thenif (a2d(i,j).gt.a2d(i,j-1)) then
if (a2d(i,j).gt.a2d(i,j+1)) thengoto 100
endifendif
endifendif
endifpx=xpy=ybxx=bx(x,y,px,py)byy=by(x,y,px,py)if (bxx.gt.0) then
px=x-0.0001else
px=x+0.0001endifif (byy.gt.0) then
py=y-0.0001else
py=y+0.0001endifdo s=1,step
1 dz=0.1if (z.ge.11.d0) then
z=z-10.d0zo=zo+1
endifzi=zpz=zcall parameters(betax,betay,mx,cx,my,
& cy,a1,a2,a3,bz,x,y,z,zo,px,py)px=xpy=yz=dble(int(z))+1checkx=0checky=0checkz=0if (abs(a1).lt.1.d-17) then
call mfl1d(x,y,pz+(zo*10.d0),z+(zo*10.d0),bz,a2,a3)goto 95
endif
52
5 x=(betax*dexp(a1*z/bz))-(mx*z/a1)& -((((cx+a3)/bz)+(mx/a1))*bz/a1)
y=(betay*dexp(-a1*z/bz))+(my*z/a1)& +((((cy-a2)/bz)-(my/a1))*bz/a1)
if (checkz.eq.1) thenif((int(x).eq.int(px)).and.(int(y).eq.int(py))) then
call parameters(betax,betay,mx,cx,my,& cy,a1,a2,a3,bz,x,y,z,zo,px,py)
px=xpy=y
elsezi=zi-dzdz=dz*0.9
endifendifedgex=0edgey=0if ((integ(x).ne.integ(px))
& .and.(abs(x-dble(int(x))).gt.1.d-8)& .and.(abs(px-dble(int(px))).gt.1.d-8)) then
edgex=1else
if (abs(x-px).gt.1.d0) thenedgex=1
endifendifif ((integ(y).ne.integ(py))
& .and.(abs(y-dble(int(y))).gt.1.d-8)& .and.(abs(py-dble(int(py))).gt.1.d-8)) then
edgey=1else
if (abs(y-py).gt.1.d0) edgey=1endifif ((edgex.eq.1).or.(edgey.eq.1)) then
zz1=0.d0zz2=0.d0if (edgex.eq.1) then
checkx=checkx+1if (x.gt.px) then
if ((x-px).lt.(nx-10)) thenxx=dble(int(px))+1.d0
elsexx=0.d0
endifelse
if ((x-px).lt.-(nx-10)) thenxx=dble(nx)
elsexx=dble(int(px))
endifendifzz1=findzx(a1,a3,bz,betax,mx,cx,pz,xx)if (zz1.le.pz) zz1=pz-1.d0
checkz=0endifif (edgey.eq.1) then
checky=checky+1if (y.gt.py) then
if ((y-py).lt.(ny-10)) thenyy=dble(int(py))+1.d0
elseyy=0.d0
endifelse
if ((y-py).lt.-(ny-10)) then
53
yy=dble(ny)else
yy=dble(int(py))endif
endifzz2=findzy(a1,a2,bz,betay,my,cy,pz,yy)if (zz2.le.pz) zz2=pz-1.d0
checkz=0endifif (edgex.eq.edgey) then
& if ((zz1.gt.int(pz)).and.(zz1.lt.(dble(int(pz))+1.d0))) then
& if ((zz2.gt.int(pz)).and.(zz2.lt.(dble(int(pz))+1.d0))) then
if (zz1.gt.zz2) thenz=zz2edgex=0x=(betax*dexp(a1*z/bz))-(mx*z/a1)
& -((((cx+a3)/bz)+(mx/a1))*bz/a1)y=yyif ((integ(x).ne.integ(px))
& .and.(px.ne.dble(int(px)))) z=pz-1.d0else
z=zz1y=(betay*dexp(-a1*z/bz))+(my*z/a1)
& +((((cy-a2)/bz)-(my/a1))*bz/a1)x=xxedgey=0if ((integ(y).ne.integ(py)).and.
& (py.ne.dble(int(py)))) z=pz-1.d0endif
elsez=zz1y=(betay*dexp(-a1*z/bz))+(my*z/a1)
& +((((cy-a2)/bz)-(my/a1))*bz/a1)x=xxedgey=0if ((integ(y).ne.integ(py))
& .and.(py.ne.dble(int(py)))) z=pz-1.d0endif
elseif ((zz2.gt.int(pz))
& .and.(zz2.lt.dble(int(pz+1.d0)))) thenz=zz2x=(betax*dexp(a1*z/bz))-(mx*z/a1)
& -((((cx+a3)/bz)+(mx/a1))*bz/a1)y=yyedgex=0if ((integ(x).ne.integ(px))
& .and.(px.ne.dble(int(px)))) z=pz-1.d0else
z=pz-1.d0endif
endifelse
if (edgex.eq.1) thenif ((zz1.gt.int(pz))
& .and.(zz1.lt.dble(int(pz+1.d0)))) thenz=zz1y=(betay*dexp(-a1*z/bz))
& +(my*z/a1)+((((cy-a2)/bz)-(my/a1))*bz/a1)x=xxif ((integ(y).ne.integ(py))
& .and.(py.ne.dble(int(py)))) z=pz-1.d0
54
elsez=pz-1.d0
endifelse
if ((zz2.gt.int(pz)).and.(zz2.lt.dble(int(pz+1.d0)))) then
z=zz2x=(betax*dexp(a1*z/bz))
& -(mx*z/a1)-((((cx+a3)/bz)+(mx/a1))*bz/a1)y=yyif ((integ(x).ne.integ(px))
& .and.(px.ne.dble(int(px)))) z=pz-1.d0else
z=pz-1.d0endif
endifendifcheckz=0if ((z.le.pz).or.(z.gt.(pz+1.d0))) then
if (dz.lt.1.d-10) thenif (edgex.eq.1) then
x=dble(int(x+0.01))y=py
endifif (edgey.eq.1) theny=dble(int(y+0.01))x=pxendif
elsezi=zi+dzz=zicheckz=1goto 5
endifendif
endifoox=oxooy=oyif ((x.ge.nx).and.(x.gt.px)) then
x=x-dble(nx)oox=ox+1
elseif ((x.lt.-1.d-10).and.(x.lt.px)) then
x=x+dble(nx)oox=ox-1
endifendifif ((y.ge.ny).and.(y.gt.py)) then
y=y-dble(ny)ooy=oy+1
elseif ((y.lt.-1.d-10).and.(y.lt.py)) then
y=y+dble(ny)ooy=oy-1
endifendifox=ooxoy=ooy
95 if (z.ne.int(z)) goto 1if ((s-kstep*int(s/kstep)).eq.0) then
p=p+1xp(p)=(x+(ox*nx))*trxyp(p)=(y+(oy*ny))*tryzp(p)=(z+(zo*10.d0))*trzendif
enddo100 return
endc---------------------------------------------------------------
55
subroutine parameters(betax,betay,mx,cx,my,cy,a1,a2,a3,bz,x,y,& z,zo,px,py)
include ’parm.h’real*8 mx,cx,my,cy,a1,a2,a3,x,y,px,py,x3,y3,betax,betay,bzreal*8 zinteger x1,x2,y1,y2integer nx,ny,nzreal*8 lx,ly,lzcommon /lbox/ lx,ly,lzcommon /nbox/ nx,ny,nzreal*8 a2d,bx1,by1common /bslab/ bx1(nzmax+2),by1(nzmax+2)common /aa/ a2d(nxmax,nymax)integer i,j,k,zo,integ,ki,k1,k2
x3=xy3=yi=integ(x)j=integ(y)if (abs(x-integ(x)).lt.1.d-12) then
if (x.lt.px) thenx3=x3-1i=i-1
endifendifif (abs(y-integ(y)).lt.1.d-12) then
if (y.lt.py) theny3=y3-1j=j-1
endifendifcall pgrid(x1,x2,y1,y2,x3,y3)ki=integ(z)k1=ki+(zo*10.d0)+3if (k1.gt.nz) k1=k1-nz
k2=k1+1if (k1.eq.nz) k2=1mx=bx1(k2)-bx1(k1)my=by1(k2)-by1(k1)cx=((ki+1)*bx1(k1))-(ki*bx1(k2))cy=((ki+1)*by1(k1))-(ki*by1(k2))a1=a2d(x2,y2)-a2d(x1,y2)-a2d(x2,y1)+a2d(x1,y1)a1=a1*nx/lxa2=(j*(a2d(x1,y2)-a2d(x2,y2)))
& +((j+1)*(a2d(x2,y1)-a2d(x1,y1)))a2=a2*ny/lya3=(i*(a2d(x2,y1)-a2d(x2,y2)))
& +((i+1)*(a2d(x1,y2)-a2d(x1,y1)))a3=a3*nx/lxbetax=(x+(mx*z/a1)+((((cx+a3)/bz)
& +(mx/a1))*bz/a1))*dexp(-a1*z/bz)betay=(y-(my*z/a1)-((((cy-a2)/bz)
& -(my/a1))*bz/a1))*dexp(a1*z/bz)returnend
c---------------------------------------------------------------
function findzx(a1,a3,bz,betax,mx,cx,zz,xx)integer l,countsreal*8 a1,a3,bz,betax,mx,cx,zz,xx,findzxreal*8 fx,dfx,zoo,fx2
fx2=100.d0zoo=zz
56
counts=0105 counts=counts+1
fx=(a1*bz*betax*dexp(a1*zoo/bz))-(mx*zoo*bz)& -((((cx+a3)*a1)+(mx*bz))*(bz/a1))-(xx*bz*a1)
dfx=(betax*a1*a1*dexp(a1*zoo/bz))-(mx*bz)zoo=zoo-(fx/dfx)if (abs(zoo-zz).lt.100.d0) then
if ((abs(fx/dfx).lt.1.d-10).and.(abs(fx).lt.1.d-10)) thenif (abs(fx).le.abs(fx2)) findzx=zoo
goto 110else
if (abs(fx).le.abs(fx2)) thenfindzx=zoofx2=fx
endifif (counts.lt.100) goto 105
endifelse
zoo=zz-1endif
110 returnend
c---------------------------------------------------------------
function findzy(a1,a2,bz,betay,my,cy,zz,yy)integer l,countsreal*8 a1,a2,bz,betay,my,cy,zz,yyreal*8 fy,dfy,findzy,zoo,fy2
fy2=100.d0zoo=zzcounts=0
115 counts=counts+1fy=((-a1)*bz*betay*dexp(-a1*zoo/bz))-(my*zoo*bz)
& -((((cy-a2)*(-a1))+(my*bz))*(-bz/a1))-(yy*bz*(-a1))dfy=(betay*a1*a1*dexp(-a1*zoo/bz))-(my*bz)zoo=zoo-(fy/dfy)if (abs(zoo-zz).lt.100.d0) then
& if ((abs(fy/dfy).lt.1.d-10).and.(abs(fy).lt.1.d-10)) then
if (abs(fy).lt.abs(fy2)) findzy=zoogoto 120
elseif (abs(fy).lt.abs(fy2)) then
findzy=zoofy2=fy
endifif (counts.lt.100) goto 115
endifelse
findzy=zz-1endif
120 returnend
c---------------------------------------------------------------
function app(x,y)include ’parm.h’integer nx,ny,nzcommon /nbox/ nx,ny,nzreal*8 a2dcommon /aa/ a2d(nxmax,nymax)real*8 s1,s2,x,yreal*8 appx,appx2,appx1,appinteger t1,t2real*8 xx,yy
xx=x-nx*int(x/(1.*nx))if (xx.le.1) xx=xx+nx
57
yy=y-ny*int(y/(1.*ny))if (yy.lt.1) yy=yy+nyi=integ(xx)j=integ(yy)s1=xx-integ(xx)s2=yy-integ(yy)if(i.ge.nx+1)i=i-nxif(j.ge.ny+1)j=j-nyt1=i+1t2=j+1if(i.eq.nx)t1=1if(j.eq.ny)t2=1if ((i.eq.0).or.(i.eq.nx)) then
i=nxt1=1
endifif ((j.eq.0).or.(j.eq.ny)) then
j=nyt2=1
endifappx1=a2d(i,j)*(1-s1)+a2d(t1,j)*s1appx2=a2d(i,t2)*(1-s1)+a2d(t1,t2)*s1appx=appx1*(1-s2)+appx2*s2app=appx
returnend
c---------------------------------------------------------------
subroutine mfl1d(x,y,pz,z,bz,a2,a3)include ’parm.h’integer i,j,nx,ny,nzcommon /nbox/ nx,ny,nzreal*8 bx1,by1common /bslab/ bx1(nzmax+2),by1(nzmax+2)real*8 x,y,z,h,dh,dz,bzreal*8 lx,ly,lz,a3,a2,dx,dy,pzcommon /lbox/ lx,ly,lz
dx=0.d0dy=0.d0h=z-pzj=integ(h)dh=h-jdo i=0,j
if (i.eq.j) thendz=dh
elsedz=1.
endifcall xy1d(dx,dy,pz,dz,bz,a2,a3)x=x+dxy=y+dy
enddoreturnend
c---------------------------------------------------------------
subroutine xy1d(dx,dy,pz,h,bz,a2,a3)include ’parm.h’integer nz,i,jj,ii,nx,nycommon /nbox/ nx,ny,nzreal*8 bx1,by1common /bslab/ bx1(nzmax+2),by1(nzmax+2)real*8 zz,h,lz,pz,a2,a3real*8 dx,dy,bz,over,abc
58
pz=pzzz=pz-nz*dble(int(pz/nz))over=0.i=integ(zz)ii=i-int(dble(i)/dble(nz))+3if (ii.eq.0) ii=nzjj=ii+1if (ii.eq.nz) jj=1
z2=zz+hif (z2.gt.i+1) then
z2=(i+1.)over=zz+h-i-1.
endifdx=(bx1(jj)-bx1(ii))*((z2)**2-zz**2)/2.
dx=dx+(((bx1(ii)*(i+1))-(bx1(jj)*i)+a3)*(z2-zz))dx=dx/bzdy=(by1(jj)-by1(ii))*((z2)**2-zz**2)/2.dy=dy+(((by1(ii)*(i+1))-(by1(jj)*i)-a2)*(z2-zz))dy=dy/bzzz=z2if (over.ne.0) then
ii=ii+1if (ii.eq.0) ii=nzjj=ii+1if (ii.eq.nz) jj=1z2=z2+overdx=(bx1(jj)-bx1(ii))*((z2)**2-zz**2)/2.dx=dx+(((bx1(ii)*(i+1))-(bx1(jj)*i)+a3)*(z2-zz))dx=dx/bzdy=(by1(jj)-by1(ii))*((z2)**2-zz**2)/2.dy=dy+(((by1(ii)*(i+1))-(by1(jj)*i)-a2)*(z2-zz))dy=dy/bz
endifreturnend
c---------------------------------------------------------------
subroutine pgrid(x1,x2,y1,y2,x,y)integer i,j,x1,x2,y1,y2,integinteger nx,ny,nzreal*8 x,y,ox,oy,xx,yy,bx,bycommon /nbox/ nx,ny,nz
if (x.gt.0) thenox=1.*dble(int(x/nx))
elseox=-1.+1.*dble(int(x/nx))
endifxx=x-dble(nx)*oxif (y.gt.0) then
oy=1.*int(y/ny)else
oy=-1.+1.*dble(int(y/ny))endifyy=y-dble(ny)*oyi=integ(xx)j=integ(yy)x1=i-(nx*int(i*1./nx))y1=j-(ny*int(j*1./ny))if (x1.le.0) x1=x1+nxif (y1.le.0) y1=y1+nxx2=x1+1y2=y1+1if ((x1.eq.0).or.(x1.eq.nx)) then
59
x1=nxx2=1
endifif ((y1.eq.0).or.(y1.eq.ny)) then
y1=nyy2=1
endifreturnend
c---------------------------------------------------------------
function bx(x,y,px,py)include ’parm.h’integer i,j,x1,y1,x2,y2,integinteger nx,ny,nzcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,c1,c2common /aa/ a2d(nxmax,nymax)real*8 ox,oy,bx,px,py,x3,y3,tyreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
ty=dble(ny)/lyx3=xy3=yi=integ(x3)j=integ(y3)if (abs(x3-integ(x3)).lt.(1.d-8)) then
if (((x3-px).lt.0).or.((x3-px).gt.500))thenif ((x3-px).gt.(-500)) then
if (i.ne.0) theni=i-1
elsei=nx-1x3=dble(nx)
endifendif
endifendifif (abs(y3-integ(y3)).lt.(1.d-8)) then
if (((y3-py).lt.0).or.((y3-py).gt.500))thenif ((y3-py).gt.(-500)) then
if (j.ne.0) thenj=j-1
elsej=ny-1y3=dble(ny)
endifendif
endifendifx1=i-(nx*int(i*1./nx))y1=j-(ny*int(j*1./ny))if (x1.le.0) x1=x1+nxif (y1.le.0) y1=y1+nxx2=x1+1y2=y1+1if ((x1.eq.0).or.(x1.eq.nx)) then
x1=nxx2=1
endifif ((y1.eq.0).or.(y1.eq.ny)) then
y1=nyy2=1
endifc1=((i+1.)*(a2d(x1,y2)-a2d(x1,y1)))+(i*(a2d(x2,y1)-a2d(x2,y2)))c2=a2d(x1,y1)+a2d(x2,y2)-a2d(x2,y1)-a2d(x1,y2)
60
bx=(c1+(c2*x3))*tyreturnend
c---------------------------------------------------------------
function by(x,y,px,py)include ’parm.h’integer i,j,x1,y1,x2,y2,integinteger nx,ny,nzcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,c1,c2,x3,y3common /aa/ a2d(nxmax,nymax)real*8 xx,yy,ox,oy,by,px,py,txreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
tx=dble(nx)/lxx3=xy3=yi=integ(x3)j=integ(y3)if (abs(x3-integ(x3)).lt.(1.d-8)) then
if (((x3-px).lt.0).or.((x3-px).gt.500))thenif ((x3-px).gt.(-500)) then
if (i.ne.0) theni=i-1
elsei=nx-1x3=dble(nx)
endifendif
endifendifif (abs(y3-integ(y3)).lt.(1.d-8)) then
if (((y3-py).lt.0).or.((y3-py).gt.500))thenif ((y3-py).gt.(-500)) then
if (j.ne.0) thenj=j-1
elsej=ny-1y3=dble(ny)
endifendif
endifendifx1=i-(nx*int(i*1./nx))y1=j-(ny*int(j*1./ny))if (x1.le.0) x1=x1+nxif (y1.le.0) y1=y1+nxx2=x1+1y2=y1+1if ((x1.eq.0).or.(x1.eq.nx)) then
x1=nxx2=1
endifif ((y1.eq.0).or.(y1.eq.ny)) then
y1=nyy2=1
endifc1=(j+1.)*(a2d(x1,y1)-a2d(x2,y1))+j*(a2d(x2,y2)-a2d(x1,y2))c2=a2d(x2,y1)+a2d(x1,y2)-a2d(x1,y1)-a2d(x2,y2)by=(c1+(c2*y3))*tx
returnend
c---------------------------------------------------------------
function integ(x)
61
integer integreal*8 x
integ=int(x)if (x.lt.0) integ=integ-1if (abs(1.d0+dble(integ)-x).lt.(1.d-8)) then
integ=integ+1endif
returnend
c---------------------------------------------------------------
subroutine dxy(xp,ddz,dstep,dx2)integer ddz,i,dstepreal*8 xp(ddz)real*8 ndata,dx2,results,sumdx2
i=1j=0sumdx2=0.d0ndata=0.d0
25 results=xp(i+dstep)-xp(i)sumdx2=sumdx2+(results**2.)i=i+1ndata=ndata+1.d0
c if (ndata.eq.20000) goto 26if ((i+dstep).lt.ddz) goto 25
26 dx2=sumdx2/ndatareturnend
c---------------------------------------------------------------subroutine edge(x,y,z,zmax,bz,px,py)
integer nx,ny,si,nzinteger y1,y2common /nbox/ nx,ny,nzreal*8 x,y,z,dz,bx,by,x3,y3,bzreal*8 edx,edy,zmax,ztox,ztoy,app1,appreal*8 bxcheck,bycheck,px,py
x3=xy3=yif (abs(x-integ(x)).lt.(1.d-8)) then
bxcheck=bx(x,y,px,py)if (bxcheck.lt.0) then
x3=x-1.endif
endifif (abs(y-integ(y)).lt.(1.d-8)) then
bycheck=by(x,y,px,py)if (bycheck.lt.0) then
y3=y-1.endif
endify1=integ(y3)y2=y1+1call zmaxx(x,y,z,edx,zmax,bz,px,py)edy=ztoy(x,y,z,zmax,bz,px,py)if (zmax.le.z) then
edy=dble(y2)+1.endifif ((edy.ge.dble(y2)).or.(edy.le.dble(y1))) then
call zmaxy(x,y,z,edy,zmax,bz,px,py)edx=ztox(x,y,z,zmax,bz,px,py)
endifreturnend
c---------------------------------------------------------------
62
subroutine zmaxx(x,y,z,edx,zmax,bz,px,py)include ’parm.h’integer nx,ny,x1,x2,y1,y2integer i,j,integ,nzcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,z,c1,c2,ztox,dzcommon /aa/ a2d(nxmax,nymax)real*8 z1,z2,zmax,edx,x3,y3,by,bx,bz,xxxreal*8 bxcheck,bycheck,xx2,xx1,px,py,ratioreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
ratio=(nz*lx)/(nx*lz)bxcheck=bx(x,y,px,py)i=integ(x)j=integ(y)if (i.lt.0) i=i-1if (j.lt.0) j=j-1x3=xy3=yif (abs(x-integ(x)).lt.1.d-8) then
if (bxcheck.lt.0) thenx3=x-1.i=i-1
endifendifif (abs(y-integ(y)).lt.1.d-8) then
bycheck=by(x,y,px,py)if (bycheck.lt.0) then
y3=y-1.j=j-1
endifendifcall pgrid(x1,x2,y1,y2,x3,y3)c1=(i+1.)*(a2d(x1,y2)-a2d(x1,y1))
& +(i)*(a2d(x2,y1)-a2d(x2,y2))c2=a2d(x1,y1)+a2d(x2,y2)-a2d(x1,y2)-a2d(x2,y1)c1=c1*nx/lxc2=c2*nx/lxif (bxcheck.gt.0) then
edx=dble(i+1)else
edx=dble(i)endifif (c2.ne.0) then
dz=((bz/c2)*dlog(abs((c1+(c2*edx))/(c1+(c2*x)))))*ratioelse
dz=(edx-x)/c1endifif (dz.lt.1.d-8) then
bxcheck=-bxcheckif (bxcheck.gt.0) then
edx=dble(i+1)else
edx=dble(i)endifif (c2.ne.0) then
dz=((bz/c2)*dlog(abs((c1+(c2*edx))/(c1+(c2*x)))))*ratioelse
dz=(edx-x)/c1endif
endifzmax=z+dzxxx=ztox(x,y,z,zmax,bz,px,py)if ((abs(xxx-edx).gt.1.d-8).or.(abs(xxx-x).lt.1.d-8)) then
63
zmax=z-1.endif
returnend
c---------------------------------------------------------------
subroutine zmaxy(x,y,z,edy,zmax,bz,px,py)include ’parm.h’integer nx,ny,x1,x2,y1,y2integer i,j,integ,nzcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,z,c1,c2,ztoy,dzcommon /aa/ a2d(nxmax,nymax)real*8 z1,z2,zmax,edy,x3,y3,by,bx,bz,yyyreal*8 bycheck,bxcheck,yy1,yy2,px,py,ratioreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
ratio=(nz*lx)/(lz*nx)bycheck=by(x,y,px,py)i=integ(x)j=integ(y)if (i.lt.0) i=i-1if (j.lt.0) j=j-1x3=xy3=yif (abs(x-integ(x)).lt.1.d-8) then
bxcheck=bx(x,y,px,py)if (bxcheck.lt.0) then
x3=x-1.i=i-1
endifendifif (abs(y-integ(y)).lt.1.d-8) then
if (bycheck.lt.0) theny3=y-1.j=j-1
endifendifcall pgrid(x1,x2,y1,y2,x3,y3)c1=(j+1.)*(a2d(x1,y1)-a2d(x2,y1))+j*(a2d(x2,y2)-a2d(x1,y2))c2=a2d(x2,y1)+a2d(x1,y2)-a2d(x2,y2)-a2d(x1,y1)c1=c1*ny/lyc2=c2*ny/lyif (bycheck.gt.0) then
edy=dble(j+1)else
edy=dble(j)endifif (c2.ne.0) then
dz=((bz/c2)*dlog(abs((c1+(c2*edy))/(c1+(c2*y)))))*ratioelse
dz=(edy-y)/c1endifif (dz.lt.1.d-8) then
bycheck=-bycheckif (bycheck.gt.0) then
edy=dble(j+1)else
edy=dble(j)endifif (c2.ne.0) then
dz=((bz/c2)*dlog(abs((c1+(c2*edy))& /(c1+(c2*y)))))*ratio
else
64
dz=(edy-y)/c1endif
endifzmax=z+dz
returnend
c---------------------------------------------------------------
function ztoy(x,y,pz,z,bz,px,py)include ’parm.h’integer nx,ny,x1,x2,y1,y2integer i,j,integ,nzcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,z,c1,c2,pzcommon /aa/ a2d(nxmax,nymax)real*8 ztoy,x3,y3,bx,by,bz,dx,dyreal*8 bycheck,bxcheck,px,py,ratioreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
ratio=(lz*nx)/(nz*lx)bycheck=by(x,y,px,py)i=integ(x)j=integ(y)if (i.lt.0) i=i-1if (j.lt.0) j=j-1x3=xy3=yif (abs(x-integ(x)).lt.(1.d-8)) then
bxcheck=bx(x,y,px,py)if (bxcheck.lt.0) then
x3=x-1.i=i-1
elsex3=dble(integ(x))
endifendifif (abs(y-integ(y)).lt.(1.d-8)) then
if (bycheck.lt.0) theny3=y-1.j=j-1
elsey3=dble(integ(y))
endifendifcall pgrid(x1,x2,y1,y2,x3,y3)c1=(j+1.)*(a2d(x1,y1)-a2d(x2,y1))+(j*(a2d(x2,y2)-a2d(x1,y2)))c1=c1*ny/lyc2=a2d(x2,y1)+a2d(x1,y2)-a2d(x1,y1)-a2d(x2,y2)c2=c2*ny/lyif (c2.ne.0) then
ztoy=(((c1+(c2*y))*dexp((c2/bz)*ratio*(z-pz)))-c1)/c2else
ztoy=c1*(z-pz)+yendif
returnend
c---------------------------------------------------------------
function ztox(x,y,pz,z,bz,px,py)include ’parm.h’integer nx,ny,x1,x2,y1,y2,nzinteger i,j,integcommon /nbox/ nx,ny,nzreal*8 a2d,x,y,z,c1,c2,pzcommon /aa/ a2d(nxmax,nymax)
65
real*8 ztox,x3,y3,by,bx,bz,dx,dyreal*8 bxcheck,bycheck,px,py,ratioreal*8 lx,ly,lzcommon /lbox/ lx,ly,lz
ratio=lz*nx/(lx*nz)bxcheck=bx(x,y,px,py)i=integ(x)j=integ(y)if (i.lt.0) i=i-1if (j.lt.0) j=j-1x3=xy3=yif (abs(x-integ(x)).lt.(1.d-8)) then
if (bxcheck.lt.0) thenx3=x-1.i=i-1
elsex3=dble(integ(x))
endifendifif (abs(y-integ(y)).lt.(1.d-8)) then
bycheck=by(x,y,px,py)if (bycheck.lt.0) then
y3=y-1.j=j-1
elsey3=dble(integ(y))
endifendifcall pgrid(x1,x2,y1,y2,x3,y3)c1=((i+1.)*(a2d(x1,y2)-a2d(x1,y1)))
& +(i*(a2d(x2,y1)-a2d(x2,y2)))c2=a2d(x1,y1)+a2d(x2,y2)-a2d(x2,y1)-a2d(x1,y2)c1=c1*nx/lxc2=c2*nx/lxif (c2.ne.0) then
ztox=(((c1+(c2*x))*dexp((c2/bz)*ratio*(z-pz)))-c1)/c2else
ztox=c1*(z-pz)+xendif
returnend
c---------------------------------------------------------------
subroutine locate(x,y,ox,oy,check)integer i,j,integ,ox,oy,checkinteger oox,ooy,nx,ny,nzreal*8 x,y,xx,yy,bx,bycommon /nbox/ nx,ny,nz
if (x.gt.1.d-11) thenoox=1*dble(integ(x/nx))
elseoox=-1+1*dble(integ(x/nx))
endifox=ooxx=x-dble(nx)*ooxif (y.gt.1.d-11) then
ooy=1*integ(y/ny)else
ooy=-1+1*dble(integ(y/ny))endifoy=ooyy=y-dble(ny)*ooy
returnend