雅可比方法收敛然后发散

时间:2015-09-01 02:56:52

标签: algorithm fortran numeric numerical-methods

我正在努力使用雅可比方法求解泊松方程(在2d轴对称圆柱坐标系中)。 L2范数从第一次迭代的~1E3(我的猜测非常糟糕)减少到非常慢的~0.2。然后,L2范数在多次迭代中开始增加。

我的几何结构是平行板,两个板上的r = 0处都有尖点。 (如果那很重要)。

我的代码中是否有错误?我需要使用其他算法吗? (我还没有工作的DADI算法。)

这是我的Jacobi方法算法。然后这只是在一个while循环中。

subroutine Jacobi(PoissonRHS, V, resid)
implicit none
real, dimension(0:,0:) :: PoissonRHS, V
REAL resid
integer :: i,j, lb, ub
real, dimension(0:size(V,1)-1, 0:size(V,2)-1) :: oldV

real :: dr = delta(1)
real :: dz = delta(2)

real :: dr2 = (delta(1))**(-2)
real :: dz2 = (delta(2))**(-2)

integer :: M = cells(1)
integer :: N = cells(2)


oldV = V
!Note: All of the equations are second order accurate

!If at r = 0 and in the computational domain
! This is the smoothness condition, dV(r=0)/dr = 0
    V(0,:) = (4.0*oldV(1,:)-oldV(2,:))/3.0

!If at r = rMax and in the computational domain
! This is an approximation and should be fixed to improve accuracy, it should be
! lim r->inf V' = 0, while this is V'(r = R) = 0
    V(M, 1:N-1) = 0.5 / (dr2 + dz2) * (     &
        (2.0*dr2)*oldV(M-1,1:N-1) +         &
        dz2 * (oldV(M,2:N) + oldV(M,0:N-2)) &
        - PoissonRHS(M,1:N-1))

do i = 1, M-1
    lb = max(0, nint(lowerBoundary(i * dr) / dz)) + 1
    ub = min(N, nint(upperBoundary(i * dr) / dz)) - 1

    V(i,lb:ub) =  0.5 / (dr2 + dz2) * ( &
        ((1.0 - 0.5/dble(i))*dr2)*oldV(i-1,lb:ub) + &
        ((1.0 + 0.5/dble(i))*dr2)*oldV(i+1,lb:ub) + &
        dz2 * (oldV(i,lb+1:ub+1) + oldV(i,lb-1:ub-1)) &
        - PoissonRHS(i,lb:ub))

    V(i, 0:lb-1) = V0
    V(i, ub+1:N) = VL
enddo

!compare to old V values to check for convergence
resid = sqrt(sum((oldV-V)**2))

return
end subroutine Jacobi

1 个答案:

答案 0 :(得分:1)

基于额外的读数,它似乎是一个精确的问题。因为(例如),我有表达式

  ...  
  <activity
        android:name=".SwitchActivity"
        android:excludeFromRecents="true"
        android:label="@string/title_activity_switch"
        android:noHistory="true"
        android:launchMode="singleTask"
        android:clearTaskOnLaunch="true"
        android:stateNotNeeded="true"
        android:theme="@android:style/Theme.NoDisplay">
  ...

其中 V(i,lb:ub) = 0.5 / (dr2 + dz2) * ( & ((1.0 - 0.5/dble(i))*dr2)*oldV(i-1,lb:ub) + & ((1.0 + 0.5/dble(i))*dr2)*oldV(i+1,lb:ub) + & dz2 * (oldV(i,lb+1:ub+1) + oldV(i,lb-1:ub-1)) & - PoissonRHS(i,lb:ub)) dr2非常大。因此,通过分发这些,我得到的条件是〜1,代码收敛(缓慢,但这是数学的函数)。

所以我的新代码是

dz2