Based on Intuitive Physics

Jeffrey Ventrella

1997

Download a free Windows simulation now! (it's small - 167 kb)

NOTE - in this simulation, you can stir the fluid around in real time.

If you have a fast PC, it's really smooth

Another thing which is familiar to most of us is the visual symbol known as the arrow. The arrow is used both as an annotation device and as a symbol of motion. In either case it implies direction (of attention and energy respectively). The arrow is often used in scientific data visualizations of computer simulations of fluids to depict velocity and angle of flow in a field. These visualizations often show a vast array of arrows of differing lengths and angles. I was inspired originally by images of this sort, and had begun to imagine a large population of arrows constantly changing lengths and angles, and relaying information to and from each other. This is the visual output of many fluid dynamics simulations. But for me it served as an input to my thinking about the logic behind the dynamics.

In my mind there was also something beautiful and universal about the high-resolution color animations of turbulence produced in such centers as the National Center for Supercomputer Applications, in Champagne, Illinois, and at Los Alamos, New Mexico. Though I had virtually no understanding of the mathematics behind these beautiful scientific animations, I did have a sense that something essential and maybe even simple was behind the natural phenomena being studied, and that effects such as vortices and pressure waves could emerge from simple rules that can be implemented without the use of large equations.

Since I think more often on a geometric level than on a numerical level, I found the arrow as a useful tool to think with, as I set out to generate theories and construct a model. In a way, I have viewed the many little arrows as agents, which "give" and "take" information among themselves on a local level, resulting in the effect of fluid flow on a global level. So, equipped with my arrow agent, as a tool to think with, I set out to try my own fluid dynamics model.

This paper is written by a person initially trained in visual art, communication design, animation, and art education, and then later, software programming. The thinking styles based in my training in the arts have always informed my programming. Thus, the Navier-Stokes equation, and such mathematical descriptions of fluid flow have not been used in the building of my model. I am more interested in a naive, constructionist approach to modeling a natural phenomenon. That one can use a naive physics to build theories and procedures which result in beautiful and realistic animations is as interesting to me as building scientifically valid simulations.

And so I would like to share with you some of the fruits of my explorations. These exist in four forms: 1) as a computer program, 2) as set of computer animations on videotape, 3) as a downloadable, realtime interactive animation, and 4) as documentation, which you are reading. No mathematics is used in this paper to describe my model, and this is consistent with the way in which I built the model, with many diagrams of arrows, and many long moments at puddles in the road.

In this model, the computational domain is a two-dimensional grid of cells. It is a cellular automaton - in the running of the animation, the entire grid of cells is updated in discrete time steps. At each time step, information from each cell is propagated to the neighboring cells surrounding it.

As the grid of cells is scanned, cell by cell, each cell takes turns spreading information out to its neighbor cells. This propagation of information from cell to cell across the grid over many time steps gives rise to effects such as fluid flow and pressure waves. The manner in which the information is exchanged from cell to cell is determined by a set of rules which I designed according to a general understanding of how fluids behave. These rules comprise the physics of the simulation.

On the microscopic level of the cell and its neighborhood, this cell-wise transfer of information may seem unrealistic, in terms of the way real fluids behave. But as one brings the view back to see the effect over a patch of many cells, the discrete nature of these interactions blurs and the result is more continuous flow. Consequently, the more cells I use in the model, and the smaller the cells, the more realistic the animation.

Potential energy consists of a pressure differential (energy that will be released as radial motion) and is expressed as a pressure value which can be either positive or negative. In this paper, pressure is represented graphically as a dot. The size of the dot shows the amount of pressure. If pressure is positive it is shown as white, if negative, it is shown as black.

These two forms of energy, which I call flow and pressure, comprise the main elements of the fluid dynamics model, and they are constantly exchanged throughout the simulation. From one time step to the next, the flow energy of a cell can be partially or fully converted into pressure, as it is passed to its neighbors, depending on the conditions within those neighbors, and its relation to them. Imagine a tide of water gushing onto a vertical wall, like the edge of a dock: the motion energy of the water as it flows toward the wall is partially converted to pressure energy at the region where it hits the wall.

Pressure can also be converted into flow from one time step to the next. Imagine, for example, an underwater explosion. The pressure from the explosion propels water in all directions away from the explosion: pressure is converted into flow as a sphere of outward-radiating motion (in the immediate vicinity around the center of the explosion.)

The conversion between the two forms of energy often oscillates. For instance, where regions of opposing flow are coming against each other, a high pressure region results. This pressure region then causes a backlash of flow away from itself, as illustrated:

In any physics model such as this, all these conversions from one form of energy to another should be precise, and no energy should be lost or gained in the process - only shuffled around within the system. If any energy is lost in the process, the accumulation of these losses over a number of time steps, can have exaggerated effects, and the energy will quickly drain. Likewise, any slight addition of energy due to imprecise computations can cause an exponential increase of energy over a short period of time.

