Zephyr (SSFR)
Source Code for Subspace Fluid Re-Simulation


Download the code: ZEPHYR.tar.gz
This code is released under the GNU public license.
Copyright 2013, Theodore Kim.

This code contains components of previous code releases, including Wavelet Turbulence, Cubica, and Closest Point Turbulence. As such, it may also contain third party components from those packages. See the respective source distribution webpages for details. The Modified Incomplete Cholesky preconditioner was implemented by John Delaney.


This is a reference implementation of the algorithm described in the paper Subspace Fluid Re-Simulation. It is intended to be the simplest possible working example of a cubature-based advection scheme. In keeping with this simplicity, bells and whistles such as obstacle handling and MacCormack support have been removed.

Building the code:

We have successfully built this code in Mac OSX (10.6, Snow Leopard) and Linux (Ubuntu 12.02). The default Makefile is for OSX, and the Linux Makefile is Makefile.ubuntu. We have made an effort to remove dependencies on external libraries, so aside from some commonly available libraries (zlib, libpng, GLUT), you should not need to download and install anything special in order to successfully compile. Notably, Zephyr requires the Eigen library, but it comes included in the download. You should be able to build using the following sequence:

    gunzip ZEPHYR.tar.gz
    tar -xvf ZEPHYR.tar
    cd ZEPHYR
If you are using Linux, replace the last line with make ubuntu. If you are successful, the binaries
should now be in the ZEPHYR/bin directory.

Running the code:

The configuration file for a very small example is provided, ./cfg/stam.64.cfg. Running the entire subspace pipeline on a large example can be very time consuming, so it is highly recommended that you first verify that this example can be run successfully. The following is the execution sequence.

From the ZEPHYR directory, generate the snapshot data by running 50 steps of a full-rank fluid simulation:

    ./bin/fluidStam3D ./cfg/stam.64.cfg

Take the SVD of the simulation data (i.e. build the "empirical eigenvectors") in order to construct a subspace:
    ./bin/svdOutOfCoreMultiple ./cfg/stam.64.cfg
Generate a semi-Lagrangian cubature scheme for that subspace:
    ./bin/cubatureGeneratorStamStaged ./cfg/stam.64.cfg
Finally, re-simulate the original sequence in the subspace using the cubature scheme:
    ./bin/reducedStagedStam3D ./cfg/stam.64.cfg
For this small example, running the code from end to end should only take about 10 minutes. Higher resolution simulations will take longer, but the speedups will be correspondingly larger. For example, if you instead run ./cfg/stam.200.cfg, you will reproduce the "Stam Plume" result from the paper, whose image is at the top of this page. You will have to wait more than a dozen hours to generate the training data and the cubature scheme however, and you will need a machine with 96 GB of memory. Rendering time is also not included, so additional effort will need to be invested on this front as well.

By default, reducedStagedStam3D loads up the original simulation data and compares it to the subspace result. If the cubature has trained correctly, you should see the relative error of the velocity field in the subspace simulation remain below 1%. This comparison has two additional ramifications:

  • The subspace simulator will not run as fast as it otherwise would, since it pulls a comparison file from disk every timestep.
  • The subspace simulator will die after 50 timesteps, as it will try to read ground truth data for frame 51, and the read will fail.
If your simulation gets to 50 timesteps and outputs something along the lines of,
    Ground truth difference for frame 50
    velocity abs error: 0.00488207
    velocity relative error: 0.00115117
    density abs error: 0.0378023
    density relative error: 0.00158093
then your installation has succeeded. The exact numbers you get may be slightly different, as the number of cores on your system will slightly change the exact cubature scheme that is discovered. OpenMP is used to distribute the work for importance sampling, which introduces a small amount of non-determinism.

If you wish to deactivate this ground truth comparison, comment out the call diffGroundTruth() in the function SUBSPACE_FLUID_3D_EIGEN::stepReorderedCubatureStam().

This material is based upon work supported by a National Science Foundation CAREER award (IIS-1253948). We acknowledge rendering support from the Center for Scientific Computing from the CNSI, MRL: an NSF MRSEC (DMR-1121053), Hewlett-Packard, and NSF CNS-0960316. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of the National Science Foundation.