Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SOR程序不收敛(FORTRAN到C转换)_C_Fortran - Fatal编程技术网

SOR程序不收敛(FORTRAN到C转换)

SOR程序不收敛(FORTRAN到C转换),c,fortran,C,Fortran,我们正在尝试将FORTRAN程序转换为C。这是一个SOR实现,它应该在大约200次迭代中收敛,但C代码不起作用。大约在第100次迭代时,它变得“奇怪”(它开始非常缓慢地收敛) 以下是原始代码: PROGRAM Main ! *** Solution of Laplace's Equation. ! *** ! *** Uxx + Uyy = 0 ! *** 0 <= x <= pi, 0 <= y <= pi ! *** U(x,pi) = sin(x), U(

我们正在尝试将FORTRAN程序转换为C。这是一个SOR实现,它应该在大约200次迭代中收敛,但C代码不起作用。大约在第100次迭代时,它变得“奇怪”(它开始非常缓慢地收敛)

以下是原始代码:

PROGRAM Main

! ***  Solution of Laplace's Equation.
! ***
! ***  Uxx + Uyy = 0
! ***  0 <= x <= pi, 0 <= y <= pi
! ***  U(x,pi) = sin(x), U(x,0) = U(0,y) = U(pi,y) = 0
! ***
! ***  then U(x,y) = (sinh(y)*sin(x)) / sinh(pi)
! ***
! ***  Should converge with
! ***            tol = 0.001 and M = 20  in  42 iterations.
! ***   and with tol = 0.001 and M = 100 in 198 iterations.
! *** 

  INTEGER M
  PARAMETER (M   = 100)

  REAL*8   PI
  REAL*8   DATAN
  REAL*8   unew(0:M+1,0:M+1), uold(0:M+1,0:M+1)
  REAL*8   solution(0:M+1,0:M+1)
  REAL*8   omega, tol, h
  INTEGER  i, j, iters

  PI = 4.0D0*DATAN(1.0D0)

  h = PI/FLOAT(M+1)

  DO i=0,M+1
     uold(i,M+1) = SIN(FLOAT(i)*h)
  END DO

  DO i=0,M+1
     DO j=0,M
        uold(i,j) = FLOAT(j)*h*uold(i,M+1)
     END DO
  END DO

  DO i=0,M+1
     DO j=0,M+1
        solution(i,j) = SINH(FLOAT(j)*h)*SIN(FLOAT(i)*h)/SINH(PI)
     END DO
  END DO

  omega = 2.0/(1.0+SIN(PI/FLOAT(M+1)))
  tol   = 0.001

  CALL SOR (unew, uold, solution, omega, tol, m, iters)

  PRINT *, " "
  PRINT *, " Omega = ", omega
  PRINT *, " It took ", iters, " iterations."

  STOP
END PROGRAM Main


REAL*8 FUNCTION ComputeError (solution, u, m, iters)

  INTEGER m, iters
  REAL*8  u(0:m+1,0:m+1)
  REAL*8  solution(0:m+1,0:m+1)

! *** Local variables

  REAL*8  error
  INTEGER i, j

  error = 0.0

  DO j=1,m
     DO i=1,m
        error = MAX(error, ABS(solution(i,j)-u(i,j)))
     END DO
  END DO

  PRINT *, "On iteration ", iters, " error = ", error

  ComputeError = error

  RETURN
END FUNCTION ComputeError

SUBROUTINE SOR (unew, uold, solution, omega, tol, m, iters)

  INTEGER m, iters
  REAL*8  unew(0:m+1,0:m+1), uold(0:m+1,0:m+1)
  REAL*8  solution(0:m+1,0:m+1)
  REAL*8  omega, tol

! *** Local variables

  REAL*8  error
  INTEGER i, j

! *** External function.

  REAL*8   ComputeError
  EXTERNAL ComputeError

! *** Copy bonudary conditions.

  DO i=0,m+1
!     print *,i
     unew(i,m+1) = uold(i,m+1)
     unew(m+1,i) = uold(m+1,i)
     unew(i,  0) = uold(i,  0)
     unew(0,  i) = uold(0,  i)
  END DO

! *** Do SOR until 'tol' satisfied.

  iters = 0
  error = ComputeError (solution, uold, m, iters)

  DO WHILE (error .GE. tol)

! *** Do one iteration of SOR

     DO j=1,m
        DO i=1,m
           unew(i,j) = uold(i,j) + 0.25*omega* &
                (unew(i-1,j) + unew(i,j-1) + &
                uold(i+1,j) + uold(i,j+1) - &
                4.0*uold(i,j))
        END DO
     END DO

! *** Copy new to old.

     DO j=1,m
        DO i=1,m
           uold(i,j) = unew(i,j)
        END DO
     END DO

! *** Check error every 20 iterations.

     iters = iters + 1

     IF (MOD(iters,2) .EQ. 0) THEN
        error = ComputeError (solution, uold, m, iters)
     END IF

  END DO

  RETURN
END SUBROUTINE SOR
主程序
! ***  拉普拉斯方程的解。
! ***
! ***  Uxx+Uyy=0

! *** 0您对iters有问题,您正在通过值传递,但它看起来应该通过引用传递(即作为C中的指针)。(请注意,gcc会为此生成一个警告-请确保您正在使用
-Wall
进行编译,以捕获此类问题。)

看起来你也误译了这句话:

h = pi / (M + 1);
它很可能是:

h = pi / (M + 2);
通过此更改,我在196次迭代后获得收敛:

...
On iteration 192 error = 0.001293
On iteration 194 error = 0.001104
On iteration 196 error = 0.000930

 Omega = 1.939676
 It took 196 iterations.
(这还包括对
iters
bug的修复)


当然,可能还有其他的bug需要修复…

可能不是直接的问题,但是您的
iters
有一个问题,您通过值传递它,但它看起来应该通过引用传递(即作为C中的指针)。请注意,gcc会为此生成警告-请确保您是使用
-Wall
编译的。为什么要将Fortran代码转换为这样一个简单的经典问题?有几十个C实现。@VladimirF这是一些类的额外练习。@VladimirF:OK-在
iters
单独修复后,它仍然没有收敛,但是修复
h
计算似乎也能解决问题。实际上,这取决于你如何度量收敛。因为在这里,你用真正的解来衡量它,它实际上以前没有收敛。它实际上收敛到了一个错误的解,一些测量收敛性的方法会显示它也在收敛。干杯,伙计!你真棒!
...
On iteration 192 error = 0.001293
On iteration 194 error = 0.001104
On iteration 196 error = 0.000930

 Omega = 1.939676
 It took 196 iterations.