I am trying to solve the Poisson equation numerically using the FDM method in C++. But I have a little confusion with the iterative process. I understand that the number of iterations should go until the solution converges, but how to calculate if the error is greater/less than the tolerance level? Here is a small piece of code I tried in C++ but it is flawed. I checked some other codes posted online and some has calculated the average of the residual values in a matrix and checked accordingly. I'd appreciate it if anyone could help me with the concept.

void calculate_voltage(){
    voltage_initialization();   //creating a matrix V and initilizing with Dirchilet's boundary condition
    double tolerance = pow(10,-5);
    bool done = true;
    int itr = 0;
    double pi = 3.14;
    double t = cos(pi/nx) + cos(pi/ny);
    double omega = (8 - sqrt(64 - 16*pow(t,2)))/(pow(t,2));  //relaxation parameter
    while(done == true){
        itr ++;
        for(int i = 1;i<nx-1;i++){
            for(int j = 1;j<ny-1;j++)
                double vv = (V[i-1][j] + V[i+1][j] + V[i][j-1] + V[i][j+1] + step_size_ * source[i][j])/4.0; 
                double R = vv - V[i][j];     //residual for SOR
                if(abs(R) <= tolerance){done = false;}        //to check if the correction converges or not
                V[i][j] = V[i][j] + omega* R;           //new V
  • 1
    $\begingroup$ What you are doing here is basically if at any point the residual is less than tolerance, stop. You should use norm of the residual vector as an indicator. I guess easiest for you would be max residual or l2-norm of the residual. $\endgroup$ – Abdullah Ali Sivas Jul 20 '20 at 18:53
  • $\begingroup$ I would suggest that you also add a "pessimistic" stop criterion to your code. The most common would be maximum number of iterations allowed. $\endgroup$ – nicoguaro Jul 20 '20 at 21:47
  • $\begingroup$ @nicoguaro you mean without calculating the tolerance? $\endgroup$ – Ritika Shrestha Jul 21 '20 at 7:01
  • $\begingroup$ @AbdullahAliSivas I referred to a code posted online and took the average of the residuals over the loop. I should create a residual vector and check the norm too. $\endgroup$ – Ritika Shrestha Jul 21 '20 at 7:04
  • $\begingroup$ No, you do both. The idea is to obtain convergence, but if you don't in the number of iterations given, you stop. $\endgroup$ – nicoguaro Jul 21 '20 at 13:47

Since you're solving the linear poisson equation $Ax = b$ I'd just check that the L2-norm of the residual vector illustrates convergence. I think the best thing to do is to calculate the initial norm $\rho_0 = ||b||_2$ and then have two tolerances, one relative ($\epsilon_r$) and one absolute ($\epsilon_a$) and you would terminate if either of them is satisfied. So if $\frac{\rho_i}{\rho_0} < \epsilon_r$ or if $\rho_i < \epsilon_a$ where $\rho_i = ||b - Ax_i||_2$. You could also use the max value of the residual to check (the infinity norm), but the most commonly used ones is the 2-norm, and this extends nicely to GMRES and other krylov solvers. regarding actual values, I'd say try an initial absolute tolerance of $1e-14$ and relative of $1e-12$ and see if that works. You can also plot convergence as a function of iterations which may be instructive.

  • 1
    $\begingroup$ Thank you. I checked the L2-norm and it worked. The convergence is fast too. $\endgroup$ – Ritika Shrestha Jul 21 '20 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.