void acarFluid::step() { //smooth level set? smoothLevelSet(levelset, levelsetSmooth); //solve for stream function using the level set fftw_execute( levelsetPlan); solvePoisson(levelsetF, streamF); fftw_execute(streamPlanI); //use stream function to compute velocity computeVelocity(stream, velocityU, velocityV); //use velocity to advect (level set?, smoothed level set?, vorticity?) advectLinear(levelset, levelsetTemp); for(int i=0;i<width*height;++i) levelset[i] = levelsetTemp[i]; //repeat }
////////////////////////////////////////////////////////////////////// // project into divergence free field ////////////////////////////////////////////////////////////////////// void FLUID_3D_MIC::project() { TIMER functionTimer(__FUNCTION__); int index, x, y, z; setObstacleBoundaries(); // copy out the boundaries if(_domainBcLeft == 0) _velocity.setNeumannX(); else _velocity.setZeroX(); if(_domainBcTop == 0) _velocity.setNeumannY(); else _velocity.setZeroY(); if(_domainBcFront == 0) _velocity.setNeumannZ(); else _velocity.setZeroZ(); // calculate divergence index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { Real xright = _velocity[index + 1][0]; Real xleft = _velocity[index - 1][0]; Real yup = _velocity[index + _xRes][1]; Real ydown = _velocity[index - _xRes][1]; Real ztop = _velocity[index + _slabSize][2]; Real zbottom = _velocity[index - _slabSize][2]; if(_obstacles[index+1]) xright = - _velocity[index][0]; if(_obstacles[index-1]) xleft = - _velocity[index][0]; if(_obstacles[index+_xRes]) yup = - _velocity[index][1]; if(_obstacles[index-_xRes]) ydown = - _velocity[index][1]; if(_obstacles[index+_slabSize]) ztop = - _velocity[index][2]; if(_obstacles[index-_slabSize]) zbottom = - _velocity[index][2]; _divergence[index] = -_dx * 0.5f * ( xright - xleft + yup - ydown + ztop - zbottom ); _pressure[index] = 0.0f; } _pressure.copyBorderAll(); _cachedDivergence = _divergence; // solve Poisson equation solvePoisson(_pressure, _divergence, _obstacles, false); _cachedPressure = _pressure; // project out solution -- more matrix-friendly version Real invDx = 1.0f / _dx; index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { if (x == 1) _velocity[index][0] -= (_pressure[index + 1] - _pressure[index]) * invDx; else if (x == _xRes - 2) _velocity[index][0] -= (_pressure[index] - _pressure[index - 1]) * invDx; else _velocity[index][0] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx; if (y == 1) _velocity[index][1] -= (_pressure[index + _xRes] - _pressure[index]) * invDx; else if (y == _yRes - 2) _velocity[index][1] -= (_pressure[index] - _pressure[index - _xRes]) * invDx; else _velocity[index][1] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx; if (z == 1) _velocity[index][2] -= (_pressure[index + _slabSize] - _pressure[index]) * invDx; else if (z == _zRes - 2) _velocity[index][2] -= (_pressure[index] - _pressure[index - _slabSize]) * invDx; else _velocity[index][2] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx; } }