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); }
/*************************************************************** * 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); }
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]); }
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; }
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; }
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); }
/*************************************************************** * 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); }