Document 11261015

advertisement
LATTICE GAS HYDRODYNAMICS
WITH GALILEAN INVARIANCE
by
PETER A. DONIS
S.B., Nuclear Engineering
Massachusetts Institute of Technology
1987
SUBMITTED TO THE DEPARTMENT OF NUCLEAR ENGINEERING
IN PARTIAL FULFILLMENT OF THE REQUIREMENTS
FOR THE DEGREE OF
MASTER OF SCIENCE IN NUCLEAR ENGINEERING
at the
MASSACHUSETTS INSTITUTE OF TECHNOLOGY
September 1988
@Massachusetts Institute of Technology 1988
d
Signature of Author.....
/
/
. ........
..... k; . ..a.'o .&.4. ..a . . a.......
..
'
A...'II
...
- Department of Nuclear Engineering
September 16, 1988
/
Certified by ..
.....
. ..
. ..............
.
.
.
.....
.
Kim Molvig
Thesis Supervisor
Accepted by ................
a
..................
.....................
Professor Alan Henry
Chairman, Departmental Committee on Graduate Studies
1
;axsY
8INSTI
MAY 08 1988
'NSl~r
LATTICE GAS HYDRODYNAMICS
WITH GALILEAN INVARIANCE
by
PETER A. DONIS
S.B., Nuclear Engineering
Massachusetts Institute of Technology, 1987
Submitted to the Department of Nuclear Engineering
on September 21, 1988 in partial fulfillment of the requirements
for the Degree of Master of Science in Nuclear Engineering
LBSTRACT
A method is developed for ensuring Galilean invariance in lattice gas simulations of
hydrodynamics. First the necessity for Galilean invariance is established by deriving the
general hydrodynamic momentum equation for a lattice gas and showing the effects of
non-Galilean invariance, specifically the need to restrict consideration to incompressible
flows and the incorrect handling of passive scalars. Then a generalized formalism for
describing the update rules of a lattice gas simulation is developed, in order to facilitate
further work on hydrodynamic simulations using the methods discussed in this thesis.
Finally, the specific lattice gas used to test the method for ensuring Galilean invariance
is described and its macroscopic properties developed.
The lattice gas is realized in a FORTRAN code which is run on a MicroVAX II
machine utilizing special system functions which allow direct manipulation of bits of
computer storage by Boolean operations. The output of the code shows that the method
Lsed to ensure Galilean invariance which is developed can in fact meet the requirements
of equilibrating to a state in which the Galilean invariance condition is met and of
reaching such a state on a time scale which is short compared with the hydrodynamic
time scale. The simulation is subject to statistical fluctuations, but these are expected
to become smaller as the size of the simulation is increased.
Thesis Supervisor: Dr. Kim Molvig
Title: Professor of Nuclear Engineering
1
Introduction
The research described in this thesis is intended to show that a lattice gas, or
cellular automaton (referred to herein by the shorthand term 'CA' for convenience)
can be constructed to exhibit true Galilean invariance. This property is essential
for any lattice gas which will be used to simulate hydrodynamic problems, and
previous CA's, while able to exhibit Galilean invariance, have done so via methods
which limited them to incompressible flows, and also introduced errors in other areas
such as the transport of passive scalars. The present work will develop a method
for ensuring Galilean invariance which may be applied in complete generality to
hydrodynamic flows, and which preserves the correct transport laws.
The CA developed herein is not in itself capable of real hydrodynamic simulations, for reasons which will be discussed in detail in section 4 below. The Galilean
invariance property is only one of several which are necessary for a hydrodynamic
simulation; other such properties are discussed somewhat herein, but a fuller treatment of these other elements will be postponed to future work, since they do not
bear directly on the Galilean invariance problem. The CA which ensures Galilean
invariance must therefore be integrated with these other elements to produce a complete hydrodynamic simulation. In order to facilitate such integration, attention is
given in section 3 to developing a general formalism for describing CA's of this class.
This formalism is derived in as much generality as possible, far more than is necessary for simply studying the Galilean invariance CA discussed herein; the generality
is necessary mainly because of the much-increased complexity of automata which
combine all the necessary elements.
The CA is actually realized in a FORTRAN code which is run on a MicroVAX II
machine, using special 'bitwise' intrinsic functions which perform Boolean operations
directly on bits of computer storage.
This enables the programmer to take full
advantage of the Boolean nature of lattice gas simulations; these bit operations
are much faster than the floating-point operations normally used in hydrodynamics
codes, and they are also more 'robust' in the sense that there are no undefined
operations or numerical instabilities of the type so often encountered in floatingpoint codes. Thus, the complexity of the code is greatly reduced, since there is
no need to include error control methods, iterative evaluations of functions and
derivatives, convergence criteria, and so on. The only really slow operations in the
code are the input and output operations and the initialization of the variables,
where floating point operations cannot be avoided.
2
2.1
Background
Galilean Invariance
In order to understand the problem which the present CA is intended to solve, it is
necessary to go into some detail in discussing hydrodynamic theory, specifically to
observe the effect on system behavior of not having Galilean invariance. The property of Galilean invariance itself is rather simple to grasp, and was first recognized
by Galileo (hence the name); it simply means that certain physical situations are
'equivalent' in the sense that they produce the same results although they apparently involve different actions to the observer. Thus, if you are hot and want to cool
down, it makes no difference whether you stand in front of a fan or get on a bicycle
and ride fast enough to create a breeze; the result is the same, wind blowing past
you (from your point of view). Put this baldly, it sounds as though any reasonable
simulation of a physical system would have to have this property; however, there is
also a quantitative side to the question, which is not so easily dismissed as intuitively
obvious.
In the just stated problem, for example, Galilean invariance would require that,
if you rode your bicycle in still air at 10 miles per hour, you would experience exactly
the same cooling effect as if you were standing in front of a fan which created a 10
mph wind. Mathematically, this means that the law of heat transfer from your body
to the air is invariant under the transformation of coordinates
XI =
t'
--
0t
= t
(1)
where x, t are coordinates with reference to the ground (i.e., coordinates when standing still in front of the fan), x', t' are coordinates with reference to the moving bicycle, and v 0o is the relative velocity of the wind, in this case 10 mph. This coordinate
transformation is called the Galilean transformation, and all the laws of classical
(i.e., non-relativistic) physics (and hydrodynamics in particular) must be invariant
under it. Of course, the full transformation involves not only the 'basic' coordinates
x, t, as in equation (1), but also all other physical quantities; this will be important
when we actually apply it to the hydrodynamic equations in section 2.2.
A hydrodynamic example would be the following: suppose we set up a pipe flow
problem with a certain peak velocity vo in the center of the pipe. Then any results
we obtain should be exactly the same quantitatively as those obtained from leaving
the fluid within the pipe at rest and moving the pipe with velocity vo relative to the
fluid in the center of the pipe. The equivalence of the two cases can be given an exact
mathematical expression, as will be shown in section 2.2 below; previous automata
were only able to satisfy this expression by requiring incompressible flow and then
re-scaling the time coordinate, which did not take care of errors in the transport of
passive scalars, and was not a 'true' solution to the problem. The purpose of this
thesis will be to show that the mathematical condition can be satisfied without any
limitations on the scope of the simulation. In order to show this, we must derive
the hydrodynamic equations for a general CA, and it is to this that we shall now
turn our attention.
2.2
Hydrodynamic Equations
In order to construct the hydrodynamic equations for a CA, the primitive quantities
on which all the mathematics are based must first be defined. We start out with the
assumption that the lattice gas is composed of a finite number of 'types' of particles,
indexed by type number j, which move about on the lattice and whose motions and
interactions generate all of the properties of the system. For each particle type j,
the following quantities are presumed known:
mj = mass of particle of type j;
cji= velocity vector of particle of type j;
fj = energy of particle of type j.
It is important to note that these quantities can be chosen arbitrarily when
constructing the CA in order to make the macroscopic equations come out in a
desired form; there are no a prioriconsiderations which dictate a certain choice for
any of them. For the purpose of the following derivations, however, we leave them
arbitrary and make no assumptions about their nature to begin with.
The reader will notice that the velocity vector ci has a second index; this is the
'direction index' i of the velocity vector. We assume that each moving particle type
has a specific number of 'directions' allowed to it, so that the full velocity vector
for a given particle of that type is c4i, the velocity of particle type j in direction i.
We assume that the magnitude of this vector is the same for all particles of type j,
regardless of direction, and can be written simply as cj. The implications of having
this second index i on c4' will become clear in a moment.
We can now distinguish two concepts of importance for understanding CA dynamics: 'site' and 'state'. The 'site' concept is rather obvious: the CA is constructed
on a discrete lattice on which the particles move, and all such movements must be
from one site to another: a particle cannot be caught 'between' sites. Time, of
course, is also discrete in this model, being measured in 'steps', so that each particle
must be on a lattice site at each 'step'. On a square lattice, which is used for the
class of CA's to be discussed in section 3, if we define the distance between two
adjacent lattice sites as 1, then all velocity magnitudes cj must be equal to the
square root of an integer (by the Pythagorean theorem). On other regular lattices,
the velocity might have another form, but for all lattice gas systems velocity, like
space and time, is discretized, and therefore so are the energy and momentum of
the particles (if we assume that both of these must be dependent on velocity, as is
usual in kinematics).
The 'state' concept is a bit different; it refers to the Boolean nature of the CA
'update rule' which determines the particle interactions. The rule cannot be Boolean
unless the input variables are Boolean, and the input variables cannot be Boolean
unless the particles on the lattice obey the 'exclusion principle', so that no two can
occupy the same 'state' at a given time step. The 'state', then, is defined to be the
existence or non-existence of a particle of type j moving in direction i at time step
t and at lattice site x, and the Boolean variable is nji (x, t); it is 1 if the state is
occupied by a particle, and 0 if the state is empty. Note that this means that the
number of states for a given particle type j is not necessarily equal to the number
of lattice sites; only for particles whose velocity cj = 0 will the 'state number' be
equal to the site number.
This inequality of states and sites becomes important when deriving the hydrodynamic equations for the system. The system dynamics are described most
basically by a set of 'update equations', one for each species of particle present in
the system; for a CA such as we have been discussing, a 'species' is defined as the
ensemble of all particles of the same type j moving in the same direction i. Each
update equation is then a local, discrete equation which is written as follows:
nj; (X'+
t+
+j,1)= nji (X', t) + Cji
(2)
where nj1 (X,t) here is the Boolean variable, and the 'collision operator' Cji contains
all the information about interactions with other species of particles. The structure
of Cji is determined by the 'update rule' for the specific CA under consideration; section 3 is concerned with deriving a generalized formalism for describing CA update
rules, but for this derivation we need no information about Cjj's specific structure
as long as it locally conserves mass, momentum, and energy at each lattice site. The
reason for this stipulation will become clear shortly.
The update equation (2) is discrete in the sense that it presupposes a specific
lattice site separation and time step length, both of which are set equal to 1 for
convenience and are not viewed as variables or infinitesimal quantities. We now,
however, invoke the assumption that the hydrodynamic events in which we are
interested happen on space scales that are much larger than the spacing between
adjacent lattice sites, and on time scales which are many CA time steps long; this
allows us to pass from the Boolean variables nji(x, t) to the 'distribution functions'
nji (X,t) for each species by a process of 'ensemble averaging'. This averaging process
should produce a distribution function nji (X,t) which is normalized to 1 and which
gives the probability of finding a particle of species j, i at a given lattice location
(X, t); in order for this to be true, however, the species must be indexed by state and
not by lattice site, and this explains the necessity of the second index i to distinguish
between species.
The assumption underlying the ensemble averaging process is that the discrete
update equation for the Boolean variable is identical in form to the continuous
equation for the distribution function, because the distribution function describes
the 'average behavior' of the particle species. Thus, equation (2) can be viewed
not only as an equation for the Boolean variables but also as an equation for the
distribution function, and with this and the time and space scaling described above,
which allows us to view the CA lattice site spacing and time step length as infinitesimals, we can manipulate equation (2) as a continuous equation. We therefore move
nji (X,t) to the left side of (2) and Taylor-expand in i and t; the zero-order term of
the expansion is then cancelled by the nji (j, t) moved from the right side, and if we
then retain only the terms to leading order, we are left with the first-order 'kinetic
equation' for the continuous distribution function nji (X', t):
nji (*,t) + V.-jinji (', t)= Cji.
(3)
Note that in (3) the velocity vector cji has been brought inside the derivative operator V; this is permissible because c'j is a constant and does not vary in space. This
change is necessary in anticipation of taking moments over all species j, i, since the
resulting equations will involve not C'ji but U1,which does vary in space and therefore
should be included under the operator V.
The hydrodynamic equations, or 'Euler equations', are then obtained by multiplying the kinetic equation (3) by the primitive quantities of the system and summing over all j, i. Here the nature of the collision operator becomes important,
because if it locally conserves mass, momentum, and energy, then all of the 'moments' which we take on the kinetic equation to obtain the Euler equations will
vanish when taken over the collision operator. Thus, since all CA update rules with
which we are concerned do in fact conserve mass, momentum, and energy locally,
the right side of equation (3) vanishes when the moments are taken, and we obtain
i
(,t)
_n.i (t,t)+ V. j (nj
mii
=
0.
(4)
These moments give the Euler equations for the 'fluid variables' p (mass density), Ui
(average fluid velocity), and U (average fluid internal energy). We will not consider
the energy equation here, which is given by the third moment in (4). The first two
yield the continuity equation (mass conservation),
p+V pd= 0
(5)
and the momentum equation,
p +V P= 0
(6)
where the pressure tensor P is given by P = Ej,i m•c'jCiini (0, t).
The pressure tensor is an important quantity in hydrodynamics, and its form
makes a considerable difference in the complexity of the equations involving it, i.e.,
both the momentum and the energy equations. It can be shown that if the velocity
vectors c'j satisfy certain conditions involving the tensors which can be constructed
from them (which conditions will in fact be satisfied for the full hydrodynamic CA
of which the present automaton is a part), then the pressure tensor P is isotropic
and can be written as
P = IP, + gpd•
(7)
where the factor g is in general not unity for lattice gases. This factor g is the
crucial parameter for Galilean invariance, for if we re-write the momentum equation
(6) using the pressure tensor defined in (7) and the continuity equation (5) , we
obtain
p--
+ gpd' V + u'V -[p' (g- 1)] = -VP,.
(8)
Equation (8) will only exhibit Galilean invariance if g= 1; this is shown by performing the coordinate transformation (1) on the equation, which is most easily done by
writing the variables for the old frame in terms of the new and substituting directly
into (8):
U
a
at
=
U
a
at'
-
+ Vo
- o. V
V = V,
where v-'is the relative velocity of the two frames. These substitutions yield the
new equation in the primed frame:
P'
' V'' + 'V'
+p (g - 1) (Vo - V'i + io0V' -')
' (g- 1)]
±1o)
)o
+ 2 +
0
= -VP,.
V'p (g - 1)
(9)
Obviously, (9) is only identical in form to (8) (as it must be to satisfy Galilean
invariance) if all of the 'spurious' terms involving i 0 in the second line of (9) vanish,
and that can only happen if g= 1.
The derivation of the momentum equation for non-isotropic pressure tensors is
somewhat more complicated, but yields the same final condition that the factor g be
unity to guarantee Galilean invariance. However, the actual mathematical form of g
is slightly different from the isotropic case. This is important for the present purpose
because, as will be shown in section ??, the pressure tensor for the CA developed
in the present thesis is not isotropic, although the tensor for the full hydrodynamic
CA to be developed using the methods discussed here will have an isotropic pressure
tensor.
We should pause a moment here to reflect on the real importance of the Galilean
invariance condition g= 1; what would happen if, as has been the case for previous
lattice gas simulations, g was actually a function of the mass density p, and not
generally unity? Having done the transformation from (8) to (9), we can at once
give the answer: if g is not unity, spurious effects having nothing to do with real
physics will appear depending on the frame of reference of the calculation. In the
pipe flow problem mentioned in section 2.1, for example, equation (8) would be
valid for the case of the pipe at rest, and equation (9) for the case of the fluid
initially at rest and the pipe moving with velocity v0 . The simplest illustration of
the difference would be that, for a given pressure drop over the pipe (i.e., right sides
of both equations equal), the observed laminar flow profile would not be the same
in both cases; in particular, it would not be parabolic for the case which obeyed
equation (9) if it were for the case which obeyed equation (8). Other more subtle
effects involve the transport of passive scalars, which would in general not be carried
along at the fluid velocity i'. It is obvious just from the pipe flow example, however,
that a simulation which does not guarantee Galilean invariance is not viable.
Previous automata got around this problem by restricting their scope to incompressible flows, which eliminates the third term in equation (8), and then re-scaling
the time coordinate in order to make the Galilean transformation of the first two
terms come out properly. Obviously this is restrictive since it does not allow handling of compressibility; however, there is the further problem that the handling of
passive scalars is not solved by this method. The present CA labors under no such
restrictions; however, before going into the specific methods used in it to ensure
true Galilean invariance, it will be useful to first develop a generalized formalism
for describing the family of CA's of which the present one is a member, so that the
methods used to ensure g= 1 can be generalized. After all, the present CA, although
exhibiting true Galilean invariance, is hardly suited to true hydrodynamic modeling; much more complexity and flexibility has still to be added, and the Galilean
invariance solution is but a step on the road. The non-isotropy of the pressure tensor, mentioned above, is just one example of an area in which the present CA is
inadequate.
3
Generalized Automaton Formalism
The purpose of this section is to construct, in as general a form as possible, an
expression for a CA update rule which can be applied to any automaton used to
simulate hydrodynamics.
As stated in section 2.2, the 'state variables' used to
describe this class of CA's are the Boolean variables nji (X,t) which indicate the
presence or absence of a particle of type j moving in direction i as a function of
the time and space coordinates. The lattice used is a square lattice, so that the
magnitude of each velocity vector ci must be the square root of an integer; however,
no further restriction will be made in this section on the velocity vectors for the
particle types.
Each particle type j also has associated with it three other quantities, the 'primitive variables' already referred to in connection with the derivation of the hydrodynamic equations. Here, however, we do not leave these variables totally arbitrary,
but impose definite conditions on their form and values. To be specific, the class
of CA's which we will now consider has the following restrictions on the primitive
variables:
mass mj either 0, or nonzero value indep. of j;
momentum pj = mjcj for m3j : 0 or c1 for mi = 0;
energy ej = imic3 for m.7 Oor pj for m, = 0.
The reader will notice the restriction on the mass mj; all particle types j with mj
$
0
must have the same value for their mass (usually taken to be 1 for simplicity, but
may be given another value if convenient). This restriction is mainly to reduce the
number of possible interactions which satisfy the local conservation laws of mass,
momentum, and energy; if varying masses are allowed on the lattice the mathematics
becomes overly complicated without introducing any really new physics.
One feature of this class of CA's which immediately distinguishes it from previous automata is the presence of the energy variable Ej as a property distinct from
the mass mi. The fact that different particle types with different energies and energy/mass ratios can exist on the lattice means that the system as a whole can
exhibit a property temperature which can vary with time and can be shown to follow the familiar laws of thermodynamics (this subject is dealt with in reference [?],
a previous thesis by the present author, and also in reference [?]). In hydrodynamic
terms, this means that the energy equation, derived from the third moment of the
kinetic equation as shown in (4), is not simply equivalent to the continuity equation
derived from the first moment, but brings in new and important physics of its own.
Thus, this class of CA's requires all three Euler equations to completely describe its
dynamics, although here we are concerned only with one of them.
Our task now is to construct an 'update rule' for each Boolean variable nji (xz,t);
that is, we want a finite set of Boolean operations which we can perform on nji (X,t)
to obtain nji (x, t + 1). The series of operations need not be identical for all j and i;
however, the form in which we derive the update rule should, for convenience, be as
independent of j and i as possible. This is because each of these update rules will
give the collision operator in the update equation (2), and we would like to preserve
as much as possible the generality of form of that equation.
As it happens, one such form which fits these requirements admirably is that
which has already been used to describe the update rule for the temperaturemodeling CA of the author's previous thesis. In Boolean notation, this rule has
a very simple and intuitive form:
nj; (x,,t + 1)= [nji (x,t) A jAvCij
(10)
where Cji and Aji are the 'creation sum' and 'annihilation sum' respectively, and
include the effects of all interactions which can either create or destroy a particle
of type j in direction i. The rule (10) then says simply that a particle of type j in
direction i will be present at time t + 1 if: a) it was present at time t and was not
destroyed by, any process, or b) it was created at time t by some process. When
averaged as described in section 2.2, this equation assumes the simple form
a-n (j,t)+V. -• nji (i,t) = C, = Ci - Aji
(11)
where Cji and Aji are the 'averaged' Cji and Aji and represent the probability that
a particle at location (X, t will be created or annihilated, respectively.
We should note that this update rule is entirely local (it only involves functions
at lattice site x) as long as Ci and Aj3 can be constructed entirely from Boolean
variables at site x. Since we will observe this condition, we can suppress the space
variable in our notation and simply write nj and n•t for our state variables, in the
interest of compactness. It will also be convenient to replace the Boolean notation
of (10) by conventional arithmetic notation, in order to facilitate the change to
continuous variables which must be made in order to derive hydrodynamic equations
as was done in section 2.2 above. Thus, the Boolean functions AND (A) and OR
(V) will be represented by multiplication and addition in what follows; the reader
should bear in mind that all of the equations in this section are Boolean equations
and all variables and functions can only assume the values 1 and 0.
3.1
Truth Functions
In order to derive the forms of the creation and annihilation sums C~i and Aji all
possible particle interactions on the lattice must be somehow described. In work
dealing with the temperature-modeling CA discussed in the author's previous thesis,
processes were indexed as CP or Ai, where p was the 'process index' and the C or
A meant that the process created or annihilated a particle of type j in direction
i. However, this notation did not take advantage of the inherent symmetries of the
processes which were being described, so that the same process could be described by
two or three equally valid notations, and processes which were related by symmetry
operations did not bear any simple resemblance in notation. In the present formalism
processes are instead described by 'truth functions' Tp•, indexed only by the 'process
index' p and a 'direction index' i, which allows us to distinguish rotations of a given
process p, which involve the same particle types but different directions. It is not
necessary to add a particle index j; such an index would give no new information,
and could not take the place of either of the two indices already described, since a
given process p must always involve the same particle types, even though it can be
rotated to involve different directions.
I
forward
inverse
Figure 1: Odd Photon Process
The usefulness of the truth function notation stems from the fact that processes
on the square lattice exist in pairs which are related by the TP operator, which
stands for time reversal and parity reversal (reflection through the origin). Thus,
each process index p and direction i actually indexes two interactions, one 'forward'
and the other 'inverse', which can be transformed into each other by the TP operator.
An example of such a pair is given in Figure 1; we will use the Feynman diagram
notation to diagram interactions, so that the T operator simply reverses the direction
of each arrow and the P operator reflects each arrow through the center of the
diagram. Here the straight lines are particles with mj = 1 and the wiggly lines are
'photons', or particles with mj = 0. Although in this diagram only two types of
velocity vectors are shown, the TP-symmetry pairs exist for other velocity vectors
and particle types as well.
Each pair of processes is then described by the pair of truth functions Tf, Ti.
The notation Tip stems from the fact that the two functions are 'dual' to each other;
the TP operator translated into Boolean terms means simply replacing each Boolean
variable nt by its complement
Fj',
which is the dual operation (note that the Boolean
notation for the complement has been retained). The Boolean variables which make
up the truth function are those for the states which the process involves: the function
is the product of the variables for all the 'input states' and the negations of all the
variables for the 'output states', and therefore expresses the condition that all the
necessary input states be occupied and all the necessary output states be empty for
the process to occur. Since the TP operator reverses input and output states, the
Boolean dual operation should indeed, by this reasoning, produce Tip from T!'(since
the complement of the complement gives the original Boolean variable). In this
notation, the truth functions for the processes shown in Figure 1 are:
T/1=njn
Ti= -1,i
nEi
,+- n
(12)
,(13)
where j = 1 denotes the particles moving horizontally and vertically, j = 2 denotes
the particles moving 'diagonally', and j = p denotes the photons. The direction
indices i run from 1 to 4 for this specific system, being indexed clockwise starting
with 'straight up' for j = 1,p and with 'up and to the right' for j = 2. The 'dual'
nature of the pairing should be obvious from (18) and (??).
The actual number of process indices p, particle types j, directions i, and so on
depends, of course, on the specific CA; however, in this formalism we are making no
assumptions about these matters. The only point which is crucial is that the truth
functions for each possible process pair be producible given the primitive variables
mj, cj, e for the system. This condition is met by considering the main requirement
which all possible processes must meet: they must conserve mass, momentum, and
energy locally at the lattice site at which they take place. Using these conservation laws, the possible combinations of states can be systematically examined, and
'interactions' which do not obey the laws can be discarded, leaving only the permissible processes. Once the involved states for each process are known, the forward
and inverse truth functions can easily be constructed. The decision as to which
process of a pair is 'forward' and which 'inverse', or how to assign the indices p, j, i,
is completely arbitrary, although it is advisable to choose such assignments to be as
straightforward mnemonically as possible.
3.2
Process Masks
When processes are enumerated and examined for a CA, it may turn out that some
process has only one output state (i.e., it only creates one particle).
If that is
the case, then the inverse process is 'spontaneous'; that is, having only one input
state (since input and output states are reversed to obtain the inverse), it can
occur without the necessity of a collision between two or more particles.
These
spontaneous processes have associated with them a 'decay coefficient' vp, which is a
number between 0 and 1 that determines the probability of the spontaneous process
occurring. Letting this coefficient in general be other than unity allows one to have
considerable control over the macroscopic properties of the system, as will be shown
in section 4.3 below.
There are many ways of implementing this coefficient vp into the update rule.
One method is to multiply the truth function for each spontaneous process by vp;
while straightforward and simple, this has the fatal flaw of removing the Boolean
character of the truth function, and therefore of the update rule, so that another
method must be sought. The solution arises from the fact that vp is an 'average'
or 'probabilistic' quantity; that is, it only strictly applies when a large number of
time steps and space locations are considered. We can therefore use any method in
the update rule which will yield the correct average over a large number of process
'events', no matter what its nature microscopically; we need not worry about trying
to locally simulate (using a random number generator or some similar method) the
probabilistic nature of the overall interaction. The method which is assumed in
this general formalism is that of creating a Boolean variable PP, or 'process mask',
which is 1 on a fraction vp of the total number of lattice sites. Thus, over a large
enough number of time steps, the decay process p will happen a fraction vp of the
time. In order to keep the formalism consistent, we also define process masks for
non-spontaneous processes; we simply set them to 1 everywhere, so that in effect
we are associating a coefficient vp = 1 with these processes (they happen whenever
their truth function is 'on').
Another function of the process mask once defined, which was quite useful in the
CA described in the present author's previous thesis, is to take care of cases in which
processes 'conflict' (i.e., share input or output states). Specifically, it may happen
that several different processes produce only one output state, which happens to be
the same one; then the inverse process, with the same input state in both cases, will
have several possible output states. Again, a random number generator could be
used to choose between the possible states at each occurrence of the decay; however,
the process masks afford a much faster solution. If the number of processes p which
share states in this way is N, then we simply 'seed' each mask with a probability of
vp/N, taking steps to ensure that no two masks are 1 at the same site.
The total 'truth condition' for a process p to occur is then given by PPTI'; the
truth function and the process mask must both be 1 at the lattice site for the process
to occur. From here on in this discussion, therefore, the terms 'truth function' and
'truth condition' will be assumed to stand for PPTj' unless the context makes it clear
that only I is meant.
3.3
Matrix Element
The truth condition PPT•' is the primary condition for a process to occur; however,
it has already been mentioned that several processes may share input or output
states and therefore 'compete'. The use of process masks can help to alleviate this
problem by effectively 'labeling' sites so that only certain processes can happen at
each; however, this method can quickly become cumbersome when a large number
of interactions are possible on the lattice, since steps must be taken to ensure that
the masks for two conflicting processes are not both 1 at a given site. Therefore, it
is desirable to find some other method of dealing with competing processes.
The simplest method, and the one which will be treated in this formalism, is
to require that the truth functions for all competing processes be 'off' in order for
a process whose truth condition is 'on' at a given site to actually happen. We
therefore define another Boolean function called the 'matrix element' M (whose
indices have not yet been determined) which is 1 only if no other competing truth
functions are 1 at the site in question. To keep the formalism general, however,
we cannot assume anything about the nature of the processes which would tell us
which p indices 'compete' with one another. Therefore, the matrix element M must
include all other processes, whether they actually 'compete' or not, in the general
formalism. This condition is evidently stricter than necessary to avoid competition,
since by it two processes p which do not share either input or output states will still
be mutually excluded by the matrix element. The advantages and drawbacks of this
method will be discussed in a moment; first, however, let us develop the form of the
matrix element based on this criterion.
Logically, the assertion that no competing truth functions be 'on' is expressed by
multiplying (linking with AND) the negations of all the truth functions. We might
suppose that simply negating all processes with a p index different from that of the
process we are interested in would be enough; however, to be completely general,
we should include both indices on the truth function, p and i, in order to take into
account processes with the same p but different i which might also compete. We
can therefore state the form of the general matrix element Alf':
1
Mr =
(P"'~ )
P( I')
H (PP
i)
p3p iti
)( PpT
(14)
Ti
The full condition for process p, i to happen is now given by MiPPTjP; the process
will actually take place only if: a) the truth condition is satisfied (process mask and
truth fn. both 1), and b) the truth conditions for all other processes are not satisfied.
For convenience in further discussion (and also for easier code implementation) we
transform (14) by De Morgan's Rule into
n=
(z
[P~'q.+
PPiIb]
[7V
PPpT + P(15)
which becomes our general matrix element form.
It is fairly easy to see that the 'inverse matrix element', Al', is equal to Mi": we
simply replace each Boolean function in either (14) or (15) by its inverse or 'dual',
and remember that the dual of the dual is equal to the identity operator. This is
easiest to see in (15), where the substitution immediately leads to the same equation.
Thus, we can use the same matrix element for both the forward and inverse process
for each p and i. This equivalence, although not further discussed in this thesis, is
important in thermodynamic theory for reasons which are discussed in reference [?].
Although the matrix element (15) is attractive from the standpoint of simplicity,
it has, as already mentioned, some drawbacks from the standpoint of actual physical
modeling. The most obvious drawback is that interactions on the lattice happen less
often than they would if only 'competing' processes were disallowed and processes
which shared no input and output states were allowed to take place simultaneously
at a given lattice site. This effect is negligible at low densities where the probability
distributions nij(i, t) are all much less than 1; however, at higher densities, the
probability of two truth functions being satisfied at the same lattice site gets larger,
and we will find that the automaton becomes 'frozen' as the matrix element disallows
more and more processes, even if they do not actually compete. However, there is
no immediately apparent way to formalize generally the conditions that would have
to be satisfied for two truth conditions PPT/', PP'T,,' to share input and/or output
states, since this depends on the specific forms of the truth functions, and therefore
on the specific structure of a given CA.
There is also the possibility of dispensing with the matrix element altogether by
using a 'cycle rule', which updates the processes one at a time according to some
definite order, so that conflicts never arise. Thus, supposing that we have three
processes p and four directions i for each process, we would take a state nji (X, t),
update it using process p = 1, i = 1, say, then take the output from that update
and update it using p = 1, i = 2, and so on until we had covered all possible
combinations of p, i. We could even vary the order in which the processes are taken
on different time steps, in order to achieve some sort of 'equal mixing' of the effects
of each process. It is not clear at this writing whether such a 'cycle rule' could
be formalized in a form sufficiently simple as to allow expression in the form (10);
certainly it is not clear a priori that the form (10) is valid for the cycle rule, since
each process, whether creating or annihilating a particle j, i, acts on a different
'input state' than all other processes, so that they cannot be summed together in
any simple way.
Future work on the complete hydrodynamic CA may attempt to use the 'cycle
rule', or some other method of avoiding the 'freezing out' of processes at high densities that occurs with the present matrix element. However, this problem is not
directly related to the Galilean invariance question, so we will devote no further attention to it in this thesis. The simulations discussed in section 5 were for the most
part done at densities low enough that the matrix element effects were negligible.
3.4
Creation and Annihilation Sums
We are now in a position to construct the creation and annihilation sums Cji and
Aji. First, we must define two Boolean functions which will enable us to write the
two sums in a very symmetric and elegant manner. The first is the 'sign function'
S':; it is defined arbitrarily to be 1 if the 'forward' process p creates a particle of
type j (irrespective of direction). Therefore, the complement S' is 1 if the 'forward'
process p annihilates a particle of type j, or, equivalently, if the inverse process p
creates a particle of type j. The sign function may therefore be viewed as implicitly
defining which process of each dual pair is 'forward' and which 'inverse'.
The second function which we shall define is the 'index function' F,,I. The
plethora of indices here is not really that difficult to understand; the index function
will be 1 if the permutation of indices p, j, i,i' is 'allowed', in the sense that the
variable nji is an 'argument' of the truth function pair Ti,,
•i,.A Boolean variable
is said to be an 'argument' of a truth function pair if it appears in one function of
the pair and its complement appears in the other (it makes no difference which fn.,
forward or inverse, has the variable and which has the complement). The function
17-,i, is therefore something of a 'bookkeeping' function which matches each truth
function pair with the variables nji which it is capable of creating or annihilating.
The indices j, i must of course refer to the indices of the creation and annihilation
sums, which is why it is necessary to introduce a second direction index i' for the
truth function pair (since its direction index need not, in general, match the direction
indices of all its arguments).
Armed with these two functions, we can now state the forms of the creation and
annihilation sums:
CM, SF
MPPTT, +
p
M Pt
,
(16)
it
=
+ SMPpT]
j M ,PPTMVPT
(17)
The symmetry of (16) and (17) will become quite useful when the update rule is
averaged and converted to continuous variables and cast in a form like (11). This is
not actually done here, however, since it will not be necessary to derive the Galilean
invariance condition. This completes the development of the generalized automaton
formalism; the update rule (10), combined with the sum definitions (16) and (17)
and the matrix element (15), can be applied to any CA of the general class defined
at the beginning of this section.
j=1
j=2
Figure 2: 012 CA Particles and Directions
4
The Galilean Invariance Automaton
Having discussed at length the theoretical background for the Galilean invariance
problem, it is now time to describe the specific CA which is used to solve it. The
generalized formalism developed in the previous section will be used to describe the
update rule; however, now the specific forms of the Boolean functions and the limits
on the indices can be given. First, however, we must specify the 'primitive variables'
for this automaton. There are three types of particles on the lattice, indexed by
j = 0, 1, 2; the j indices are set up so that cj = v'J.
Thus, the j = 0 particle, or
'stopped particle', does not move but always remains at the same lattice site until
annihilated by some process. The j = 1 particle moves horizontally and vertically,
and the j = 2 particle moves diagonally, as shown in figure 2. This range of j indices
gives rise to the name '012 CA' for the automaton, which will be used hereafter to
refer to it.
All particles have mass mj = 1; there are no massless 'photons' in the 012 CA.
= mjmc
The velocity vectors have already been given, and the energies are e ==
j.
The moving particle types each have four possible direction indices, as shown in
Figure 2, in the range i = 0 to i = 3. This completes the listing of the primitive
variables for the 012 CA, and we now proceed to derive the update rule according
to the generalized formalism of section 3.
4.1
Update Rule
An examination of the range of possible input and output states for the 012 CA
will soon lead to the conclusion that only three pairs of processes are possible which
locally conserve mass, momentum, and energy. These are all diagrammed in Figure
3, and the p indices and definitions of forward and inverse for each process pair
are as shown there. In each diagram in Figure 3, the processes have been shown
with direction index i = 0; rotation of each diagram clockwise through 90 degrees
produces, in successive steps, the i = 1, i = 2, and i = 3 diagrams for each process
pair. The reader will note several symmetries in the 'self-collision' processes (p =
2, 3) which will be discussed in a moment.
From the diagrams in Figure 3 it is a simple matter to construct the truth
functions for the three process types. We need only do so for the forward processes,
since the dual operation will give us the inverses immediately once we have the
forward truth functions. We adopt for convenience the notation no0 o for the 'stopped'
particle; since it does not move, it really has no 'direction index', but in order to
keep the formalism consistent we assign all stopped particles the index i = 0, and
construct the update rule accordingly. The three forward truth functions then are:
Ti = n, n,n+1
i
2,i f0,0
(18)
Ti = ni,i nl,i+2 iil,i+l i,i+3
(19)
forward
inverse
=1
++
inverse
forward
forward
p= 2
inverse
p= 3
Figure 3: Process Diagrams for 012 CA
S=
n 2 ,i n 2 ,i+2 f2,i+l
ff 2 ,i+ 3
(20)
where we have suppressed the time index t since it is understood that all variables
are evaluated at the same time step.
The reader will perhaps have noticed at this point that of the three process pairs
described in (18), (19), (20), none are 'spontaneous' in the sense defined in section
3.2. It would seem, then, that process masks for the 012 CA are superfluous, since
they would all be 1 in any case. However, it is desirable for reasons of flexibility
to attach a coefficient v, that is different from 1 to at one process, even if it is
not strictly 'spontaneous'. Such a process would have to be one in which two or
more types of particles are involved, since the flexibility desired is in controlling the
thermal equilibration of the system (see section 4.3 for a fuller explanation of this),
and the only such process in the 012 CA is the p = 1 process. (The 'self-collision'
processes p = 2,3 in this model must have v = because of symmetry properties
such as those discussed in Appendix B as well as the above reasons.) We therefore
choose to define a coefficient Vi for the inverse p = 1 process which is in general not
unity; therefore, although all other process masks are 1, the mask P' is 1 only on a
fraction v, of the lattice sites.
Once we know the truth functions and process masks, the rest of the update rule
then follows from the general equation (10), the forms (16) and (17) for Cji and Aji,
and the matrix element (15). The only two functions not yet known are the sign
function SP and the index function -•,i,. Inspection of the truth functions (18),
(19), (20) will show that the sign function must be defined as follows:
Sy -S
1 for p =1 and j = 0,j = 2;
j 0
for all other cases.
(21)
The index function is a bit more complex, and its exact nature is not really
germane to the discussion here, as long as it is known for all permutations of its
indices. Discussion of the detailed structure of Y..,, will therefore not be given here,
but can be found in Appendix B. A few features can, of course, be easily gleaned
from the truth functions: Y•',,i, must be 0 for j = 0 and i j 0 (regardless of p and
i'), and must also be zero for j = 2 and i' # i, since the direction index of the type 2
particle always matches that of the truth function. Finally, the index function serves
to 'pick out' the correct self-collision permutation of p, j; thus it is 0 for p = 2,j
and p = 3, j
$
$
1
2. The rest of the structure can be derived in similar fashion, so that
we can assume that -~.Fyis a known function; its exact values will not matter in
the development to follow.
The upshot of all this is that, using the generalized formalism of section 3 and
the truth functions and primitive variables defined above, a complete Boolean update rule can be constructed for the 012 CA, and translated into computer code for
implementation. The rest of this section will therefore be concerned with the macroscopic behavior of the 012 CA, assuming that the microscopic behavior is exactly
known.
4.2
Equation for Galilean Invariance
Having defined the 'primitive variables' for the 012 CA, we must now use them
to derive forms for the macroscopic variables which appear in the hydrodynamic
equations, specifically the momentum equation (6), in order to derive an expression
for the factor g. Thus, we need expressions for the mass density p, the fluid velocity
ui,
, mc-'j
mj c-'jnji (X,t). These will in turn
and the pressure tensor defined by P =
lead us to an expression for g, which must be 1 to guarantee Galilean invariance.
We must first define the probability distributions njf (X,t) for the three types of
particles present on the lattice. Letting S be the number of lattice sites, we have
S possible 'states' for the stopped particles and 4S states for each type of moving
particle. If Nj(t) denotes the number of particles of type j present on the lattice
at time step t, then the probability of finding a particle of type j in a given state
is simply the number of particles divided by the total number of states. We will
denote this 'averaged' probability by nj; the three nj are then given by
no =-
No
N1
n 4S
N2
n2 = N
(22)
4S
The averaged probabilities nj are then, on the large hydrodynamic scale, taken to
be the values of the distribution function (or, more accurately, expectation value)
nji (X,t) at the spatial location X'defined by the 'lattice cell' over which the averages
nj are taken. This is justified by the 'continuum limit' arguments given in section
2.2.
The mass and energy densities are now easily generated; we define
1
N,
pES-
(23)
· E 2s . N6,
(24)
p = no + 4nl + 4n 2,
(25)
E = nl + 2n 2 .
(26)
and obtain immediately
The difference in normalization between p and e will become convenient when the g
expression is derived below. The energy density E, while not directly present in the
momentum equation, is necessary for calculating the thermodynamic equilibrium of
the system (as is done in section 4.3 below), and also will arise in the evaluation of
the pressure tensor.
We will not derive the form for the fluid velocity, since its exact form will not
affect the g equation, and therfore come to the pressure tensor. Using the form
P = Ej,i mjnjC-jiC'ji, we find that
P=I [
2
= cInj
2c
n-y
(1 _- 32 u
21
1/iu-
f 3P
-
a
j
nj
12
+21T2i
-T-
(27)
where the coefficients aj and fj' depend in a complex fashion which we shall not
discuss on the exact distribution function of particles in the lattice cell; the coefficient
3 is given by / = p/2E and comes from the coefficient of the first-order term of
the expansion of the distribution nji (X,t) about its average value nj, and we have
introduced the second-rank identity tensor I and the fourth-rank tensor
T=
njf//c
i
i(28)
j,i
Also, in (27) we have retained the notation Ai to represent 1 - nj for compactness.
The pressure tensor (??) is not isotropic, as will be seen in a moment, for the
012 CA presently under discussion, since the fourth-rank tensor T is not completely
symmetric. It is worth noting, however, that for the complete hydrodynamics code
which will draw on the work discussed here, the tensor T is in fact completely
symmetric, so that the pressure tensor for that system is isotropic. Non-isotropy of
the pressure tensor is unimportant for the present CA, since it is not intended to
model actual fluid flows but only to investigate methods of ensuring that g = 1; for
a simulation of real flows, however, isotropy of P is highly desirable because of the
much simpler form of the Euler equations, as shown in section 2.2.
The coefficient of the identity tensor I in (27) is the 'scalar pressure' P,, which
we are not concerned with here because it does not affect the factor g; we therefore
need evaluate only the last term in (27) to obtain an expression for g. Furthermore,
for the purposes of the present discussion we will take only the low-density limit of
g, meaning that we can set fý' = 1 and drop it out of the equation, and that we
assume that all complements iij are 1 also. This yields the expression
T = 4n2A
(4 )
+ (4) (2n, - 8n 2 )
(29)
where dA)
is the completely symmetric fourth-rank tensor and 0(4) is the 4-index
Kronecker delta (which is 1 only if all indices are equal). Performing the double dot
product in the last term of (??) then yields a term of the form
4P8nn2 5i
= gp- d
(30)
which yields the expression for g when 3 = p/ 2 6 is substituted:
pn,
(31)
We can finally render this in terms of the known occupation numbers nj in order to
have an equation directly derivable from the automaton output:
n 2 (no + 4ni + 4n 2 )
(ni + 2n2)2
Our condition for Galilean invariance is now simply g = 1, or, manipulating
equation (32),
(ni + 2n2)2 = n2 (no +4n1 +4n2)
n2 + 4nln 2 + 4n2 = non2 + 4nln 2 + 4n2
=- n = non2.
(33)
Equation (33) is quite simple and elegant, and its simple form depends crucially on
the mass and energy density normalizations chosen in (23) and (24) being different.
In order to actually calculate g in the computer code, equation (32) is used, since g
may not be exactly 1; however, equation (33) is more useful intuitively in grasping
the nature of the g = 1 condition.
4.3
Equilibrium Properties
We will now study in some detail the equilibrium state of the 012 CA system under
the constraint g = 1; our aim is to show that the equilibrium occupation numbers
nj can be expressed in terms of the fluid variables p and E. Such an expression is
useful for two reasons. First, it enables us to put a 'check' on the computer code by
comparing the actual occupation numbers with those predicted on the basis of the
p and e in the lattice cell. Second, it is important for any further development of
hydrodynamics, transport theory, and other macroscopic properties of the system
to understand the equilibrium, the degrees of freedom inherent in the system, and
so on.
We start with equations (25) and (26) for the mass and energy density, equation
(33) for the g = 1 constraint, and the thermodynamic equilibrium condition for the
012 CA
n1
n2 = no0n ij
2 1
(34)
where the 'average decay coefficient' v is equal to the decay coefficient v, for the
inverse p = 1 process that was introduced in section 4.1. We can immediately
combine equation (34) with (33) to cancel the occupation numbers on both sides of
(34), leaving only the complements:
io22
(35)
=
which will determine the equilibrium v given the three occupation numbers nj; thus
we can see that the decay coefficient also will be determined from the fluid variables.
We next observe that equation (33) can be recast in the form
no
nil
rt1
T•2
(36)
so that we can define the ratio R = no/ni = nl/n 2, and write equations (25) and
(26) as follows:
p=n 2 (R 2 + 4R+4) = (R+2)2 n2
= (R + 2) n 2 .
(37)
(38)
Equations (37) and (38) at once yield the solutions for R and nz:
R =
P
(39)
-2
62
(40)
n2 = -P
and equation (35) yields the solution for v:
(1
- R)2 n 2
(1-=
v
(1- Rn2)2
(41)
These three equations completely determine the occupation numbers and v in terms
of the fluid variables p and E.
In order to understand exactly what we have just done, let us now define the
thermodynamic temperature of the system. We first make the notational definition
j -=nj/Aj; then we define the temperature as
T=
1
.
log( )
(42)
At thermodynamic equilibrium, from equation (34) we obtain the condition that
vfo
hl
- --,
i
nz2
(43)
and if we define a 'particle temperature' T1 2 as
T12
(44)
log ()
then it is obvious that at equilibrium T12 = T. More importantly, however, the
equilibrium temperature T is exactly determined by the fluid variables p and e and
the g = 1 condition, since they determine the occupation numbers and v through
equations (39), (40), and (41). Thus, what we have done is to show that the thermodynamic temperature is not really a free variable of the system, if p and C are
considered free variables.
Another implication of what we have done is that the system must be allowed
to relax to g = 1; it cannot be constantly maintained in a g = 1 state. To show
this, recall that we defined the ratio R between the occupation numbers, and that
this definition did not depend on the system being in thermodynamic equilibrium.
In fact, our solutions for R and n z were actually solutions for the condition g = 1
only, without reference to equilibrium at all! The only place in which we used the
equilibrium condition was in determining v from the other variables. The reader
might at this point accuse the author of a bit of false advertising, since this section
was entitled 'Equilibrium Properties' and it seems as though the system properties
can be determined out of equilibrium as well; however, consider what adding the
equilibrium condition does to the system behavior. We can determine the necessary
occupation numbers for g = 1 without using any equilibrium condition, and these
occupation numbers are uniquely defined in terms of the fluid variables p and e;
however, the system will only reach those occupation numbers in steady state if the
decay coefficient v is the correct value to make those occupation numbers define a
thermodynamic equilibrium state. If v is not at the proper value, given by equation
(41), then the system will not equilibrate to the proper occupation numbers for g
to equal 1. And, even if v is at its proper value, the system need not start out in
thermodynamic equilibrium; if it is perturbed from that equilibrium, it will take
time to relax again, and during that time g will not be 1.
Therefore, the problem of ensuring g = 1 boils down to the problem of ensuring
that v is at the correct value given by equation (41); if that is the case, then
given enough time the system will equilibrate and reach a steady state in which
the occupation numbers are in the correct ratios R to give g = 1. In order for
this to be satisfactory for hydrodynamic simulations, the equilibration time for the
'lattice cell' must be very short compared to the hydrodynamic time scale, so that
macroscopically the system is perceived as having g = 1 all the time, because the
small perturbations and re-relaxations happen too fast to be distinguished. These
two requirements-make v assume the correct value, and make sure that the system
relaxes to g = 1 fast enough-form the basis for judging the code results given in
section 5; in the remainder of this section we will discuss the method used to meet
these requirements in the 012 CA.
4.4
Methods For Ensuring G = 1
Since the problem of ensuring g = 1 boils down to ensuring that v is the correct
value, and since the correct value for v is given by equation (41), the simplest
solution would seem to be determining p and Eat each time step, calculating v from
(41), and then letting that calculated value be the v for the next time step. This
is in fact the method used in the 012 CA code, with several slight modifications;
but it has the drawback of involving a larger-than-desired number of floating point
operations, which offsets some of the speed advantage of the Boolean update rule.
The modifications in the actual code are all aimed at making the number of such
operations as small as possible; but it is worthwhile to ask whether there might
not be some other way of making v assume the correct value which is even faster,
perhaps Boolean in character. Such a 'mask automaton' has not, as of this writing,
been made to work, but prospects for constructing a viable one seem good as of this
writing.
The actual 012 CA code does use equation (41) to calculate v, after calculating
R and n 2 for equilibration using (39) and (40). It then uses the new value of v
to 'seed' the process mask for the inverse p = 1 process before the next update
step. However, the code only re-calculates v if the fluid variables p and E have
changed since the last time step; if they are the same, then the masks are not reseeded in order to save operations. Unavoidable fluctuations in the random number
generator mean that the actual value of v obtained will not be exactly equal to
the calculated value for equilibration; however, the difference is typically less that 1
percent for the lattice size worked with here, and will become smaller as the number
of lattice sites gets larger. Another reason for not re-seeding the masks every time
step is that we wish to measure the equlibration time of the system after an initial
perturbation; thus, after p and E have been changed and a new mask created, the
mask is left constant for a number of steps in order to let the system relax. The
hope is that this relaxation will take place in a number of time steps which is fairly
small compared to the number of time steps required for a particle to cross the
'lattice cell'; this latter time is taken to approximate the hydrodynamic time scale
(since the lattice cell is considered to be a point in the hydrodynamic system), and
we need to have the CA relax to g = 1 on a time scale which is short compared to
the hydrodynamic time scale in order to justify the change to continous variables
which was necessary to derive the hydrodynamic equations in section 2.2.
5
Results of Code Simulations
The detailed structure of the computer code will not be discussed here, since understanding it is not essential to interpreting the results of the simulation. A fairly
detailed discussion of the code can be found in Appendix 1. The basic plan, once the
code for the update rule had been tested and found to conserve mass, momentum,
and energy in a fully closed system (the most basic possible test), was to attach the
necessary input and output machinery so that the value of g and any other parameters of interest could be monitored, and then to perturb the system by changing
p and e and observe relaxation to thermal equilibrium and g = 1. An output of
the 'effective' v (as calculated from the actual process masks) versus the calculated
v for equilibration was also generated, but it conveys little information beyond the
fact that v was within 1 percent of its calculated value (quite acceptable considering
the unavoidable fluctuations in the random number generator).
Output from several runs of the code is shown in Figures 4 through 7. For each
run there is a series of three graphs: first, a plot of the actual perturbations created
in the system in terms of the mass density p and energy density E present on the
lattice; second, a plot of g versus time, in which the perturbations and relaxations
can be observed; and third, a plot of the two temperatures T12 and T versus time, so
that thermal equilibration can be verified. The lattice size used for all simulations
was 64 by 66 sites, which is the typical desired size for a 'lattice cell' in a largescale hydrodynamic simulation; thus, the hydrodynamic space scale is taken to be
64 lattice sites long, and the time scale to be 64 CA time steps long. The fact
that the equilibration times observed were 10 percent or less of the hydrodynamic
scale supports the assumptions underlying the change from discrete to continuous
variables necessary to developing the hydrodynamic equations.
5.1
Run 1 (Figure 4)
This run is the longest in time of the runs given here, and exhibits most of the
essential features of the automaton, being a representative example of several similar
runs of the code. The density and energy perturbations, as can be seen from Figure
4, are sinusoidal. The 'noise' at the beginning and end of the plot of g is probably
due to statistical effects (see section 5.3 below), which are dependent on the density;
as p increases towards the middle of the run, the noise is observed to damp out and
the value of g remains much closer to 1. It should be noted that the effective v
on the lattice, determined by the process masks, will not be exactly equal to the
calculated v required for equilibration; the error is due to statistical fluctuations in
the random number generator and is typically 1 percent for the lattice size of these
simulations. The error, of course, decreases as the number of lattice sites increases.
This is one of several statistical effects on the system behavior; another such effect
is investigated in section 5.3 below.
Also, from both the g and temperature plots the equilibration time of the system
is observed to be well under 10 time steps, which is the interval at which perturbations were applied (the sharp 'spikes' in the g and temperature plots show the
occurrence of the perturbations, as does the plot of p and e). The two temperatures
T12 and T are not exactly the same throughout the run, but except for the 'spikes'
they are close enough to make any variations probably statistical in nature, so that
the width of the spikes themselves can be taken as giving the equilibration time.
Since the spike width is considerably less than the spacing between the spikes, we
know that the equilibration is taking place in well under 10 time steps; a tentative
average would be 4 or 5 time steps, which is under 10 percent of the 64-time step
hydrodynamic scale. A similar equilibration time is observed in run 2 (Figure 5).
5.2
Run 2 (Figure 5)
This run is interesting for two reasons, the first of which is that the densities achieved
were well above those at which the low-density limit used to derive the g = 1
equation in section 4.2 is valid. The units of p and Eon the plots shown are particles
per site and energy units (energy of type 1 particle = 1) per state (recall equations
(23) and (24) and their different normalizations); thus the maximum value for p is
9.0, and for e, 3.0. Values of these parameters in the first run reached more than 80
percent of maximum, so that the low-density theoretical calculations of sections 4.2
and 4.3 should not have applied. However, the plot of g versus time and temperature
versus time show that thermal equilibration is nearly perfect and g is still 1 within 2
percent after equilibration, so that even in regimes outside that of strict theoretical
validity the code simulation does a good job of achieving its goal. Study of the g plot
will reveal that the equilibrated value of g seems to be decreasing with the increasing
densities; this can be understood by taking higher-order corrections into account in
our calculations, but only at the cost of much more work, and it is refreshing to
find that we can make a much simpler calculation and still obtain results which are
quite accurate.
The second interesting aspect of this run is the achievement of a negativetemperature state after time step 10. This occurs, as is discussed in reference [?],
because the system has an upper bound for its total energy, corresponding to a
state in which nl and n2 are both 1 (all type 1 and 2 states filled). Such a state
has no real meaning in a hydrodynamic simulation; however, its occurrence here
opens up the possibility of modeling highly degenerate systems using a CA similar
to the one described here. In terms of the equilibrium equations of section 4.3, such
a state satisfies the g = 1 condition by having an 'inverted population' in which
n2
> ni > no, rather than the reverse, which would be the normal case for a hy-
drodynamic problem. This corresponds to the ratio R = no/nl = nl /n being less
than 1, and the condition for this, derived from equation (39), is
P < 3.
(45)
This condition can readily be verified from examining the plot of p and Ein Figure
5.2. Such a state is stable as long as the system is isolated and cannot exchange
energy with the outside world, which is just another way of saying that there are
only a finite number of states that can be occupied, and hence an energy upper
bound.
5.3
Runs 3 and 4 (Figures 6 and 7)
These runs were done mainly to investigate the 'noise effect' of statistical fluctuations
on the system behavior. The perturbations on p and e were very small for both runs,
so that the system could be treated as virtually closed while still allowing the routine
which re-calculates v and re-seeds the masks to work (since it only changes the masks
if p and E change). As is obvious from examining Figures 6 and 7, the fluctuations
affect g to a considerable extent (as much as 12 percent fluctuation either way from
g = 1), but affect the temperature to a lesser extent. Also, by comparing the figures,
we find that as the density and energy increase, the amplitude of the g fluctuations
grows smaller.
We can justify this on the basis of a simple argument; recall the formula for g
pn2
(46)
and let g be perturbed by a small amount Sg from its equilibrium value of 1, thus:
g = 1+ 6g
(47)
Then substitute (47) into (46) and arrive at an expression for Sg:
g=
- 1.
(48)
If we let n2 also be perturbed by a small amount Sn 2 from its equilibrium value of
e2 / p , we find that
5g
= PSn2 .
(49)
If we now take the 'standard deviation' of g by the usual methods of statistics,
we find that it is given by (49), with the standard deviation of n 2 replacing 6n 2 . We
assume that the standard deviation of n2 will be fairly constant with p and e, and
therefore the amplitude of fluctuations in g will vary as p/c 2 . The values of this are:
for run 3, p/e 2
117; for run 4, p/l 2
be approximated by
run 3, a•
(gma, - gmi,)
20. The observed standard deviations can
for this rough calculation, which yields: for
0.14; for run 4, a 1 0.042.
For the formula (49) to be valid, we should have the standard deviations in the
same ratio as the p/e2 factors; the actual ratios are 5.8 for the factors and 3.3 for
the deviations, which suggests that the effect of changes in n 2 is mitigating the p/c2
effect somewhat. However, the main observation, that increasing p and Cdecreases
the fluctuation amplitude, is supported by our calculation here. Furthermore, we
can say that it is necessary to increase both p and Ein order to achieve this effect;
simply increasing p by itself (for example by adding more stopped particles to the
system) will actually increase the fluctuation amplitude, according to (49). Thus,
the fluctuations decrease in amplitude as more particles of all types are added to the
system in equal ratios. We can observe this effect in run 1 as well: the 'noise' at the
beginning and end of the run, as plotted in Figure 4, has ple2 0 60 and o - 0.13,
so that it fits very well with the values from run 4, although not so well with those
of run 3. In the middle of run 1, the value of p/E2 is down to 4, and the fluctuations
are hardly observable.
5.4
Conclusions
The Galilean invariance code developed in this thesis does ensure g = 1 to a degree
of accuracy commensurate with the inherent statistical errors in the system. Most
of these errors will become negligible as larger and larger systems are dealt with;
the assumptions underlying the theoretical development were meant to apply to the
hydrodynamic system as a whole and not to a single 'lattice cell' which is meant
to simulate a point or infinitesimal element of the fluid. The fact that already the
deviations in g (as calculated in section 5.3) are not much higher than 10 percent,
when only a single lattice cell is being considered, indicates that over many lattice
cells the g = 1 condition would hold quite well on a macroscopic scale.
INOAItUSILONVS. TIHE
I
I
a Vs.
TuPiA&m vs. mIV
115
Iwolw
I(.,
~JWAil~
Il
I.
-
I
. -
.-.
_.-.-.
I
~ft
......................................
I
I
n i
I
I
93~SZI
rl5
Figure 4: Code Run 1 Output
46
I
I
I
I
I
.A
090
5
torm
VI.
A40 UP$2LON
VS,rfli
rIM(
TEMrUIAT0ICS
VS.ri[[
i
1.40
I.20
.10
.70
so
z
Figure 5: Code Run 2 Output
47
.1%
-1'A
Ii
·· I
of
f
1
,1....
1
I
.
he
P111MOR
Is.Till
1
.
".""...I 1....
I....TI
I
.I2
.Me
a·
-
1,,
I ,
r-
....I
....I.,.I,,.,I
1
3
...
.I
. .....
2
2
:,,~
I.
.... ...I....I ....
2!
:
3
: z
TIM'
4 VI. fTII
TNIPCNIATII
VS. Mfll
21.00
:"'1""1""1""1"'
'1""~"'
I""1""I""1"T~I' "'l""r'"T""
19.06
_€r
-rc
..
.
.
:
TINS
TIM
Figure 6: Code Run 3 Output
:
2-
1*0ANO 9PSLE
VS. Tilt
.IS
.70
I
r
.94
I
t
.4.
.4.
t
.1@
'.1
!..
LA-A.W-LA."J.".
.. . . . . . . . . . .
.. . ..
.. ..
.. . .
.
1.10 C
E
F
i
1.30
ic
r
E
5.0.
-3.N9
'....r....l....l
S
"
...
,1....1....1
.,..1.,..I....I
3
I
.
.
TUPCIEATIV
v. sus
SV1I.TIMA
I,.-
Il.',
t
S
....
-
z
rTms
Figure 7: Code Run 4 Output
49
APPENDICES
A
Remarks on the Code
A listing of the FORTRAN code used to realize the CA developed in this thesis is
provided in Appendix C. Here a few remarks on its logical structure and adaptations
made in writing it will be made. The code is written in seven separate 'modules',
each containing one or more subroutines which are intended to accomplish a given
task. The first module, 'program newca', is the main program which calls all the
subroutines and orchestrates the running of the code. Its structure is very simple,
which is why the module method has been used in the code: input is read in, the
array is initialized, and the 'output' routine called to calculate system parameters.
Then the 'time step loop' is entered; at each step the move routine, the mask initialization routine, the update rule, and the output routine are called in succession,
so that the lattice is run through one update cycle and the new system parameters
calculated for use in the next cycle. Finally, after the last time step, the output
routine is called again to finish things up. The conditional statement in the time
step loop is to determine whether particles will be added or subtracted from the
system in the move routine.
The Boolean variables nji(x, t) are stored in 'words' of 32 bits each in the computer memory; the exact 'arrangement' of the words on the lattice is not terribly
important, since it affects only the move subroutine (q.v.). The 32-bit words mean
that the update rule actually 'processes' 32 lattice sites at a time; this parallelism
is another advantage of using Boolean variables for simulations. The words are
'aligned' horizontally except for the left and right walls, which are aligned vertically;
therefore, the lattice must be a multiple of 32 sites long in the vertical direction and
a multiple of 32 plus 2 extra sites in the horizontal direction. The vertical wall words
are mainly there to make the move loop easier.
The six 'modules' are each briefly described below:
Input Module: Contains the subroutine 'input', which reads in program parameters from a data file and from the keyboard, opens all necessary output files, and
calculates parameters necessary for other subroutines. Most of the parameters have
to do with proper referencing of array variables.
Initialization Module: Contains the subroutines 'init' and 'mask'; the first initializes the particle variables ni(x, t), the sign function S., and the index function
s., i,,; it also sets all process masks except for the inverse p = 1 mask to 1 everywhere. The second subroutine initializes the inverse p = 1 mask if given a value of
v in the variable 'xnew' which is different from the value 'xnuO' from the previous
time step.
Move Module: This subroutine, 'move', is the most complex of the routines in
the code; its purpose is to 'propagate' the particles according to their velocity vectors
cli. In order to do this, system subroutines and functions which can 'circular shift'
bits in a word of memory, set bits to 1 or 0, and move bits from one word to another,
are utilized. At the end of the move routine is a section to add or remove particles,
if that is called for; the condition is that the variable 'iset' be nonzero for particles
to be added or subtracted. The number of particles (bits) added or subtracted from
each word is given by the variable 'jtest'.
Update Module: This contains the subroutine 'update', which actually realizes
the CA update rule by translating the Boolean equations directly into FORTRAN
statements, using special system functions which perform logical operations directly
on bits of storage. The array reference variables have been chosen to match as
closely as possible the indices in the formalism; thus i is used for direction, j for
particle type, and p for process index. The functions SP and Pj,y (stored in the
variables 's' and 'findex') are presumed given in the subroutine (they are initialized
by the 'init' routine).
Output Module: Contains the routines 'output' and 'maskcount'; the latter simply counts the number of bits which are 1 in all the inverse p = 1 process masks
on the lattice and returns that value so that the output routine can calculate the
'effective' v on the lattice. The output routine can take several paths depending on
whether it is called with a positive, zero, or negative argument (corresponding to
the middle, end, and beginning of the code); each path outputs only those variables
necessary for the section of the code in which it is called. If called in the time step
loop it will send to plot files data for the plots of g, temperature, p, and E versus
time. It also, unless called at the end of the code, calculates the required v for
equilibration based on the present values of p and c, and returns that value in the
variable 'xnew' for use by the mask initialization routine.
Counting Module: This contains three subroutines: 'count', 'wallcount', and
'countbits'. The first is the 'main' counting subroutine, which calls the other two;
its job is, given the total lattice state, to count the number of particles of each type
on the lattice and return them in the array 'inumber', indexed by j (from 0 to 2).
The wallcount routine simply counts the particles at the walls (or edge words) of
the lattice, since those words are referenced somewhat differently from the interior
words. The countbits routine, given an input word of memory, will return in the
variable 'icount' the number of bits in that word which are 1.
B
The Index Function
The simple forms for the creation and annihilation sums Cji and Aji in the generalized CA update rule developed in section 3 is made possible in large part by
the introduction of the 'index function' 44,,, as a method of selecting the proper
permutations of particle species indices j, i and truth function indices p, i'. The
purpose of this appendix is to explicitly derive the form of .•ji, for the 012 CA,
as an example of how the process might be done in general. The straightforward
method of determining Y•,,., is simply to systematically examine all permutations
of its indices and pick out those which should return a value of 1. Obviously this
method will become cumbersome for large numbers of processes and particle directions such as will be present in a full hydrodynamic CA; however, we will find as
we go that there are definite symmetries in the truth functions which make the task
considerably easier.
We begin, then, with the p = 1 process, which since it involves multiple particle
types is expected to have the most permitted permutations. For this process we first
observe that the j = 0 particle is defined to have 'direction' i = 0 for convenience in
the formalism; therefore the permutations j = 0,i # 0 are at once disallowed. For
i = 0, however, all of the four truth function indices i' must be included, since all
of them involve the stopped particle (it makes no difference in which direction the
type 1 and 2 particles move, they will produce the same stopped particle since there
is only one at a given site). Therefore, the permutations which give .F i,., = 1 for
p = 1,j = 0 are: i = 0, all i'. For the j = 2 particle, we have an 'opposite' situation:
all i indices may be permitted, but for each i the truth function index i' must be
the same as the particle direction i, so that the permutations which give . ,i, = 1
for p = 1, j = 2 are: all i, and i' = i.
The j = 1 particle introduces a new subtlety. Since two particles of this type are
involved in the p = 1 interaction, we should have two truth function indices i' for
each particle direction i. The question then becomes: which two? Obviously one of
them is i' = i from the truth function
Til, = nl,i,
ni,'+I n2,i io,o;
0
(50)
however, we must be careful not to be misled by (50) into choosing i' = i + 1 for the
second permitted permutation. I have deliberately written i' in (50), instead of i
as was done in developing the formalism of section 3, in order to make it clear that
the truth function index is meant, not the particle index. We must then choose the
permutation so that both 'functions' of i' in the indices for the type 1 particles will
yield i. The choice i' = i is one, but the other is i' +1 = i, which is then reversed to
i' = i - 1, or, since we are adding and subtracting modulo 4, i' = i + 3. The allowed
permutations for p = 1,j = 1 are therefore: all i, and i' = i or i' = i + 3.
The 'self-collision' processes (so called because they only involve one particle
type-they do, however, involve multiple particle 'species', as defined in section 2.2)
are much simpler to deal with, since we can immediately eliminate two out of the
three possible j indices for each p. The two cases are exactly analogous, so we shall
consider the p = 2, j = 1 case and then generalize to both cases. For this case, we
might be tempted at first to say that there should be two truth function indices for
each particle direction which will give 17.,, = 1, by a similar argument to that just
used for the p = 1, j = 1 case; the two permutations would then, by an analogous
procedure, be found to be i' = i and i' = i + 2. However, if we examine the truth
function
T2i = nl1,i' 1,i'+2 1,i'+1 1,i'+3,
(51)
we find that it possesses the symmetry properties
,2
*2
T = T+2 =Tir+
1 =Ti'+
3,
(52)
so that the two functions given by the permutation we found are actually one and
the same. We can therefore not include both in 17.,Y,, because of the necessity of
avoiding 'double counting' of processes; there is really only one process of which
the variable nji is an 'argument' (in the sense defined in section 3.4), but because
of symmetries it has several different truth function expressions. Therefore, we can
only select one permutation of i, i' to give .T, = 1; we choose i' = i for simplicity,
but it should be noted that we could just as well choose i' = i + 2 without affecting
the consistency of the update rule in any way.
The final summary of .•T,%,for the self-collision processes then proceeds as follows: for p = 2, 3, Y!,,y = 1 if: j = p- 1 (made possible by the convenient choice
of indices; this is not a fundamental property), and i' = i (for all i). The complete
structure of 7•,,, is therefore as follows:
1.,i,, = 1 if and only if:
p = land:
j = 0,i = O(all i'),
j = 1,i' = iori' = i + 3,
j = 2, i' = i;
p=2,3and: j=p-l,i'=i.
C
FORTRAN Code List
Main Program
program newca
real*8 pi
pi=3.1415926535898
write(*, 1111)
read(*, *)itmax, itest,jtestO,xfreq
xj=real (jtest0)
xf=pi*xfreq
call input
call init
50
999
1111
2223
2224
call output(-1)
write (6,2223)
isign=•
do 50 istep=1,itmax
iset=0
if(mod(istep,itest) .eq.0)then
iset=l
jtest=nint (xj*sin(xf*real (isign)))
write(*,*)jtest
isign=isign+l
endif
call move(iset,jtest)
call mask
call update
call output (istep)
continue
write(6,2224)
call output(0)
stop 'THANKS FOR THE MEMORIES!'
format(/' INPUT MAX. TIME STEPS, ITEST, JTESTO, XFREQ')
format(///' START EXECUTION.')
format(///' STOP EXECUTION.')
end
Common Blocks:
gram modules.
common
common
common
common
common
common
common
common
common
common
These are all referenced via 'include' statements in the pro-
/calc/ inumber(0:2)
/cint/ n(1:2,0:3,1:32768),nstop(32768),sitemax
/cwalll/ 11(32768),13(32768),15(32768),17(32768)
/cwall2/ 12(32768),14(32768),16(32768),18(32768)
/cwalll/ lleft2(32),lleft3(32),lleft4(32)
/cwallr/ Iright6(32),lright7(32),lright8(32)
/parameters/ jm, im,in,iml,im2
/startup/ xd0,xdi,xd2,xnuO,seed
/storage/ sitenumber,swallnumber
/updt/ pmask(3,32768),pmaski(3,32768),s(1:3,0:2)
Input Module
subroutine input
implicit integer*4 (l-t)
common /master/ nclosure
include 'cint.for'
include 'storage.for'
include 'parameters.for'
include 'startup.for'
open(unit=9,file='thesis.dat',status='unknown')
open(unit=6,file='thesis.out',status='new')
write(*,8990)
read(*,*)seed
read(9,*)imax,jmax
read(9,*)nplot
if(nplot.eq.0)goto 8499
open(unit=10,file='g.dat',status='new')
open(unit=11,file='nu.dat',status='new')
open(unit=12,file='temp.dat',status='new')
open(unit=13,file='dens.dat',status='new')
8499 read(9,*)xdO,xdl,xd2
8500
jm=(jmax-2)/32
im=imax*jm
in=imax/32
iml=im-jm
im2=1+jm
sitemax=iml-jm
sj 1=sitemax-jm
sj 2=im2
sitenumber=sitemax*32
swallnumber=(2*(imax+jmax))-4
write (6,5500)
write(6,5501)imax,jmax
write(6,5551)jm,im,in
write(6,5553)xd0,xd1,xd2
c
dinum=real(sitenumber)
dfactor=real(imax*jmax)/dinum
dwfactor=real(swallnumber-4)/dinum
xdO=xdO*dfactor
xdl=xd* (1.0+(dwfactor/4.0))
xd2=xd2*(1.0+(dwfactor/2.0)+(1. 0/dinum))
5500
5501
5551
5553
return
format(/' OUTPUT FILE FOR CA PROGRAM')
format(///i5,' by ',i5,' total array sites.')
format(/i5,' words per row,',i5,' words, and',i5,' side words.')
format(/' Input occupation numbers: ',4f6.3)
8990
format(/' INPUT RANDOM NUMBER SEED')
end
Initialization Module
subroutine init
implicit integer*4 (l-t)
include 'updt.for'
include 'cint.for'
include 'startup.for'
do 10 k=1,sitemax
13
11
15
10
do 10 kk=0,31
ycheck=ran(seed)
if(ycheck.gt.xd0)goto 13
nstop (k)=ibset (nstop (k) ,kk)
do 15 i=0,3
ycheck=ran(seed)
if(ycheck.gt.xdl)goto 11
n(1,i,k)=ibset (n(1,i,k) ,kk)
ycheck=ran(seed)
if(ycheck.gt.xd2)goto 15
n(2,i,k)=ibset(n(2,i,k),kk)
continue
continue
c
do 25 p=1,3
do 25 j=0,2
25 s(p,j)=0
s(1, 2)=not(s(1, 2))
s(1,0)=not(s(1,0))
do 26 p=1,3
do 26 j=0,2
do 26 i=0,3
il=mod(i+3,4)
do 26 ii=0,3
findex(p,j,i,ii)=0
if(p.eq. )then
if((j.ne.0).and.(i.eq.ii))findex(p,j,i,ii)=
+
not(findex(p,j,i,ii))
if((j.eq.1).and.(ii.eq.il))findex(p,j,i,ii)=
+
not(findex(p,j,i,ii))
endif
if(p.eq.2)then
if((j.eq.1).and.(i.eq.ii))findex(p,j,i,ii)=
+
not(findex(p,j ,i,ii))
endif
if(p.eq.3)then
if((j.eq.2).and.(i.eq.ii))findex(p,j,i,ii)=
not (findex(p,j,i,ii))
26
27
endif
continue
do 27 ii=0,3
findex(1,0,0, ii)=not(findex(1,0,0,ii))
continue
C
psset=0
29
psset=not (psset)
do 29 k=l,sitemax
pmask (, k)=psset
pmask (3,k)=psset
pmaski(3,k)=psset
pmask(2,k)=psset
pmaski (2,k)=psset
continue
xnuO=0 .01
return
end
C
35
30
39
subroutine mask
implicit integer*4 (l-t)
include 'updt.for'
include 'cint.for'
include 'startup.for'
include 'storage.for'
if(xnew.eq.xnu0)goto 39
xnu0=xnew
do 30 k=1,sitemax
pdset=0
do 35 ibit=0,31
ycheck=ran(seed)
if (ycheck.gt. xnu0) goto 35
pdset=ibset (pdset, ibit)
continue
pmaski (i, k)=pdset
continue
return
end
Move Module
subroutine move(iset,jtest)
implicit integer*4 (l-t)
logical*4 bitvalue
dimension lni(32768),1n2(32768),1n3(32768),1n4(32768)
dimension 1n5(32768),1n6(32768),1n7(32768),1n8(32768)
dimension lleft6(32),11eft7(32),lleft8(32)
include 'cint.for'
include 'parameters.for'
include 'cwall.for'
do 800 i=im2,imi
k=i-jm
l1(i)=n(1,0,k)
12(i)=n(2,0,k)
13(i)=n(1, 1,k)
14(i)=n(2, 1,k)
15(i)=n(1,2,k)
16(i)=n(2,2,k)
17(i)=n(i,3,k)
18(i)=n(2,3,k)
800
700
710
continue
do 700 i=1,iml
shift=i+jm
In6(i)=ishftc(16(shift),-1,32)
In5(i)=15(shift)
In4(i)=ishftc(14(shift),1,32)
continue
do 710 i=im2,imi
In3(i)=ishftc(13(i),1,32)
In7(i)=ishftc(17(i),-1,32)
continue
do 720 i=im2,im
shift=i-jm
In2(i)=ishftc(12(shift),1,32)
720
725
726
In (i)=lI (shift)
In8(i)=ishftc(18(shift) ,-1,32)
continue
do 725 i=l,in
lleft2(i)=ishftc(lleft2(i), 1,32)
lleft4(i)=ishftc(lleft4(i),-1,32)
Iright6(i)=ishftc(lright6(i),-1,32)
Iright8(i)=ishftc(lright8(i),1,32)
continue
do 726 i=l,in-1
shift=i+1
call mvbits(lleft4(shift),31,1,lleft4(i),31)
lleft4(shift)=ibclr(lleft4(shift),31)
call mvbits(lright6(shift),31,1,lright6(i),31)
Iright6(shift)=ibclr(lright6(shift),31)
ip=in-i
ipl=ip+1
call mvbits(lleft2(ip),0,1,lleft2(ipl) ,0)
lleft2(ip)=ibclr(lleft2(ip),0)
call mvbits(lright8(ip),0,1,lright8(ipl),0)
Iright8(ip)=ibclr(lright8(ip),0)
continue
do 730 i=1,in
kk=(i-1)*32
do 730 j=1,32
k=kk+j
ikjm=k*jm
iki=ikjm-jm+l
jd=j-1
731
730
if(k.eq.imax)goto 731
call mvbits(ln4(ikjm),0,1,lright4(i),jd)
call mvbits(In6(ikl),31,1,lleft6(i),jd)
if(k.eq.1)goto 730
call mvbits(in3(ikjm),0,1,lright3(i),jd)
call mvbits(In7(ikl),31,1,lleft7(i),jd)
call mvbits(in2(ikjm),0,1,lright2(i),jd)
call mvbits(1n8(iki),31,1,lleft8(i),jd)
continue
745
740
do 740 i=im2,iml
il=im-i
ill=ii+1
id=i-1
if(mod(i,jm) .eq.0)goto 745
call mvbits(1n4(il),0,1,ln4(ill),0)
call mvbits(in3(il),0,1,ln3(i1I),0)
call mvbits(in2(ii),0,1,ln2(i11),0)
if(mod(i,jm) .eq.1)goto 740
call mvbits(In8(i),31,1,ln8(id),31)
call mvbits(In7(i),31,1,ln7(id),31)
call mvbits(In6(i),31,,1ln6(id),31)
continue
do 750 i=l,jm-1
itop=iml+i
jtop=im-i
jbot=jm-i
il=i+l
itopi=itop+l
jtopi=jtop+l
750
jbotl=jbot+l
call mvbits(1n4(jbot),0,1,1n4(jbotl),0)
call mvbits(ln2(jtop),0,1,1n2(jtopl),0)
call mvbits(ln6(ii),31,1,ln6(i),31)
call mvbits(ln8(itopl),31,1,ln8(itop),31)
continue
do 760 i=l,in
kk=(i-1)*32
do 760 j=1,32
k=kk+j
ikjm=k*jm
ikl=ikjm-jm+1
jd=j-1
if(k.eq.1)goto 761
call mvbits(lleft2(i),jd,1,1n2(ikl),0)
call mvbits(lright8(i),jd,1,1n8(ikjm),31)
if(k. eq. imax)goto 760
call mvbits(lleft3(i),jd,l,ln3(ikl),0)
761
call mvbits(lright7(i),jd,1,ln7(ikjm),31)
call mvbits(lleft4(i),jd, 1,n4(ikl) ,0)
760
call mvbits(lright6(i),jd,1,ln6(ikjm),31)
continue
c
do 300 i=1,in
lleft2 (i)=lleft6 (i)
lleft6 (i)=0
lleft3(i)=lleft7(i)
lleft7 (i)=O
lleft4(i)=lleft8 (i)
lleft8 (i)=0
Iright8 (i)=lright4 (i)
Iright4(i) =0
Iright7 (i) =lright3 (i)
lright3 (i) =0
Iright6 (i) =lright2 (i)
300
350
Iright2 (i) =0
continue
do 350 i=1,jm
itop=iml+i
In8 (i) =n4(i)
In4(i)=0
Inl (i) =In5 (i)
In5(i)=0
In2 (i)=1n6 (i)
In6(i)=0
In4 (itop) =1n8 (itop)
In8 (itop)=0
In5 (itop) =nl (itop)
Inl(itop)=0
In6 (itop) =1n2 (itop)
In2 (itop)=0
continue
do 765 i=l,im
11 (i) =Inl (i)
12 (i) =1n2 (i)
13 (i) =1n3 (i)
14 (i) =n4 (i)
15 (i) =n5 (i)
16(i)=1n6(i)
17(i)=ln7(i)
765
770
18(i)=ln8(i)
continue
do 770 i=im2,iml
k=i-jm
n(2,0,k)=12(i)
n(2,0,k)=12(i)
n (1, 1, k) =13 (i)
n (2, 1, k)=14 (i)
n(1,2,k)=15(i)
n(2,2,k)=16 (i)
n(1,3,k)=17(i)
n(2,3,k)=18(i)
continue
c
if(iset.eq.0)goto 799
C
if (jtest.le.0)goto 395
c
do 389 k=1,sitemax
j sub0=O
jsubl=O0
j sub2=0
381
do 388 ibit=0,31
if(jsubO.gt.jtest)goto 381
bitvalue=btest (nstop (k) , ibit)
if (.not.bit value) then
nstop (k)=ibset (nstop(k), ibit)
j sub0=j sub0+1
endif
do 386 i=0,3
if(jsubl.gt.jtest)goto 382
bitvalue=btest (n(i, i,k), ibit)
if (.not. bitvalue) then
382
386
388
389
n(l,i,k)=ibset(n(l,i,k),ibit)
jsubl=jsubl+l
endif
if(jsub2.gt.jtest)goto 386
bitvalue=btest(n(2,i,k),ibit)
if(.not.bitvalue)then
n(2,i,k)=ibset(n(2,i,k),ibit)
j sub2=j sub2+1
endif
continue
continue
continue
c
395
if(jtest.ge.0)goto 799
jtest=abs (jtest)
c
do 399 k=l,sitemax
jsub0=0
jsub =0
jsub2=0
391
392
do 398 ibit=0,31
if(jsubO.gt.jtest)goto 391
bitvalue=btest(nstop(k),ibit)
if(bitvalue)then
nstop(k)=ibclr(nstop(k),ibit)
jsub0=jsub0+1
endif
do 396 i=0,3
if(jsubl.gt.jtest)goto 392
bitvalue=btest(n(1,i,k),ibit)
if (bitvalue) then
n(1,i,k)=ibclr(n(1,i,k),ibit)
jsubi=jsubi+1
endif
if(jsub2.gt.jtest)goto 396
bitvalue=btest(n(2,i,k),ibit)
if (bitvalue)then
n(2,i,k)=ibclr(n(2,i,k),ibit)
jsub2=jsub2+1
endif
continue
continue
continue
396
398
399
C
799
return
end
Update Module
subroutine update
implicit integer*4 (l-t)
integer*4 findi
include 'updt.for'
include 'cint.for'
dimension t(1:3,0:3),ti(1:3,0:3),matrix(1:3,0:3)
do 100 k=1,sitemax
c
+
+
190
do 190 i=0,3
il--mod(i+1,4)
t(l,i)=iand(n(l,i,k),iand(n(l,il,k),
not(ior(n(2,i,k),nstop(k)))))
ti(1,i)=iand(n(2,i,k),iand(nstop(k),
not(ior(n(1,i,k),n(1,ii,k)))))
continue
do 191 p=2 ,3
jp=p-i
+
+
195
t(p,0)=iand(n(jp,0,k),iand(n(jp,2,k),
not(ior(n(jp,1 ,k),n(jp,3,k)))))
ti(p,0)=iand(n(jp,1,k),iand(n(jp,3,k),
not(ior(n(jp,O,k),n(jp,2,k)))))
do 195 i=1,3
t (p,i)=ti(p,i-1)
ti(p,i)=t (p,i-1)
continue
191
continue
C
do 150 p=1,3
do 150 i=0,3
melement=0
do 155 pp=1,3
if (pp.eq.p)goto 155
if((p.gt.1).and.(pp.gt.1))goto 155
p i=pmask (pp, k)
pi i=pmaski (pp,k)
do 155 ii=0,3
t =t (pp,ii)
tii=ti(pp,ii)
melement=ior(melement,ior(iand(pi, t ),
+
155
iand(pil,til)))
continue
ppl=pmask(p,k)
ppii=pmaski (p, k)
do 157 ii=0,3
if(ii.eq.i)goto 157
ti=t(p,ii)
tii=ti(p,
+
157
150
ii)
melement=ior(melement, ior(iand(ppl,tl),
iand(ppil,til)))
continue
matrix (p, i)=not (melement)
continue
c
do 103 ji=0,2
do 103 i=0,3
psum=O
msum=0
do 104 p=1,3
sl=s(p,j)
sbarl=not (si)
p l=pmask (p, k)
pil=pmaski (p, k)
do 104 ii=0,3
mpi=matrix (p, ii)
tli=t(pii)
+
tili=ti(p, ii)
termi=iand(pl,iand(mpi,tli))
term2=iand(pi, iand(mpi,tili))
findl=findex(p,j,i,ii)
psum=ior(psum,iand(findi,ior(iand(sl,terml),
iand(sbari,term2))))
msum=ior(msum,iand(findl, ior(iand(sbarl,terml),
+
104
103
iand(sl,term2))))
continue
if(j.eq.0)then
nstop(k)=ior(iand(nstop(k),not(msum)),psum)
goto 103
endif
n(j,i,k)=ior(iand(n(j,i,k),not(msum)) ,psum)
continue
c
100
continue
200
return
end
C
Output Module
subroutine output(icode)
implicit integer*4 (l-t)
dimension f(0:2),fhat(0:2)
include 'storage.for'
include 'calc.for'
include 'startup.for'
common /maskc/ kmasknum
call count(icode)
mass=inumber(0)+inumber (1)+inumber(2)
menergy=inumber(1)+(2*inumber(2))
xmass=real (mass)
xenergy=real(menergy)
sites=sitenumber+swallnumber
xsnum=real(sitenumber)
xsites=real(sites)
density=xmass/xsites
epsilon=xenergy/(4. O0*xsites)
do 4000 j=0,2
xstates=real(j*swallnumber+4*sitenumber-4)
xnumber=real(inumber(j))
if(j.eq.O)f(j)=xnumber/xsites
if(j.ne.O)f(j)=xnumber/xstates
fl=1.-f(j)
fhat(j)=f(j)/fl
4000
continue
c
if(icode.eq.0)goto 1909
C
gnum=f(2)*(f(0)+(4.0*f(1))+(4. O*f (2)))
gden=(f(1)+(2.0*f(2)))
gee=gnum/(gden*gden)
C
are= (4.0*xmass/xenergy)-2.0
entwo= (xenergy*xenergy)/ (16. O*xmass*xsites)
if(are*entwo .eq. 1)then
xnew=0. 99998
goto 1905
endif
+
1905
xnew=1.O-((entwo*(1.O-are)*(1.0-are))/
((1.0-(are*entwo))**2.0))
if(icode.lt.0)goto 1909
c
call maskcount
xnu=real (kmasknum)/xsnum
if(xnu.le.0)xnu=0.00001
beta12=log(fhat(1)/fhat(2))
xtempl2=1./beta12
beta=log(xnu*(fhat(0)/fhat(1)))
xtemp=l./beta
c
if(icode.gt.0)goto 1910
c
write(6,1998)
write(6,1991)mass,menergy
write (6,4901)sites
write(6,4902)f (0),f(1),f(2)
goto 1999
1910 write(6,1993)icode,gee,xnu0,xnu,xtemp2,
,
+
density,epsilon
if(nplot. eq.0)goto 1999
write(10,1994)icode,gee,gr2
write(11,1994)icode,xnu,xnu0
write(12,1994)icode,xtempl2,xtemp
write(13,1994)icode,density,epsilon
1999 return
1991 format(/' Total mass: ',i7,' -- Total energy: ',i7)
1992 format(/' g, T(12,0nu), tmask: ',4f11.8)
1993 format(' Step: ',i3,lx,f9.5,1x,2f9.5,1x,
+
2f9.5,lx,2f9.5)
1994 format(i4,2f20.12)
1998 format(//,' System properties:')
4901 format(/' Number of array sites: ',i10)
4902 format(/' Occupation numbers (0,1,2): ',3f11.8)
end
1909
c
5001
subroutine maskcount
implicit integer*4 (l-t)
include 'updt.for'
include 'cint.for'
common /maskc/ kmasknum,knumber
common /countup/ icount
kmasknum=0
do 5001 k=1,sitemax
call countbits(pmaski(1,k))
kmasknum=kmasknum+icount
continue
return
end
Counting Module
1050
subroutine count(icode)
implicit integer*4 (l-t)
dimension itotal(1:3,0:3)
common /cwallc/ iwall(1:2)
include 'cint.for'
include 'calc.for'
common /countup/ icount
inumber0=0
do 1050 k=i,sitemax
call countbits(nstop(k))
inumber0=inumber0+icount
continue
inumber(0)=inumberO
do 1000 j=1,2
inumberl=0
do 1010 i=0,3
itotall=0
do 1020 k=1,sitemax
1020
1010
call countbits(n(j,i,k))
itotall=itotall+icount
continue
itotal(j,i)=itotall
inumberl=inumberl+itotall
continue
inumber(j)=inumberl
1000
continue
call wallcount
do 1500 j=1,2
inumber(j)=inumber(j)+iwall(j)
1500
continue
if(icode.ne.0)goto 1099
write(6,1599)inumber(0) ,inumber(1) ,inumber(2)
1099
1599
return
format(/' Particle counts: ',3i6)
end
c
c
c
4000
subroutine wallcount
implicit integer*4(1-t)
common /cwallc/ iwall(1:2)
common /countup/icount
include parameters.for
include cwall.for
common /parameters/ jm,im,in,iml,im2
common /cwalll/ 11(32768),13(32768),15(32768),17(32768)
common /cwall2/ 12(32768),14(32768),16(32768),18(32768)
common /cwalll/ lleft2(32),lleft3(32),lleft4(32)
common /cwallr/ Iright6(32),lright7(32) ,lright8(32)
iwalli=0
iwall2=0
do 4000 i = l , jm
itop=iml+i
call countbits(ll(i))
iwall =iwall +icount
call countbits(18(i))
iwall2=iwall2+icount
call countbits(12(i))
iwall2=iwall2+icount
call countbits(15(itop))
iwalll=iwalli+icount
call countbits(14(itop))
iwall2=iwall2+icount
call countbits(16(itop))
iwall2=iwall2+icount
continue
do 4010 i=l,in
call countbits(lleft3(i))
iwalll=iwalll+icount
call countbits(lleft2(i))
iwall2=iwall2+icount
call countbits(lleft4(i))
4010
iwall2=iwall2+icount
call countbits(lright7(i))
iwalll=iwalll+icount
call countbits (lright6 (i))
iwall2=iwall2+icount
call countbits(lright8(i) )
iwall2=iwall2+icount
continue
iwall (1)=iwalll
iwall (2)=iwall2
return
end
c
subroutine countbits (narg)
implicit integer*4 (l-t)
common /countup/ icount
2010
2000
nargl=narg
icount=0
nset=1
do 2000 jjj=1,32
ntest=iand(nargl,nset)
if(ntest.eq.0)goto 2010
icount=icount+l
nargi=ishft (nargl,-1)
continue
return
end
Download