Assignment 3
Table of Contents
- 1 Getting Started
- 2 Implementation Details
- 3 Interactive Controls
- 4 Debugging Tips
- 5 Submission
- 6 References
In this assignment, you will implement a 2D fluid simulation using the Weakly Compressible Smoothed Particle Hydrodynamics (WCSPH) method, using the EUROGRAPHICS 2019 course notes by Koschier et al. as a reference for the details.
1 Getting Started
Pull the latest A3 starter code from: https://github.coecis.cornell.edu/cs5643/assignments-sp25.
Running python3 main.py
will display a GUI with initial
particles.
The framework consists of four files:
main.py
: Simulation loop and GUIscene.py
: Particle position initializationutils.py
: SPH constantstodo.py
: Your implementation code goes here
To record a simulation video, use
python3 main.py --video
. Recording stops when you press the
ESC key, generating both MP4 and GIF files. Here
is the reference video. Note that this video is only for reference, and
your results don’t need to be exactly the same.
2 Implementation Details
2.1 Density Computation
In SPH, a field \(A\) is discretized using sampling points (particles) \(j\) as:
\[\langle A(\vec x)\rangle = \sum_j A_j\frac{m_j}{\rho_j}W(\|\vec x-\vec x_j\|, h)\]
Where \(m\) is mass, \(\rho\) is density, and \(W\) is the kernel function. For density itself, the equation simplifies to:
\[\langle \rho(\vec x)\rangle = \sum_j m_jW(\|\vec x-\vec x_j\|, h)\]
You can use this cubic spline kernel:
\[W(r, h) = \frac{40}{7\pi h^2} \begin{cases} 6(q^3 - q^2) + 1 &\text{for }0\le q < \frac{1}{2}\\ 2(1 - q)^3 &\text{for }\frac{1}{2}\le q < 1\\ 0 &\text{otherwise} \end{cases} \]
These equations match what you implemented in problem set 3.
2.2 Pressure Computation
In WCSPH, pressure for particle \(i\) is directly computed from density:
\[p_i = B((\frac{\rho_i}{\rho_0})^\gamma - 1)\]
, where \(\rho_0\) is the default density, \(\gamma\) and \(B\) are constants. When \(\gamma=1\), it is actually the pressure for ideal gas. To simulate fluids with high resistance to compresssion (like water), we use \(\gamma\) = 7 in our assignment.
2.3 Acceleration Computation
From the Navier-Stokes equations for a fluid without viscosity:
\[\frac{D\vec u}{Dt} + \frac{1}{\rho}\nabla p = \vec g\]
To calculate acceleration and update velocity, we need the pressure gradient. For particle \(i\), this is:
\[\langle \nabla p_i \rangle = \rho_i\sum_j m_j(\frac{p_i}{\rho_i^2} + \frac{p_j}{\rho_j^2})\nabla_iW_{i, j}\]
, where \(\nabla_iW_{i, j} = \frac{\partial W(\|\vec x_i - \vec x_j\|, h)}{\partial \vec x_i}\). (You might notice that the gradient of pressure here is different from \(\nabla\langle A\rangle\) in problem set 3. See here if you want to know more.)
Substituting back into the N-S equation gives the acceleration:
\[\frac{\text{d}^2x_i}{\text{d}t^2} = -\sum_j m_j(\frac{p_i}{\rho_i^2} + \frac{p_j}{\rho_j^2})\nabla_iW_{i, j} + g\]
2.4 Boundary Conditions
Boundary conditions are always one of the most annoying
interesting parts of fluid simulation. We implement boundaries using
fixed boundary particles with density \(\rho_0\) and pressure \(0\). These particles contribute to pressure
and density calculations for fluid particles, pushing them away from
boundaries. Three layers of boundary particles ensure that the full
kernel support will be covered near boundaries.
2.5 Artificial Viscosity
To improve numerical stability, we add artificial viscosity:
\[a_{viscosity}^i = \begin{cases} -\sum_j m_j\Pi_{i, j}\nabla_i W_{i, j} & v_{i, j}^T x_{i, j} < 0\\ 0 & v_{i, j}^T x_{i, j} \ge 0 \end{cases} \]
Where \(v=\frac{\text{d}x}{\text{d}t}\) is velcocity, \(v_{i, j} = v_i - v_j\), \(x_{i, j} = x_i - x_j\), and \(\Pi_{i, j}\) is given as:
\[ \Pi_{i, j} = -\frac{2\alpha hc_s}{\rho_i + \rho_j}\frac{v^T_{i, j}x_{i, j}}{\|x_{i, j}\|^2 + \epsilon h}\]
, where \(\alpha\) is the viscosity constant (we use \(0.8\) in our code). \(\epsilon = 0.01\) is introduced to avoid singularity when \(\|x_{i, j}\|\) is too small.
The final acceleration for particle \(i\) is:
\[\frac{\text{d}^2x_i}{\text{d}t^2} = -\sum_j m_j(\frac{p_i}{\rho_i^2} + \frac{p_j}{\rho_j^2})\nabla_iW_{i, j} + g + a_{viscosity}\]
3 Interactive Controls
- W, A, S, D: Control gravity direction
- E, Q: Rotate barrier particles clockwise/counter-clockwise
4 Debugging Tips
- Make sure density and pressure are computed correctly. Density at each particle should be close to \(\rho_0\), and pressure should not be too large.
- Particles are very energetic without viscosity (as shown here). If you want to see some results or debug before implementing viscosity, consider use a smaller constant \(B\) in pressure computation. (a too small \(B\) might cause boundary penetration, though)
- If particles stick to boundaries or deform in the first few frames, try setting \(\rho_i = \max(\rho_0, \rho_i)\)
5 Submission
You need to include the following in your submission:
- A PDF file including a link to the chosen commit for your
submission. If you submit a link just to your repository, we will assume
that you would like us to look at the latest commit on the
main
branch. - A demo video demonstrating the functionality of your simulation.