예제 #1
0
void StamFluidSystem::diffuse( int bnd, Array3fRef &x, const Array3fRef&x0,float diff,float dt )
{
	float a1 = dt * diff *gridDim.x*gridDim.y,
		a2 = dt * diff *gridDim.x*gridDim.z,
		a3 = dt * diff *gridDim.y*gridDim.z,
		av = (a1+a2+a3)/3.0f,
		div=(1.0f+6.0f*av);
	linear_solve(bnd, x,x0,av,div);
}
예제 #2
0
/***************************************************************
 * Ensures the velocity field is non divergent i.e. incompressible:
 * Solves a poisson equation to compute a gradient field and then
 * subtracts this from the current velocity field to obtain an
 * incompressible field. When solving for pressure it sets the
 * cells pressure field.
 ***************************************************************/
void FGS_Fluid_Solver2DS :: project (FLUID_DATA ux, FLUID_DATA uy, FLUID_DATA pressure, FLUID_DATA divergence){

    double h           = 1.0 / N * -0.5;
    double half_width  = width   * 0.5;
    double half_height = height  * 0.5;
    int    cell;
    double north, south, east, west;
    
    for (int i=1 ; i <= width; i++ )
        for (int j=1 ; j <= height; j++ ){
            cell  = GET_INDEX(i,j);
            north = grid[GET_INDEX(i,j-1)].data[uy];
            south = grid[GET_INDEX(i,j+1)].data[uy];
            east  = grid[GET_INDEX(i+1,j)].data[ux];
            west  = grid[GET_INDEX(i-1,j)].data[ux];
            
            grid[cell].data[divergence] = h * (east-west+south-north);
            grid[cell].data[pressure]   = 0;
        }
    
    set_boundary (SET_FOR_NON_VELOCITY_COMPONENT, divergence);
    set_boundary (SET_FOR_NON_VELOCITY_COMPONENT, pressure);
    
    computing_pressure = true;
    linear_solve (SET_FOR_NON_VELOCITY_COMPONENT, pressure, divergence, 1, 0.25);
    computing_pressure = false;
    
    for (int i = 1; i <= width; i++)
        for (int j = 1; j <= height; j++){
            
            cell  = GET_INDEX(i,j);
            north = grid[GET_INDEX(i,j-1)].data[pressure];
            south = grid[GET_INDEX(i,j+1)].data[pressure];
            east  = grid[GET_INDEX(i+1,j)].data[pressure];
            west  = grid[GET_INDEX(i-1,j)].data[pressure];
            
            double u_in_cell = grid[cell].data[ux],
                   v_in_cell = grid[cell].data[uy];
            
            grid[cell].data[ux] = u_in_cell - (half_width  * (east  - west));
            grid[cell].data[uy] = v_in_cell - (half_height * (south - north));
            
        }
    set_boundary(SET_FOR_HORIZONTAL_COMPONENT, ux);
    set_boundary(SET_FOR_VERTICAL_COMPONENT,   uy);

}
예제 #3
0
파일: shamir.c 프로젝트: TierNolan/Shamir
uint32_t  decode(uint32_t *x, uint32_t *shares, int n, int k)
{

    if(n < k)
    {
        return -1;
    }

    uint32_t **eqn;
    uint32_t *eqn_all;

    eqn = malloc(sizeof(*eqn) * k);
    eqn_all = malloc(sizeof(*eqn_all) * k *(k + 1));

    int a;
    for(a = 0; a < k; a++)
    {
        eqn[a] = eqn_all + ((k + 1) * a);
    }

    int b;
    for(b = 0; b < k; b++)
    {

        uint32_t xp = 1;
        uint32_t xr = x[b];

        for(a = 0; a < k; a++)
        {
            eqn[b][a] = xp;
            xp = multiply(xp, xr);
        }
        eqn[b][k] = shares[b];
    }

    solve_matrix(eqn, k);

    return linear_solve(eqn[0][0], eqn[0][k]);

}
예제 #4
0
bool Spin_qsic_trim_3::try_refine_next_step(double s12, double s23, double s31,
                                            double base_s12, double base_s23, double base_s31,
                                            double dir_s12, double dir_s23, double dir_s31, double delta_step,
                                            double &refined_epsilon,
                                            double &refined_s12, double &refined_s23, double &refined_s31) const
{
    double h00, h01, h02;
    double h10, h11, h12;
    double h20, h21, h22;
    double g0, g1, g2;

    m_spin_reduced_quadric_a.gradient(s12, s23, s31, h00, h01, h02);
    m_spin_reduced_quadric_b.gradient(s12, s23, s31, h10, h11, h12);
    h20 = -dir_s12;
    h21 = -dir_s23;
    h22 = -dir_s31;

    g0 = m_spin_reduced_quadric_a.evaluate(s12, s23, s31);
    g1 = m_spin_reduced_quadric_b.evaluate(s12, s23, s31);
    g2 = (base_s12 - s12) * dir_s12 + (base_s23 - s23) * dir_s23 + (base_s31 - s31) * dir_s31 - delta_step;

    refined_epsilon = std::sqrt(g0 * g0 + g1 * g1 + g2 * g2);

    double x0, x1, x2;

    if (!linear_solve(h00, h01, h02,
                      h10, h11, h12,
                      h20, h21, h22,
                      -g0, -g1, -g2,
                      x0, x1, x2))
    {
        return false;
    }

    refined_s12 = s12 + x0;
    refined_s23 = s23 + x1;
    refined_s31 = s31 + x2;
    return true;
}
예제 #5
0
bool Spin_qsic_trim_3::try_refine_begin_step(double s12, double s23, double s31, double radius,
                                             double &refined_epsilon,
                                             double &refined_s12, double &refined_s23, double &refined_s31) const
{
    double squared_radius = radius * radius;

    double h00, h01, h02;
    double h10, h11, h12;
    double h20, h21, h22;
    double g0, g1, g2;

    m_spin_reduced_quadric_a.gradient(s12, s23, s31, h00, h01, h02);
    m_spin_reduced_quadric_b.gradient(s12, s23, s31, h10, h11, h12);
    h20 = 2 * s12;
    h21 = 2 * s23;
    h22 = 2 * s31;

    g0 = m_spin_reduced_quadric_a.evaluate(s12, s23, s31);
    g1 = m_spin_reduced_quadric_b.evaluate(s12, s23, s31);
    g2 = s12 * s12 + s23 * s23 + s31 * s31 - squared_radius;

    refined_epsilon = std::sqrt(g0 * g0 + g1 * g1 + g2 * g2);

    double x0, x1, x2;

    if (!linear_solve(h00, h01, h02,
                      h10, h11, h12,
                      h20, h21, h22,
                      -g0, -g1, -g2,
                      x0, x1, x2))
    {
        return false;
    }

    refined_s12 = s12 + x0;
    refined_s23 = s23 + x1;
    refined_s31 = s31 + x2;
    return true;
}
예제 #6
0
void StamFluidSystem::project( Array3fRef &u,Array3fRef &v,Array3fRef &w,Array3fRef &div,Array3fRef &p )
{

	int i, j, k, m;
	for (i = 1; i <=gridDim.x; i++) {
		for (j = 1; j <=gridDim.y; j++){
			for(k=1;k<=gridDim.z;k++){
				(*div)(i,j,k) = -0.5f*
					(((*u)(i + 1, j,k)
					- (*u)(i - 1, j,k))/gridDim.x 
					+((*v)(i, j + 1,k)
					- (*v)(i, j - 1,k))/gridDim.y
					+((*w)(i, j,  k+1)
					- (*w)(i, j,  k-1))/gridDim.z);
				(*p)(i,j,k) = 0;
			}
		}
	}

	set_boundary(0, div);
	set_boundary(0, p);
	linear_solve(0,p,div,1.0f,6.0f);

	for (i = 1; i <= gridDim.x; i++) {
		for (j = 1; j <= gridDim.y; j++) {
			for(k=1;k<=gridDim.z;k++){
				(*u)(i, j,k) -= 0.5 * ((*p)(i + 1,j,k )-(*p)(i - 1,j,k))*gridDim.x;
				(*v)(i, j,k) -= 0.5 * ((*p)(i, j + 1,k)-(*p)(i, j - 1,k))*gridDim.y;
				(*w)(i, j,k) -= 0.5 * ((*p)(i, j,  k+1)-(*p)(i, j, k-1))*gridDim.z;
			}
		}
	}
	set_boundary(1, u);
	set_boundary(2, v);
	set_boundary(3, w);

}
예제 #7
0
/***************************************************************
 * Computes potential diffusion of cell values into its 
 * neighbouring cells 
 ***************************************************************/
void FGS_Fluid_Solver2DS :: diffuse (BOUNDARY_CONDITION  b,  FLUID_DATA to,  FLUID_DATA from, double coef){
    // Calculate 
    double a = deltaT*coef*width*height, c = 1.0 / (1+4*a);
    linear_solve(b, to, from, a, c);
}