Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Speedy fluid mechanics  (Read 2400 times)

keda

  • Bay Watcher
    • View Profile
Speedy fluid mechanics
« on: June 22, 2010, 07:29:11 pm »

Posting in the sand physics thread gave me an idea about how fluid mechanics could be sped up to reduce cpu load, for even large fluid masses to next to nothing. This idea would also support having multiple fluids per tile.

A fluid level is a z-position in a tile of fluid(s) ranging from 1-7. Any fluid connected with the same fluid on the same level compose a fluid layer. A fluid layer has an external border and any number of internal borders (holes), consisting of the tiles that do not have fluid on all 8 adjacent tiles on the same z-level. A sub border is a border that lies in a layer directly beneath to which there is a path consisting of fluid with no same fluid in an upper layer. Each external border has one sub-border in the layer below, while each internal border can have any number of sub-borders below. All fluids move from a border to one of its sub borders. Air has borders as well, but only in relation to fluid bodies.

Fluid displacement will work as follows:
Horizontal displacement:
For each body of fluid,
   For each layer border x
      sum the lengths of adjacent borders of any displacable material (or keep this number for each layer border) including air, to each sub border.
      If greater than the length of border x, all tiles displace 1/7 to the adjacent borders, spaced out evenly using something like Bresenham's line algorithm (may require some tweaking to handle irregular border problem, such as exclusion of already displaced border tiles until all have been displaced)
      otherwise, displace only the number of tiles that fit into the borders using same algorithm to pick out which to move.
      Update the borders.
Vertical displacement: If fluid is displaced, fluid of another type in the same tile drops, and creates a gap for potential fluid in the next z-level to drop into. this coordinate is put on an event vector. This also happens if fluid is displaced to a tile which has displaceable material below it.
The event vector is processed, by swapping fluids, which counts as displacement, thus allows bubbles to float up to its proper place after which they are removed from the event vector.

A note about displacability. If two fluids of different kind meet, one has the potential to displace the other if it does not react with it and has higher density, and there is space to displace it to, which is pushing it up, creating a new layer. This might need some resistance so that not all fluids of this kind are immediately displacable, but are sometimes not displacable.
Fluids can also destroy another fluid e.g. magma destroys sand, in which the above complication is not needed.
Fluid can also react with another to create either a third type of fluid or a solid natural rock of some kind.
If two fluids meet of the same kind, they will merge into one single body, and the external border of one will merge with the external or an internal border of the other.
Evaporation can cause bodies to split, and so perhaps the best way to handle it is not to count 1/7 tiles as fluid bodies, and fluid bodies are removed from memory if they reduce to a 1/7 layer (unless it is sandwiched with another kind of fluid on top) and is then treated as slowly evaporating fluid unless it comes in contact with a fluid that prevents this.
Cave ins, channeling, bridge retraction, hatch opening etc that cause two adjacent z tiles to be exposed to another, creates an event (pushes coordinate on event vector)
Pressurized fluids can move across different layers in the same body, in the same z level in an upper fluid level (U-teleportation) to one of its borders, or create a new layer on top if all borders are surrounded by solids.
There are probably more complications to it, but can't think of any at the moment, the basic (and major) improvement lies in how large masses of fluids move.

keda

  • Bay Watcher
    • View Profile
Re: Speedy fluid mechanics
« Reply #1 on: June 22, 2010, 08:09:57 pm »

After some afterthought it became obvious to me, spreading fluid evenly around the borders is too oversimplified and would sometimes be quite unrealistic. The solution would be to take into account distance, without dispensing with the idea of having borders that does not have to be searched for each time. It would be significantly slower than the even spread method, but it would still be significantly faster than the search method.

NW_Kohaku

  • Bay Watcher
  • [ETHIC:SCIENCE_FOR_FUN: REQUIRED]
    • View Profile
Re: Speedy fluid mechanics
« Reply #2 on: June 24, 2010, 04:59:38 pm »

Hmm... I was actually thinking of something like this myself, after becoming very annoyed at how slowly my magma channels for my magma forges filled up (took a full year to get to just 4/7), and after doing a test-run on .31.01 where I breached an aquifer by just digging stairwells straight down until I hit a cave.

In the magma trench, due to the way that magma is not pressurized, and non-pressurized fluids essentially flow by having to randomly bounce back and forth until eventually the law of averages wins out meant that getting a single layer of magma flowing all the way through the trench required what essentially amounted to a "bubble" of air (actually a lower level of magma that had other tiles of magma flowing into it) to eventually shake back and forth until it hit a crest of magma to cancel out, which would itself need to flow backwards, up the trench, until it could hit the magma vent itself.  Even there, a 6/7 "bubble" would get trapped (and merge with other bubbles) until it could randomly find the hole in the roof, and flow upwards, leaving a 7/7 pool of magma that could then be ready to accept the next "bubble" flowing back out.  That is to say, in a weird way, measuring the flow of magma into the trench was easier to see by the way that "air was flowing out".  Much of the problem was that after only about 5 tiles in, you would hit the spot where the magma would be on average 6/7, then another 5-10 tiles in, you hit the 5/7 range.  Because I had a relatively long trench, it was an extremely long wait for 4/7 and a few 5/7 tiles to start appearing.

On the other hand, the aquifer caused an entirely different kind of problem: The water that fell essentially created a waterfall, but because the water could either flow into a natural underground lake, or could flow off the edge of the map, it created very, very unrealistic water dispersion patterns. 

Basically, it managed to amount to a standing, continuous "hill of water", where it would be as deep as 5/7 or more near the stairwell I dug, but near the edges of the map (the edge was around 40 tiles away), there were parts that were almost continuously dry.  The water simply didn't seem capable of filling up a space evenly if there was a sink to match the fountain.  Granted, in most sinks, you do tend to get those little whirlpools, but this was what largely amounted to a "hill of water", which refused to distribute evenly.

I'd say what is needed, besides a way of treating a body of fluid as a single unit that seeks to level itself out as efficiently as possible, rather than as a massive quantity of individually randomized units of water, may perhaps be a way of handling "bubbles", where the voids in the liquid may itself be treated as a sort of liquid-within-a-liquid (seeking the most efficient route "up") if need be, while a sort of revised version of pressurization would press the liquids downward to best fill out a container in the most efficient method possible.
Logged
Personally, I like [DF] because after climbing the damned learning cliff, I'm too elitist to consider not liking it.
"And no Frankenstein-esque body part stitching?"
"Not yet"

Improved Farming
Class Warfare