/* C++ port of Gustav Taxen's (gustavt@nada.kth.se) C implementation of Jos Stam's fast 2D fluid solver, itself built on five hundred years of unpatented work in the study of turbulence. Portions of this code by Gustav Taxen, http://www.nada.kth.se/~gustavt/fluids/ Portions of the code by Jos Stam, from the paper "A Simple Fluid Solver Based on the FFT", available at http://www.dgp.utoronto.ca/people/stam/reality/Research/pub.html */ #include "fluid2d.h" #include #include #define floor(x) ((x)>=0.0?((int)(x)):(-((int)(1-(x))))) #define FFT(s,u)\ if(s==1) rfftwnd_one_real_to_complex(plan_rc,(fftw_real *)u,(fftw_complex*)u);\ else rfftwnd_one_complex_to_real(plan_cr,(fftw_complex *)u,(fftw_real *)u) Fluid2D::Fluid2D(int nsize, float timestep, float setviscosity) { n = nsize; dt = timestep; viscosity = setviscosity; u = new fftw_real[n * 2*(n/2+1)]; v = new fftw_real[n * 2*(n/2+1)]; u0 = new fftw_real[n * 2*(n/2+1)]; v0 = new fftw_real[n * 2*(n/2+1)]; r = new fftw_real[n * n]; r0 = new fftw_real[n * n]; g = new fftw_real[n * n]; g0 = new fftw_real[n * n]; b = new fftw_real[n * n]; b0 = new fftw_real[n * n]; u_u0 = new fftw_real[n * n]; u_v0 = new fftw_real[n * n]; plan_rc = rfftw2d_create_plan(n, n, FFTW_REAL_TO_COMPLEX, FFTW_IN_PLACE); plan_cr = rfftw2d_create_plan(n, n, FFTW_COMPLEX_TO_REAL, FFTW_IN_PLACE); t = 0.0; for( int i=0; i (n - 1)) { X = n - 1; } if (Y > (n - 1)) { Y = n - 1; } if (X < 0) { X = 0; } if (Y < 0) { Y = 0; } // Add force at the cursor location len = sqrt(dnx * dnx + dny * dny); if (len != 0.0) { dnx *= 0.1 / len; dny *= 0.1 / len; } u_u0[Y * n + X] += dnx; u_v0[Y * n + X] += dny; // Increase matter densities at the cursor location r[Y * n + X] = 10.0f * rfactor; r0[Y * n + X] = r[Y * n + X]; g[Y * n + X] = 10.0f * gfactor; g0[Y * n + X] = g[Y * n + X]; b[Y * n + X] = 10.0f * bfactor; b0[Y * n + X] = b[Y * n + X]; } /* * Copy user-induced forces to the force vectors * that is sent to the solver. Also dampen forces and * matter density. * */ void Fluid2D::setForces(void) { int i; for (i = 0; i < n * n; i++) { r0[i] = 0.995 * r[i]; g0[i] = 0.995 * g[i]; b0[i] = 0.995 * b[i]; u_u0[i] *= 0.85; u_v0[i] *= 0.85; u0[i] = u_u0[i]; v0[i] = u_v0[i]; } }