예제 #1
0
//-----------------------------------------------------------------------------
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);
}
예제 #3
0
//-----------------------------------------------------------------------------
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 );
}
예제 #4
0
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");


}