Skip to main content

Understanding Eulerian and Lagrangian Fluid Simulations

In fluid simulations, there are two dominant ways to represent a fluid: Eulerian and Lagrangian. So, what are they? Which can we use to make a good fluid simulation for a specific project? And how can we implement them?

First, let's discuss the Navier-Stokes equations, which generalize the motion of Newtonian fluids. The momentum of a particle in a Newtonian fluid is as follows:

\begin{equation}\rho\frac{\partial\overrightarrow{\mathbf{u}}}{\partial t}+\rho(\nabla\cdot\overrightarrow{\mathbf{u}})\overrightarrow{\mathbf{u}}=\rho\frac{d\overrightarrow{\mathbf{u}}}{dt}=-\nabla p+\mu\nabla^2\overrightarrow{\mathbf{u}}+\Sigma F\end{equation}

The equation above gives us a fluid's motion at a particular point, and a fluid simulation works by calculating the velocity of lots of these points and interpolating between them. (For this model, we'll ignore the viscosity term and assume that the fluid we're simulating is a superfluid, just to make things slightly more manageable.) But at which points should we solve Navier-Stokes?

One approach is to track the position of each particle in the fluid and figure out its motion at its position. This is the Lagrangian approach, which is mathematically expressed as

\begin{equation}\mathbf{X}(\mathbf{x}_0, t)\end{equation}

Simulating every molecule seems like it would be very accurate, and it is. However, it's also very computationally expensive. The Eulerian approach tracks the fluid globally, setting the reference point to a fixed position. It calculates Navier-Stokes at fixed points along the fluid, which can be much faster computationally, but it's also less accurate. Mathematically, this approach is expressed as

\begin{equation}\mathbf{u}(\mathbf{x}, t)\end{equation}

Both the Eulerian and Lagrangian approaches are functions of position and time, and they can be related with the equation

\begin{equation}\mathbf{u}((\mathbf{X}(\mathbf{x}_0, t), t)=\frac{\partial\mathbf{X}}{\partial t}(\mathbf{x}_0, t)\end{equation}

Comments

Popular posts from this blog

Multithreaded Infinite Procedural Terrain with LODs in Unity

Infinitely procedurally generated terrain can be a lot of fun in games. I can't tell you how much fun I've had exploring worlds in games like Minecraft . Unfortunately, as so many overly-ambitious indie developers will tell you, it takes a lot of work to make procedural worlds performant without a lot  of work. Thankfully, there's a solution: multithreading. Wait, don't leave! Multithreading is a lot simpler than you might think, and in this post, I'll show you how to create infinite, procedural terrain in Unity with just a few lines of code that's fast, beautiful, and even has LODs. The code is below: using System.Collections; using System.Collections.Generic; using System.Threading; using System.Linq; using UnityEngine; public class TerrainGenerator : MonoBehaviour { public Material material; public int chunkSize = 64 ; public int rangeMultiplier = 2 ; public NoiseFilter noiseFilter; public float [] LODDi...

Alpha-Beta Pruning Minimax Chess Bot

I've written a chess bot that uses the minimax algorithm to play chess, even though I barely know how to play. What could possibly  go wrong? Minimax is a decision rule in game theory that seeks to minimize the possible loss of a situation, or in this case, to prevent the AI from being at a "disadvantage" with the player. The bot plays through a bunch of moves, determines how much of a loss they incur, and chooses a move with the lowest disadvantage. My implementation is in Python and uses the python-chess   library to create a chessboard. So, let's look at the code. First, I set up the board as follows: board = chess . Board() values = {chess . PAWN: 1 , chess . KNIGHT: 3 , chess . BISHOP: 3 , chess . ROOK: 5 , chess . QUEEN: 9 , chess . KING: 0 } To calculate advantage, I iterate through all of the pieces on the chess board and add or subtract their values from a running count depending on their color. By weighing more valuable pieces, you could be...

Emotion Classification NN with Keras Transformers and TensorFlow

  In this post, I discuss an emotional classification model I created and trained for the Congressional App Challenge last month. It's trained on the Google GoEmotions dataset and can detect the emotional qualities of a text. First, create a training script and initialize the following variables. checkpoint = 'distilbert-base-uncased' #model to fine-tune weights_path = 'weights/' #where weights are saved batch_size = 16 num_epochs = 5 Next, import the dataset with the Hugging Face datasets library. dataset = ds . load_dataset( 'go_emotions' , 'simplified' ) Now, we can create train and test splits for our data. def generate_split(split): text = dataset[split] . to_pandas()[ 'text' ] . to_list() labels = [ int (a[ 0 ]) for a in dataset[split] . to_pandas()[ 'labels' ] . to_list()] return (text, labels) (x_text, x_labels) = generate_split( 'train' ) (y_text, y_labels) =...