//----------------------------------------------------------------------------- void StamFluidSolver::project ( float * u, float * v, float * p, float * div ) { int L = kds_min(_NX, _NY); // NOTE: This used to use N when we had symmetric grids float h = 1.0f/L; // TODO: Can include the * -0.5f as part of h. h *= 0.5; for (int j=1; j < _NY-1; j++ ) for (int i=1; i < _NX-1; i++ ) { div[IX(i,j)] = -h*(u[IX(i+1,j)]-u[IX(i-1,j)]+v[IX(i,j+1)]-v[IX(i,j-1)]); p[IX(i,j)] = 0; } setBound ( 0, div ); setBound ( 0, p ); linearSolve ( 0, p, div, 1, 4 ); float LL = 0.5f*L; // TODO: Can precalculate L*0.5f for (int j=1; j < _NY-1; j++ ) for (int i=1; i < _NX-1; i++ ) { u[IX(i,j)] -= LL*(p[IX(i+1,j)]-p[IX(i-1,j)]); v[IX(i,j)] -= LL*(p[IX(i,j+1)]-p[IX(i,j-1)]); } setBound ( 1, u ); setBound ( 2, v ); }
void FluidSystem::project(VelocityField &velocity) const { Grid pressure(fullDim); Grid divergence(fullDim); div(divergence, velocity, dim); divergence = -1 * divergence; setContinuityBoundaries(divergence, dim); setContinuityBoundaries(pressure, dim); linearSolve(pressure, divergence, 1, 6, dim, std::bind(&setContinuityBoundaries, std::placeholders::_1, dim)); VelocityField gradient(fullStaggeredDim); gradient.clear(); grad(gradient, pressure, dim); velocity -= gradient; if (horizontalNeumann) { setHorizontalNeumannBoundaries(velocity[0], dim); } else { setContinuityBoundaries(velocity[0], dim); } if (verticalNeumann) { setVerticalNeumannBoundaries(velocity[1], dim); } else { setContinuityBoundaries(velocity[1], dim); } setDepthNeumannBoundaries(velocity[2], dim); }
//----------------------------------------------------------------------------- void StamFluidSolver::diffuse ( int b, float * x, float * x0, float diff, float dt ) { // NOTE that diffuse is implemented very differently in the new code int L = kds_min(_NX,_NY); // TODO: Before I used N*N here, but now that we have _NX and _NY I'm using min of them. Not sure if that is right float a=dt*diff*(L*L); linearSolve ( b, x, x0, a, 1+4*a ); }
void testLinearSolve() { //solves A(m,n).x(n)=b(m). Borrows heavily from svbksb, numerical rescipies, section 2.6 UnicodeString Astring = UnicodeString("3,4,2,2;2,3,5,1;1,2,2,1"); UnicodeString Bstring = UnicodeString("3,5,2,1"); ublas::matrix<double> A = unicodeStringToMatrix<double>(Astring); ublas::vector<double> b = unicodeStringToVector<double>(Bstring); ublas::vector<double> x = linearSolve(A,b); print("A", A); print("b", b); print("x", x); printf("x should equal: 1.16667, 0.166667, -.5\n"); }