Fluid Simulation Using Vortex Particle
The views/opinions expressed in this story are my own. This story relates my personal experience and choices, and is provided for information in the hope that it will be useful but without any warranty.
This story explains the implementation of a fluid dynamics simulation engine based on the Vortex Particle method. The current implementation is very limited — in particular it does not takes into account some important physical phenomena such as vorticity stretching behaviour, nor viscosity.
It will be relevant to people interested in Computational Fluid Dynamics — the study of predicting the movement of fluids using computation — as well as people in the gaming industry looking at adding a fluid movement engine to either form parts of the game or improve visual effects. However, in both cases, this article should be considered as a brief introduction and further reading will be required.
My background is in computational fluid dynamics, aka CFD, having my first encounter with the discipline as far back as 1998 and an interest in aerodynamics from childhood. I have deviated from the field over the last few years. This post is kick-starting another foray into the field, but using an approach I have not used so far, Vortex Particle.
This post relates to my experience starting the development of an open-source fluid dynamics code using this method. The development is inspired from the series of articles by Dr Michael J. Gourlay titled Fluid Simulation for Video Games completed by theoretical background from Vortex Methods: Theory and Practice (2000) by G-H Cottet and P D Koumoutsakos — although I have to admit that the mathematics is out of reach.
At the time of writing this post, the development is limited to:
- Inviscid simulation in 3-dimensional flows;
- No vorticity stretching;
- No solid boundary treatment;
Some mathematics,
My understanding of the vortex particle method is based on the use of vorticity that relates to the velocity through the following equation:
The vortex particle method is based on discretizing the field of vorticity as distinct particles of vorticity that solved using a lagrangien approach, i.e the particle are tracked as they evolve. The velocity is recovered from the vorticity using the Biot-Savart law that reads:
Or:
In the vortex particle method, the vortex particles are advected in the flow field whilst their vorticity evolves according to the following equations :
As mentioned above this implementation does take into account vorticity stretching and particle vorticity is assumed to remain unchanged over time. In other words, the second equation above is not solved.
An Implementation,
The implementation — see Vortex Particle Simulation project on github — uses a significant amount of boiler plate code to initialize the calculation, manage vortex particles, aka vortons, output vortex particle position, as well as undertake profiling for later optimisation.
I decided to use Rust for this implementation. I recently started to use Rust and appreciate the language and compiler checks, and it is a compiled language with its associated speed.
The implementation, which is currently very light-weight as only a very small number of core features are implemented, uses a InitialConditions
trait to define the initial conditions, one Vorton
struct for the vorton and one UniformGrid
struct for a uniform grid.
A Simulation
struct is defined in lib.rs that stores the simulation information and manages the simulation algorithm. The algorithm is defined as follows:
- The array of vorton is initialized at construction of the Simulation instance. The vortons are distributed at the cell centers of a uniform grid that spans the domain, or area of interest, defined in the
InitialConditions
trait. The uniform grid discretization size is adapted to meet approximately the targeted number of vortons. The vorton’s vorticity is taken from theInitialConditions
trait vorticity function, whilst their volume is taken from the uniform grid discretization; - The vorton solver is an unsteady solver that uses the provided time-step and is currently split into two parts. In the first part, the vorton’s vorticity is evolved — this step is not currently implemented as the vorticity stretch factor is not calculated. In the second part, the vorton’s position is updated during the advection step. The vorton’s velocity is calculated at the vorton’s position using a simple brute-force algorithm that sums the contribution of all other vortons to the velocity.
And a simulation result
The following video shows an overlay of two simulations of the same vortex ring undertaken with circa 1,000 vortons, white dots, and 10,000 vortons, green dots. The two simulations show a similar behaviour despite the difference in resolution.
This story is presenting the first pass at the fluid dynamics solver with a view of developing it further in the future.