The idea of conservation of energy was important to keep in mind in the design of the model. This principle was, in fact, not too difficult to manifest in terms of computation. What was difficult, on the other hand, was designing the nature in which energy is converted from one form to the next, and devising the rules which determine these conversions. It is easy to say: "all the energy of every cell is to be divided up and distributed to its eight neighbors at every time step", but it is not easy to say which neighbor cells get the most energy, and in what form it should be given. The rules which I describe below are my solution to this problem.

1 The Flow Offspring Rule

2 The Pressure Offspring Rule

3 The Vector Conflict Rule

4 The Offspring Merge Rule

According to the vector-offspring rule, each vector (as parent) is subdivided into eight smaller vectors (as offspring) and distributed among the neighbor cells in varying amounts. The relative amounts of energy in the offspring vectors are determined by the relation of the parent's direction to the positions of the neighbor cells. For instance, if the parent vector is pointed upward, its offspring will be stronger in the cells above and below the parent cell, corresponding to this pushing and pulling effect. The offspring diagonal to the parent cell will receive a smaller amount of energy, and the offspring to the left and right will receive none, as shown in this illustration.

Stated in slightly more precise terms, if the parent vector's velocity equals exactly 1, and its direction is exactly 90 degrees (upward in this coordinate system), the offspring above and below will receive exactly one fourth the parent's energy (0.25), and the diagonal offspring will receive exactly one eighth (0.125). These add up to equal 1 - the velocity of the original parent vector.

If the parent vector is pointing in the direction of the upper right cell (45 degrees), that cell's offspring will receive one fourth of the parent's energy (0.25), as well as the lower left cell; the cells above, below, to the left, and to the right will receive one eighth (0.125); and the two remaining cells will receive none, as illustrated:

All offspring vectors receive energy according to their perpendicularity to the parent, no matter what the direction the parent vector is heading. For instance, in the following diagram, the parent vector (of value 1) is pointing in the direction exactly between the lower-right and bottom cells (62.5 degrees). Thus, the top-left, top, bottom-right, and bottom offspring receive 0.1875, while the rest receive 0.0625, corresponding to the perpendicularity of the offspring cell's relation to the parent's axis. Again, these values add up to 1, the original parent's value.

In every case, the sum of the lengths of the offspring vectors always equals the length of the parent vector, meaning that no energy is lost or gained in the process, only distributed in uneven amounts to the neighborhood. The mapping of perpendicularity to offspring amount is linear. I have experimented with other mappings, such as taking the cosine of the perpendicularity - which results in a slightly different distribution of offspring amounts. Different mappings cause different degrees to which fluid alongside a parent vector's axis is dragged along with the flow. I don't have an intuition as to what this may correspond to in the world of real fluids (perhaps viscosity?), or whether it has any correspondence at all. I hope to discover this some day, or perhaps the answer is not discoverable, but must be explained to me, in a way that would require me to re-work the push-pull theory behind this rule.

Unlike the flow offspring rule, in this case every neighbor cell receives the same amount of energy from the parent cell.

-or they may all lie in the same direction and have the same length:

In both of these cases, all the vectors in the region are in agreement with each other. They are at an equilibrium, as in a stagnant pond or the middle of a large evenly-flowing river. If there is a difference-gradient among vector angles and magnitudes, as shown in these three examples...

...the flow will be interrupted to some degree - energy passed between the cells these vectors occupy will be partially converted to pressure values. For instance, in the case of figure (a) above, the border between the two differing regions of flow will experience a pull from the bordering vectors on the right. Thus, in the next time step, offspring vectors lying at this border will be partially converted to negative pressure values - a negative pressure front will appear at this region. In the case of figure (b), the border between the two incoming regions will experience a high pressure front - the energy from these clashing vectors will be partially converted into positive pressure values. In the case of figure (c), offspring vectors would be converted into a slight mixture of both negative and positive pressure values, with a bit of positive pressure appearing at the top, due to compression, and some negative pressure at the right, due to expansion.

The vector conflict rule determines the degree in which the offspring vectors are converted - wholly, or partially - into pressure, at the next time step. This is done by considering the states of the other vectors in the neighborhood and determining the degree of conflict in each, before the offspring vectors are created. If the vectors in all the neighbor cells are identical to the parent cell, for instance, it will have no conflict and will give birth to healthy flow offspring in the next time step. If there is a conflict, meaning that some vectors are aimed in different directions or that the rate of flow is different, then the offspring will be born with some of their flow energy converted to pressure energy.

In the following illustration, the parent encounters conflict with one of its neighbor vectors, and so one of its offspring vectors is converted from flow energy to pressure energy.

In the case of the top example, conflict in the upper-right cell causes the associated offspring vector to be converted into positive pressure. In the bottom example, conflict in the cell below causes the associated offspring to be converted into negative pressure. Since the parent vector is pushing fluid ahead of itself or pulling fluid from behind, if the neighbor cell is moving fluid in the same direction and at the same rate as the parent vector, the fluid is pushed or pulled along without any resistance, but if there is a difference in flow among the cells, the fluid being pushed or pulled by the parent vector cannot move along evenly, so this resistance shows up as positive or negative pressure values.

