Dominik wrote: Sun Sep 16, 2018 7:18 pm
Hi Yeast,
thanks you for your proposal, so far it seems to be the most reasonable, although I am still unsure about the electricity model which also is interesting.
I admit that my knowledge of physics is rather limited, I had to rely on my common sense. About the “speed kinda models the pressure”, I suppose I could have put more thought into it when writing it. When I think about it, pressure describes it best, it's just that it developed from speed originally and is still called that and I never took the time to rethink what it is.
The model actually is not that dissimilar. The pipe segment has volume (same to level), and the pressure, and connections store the speed - which is just the last step flow. The speed only plays some role in the update and does not control it fully.
From what you propose I really like the idea to push towards only using the last state. I will have to think about it, might steal it. Right now I am thinking about allowing going over the pipe volume limit which would allow this and simplify things a lot.
Your equations are a simplified version of what I currently have. Unfortunately I don't think it would work very well in this form.
The main issue I see is a very low reaction speed. For example - have a straight pipe from source to drain, source is pumping, drain is closed, pipe is full. The drain opens. What I think your model does is that in first tick, only the last segments moves 1/4 of its fluid into the drain (assuming dt=1, which is about what we have) and all the rest stays in place. In next step, one more segments moves a bit, 1/16. Etc. You need "length of pipe" iterations for the wave to reach the source and quite many more to get speed. And then when you get the momentum and you close the pipe, how does the flow stop?
Even so, your ideas are inspiring, I think I will use them, if you don't mind

Thank you, D.
Thank you for your reply Dominik.
First of all, it would not be stealing. As I said, i wrote my simulation for the purpose of improving Factorio, and I even gave a short demonstration at your office when I visited Prague last year, but back then fluid realism wasn't a top priority

Anyway I would be disappointed if you didn't consider using it.
Now about the reaction speed issue. I'm absolutely sure that there is a delay in reaction, and I'm equally sure that this is
not a problem. In the situation you describe it indeed takes some time before the source 'becomes aware' that something is draining the pipe. In fact, this awareness will travel
even slower than 60 tiles per second!
The general solution for the one-dimensional wave equation is
Here u(x,t) is the amount of fluid at time t and position x. F and G can be
any two continuous functions. They represent two waves of
arbitrary shapes travelling to the right (F) and travelling to the left (G). Their shape is dependant on the circumstances (sources/drains) but because of their arguments ( x+c*t and x-c*t ) they travel exactly at speed c and -c. And c simply depends on the flow update step:
Code: Select all
connection.flow += (connection.pipe0.level - connection.pipe1.level) * c^2;
(This can easily be derived from the wave equation)
As I discussed in response to BlueTemplar, I was using more realistic physical constants than Factorio is:
Code: Select all
acceleration momentum preservation
Water: 0.01 0.999
Steam: 0.2 0.99999
Oil: 0.014 0.9
Factorio: 0.4 0.59
With my water acceleration, c^2 = 0.01, giving c = 0.1 but since we update 60 times per second, we get an effective speed of 6. So waves travel at 6 tiles/second. With (presumably) Factorio constants, we get c^2 = 0.4, giving c = 0.6325, and a speed of 38 tiles per second. Yes, that's right. Factorio already seems to have a 'reaction speed issue'. In sixty iterations, changes in supply and demand travel 'only' 38 tiles as it is. But no worries, now comes the 'not a problem' part.
(As an aside: considering a tile is roughly the size of a Factorio engineer, 6 tiles per second is pretty decent for a wave in a liquid)
Please be aware that this fixed speed of waves has
nothing to do with throughput. The flow speed and thus throughput can be huge: the speed of the wave just models how long it takes for changes in flow speed to propagate through the system.
To be more precise: the solution to the wave equation, u(x,t) = F(x-c*t) + G(x+c*t), only tells us how much fluid is at a certain time and place,
not in which direction the fluid is moving, or how fast. Even though a particular composition of the F and G may give the
appearance of a wave travelling left, the actual liquid may flow to the right. The wave is just a manifestation of changes in pressure travelling through a liquid that itself may be moving in the opposite direction. Yet it's exactly these travelling changes in pressure that you mean by 'reaction speed'. The reaction speed however is not so much a result of the 60 UPS, but a direct result of the wave equation.
Now in the case you describe where the pipe is already full and a drain opens: this causes a 'negative' wave (caused by the sudden removal of fluid) to travel towards the source at exactly the speed calculated above (depending on physical constants). For my water constants, the 'gap' would reach the source after 10 seconds for a pipe of 60 tile length. Only then will the source be able to start replenishing the pipe. So yes, there is a reaction speed. And this is completely natural, and
not a problem. There is no problem, because the 60 tile pipe acts as a reservoir to supply the drain until the source gets the message. The longer the pipe, the longer it takes the source to realise what's going on, but the bigger the reservoir will be as well.
When the drain is then suddenly closed, the incoming fluid will bounce against the end of the pipe, and send a wave back towards the source. The wave travelling backwards will effectively bring all incoming fluid to a halt as it passes it. The incoming flow plus the bounced wave will indeed rise the level temporarily to at most twice the normal level. When the reflected wave reaches the source, the source will of course stop supplying. When the system settles, the level may be slightly elevated above normal. For short pipes this can be up to twice the normal level, but for longer pipes the effect will be mitigated by friction.
Now I realise that this exact dependence of the speed of waves (or reaction speed as you call it) on a physical constant in the flow update step might be met with disbelief. In fact, it is true that as each tile responds to changes in its neighbours in the previous frame, some minute effect will travel at 60 tiles/second. But this is an approximation error! Were we to use an infinite amount of infinitely small pipe pieces and model at infinitely small time steps, this effect would vanish. Another (more obvious) approximation error is that even very large values for c^2 would not allow us to exceed a wave speed of 60 tiles/second.
I hope I succeeded in bringing this complicated matter across. If anything remains unclear, don't hesitate to ask!
TheYeast
PS. In relation to the above:
pleegwat wrote: Sun Sep 16, 2018 9:12 pm
That's a real thing; If I remember correctly it's related to the speed of sound in the liquid. Looking at the nearest neighbours on the previous tick gives you a speed of 60 tiles per second. Google gives me real speeds of 1000-1500 m/s for common fluids however.
The speed of sound would indeed be what you would get if the pipe was completely filled at all times.
In Factorio, the level of fluid in pipes is allowed to rise and fall. This means that adding 25% extra to a pipe at 50% would only raise the pressure in so far that gravity is pulling the additional fluid at the top downwards. The small increase in pressure yields the small value for c^2 above, and thus a low wave speed.
In reality, the fluid content inside a fixed length of pipe hardly changes: there are no 'air holes' to replace drained fluid with a lighter gas. So a pipe is always at 100%. When a pump tries to force in an additional 1%, the only way this can happen is by compressing the fluid. And this causes the pressure to rise very sharply, which translates into a high value for c^2, and thus a high speed of the wave.
pleegwat wrote: Sun Sep 16, 2018 9:12 pm
I'm sure a physicist will be along shortly to tell me how wrong I am.
Sorry about that
No really you were not wrong, but that speed of sound thing applies to the case where the pipes are always filled with no air holes. This may be a bit more realistic, but makes the pipes rather boring to watch in the game. Also, high values for c make simulation a bit more fickle, because there are always approximation errors because of the discrete pipe and time slices, and more extreme values tend to bring these out.
Also, it would bring the complication of having to model the transition of being empty to fully filled up. Not worth it in my opinion.