예제 #1
0
double UpdateSystemImplicit( VoronoiDiagram *voronoiDiagram, double timeStep, double timeDifference)
{

	double time;
	
	int N = voronoiDiagram->xN[0]*voronoiDiagram->xN[1]*voronoiDiagram->xN[2];
	//float **B = newMatrix( N, N);
	
	for( time = 0; time+timeStep <= timeDifference; time += timeStep){
		//fprintf( stderr, "%i. iteration:\nSetup Matrix\n", (int)(time / timeStep + 0.5));
		int passedTime = clock();
		fprintf( stderr, "Set Matrix... \n");
		setupMatrixImplicit( voronoiDiagram, timeStep, 'G');
		fprintf( stderr, "...finished ( %li clocks, %.3lf sec)\n", (clock() - passedTime), (float)(clock() - passedTime)/CLOCKS_PER_SEC);

		/*for(int m=0; m<N; m++){
			for(int n=0; n<N; n++)
				fprintf( stderr, "%6.0lf ", A[m][n]);
			fprintf( stderr, "\n");
		}*/
		/*for(int m=0; m<N; m++){
			for(int n=0; n<N; n++)
				fprintf( stdout, "%i %i %lf \n", m, n, (A[m][n]!=0.?1.:0.));
			//fprintf( stderr, "\n");
		}*/
		
		/*fprintf( stderr, "Solve Matrix\n");
		solveLinearSystemB( A, b, x, N, B);
		
		fprintf( stderr, "Actualize Values\n");
		for(int m=0; m<N; m++)
			voronoiDiagram->voronoiCells[m]->glucose = b[m];
		*/	
		for(int m=0; m<N; m++)
			x[m] = voronoiDiagram->voronoiCells[m]->glucose;

		passedTime = clock();
		fprintf( stderr, "ConjugateGradient... \n");
		ConjugateGradient( A, b, x, N, 1);
		fprintf( stderr, "...finished ( %li clocks, %.3lf sec)\n", (clock() - passedTime), (float)(clock() - passedTime)/CLOCKS_PER_SEC);
		//fprintf( stderr, "...finished ( %lisec)\n", (clock() - passedTime)/CLOCKS_PER_SEC);

		for(int m=0; m<N; m++)
			voronoiDiagram->voronoiCells[m]->glucose = x[m];
	}

	return timeDifference - time;
	
}
예제 #2
0
void StableFluid3D::projectVelocity(double dt)
{
	setBoundary();

	Vector divergence(vel.Length());
	// fill in velocities
	double dx = width / (double)resX;
	double dy = height / (double)resY;
	double dz = depth / (double)resZ;
	for (int i = 0; i < resX; ++i)
	{
		for (int j = 0; j < resY; ++j)
		{
			for (int k = 0; k < resZ; ++k)
			{
				int index = makeIndex(i, j, k);

				double div = (tempVelocities[0][i + 1][j][k] - tempVelocities[0][i][j][k]) / dx + (tempVelocities[1][i][j + 1][k] - tempVelocities[1][i][j][k]) / dy + (tempVelocities[2][i][j][k + 1] - tempVelocities[2][i][j][k]) / dz;

				vel[index] = div;
				divergence[index] = div;
			}
		}
	}

	//	vel *= density / dt;
	bool useOldPCG = false;
	if (useOldPCG)
	{
		int k = 0;
		Vector laplacianTimesPressure(pressure.Length());
		laplacian.Multiply(pressure, laplacianTimesPressure);
		r[0] = vel - laplacianTimesPressure;
		double error = r[0].Magnitude2();
		while ((std::sqrt(error) > PCG_EPS) && (k < PCG_MAXITER))
		{
			//cerr << "PCG iteration " << k << ", error: " << std::sqrt(error) << endl;
			ConjugateGradient(preconditioner, z[k % 2], r[k % 2], 0.0001, 500.0);

			++k;
			int i1 = (k - 1) % 2;
			int i2 = k % 2;
			if (k == 1)
			{
				p = z[0];
			}
			else
			{
				double beta = (InnerProduct(r[i1], z[i1])) /
					(InnerProduct(r[i2], z[i2]));
				p *= beta;
				p += z[i1];
			}
			Vector laplacianTimesP(p.Length());
			laplacian.Multiply(p, laplacianTimesP);
			double alpha = (InnerProduct(r[i1], z[i1])) /
				(InnerProduct(p, laplacianTimesP));
			pressure += alpha * p;
			r[i2] = r[i1] - alpha * (laplacianTimesP);
			error = r[i2].Magnitude2();
		}
		if (std::sqrt(error) > PCG_EPS)
		{
			std::cout << "end preconditioned conj grad " << "error: " << error << std::endl;
		}
	}
	else
	{
		p = Vector(vel.Length());
		r[0] = divergence;
		//ApplyPreconditioner(r[0], z[0]);
		double sigma = InnerProduct(r[0], z[0]);

		int k = 0;
		double error = r[0].Magnitude2();
		while (k < PCG_MAXITER)
		{
			++k;
			Vector s(vel.Length());
			s = z[0];
			int k = 0;
			laplacian.Multiply(s, z[0]);
			double rho = 1.0;
			double alpha = rho / InnerProduct(s, z[0]);
			p += alpha * s;
			r[0] -= alpha * z[0];
			error = r[0].Magnitude2();
			if (error < PCG_EPS * PCG_EPS)
			{
				pressure = p;
				break;
			}
			//ApplyPreconditioner(r[0], z[0]);
			double sigmaNew = InnerProduct(r[0], z[0]);
			double beta = sigmaNew / rho;
			s = z[0] + beta * s;
			sigma = sigmaNew;
		}
		Vector laplacianTimesPressure(pressure.Length());
		laplacian.Multiply(pressure, laplacianTimesPressure);
		r[0] = vel - laplacianTimesPressure;
		error = r[0].Magnitude2();
		while ((std::sqrt(error) > PCG_EPS) && (k < PCG_MAXITER))
		{
			//cerr << "PCG iteration " << k << ", error: " << std::sqrt(error) << endl;
			ConjugateGradient(preconditioner, z[k % 2], r[k % 2], 0.0001, 500.0);

			++k;
			int i1 = (k - 1) % 2;
			int i2 = k % 2;
			if (k == 1)
			{
				p = z[0];
			}
			else
			{
				double beta = (InnerProduct(r[i1], z[i1])) /
					(InnerProduct(r[i2], z[i2]));
				p *= beta;
				p += z[i1];
			}
			Vector laplacianTimesP(p.Length());
			laplacian.Multiply(p, laplacianTimesP);
			double alpha = (InnerProduct(r[i1], z[i1])) /
				(InnerProduct(p, laplacianTimesP));
			pressure += alpha * p;
			r[i2] = r[i1] - alpha * (laplacianTimesP);
			error = r[i2].Magnitude2();
		}
		if (std::sqrt(error) > PCG_EPS)
		{
			std::cout << "end preconditioned conj grad " << "error: " << error << std::endl;
		}
	}

	/*
	mathlib::Vector PCGr, PCGd, PCGq, PCGs;
	PCGr.Resize(resX * resY * resZ);
	PCGd.Resize(resX * resY * resZ);
	PCGq.Resize(resX * resY * resZ);
	PCGs.Resize(resX * resY * resZ);

	int iter = 0;
	PCGr = vel - laplacian * pressure;
	mathlib::ConjugateGradient(preconditioner, PCGd, PCGr);
	double deltaNew = mathlib::InnerProduct(PCGr, PCGd);
	double errBound = PCG_EPS * PCG_EPS * deltaNew;

	while ((iter < PCG_MAXITER)  && (deltaNew > errBound))
	{
	if (!(iter % 3))
	cerr << "iteration " << iter << ", error: " << deltaNew << endl;
	PCGq = laplacian * PCGd;
	double alpha = deltaNew / (mathlib::InnerProduct(PCGd, PCGq));
	pressure += alpha * PCGd;
	if ((iter % 10) == 0)
	PCGr = vel - laplacian * pressure;
	else
	PCGr -= alpha * PCGq;

	mathlib::ConjugateGradient(preconditioner, PCGs, PCGr);
	double deltaOld = deltaNew;
	deltaNew = mathlib::InnerProduct(PCGr, PCGs);
	double beta = deltaNew / deltaOld;
	PCGd *= beta;
	PCGd += PCGs;
	++iter;
	}
	cout << "end preconditioned conj grad "<< "error: " << deltaNew << endl;
	*/
	std::cout << "dt:" << dt << "\t density:" << density << std::endl;
	//	dt = 1.0;
	for (int i = 0; i < resX; ++i)
	{
		for (int j = 0; j < resY; ++j)
		{
			for (int k = 0; k < resZ; ++k)
			{
				int i1 = makeIndex(i, j, k);
				int i2;

				double deltaPressure;
				i2 = (i == 0 ? i1 : i1 - 1);
				velocities[0][i][j][k] = tempVelocities[0][i][j][k] - dt* 0.5 * (pressure[i1] - pressure[i2]) / dx;
				deltaPressure = pressure[i1] - pressure[i2];

				i2 = (j == 0 ? i1 : i1 - resX);
				velocities[1][i][j][k] = tempVelocities[1][i][j][k] - dt *  0.5 * (pressure[i1] - pressure[i2]) / dy;
				deltaPressure = pressure[i1] - pressure[i2];

				i2 = (k == 0 ? i1 : i1 - resY * resX);
				velocities[2][i][j][k] = tempVelocities[2][i][j][k] - dt * 0.5 * (pressure[i1] - pressure[i2]) / dz;
				deltaPressure = pressure[i1] - pressure[i2];
			}
		}
	}
}
예제 #3
0
int main(){
    
    double *x,*b, *bbarra;
    int n =100, i, tol =5;
    Matriz*** A, ***M, ***N;

    for(n=100; n<=10000;n=n*10){
        A = mat_esparsa(n);
        x = (double*) calloc(n+IDX,sizeof(double));
        b = (double*) calloc(n+IDX,sizeof(double));
        bbarra = (double*) calloc(n+IDX,sizeof(double));
    
        //Vetor solução
        for(int i =IDX; i< n+IDX; i++)
            x[i]=1;
        
        // Calculo do vetor b correto obtido atraves de Ax = b
        mat_multv(n,A,x,b);


        /*****SEM PRECOND*****/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;

        printf("\n\tMetodo gradiente Conjugado com pre condicionador de Sem PreCond , n= %d \n",n );
        i = ConjugateGradient(n, A, b, x,tol);
        printf("\n\ti = %d \t\n",i );




        /******Jacobi*********/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                // Matriz pre condicionador de Jacobi  
                M = JacobiPC(A, n);
                //Minv Ax = Minv b/
                N = mat_cria(n,n);
                mat_multm(n,M,A,N);
                mat_multv(n, M, b, bbarra);
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de Jacobi , n= %d \n",n );


                // Metodo gradiente Conjugado com pre condicionador de Jacobi , n= 1000
                i = ConjugateGradient(n, N, bbarra, x,tol);
                printf("\n\ti = %d \t\n",i );


                mat_libera(n,M);
                mat_libera(n,N);



        /******Gaus Seidel****/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de GaussSeidel , n= %d \n",n );
                
                M = pre_cond(A,n,1);

                i = ConjugateGradientPC(n, A, M, b, x, tol);
                printf("\n\ti = %d \t\n",i );

                mat_libera(n,M);


        /*****  SSOR  *********/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;
        
        printf("\n\tMetodo gradiente Conjugado com pre condicionador de SSOR , n= %d \n",n );
        
        M = pre_cond(A,n,1.5);

        i = ConjugateGradientPC(n, A, M, b, x, tol);
        printf("\n\ti = %d \t\n",i );

        mat_libera(n,M);

            //=======Fim do Loop======//

        free(x);
        free(b);
        free(bbarra);
        mat_libera(n,A);
    }

    for(n=100; n<=10000;n=n*10){
        A = mat_esparsa_extend(n);
        x = (double*) calloc(n+IDX,sizeof(double));
        b = (double*) calloc(n+IDX,sizeof(double));
        bbarra = (double*) calloc(n+IDX,sizeof(double));
    
        //Vetor solução
        for(int i =IDX; i< n+IDX; i++)
            x[i]=1;
        
        // Calculo do vetor b correto obtido atraves de Ax = b
        mat_multv(n,A,x,b);


        /*****SEM PRECOND*****/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;

        printf("\n\tMetodo gradiente Conjugado com pre condicionador de Sem PreCond , n= %d \n",n );
        i = ConjugateGradient(n, A, b, x,tol);
        printf("\n\ti = %d \t\n",i );




        /******Jacobi*********/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                // Matriz pre condicionador de Jacobi  
                M = JacobiPC(A, n);
                //Minv Ax = Minv b/
                N = mat_cria(n,n);
                mat_multm(n,M,A,N);
                mat_multv(n, M, b, bbarra);
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de Jacobi , n= %d \n",n );


                // Metodo gradiente Conjugado com pre condicionador de Jacobi , n= 1000
                i = ConjugateGradient(n, N, bbarra, x,tol);
                printf("\n\ti = %d \t\n",i );


                mat_libera(n,M);
                mat_libera(n,N);



        /******Gaus Seidel****/
        
                //Redefinição de x[] para estimativa inicial vetor nulo
                for(int i =IDX; i< n+IDX; i++) x[i]=0;
                
                printf("\n\tMetodo gradiente Conjugado com pre condicionador de GaussSeidel , n= %d \n",n );
                
                M = pre_cond(A,n,1);

                i = ConjugateGradientPC(n, A, M, b, x, tol);
                printf("\n\ti = %d \t\n",i );

                mat_libera(n,M);


        /*****  SSOR  *********/
        //Redefinição de x[] para estimativa inicial vetor nulo
        for(int i =IDX; i< n+IDX; i++) x[i]=0;
        
        printf("\n\tMetodo gradiente Conjugado com pre condicionador de SSOR , n= %d \n",n );
        
        M = pre_cond(A,n,1.5);

        i = ConjugateGradientPC(n, A, M, b, x, tol);
        printf("\n\ti = %d \t\n",i );

        mat_libera(n,M);

            //=======Fim do Loop======//

        free(x);
        free(b);
        free(bbarra);
        mat_libera(n,A);
    }

}
예제 #4
0
int main (void){
	double ** A0 = mat_cria(3,3);
	double *b0 = (double*)malloc(3*sizeof(double));
	double ** A1 = mat_cria(3,3);
	double *b1 = (double*)malloc(3*sizeof(double));
	double *x0 = (double*)malloc(3*sizeof(double));
	double *x1 = (double*)malloc(3*sizeof(double));

	A0[0][0] = 1;
	A0[0][1] = -1;
	A0[0][2] = 0;
	A0[1][0] = -1;
	A0[1][1] = 2;
	A0[1][2] = 1;
	A0[2][0] = 0;
	A0[2][1] = 1;
	A0[2][2] = 2;

	b0[0] = 0;
	b0[1] = 2;
	b0[2] = 3;

	A1[0][0] = 1;
	A1[0][1] = -1;
	A1[0][2] = 0;
	A1[1][0] = -1;
	A1[1][1] = 2;
	A1[1][2] = 1;
	A1[2][0] = 0;
	A1[2][1] = 1;
	A1[2][2] = 5;

	b1[0] = 3;
	b1[1] = -3;
	b1[2] = 4;


	printf("Vetor Solucao 1 \n");
	x0[0] = 0;x0[1] = 0;x0[2] = 0;
	ConjugateGradient(3, A0, b0, x0);
	printv(3, x0);

	printf("Matriz R1 \n");

	Cholesky(3, A0);
	printm(3, A0);

	printf("Vetor Solucao 2 \n");
	x1[0] = 0;x1[1] = 0;x1[2] = 0;
	ConjugateGradient(3, A1, b1, x1);
	printv(3, x1);

	printf("Matriz R2 \n");

	Cholesky(3, A1);
	printm(3, A1);

	free(A0);
	free(A1);
	free(b0);
	free(b1);
	free(x0);
	free(x1);
	return 0;
}
예제 #5
0
int ConjugateGradientPC(int n, Matriz ***A,Matriz ***M, double *b, double *x, double tol){

    double * Rk, *Rk1, *Dk, *temp, *w;
    double Alfa, Beta,y;
    int i;

    Rk = (double*) calloc(n+IDX,sizeof(double));
    Rk1 = (double*) calloc(n+IDX,sizeof(double));
    Dk = (double*) calloc(n+IDX,sizeof(double));
    temp = (double*) calloc(n+IDX,sizeof(double));
    w = (double*) calloc(n+IDX,sizeof(double));

    //R0= b - Ax;
    mat_multv(n,A,x,temp); mat_sumV(n, -1, b, temp,Rk);

    //D0 = M_inv * R0 ou M*D0 = R0
    ConjugateGradient(n,M,Rk,Dk,tol+1);

    ///Para a 1a vez o y eh diferente, muda o calculo de alpha
    y = mat_escalar_vu(n,Rk,Dk);

    // For K= 0...n-1
    for (i = IDX; i < n+IDX; ++i){
        
       // puts("A1");
        // if (Rk = 0) stop
        if(mat_modulo(n, Rk) < 0.5*pow(10,-tol)) break; 
       // puts("A2");
        // Alfa = RkT*(Dk ou W) / DkT * A *Dk
        mat_multv(n,A,Dk,temp); Alfa = y/ mat_escalar_vu(n,temp,Dk);

        // Xk1 = Xk + Alfa*Dk
        mat_sumV(n,Alfa,x,Dk,x);

        //Rk1 = Rk - Alfa * A* Dk ;; Obs: temp já contém A*Dk
        mat_sumV(n, -1*Alfa,Rk,temp,Rk1);

        ////w = M_inv * R0 ou M*w = R0
        ConjugateGradient(n,M,Rk,w,tol+1);
        
        ///
        y = mat_escalar_vu(n,Rk1,w);

        //Beta = Rk1T * w / RkT * Rk
        Beta = y / mat_escalar_vu(n,Rk,Rk);

        //Dk1 = w + Beta*Dk
        mat_sumV(n,Beta,w,Dk,Dk);

        //Atualiza o Rk
        copiaV(n,Rk,Rk1);

    }

    free(Rk);
    free(Rk1);
    free(Dk);
    free(temp);
    free(w);
    return i-IDX;

}