I have written a SOR algorithm to solve the Laplace equation on a 2d grid. The outside of the grid is fixed at 0 and the central square is fixed at 10.
I can obtain the fully converged solution for some values of the relaxation parameter $\beta$ but not others. In the other cases the convergence condition is never met and thus iterates to infinity. I suspect it is related to floating point/precision error but I don't know how to avoid it.
The condition is as follows: $$r = \sum_{i}\sum_{j}\left|V_{i,j}^{n+1}-V_{i,j}^{n}\right| \\ \frac{r}{n}<c$$ Where $n$ is the number of non-fixed points and $c$ is a small finite value. Basically, it should converge when the average pointwise change in the solution is smaller than $c$.
//Successive over-relaxation. argument b is the relaxation parameter.
unsigned int sor(double *v,double b) {
short i,j,t=1;
unsigned int s=0;
double l,r,n=((N-2)*(N-2)-1);
while (t) {//t is true when non-converged
r = 0.0;
for (i=1;i<N-1;i++) {
for (j=1;j<N-1;j++) {
if (i!=N/2 || j!=N/2) {
l = (*(v+N*(i+1)+j) + *(v+N*(i-1)+j) + *(v+N*i+j+1) + *(v+N*i+j-1))*0.25;
r += fabs(b*(l-*(v+N*i+j))); //add to residual
*(v+N*i+j) += b*(l-*(v+N*i+j)); //update new value
}
}
}
if (r/n<c) {t = 0;} //check convergence
s++;
if (s==USHRT_MAX) {t = 0;} //iteration limit is reached for some values of b. It will go higher than this, but USHRT_MAX is well beyond what is expected
}
return s;
}
The grid is $N\times N$ (defined elsewhere in the program). Ideally, c=DBL_EPSILON
. It converges well when $\beta=1$ (Gauss-Seidel) and some other values but not universally. It converges more consistently when c
is made larger but it still fails in certain areas.
It has a tendency to blow up around $\beta\geq1.5$. For larger grid sizes this means the optimal parameter is not found since convergence is never reached. In the attached image $c$ is machine epsilon.
UPDATE: I suspect $\beta=1.5$ is significant to the problem. When the numbers become very small, multiplying by anything larger than 1.5 will cause numbers to be rounded up significantly. Effectively, a $\beta$ of 1.5 will start to behave like a $\beta=2$, for which SOR will never converge...
The question is: How do I avoid this?
if (i!=N/2 || j!=N/2) {
? $\endgroup$