TheOpenSpaceProgram / new-ospgl

A space exploration game in OpenGL. Devblog: https://tatjam.github.io/index.html
MIT License
42 stars 6 forks source link

Fluid Simulation #30

Closed tatjam closed 1 year ago

tatjam commented 3 years ago

We should simulate the fluids inside of the tanks and its motions through the vehicle on a more or less accurate way. The system should avoid being "rocket-centric" as airplanes and other vehicles will also benefit from fluid simulation.

PhysicalMaterials define the physical properties of any material thing, such as what parts or planets are made of and the fuel inside tanks.

FluidTanks should offer a simple liquid-vapor equilibrium simulation, and should also implement some kind of "sloshing" dynamic and simulate ullage distribution.

Pipes are connections between fluid ports, they have physical significance and are connected between points of the vehicle so that they have a length and a radius. We can then use the Hagen-Poiseuille equation to approximate volumetric flow and then mass flow, assuming fully laminar flow, but simulating viscosity (*).

Temperature could be simulated only in tanks, or could also be included in all pipes. We should be able to simulate systems such as heat exchangers.

Conservation of Energy: We should try to conserve energy as best as we can while fluids are moving. KSP has a bunch of issues with this where you can use the fluid pumping mechanic to gain velocity.

(*) As a mixture of fluids may be flowing through the pipe, we should think what to do on this case. Simulating each fluid independently doesn't make much sense. For example, on a H2 feeding pipe to a combustion chamber, H2O backflow would be massive as the partial pressure of H2O in the tank is 0. On reality, the incoming fluid prevents any backflow: The fluid flow should more or less be equal to that of the most viscous fluid, assuming that there is enough of it as to "block" the pipe.

tatjam commented 3 years ago

I have decide to use a simple Bernoulli solved for velocity (and then volumetric flow = velocity * area) as Hagen-Poiseuille requires either extremely long pipes or very thin ones. This means that we will ignore viscosity, but density will still matter

tatjam commented 3 years ago

Junction method

We impose a simple requirement on junctions, the sum of all flows through it must be zero. As flows are proportional to the square root of the pressure difference, we can solve the system for the "pressure" at the junction. It turns out that the function is piecewise, so we first find which piece is the solution (there may only be one) by checking the signs at both ends, and then we use the Newton-Rhapson method to find the solution. 1 or 2 iterations are pretty much perfect.

There is a closed form solution, but it's quite long and probably more expensive than the approximation as it requires calculating quite a lot of powers and square roots, while the approximation is simply nx2xiterations square roots. (Maybe implement it and profile it if it matters?)

tatjam commented 3 years ago

As of this commit (https://github.com/TheOpenSpaceProgram/new-ospgl/commit/6efe199864b9fb00fa93bcfbdd6594663891f221) the plumbing editor is working but still has a bunch of bugs

tatjam commented 3 years ago

https://github.com/TheOpenSpaceProgram/new-ospgl/commit/8f71960a75d4828825946709070413d576dce260 started to implement the fluid tanks in lua

tatjam commented 2 years ago

Here's a new fluid flow algorithm I have been thinking about. It may contain some errors, but it's a written down version of the thinking I've been doing lately. Hopefully its implementation doesn't reveal a fatal flaw like the previous design had, as this one seems fairly promising, but also way more tricky to implement!

Flow direction determination algorithm:

Flow algorithm:

Considerations of the graph:

The new thinking removes the uniqueness from pipes and junctions, and now the concept of plumbing connection is even more abstract. This is inline with the conception of the plumbing system as freely modifiable in lua, users could implement realistic pipes and junctions in lua, something which was not possible in the previous design.

tatjam commented 2 years ago

The concept of true machines and flow machines can be generalized further to true ports and flow ports. This allows machines to combine both, for example, for a self-powered turbopump which consumes liquid fuel.

tatjam commented 2 years ago

This also requires changing the logic a bit as now we are finding paths between ports. This is also cleaner and easier to understand as machines may have many ports!

tatjam commented 2 years ago

I've changed the algorithm a bit, as the matrix step was unnecessary. You can simply run the algorithm to find forced paths, then remove every path incompatible with it and repeat in a loop, which is what is currently done in the code (although it doesn't compile yet so it may not work at all)

tatjam commented 1 year ago

This is kind of done, although will (may be is more appropriate) be "rewritten" in the change to generic physical systems.