The following diagrams illustrate how the vector conflict rule is used to determine the amount of conflict in neighboring cells. In this illustration, the vectors in the white boxes represent a parent vector with an upright direction. The vector in the darker box poses a potential conflict for the offspring vector about to be born. In general, the more similarity among the two vectors, the less the conflict.

Adding vectors and pressures is not as easy as just adding up numbers, like 4.5 and -56.0, as I soon found out while designing this model. In special cases, it is a simple matter: if the two vectors being added have identical directions, as shown:

-then the resulting vector should have the same direction and be twice as long. But, if you add the following two vectors together:

A logical solution is to have them cancel each other out. But to do this would imply that the energy is lost, and this would not fit with the law of conservation of energy. The energy has to go somewhere - so in this model it is converted into pressure, as in the case of the Flow Offspring Rule, when neighboring flows conflict.

These two vectors add up to form a combination of both flow and pressure:

Adding pressures is done in a similar way. For instance, adding a pressure value of -0.8 to a pressure value of 0.8 will result in a value of 0.0, with some leftover energy equaling 0.16. This remaining energy is added to the velocity of the flow vector.

After all the neighbors have contributed all their energy, and leftover energy is shuffled between flow and pressure, there remains in the end a vector with a direction and a velocity, and a pressure value, which can be either negative or positive. The purpose of all these conversions is to conserve energy - and in a realistic way. The remaining flow and pressure values contain all the energy which has been gathered from the neighbors, and the direction of the vector inherits some average of the directions of neighboring cells whose vectors have contributed the most energy. The amount of pressure energy corresponds to the degree in which accumulated vectors clash.

The following diagram illustrates how the floating bits layer is overlaid onto the fluid dynamics layer.

The illustration below demonstrates a typical frame from an animation showing the patterns which emerge among the bits, moved around by the fluid dynamics.

One common technique used in cellular automata to get around the problem of boundary effects is to let the left and right boundaries, and bottom and top boundaries "wrap-around". This way, information "falling off the edge" of the domain can reappear on the opposite edge, like a ship sailing around the world (a torus-shaped world, that is). As far as the ship is concerned, there are no interruptions in its voyage.

I decided not to do this. I decided that the way to deal with the boundary effect is to treat the boundary exactly like a boundary, as if the fluid were existing within a rectangular tub. In a college painting class, I learned how to treat the edges of the canvas an aspect of the painting itself - as something which can lend integrity to the composition. Likewise, I wanted my work of fluid art to express the cellular array that it occupies, complete with its boundaries. Besides, it is at the sides and corners of my virtual aquarium that the most interesting patterns emerge, such as swirling eddies, and lapping waves - things with tend to bring out the characteristics of my fluid.

The technique for simulating the walls of my virtual tub of water is analogous to folding the edge of a piece of paper back onto itself. This causes the propagation of energy to neighbor cells at the edge of the grid to reflect back onto the original cells, as indicated by this diagram:

Since all edges are folded like this, the four corner cells are thus reflected doubly:

With this technique, vectors which are pushing against the edge of the walls encounter some opposing vectors, in the form of their own offspring. The result is a buildup of pressure, as would result in a natural boundary where fluid is flowing toward the edge. Likewise, vectors pulling from the edge will encounter opposing vectors, in the form of their own offspring, which pull back, causing negative pressure. Vectors near the edge which are flowing parallel to the walls are not as affected by the walls, since their offspring are strongest in front and in back, not so much at their sides.

It works like this: the swisher swoops around according to some motion function, such as a set of sine waves. The dipping in and out of the water (appearing and disappearing) is calculated in a similar way. I scan the grid, and identify which cells are in the same location as the swisher at each time step. The cells which the swisher is covering are given vectors of flow which correspond exactly to the speed and direction of the swisher's motion. No pressure values are given to the cells. As the swisher moves, it propagates flow. Also, high pressure builds up immediately in front of it, and it leaves a trail of low pressure behind, and fluid rushes in to fill the low pressure trail. When the swisher disappears, the fluid still moves on its own, and eventually comes to rest. At times, the moving fluid pushes against the walls, causing eddies and pressure effects at the boundary. Sometimes the swisher comes back and creates a flow that interrupts with a flow that it had previously caused - this generates interesting turbulent effects as the conflicting flows clash. The swisher is fun!

I hope this paper helps you to share with me an appreciation for the beauty and complexity of flowing water.

I run the program at varying resolutions depending on what aspect I am working on, and whether I am testing something in the model or rendering a complete animation. The higher the resolution, the longer it takes, but the more realistic the effect. A single frame of animation can take minutes at high resolutions. When I record each frame onto videotape, I can later play the videotape to see my animations at 30 frames per second.

The program was originally developed in the Advanced Graphics Research Lab of Syracuse University, and later re-worked at Cinergi Inc. in Lenox, MA. It was later developed further at the Media Lab at MIT, and I have been developing it recently.