Poisson Equation Solver
Poisson Equation Solver
h>
#include <math.h>
#include <malloc.h>
void machineEpsilon();
double eps;
main()
{
int i,j,k,m,n,q,iterationCount=1;
double *u,*u_old,dx,dy,r,error,w,ustar,*a,*b,*b1,*x,g;
FILE *fp2;
printf("\nPlease enter the no of points to be taken in x direction:");
scanf("%d",&n);
printf("\nPlease enter the no of points to be taken in y direction:");
scanf("%d",&m);
dx = 1.0/(n-1);
dy = 1.0/(m-1);
u = (double *)malloc(m*n*sizeof(double));
u_old = (double *)malloc(m*n*sizeof(double));
a = (double *)malloc(m*n*m*n*sizeof(double));
b = (double *)malloc(m*n*sizeof(double));
b1 = (double *)malloc(m*n*sizeof(double));
//y = (double *)malloc(m*n*sizeof(double));
x = (double *)malloc(m*n*sizeof(double));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
*(u+j*n+i) = 0.0;
*(u_old+j*n+i) = 0.0;
*(b+j*n+i) = 0.0;
*(b1+j*n+i) = 0.0;
*(x+j*n+i) = 0.0;
}
}
for(i=0;i<m*n*m*n;i++)
{
*(a+i) = 0.0;
}
for(i=0;i<n;i++)
{
*(u+i) = 0.0;
*(u+(m-1)*n+i) = 0.0;
*(u_old+i) = 0.0;
*(u_old+(m-1)*n+i) = 0.0;
}
for(j=0;j<m;j++)
{
*(u+j*n) = 0.0;
*(u+j*n+n-1) = 0.0;
*(u_old+j*n) = 0.0;
*(u_old+j*n+n-1) = 0.0;
}
/*fp1 = fopen("initial.vtk","w");
fprintf(fp1,"# vtk DataFile Version 2.0\n");
fprintf(fp1,"Poisson's Equation\n");
fprintf(fp1,"ASCII\n");
fprintf(fp1,"DATASET STRUCTURED_GRID\n");
fprintf(fp1,"DIMENSIONS %d %d 1\n",n,m);
fprintf(fp1,"POINTS %d double\n",(n)*(m));
for(j=0;j<m;j++)
{
for(i=0;i<n;i++)
{
fprintf(fp1,"%lf %lf 0.0\n",i*dx,j*dy);
}
}
fprintf(fp1,"POINT_DATA %d\n",n*m);
fprintf(fp1,"SCALARS u double\n");
fprintf(fp1,"LOOKUP_TABLE default\n");
for(j=0;j<m;j++)
{
for(i=0;i<n;i++)
{
fprintf(fp1,"%lf\n",*(u+j*n+i));
}
}
fclose(fp1);*/
printf("\nPlease enter the scheme u want to use according to the following list:\n");
printf("\t1 for Gauss Elimination\n");
printf("\t2 for Richardson method\n");
printf("\t3 for Jacobi method\n");
printf("\t4 for Gauss Seidel\n");
printf("\t5 for SOR\n");
printf("\t6 for Symmetric SOR\n");
scanf("%d",&k);
if(k==5 || k==6)
{
printf("Please enter the relaxation parameter:\n");
scanf("%lf",&w);
}
machineEpsilon();
do
{
error = 0.0;
if(k==1)
{
for(i=1;i<n-1;i++)
{
for(j=1;j<m-1;j++)
{
q = (i-1)*(m-2) + j;
*(a+q*m*n+q) = -2*(dx*dx + dy*dy);
if((q-1)%(m-2)!=0)
{
*(a+q*m*n+q-1) = dx*dx;
}
if(q%(m-2)!=0)
{
*(a+q*m*n+q+1) = dx*dx;
}
if(i!=(n-2))
{
*(a+q*m*n+q+m-2) = dy*dy;
}
if(i!=1)
{
*(a+q*m*n+q-m+2) = dy*dy;
}
*(b+q) = -2*dx*dx*dy*dy;
}
}
for(j=1;j<(m-2)*(n-2);j++)
{
for(i=j+1;i<=(m-2)*(n-2);i++)
{
g = *(a+i*m*n+j)/(*(a+j*m*n+j));
*(b+i) = *(b+i) - g * *(b+j);
*(a+i*m*n+j) = 0.0;
for(q=j+1;q<=(m-2)*(n-2);q++)
{
*(a+i*m*n+q) = *(a+i*m*n+q) - g * *(a+j*m*n+q);
}
}
}
for(i=(m-2)*(n-2);i>=1;i--)
{
*(b1+i) = 0.0;
for(j=i+1;j<=(m-2)*(n-2);j++)
{
*(b1+i) += *(a+i*m*n+j) * *(x+j);
}
*(x+i) = (*(b+i) - *(b1+i))/(*(a+i*m*n+i));
}
q = 1;
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
*(u+j*n+i) = *(x+q);
q++;
}
}
break;
}
if(k==2)
{
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
r = 2*dx*dx*dy*dy + ((*(u_old+j*n+i-1) - 2 * *(u_old+j*n+i) + *(u_old+j*n+i+1))*(dy*dy))
+ ((*(u_old+(j-1)*n+i) - 2 * *(u_old+j*n+i) + *(u_old+(j+1)*n+i))*(dx*dx));
*(u+j*n+i) = *(u_old+j*n+i) + r;
}
}
}
if(k==3)
{
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
*(u+j*n+i) = 0.5*(dy*dy*(*(u_old+j*n+i-1) + *(u_old+j*n+i+1)) + dx*dx*(*(u_old+(j-1)*n+i)
+ *(u_old+(j+1)*n+i)) + 2*dx*dx*dy*dy)/(dx*dx + dy*dy);
}
}
}
if(k==4)
{
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
*(u+j*n+i) = 0.5*(dy*dy*(*(u+j*n+i-1) + *(u+j*n+i+1)) + dx*dx*(*(u+(j-1)*n+i) +
*(u+(j+1)*n+i)) + 2*dx*dx*dy*dy)/(dx*dx + dy*dy);
}
}
}
if(k==5)
{
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
ustar = 0.5*(dy*dy*(*(u+j*n+i-1) + *(u+j*n+i+1)) + dx*dx*(*(u+(j-1)*n+i) + *(u+(j+1)*n+i))
+ 2*dx*dx*dy*dy)/(dx*dx + dy*dy);
*(u+j*n+i) = w * ustar + (1-w) * *(u_old+j*n+i);
}
}
}
if(k==6)
{
for(j=1;j<m-1;j++)
{
for(i=1;i<n-1;i++)
{
ustar = 0.5*(dy*dy*(*(u+j*n+i-1) + *(u+j*n+i+1)) + dx*dx*(*(u+(j-1)*n+i) + *(u+(j+1)*n+i))
+ 2*dx*dx*dy*dy)/(dx*dx + dy*dy);
*(u+j*n+i) = w*ustar + (1-w) * *(u_old+j*n+i);
}
}
for(j=m-2;j>=1;j--)
{
for(i=n-2;i>=1;i--)
{
ustar = 0.5*(dy*dy*(*(u+j*n+i-1) + *(u+j*n+i+1)) + dx*dx*(*(u+(j-1)*n+i) + *(u+(j+1)*n+i))
+ 2*dx*dx*dy*dy)/(dx*dx + dy*dy);
*(u+j*n+i) = w*ustar + (1-w) * *(u+j*n+i);
}
}
}
if(k!=1)
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
error += pow((*(u+j*n+i) - *(u_old+j*n+i)),2);
}
}
error = sqrt(error);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
*(u_old+j*n+i) = *(u+j*n+i);
}
}
printf("error after iteration %d = %e\n",iterationCount,error);
iterationCount++;
}
}while(error>1e-06);
fp2 = fopen("solution.vtk","w");
fprintf(fp2,"# vtk DataFile Version 2.0\n");
fprintf(fp2,"Poisson's Equation\n");
fprintf(fp2,"ASCII\n");
fprintf(fp2,"DATASET STRUCTURED_GRID\n");
fprintf(fp2,"DIMENSIONS %d %d 1\n",n,m);
fprintf(fp2,"POINTS %d double\n",(n)*(m));
for(j=0;j<m;j++)
{
for(i=0;i<n;i++)
{
fprintf(fp2,"%lf %lf 0.0\n",i*dx,j*dy);
}
}
fprintf(fp2,"POINT_DATA %d\n",n*m);
fprintf(fp2,"SCALARS u double\n");
fprintf(fp2,"LOOKUP_TABLE default\n");
for(j=0;j<m;j++)
{
for(i=0;i<n;i++)
{
fprintf(fp2,"%lf\n",*(u+j*n+i));
}
}
fclose(fp2);
}
void machineEpsilon()
{
eps = 1.0;
while((1+eps)!=1)
{
eps = eps*0.5;
}
//printf("Machine Epsilon = %e\n\n",eps);
}