【问题标题】:F90 compiler dependent codeF90 编译器相关代码
【发布时间】:2014-02-13 17:05:58
【问题描述】:

我尝试运行我的 f90 代码。它是旧 f77 代码的转换版本。

当我尝试使用不同的编译器(IFORT、GFORTRAN)编译它时,我有两个不同的结果: 用两个编译器自己运行程序,看看,例如 GNUplot,情节:

plot 'orbitm.txt' u 1:2

使用两个编译器,绘图的输出非常不同!

我认为这种不同(也)依赖于COMMON 命令,我尝试用MODULE 替换它,但我发现了一些错误。

我按照 cmets 的建议对我的代码进行了一些更改:

     module data
      REAL*8 :: OME = 1.D0
      REAL*8 :: MU = 0.000954
     end module


      PROGRAM MAIN
      use data
      IMPLICIT NONE
      REAL*8  :: dist0 , dt , duepi , e , e0 , ermed , errh , H , k_max_r8
      REAL*8  :: ptau , ptau0 , px , px0 , py , py0 , t , tau , tau0 , n_step_r8
      REAL*8  :: t_per, x , x0 , y , y0, k_r8 , m_per
      INTEGER :: k , k_max  , n_step

      duepi = 8.d0*DATAN(1.D0)
      !duepi = 2.d0*3.1415926535897932d0
      t_per = duepi/OME
      n_step = 1000

!         do iX0=1,6
!          do iY0=-50,50

!       x0 = (0.5d0-MU)+(0.0001*iX0) !và da 0.449 a 0.599
!                y0 = (sqrt(3.d0)/2.d0)+(0.0001*iY0) ! va da 0.868 a 0.864

      OPEN (UNIT=11,FILE='orbitm.txt') 
      x0 = 0.47
      y0 = SQRT(3.D0)/2.D0
      tau0 = 0.d0
      px0 = OME*y0
      py0 = -OME*x0
      ptau0 = 1.d0

      x = x0
      y = y0
      tau = tau0
      px = px0
      py = py0
      ptau = ptau0
      n_step_r8 = real(n_step)
      dt = t_per/n_step_r8
      e0 = H(x,y,tau,px,py,ptau)

      k_max = 1000*n_step

      k = 0
      t = 0.d0
      errh = 0.d0

!---------
!  inizio loop integrazione
!--------
      ermed = 0.d0

      DO k = 1 , k_max
         k_r8 = real(k)
         CALL SYM4(x,y,tau,px,py,ptau,dt)
         e = H(x,y,tau,px,py,ptau)
         errh = ABS(e-e0)
         t = k_r8*dt
         IF ( MOD(k,n_step).EQ.0 ) THEN
            WRITE (11,'(4g12.5)') x , y , px , py
         ENDIF
      ENDDO
      k_max_r8 = real(k_max)



      DO k = 1 , k_max
         CALL SYM4(x,y,tau,px,py,ptau,-dt)
         e = H(x,y,tau,px,py,ptau)
         errh = ABS(e-e0)
         t = t - dt
      ENDDO
!           write(*,*) ix0,ermed,errh
!              enddo ! iY0
!            enddo ! iX0

!           close(11)
      END


      REAL*8 FUNCTION H(X,Y,Tau,Px,Py,Ptau)
      use data
      IMPLICIT NONE
      REAL*8 :: c , Ptau , Px , Py , r1 , r2 , s , Tau , X , Y

      c = COS(OME*Tau)
      s = SIN(OME*Tau)

      r1 = SQRT((X+MU*c)**2+(Y-MU*s)**2)
      r2 = SQRT((X-(1.d0-MU)*c)**2+(Y+s*(1.d0-MU))**2)

      H = (Px*Px)/2.D0 + (Py*Py)/2.D0 + Ptau - (1.d0-MU)/r1 - MU/r2

      END


      SUBROUTINE F(X,Y,Tau,Fx,Fy,Ftau)
      use data
      IMPLICIT NONE
      REAL*8 :: c, Ftau , Fx , Fy , r1 , r2 , s , Tau , X , Y

      c = COS(OME*Tau)
      s = SIN(OME*Tau)

      r1 = SQRT((X+MU*c)**2+(Y-MU*s)**2)
      r2 = SQRT((X-(1.d0-MU)*c)**2+(Y+s*(1.d0-MU))**2)


      Fx = -((1.d0-MU)*(X+MU*c))/r1**3 - (MU*(X-c*(1.d0-MU)))/r2**3
      Fy = -((1.d0-MU)*(Y-MU*s))/r1**3 - (MU*(Y+s*(1.d0-MU)))/r2**3

      Ftau = -( (1.d0-MU)*OME*MU*(-s*(X+MU*c)-c*(Y-MU*s)) )/r1**3.d0 - ( MU*(1.d0-MU)*OME*(s*(X-(1.d0-MU)*c)+c*(Y+(1.d0-MU)*s)) )/r2**3.d0

      END



      SUBROUTINE SYM2(X,Y,Tau,Px,Py,Ptau,Dt)
      IMPLICIT NONE
      REAL*8 :: Dt , ftau , ftaunew , fx , fxnew , fy , fynew , Ptau
      REAL*8 :: ptaunew , Px , pxnew , Py , pynew , Tau , taunew , X
      REAL*8 :: xnew , Y , ynew

      CALL F(X,Y,Tau,fx,fy,ftau)


      xnew = X + Px*Dt + fx*(Dt**2.d0)/2.D0

      ynew = Y + Py*Dt + fy*(Dt**2.d0)/2.D0

      taunew = Tau + Dt

      CALL F(xnew,ynew,taunew,fxnew,fynew,ftaunew)
      pxnew = Px + Dt*(fx+fxnew)/2.D0
      pynew = Py + Dt*(fy+fynew)/2.D0
      ptaunew = Ptau + Dt*(ftau+ftaunew)/2.D0

      X = xnew
      Y = ynew
      Tau = taunew
      Px = pxnew
      Py = pynew
      Ptau = ptaunew

      END

      SUBROUTINE SYM4(X,Y,Tau,Px,Py,Ptau,Dt)
      IMPLICIT NONE
      REAL*8 :: alpha , beta , Dt , dt1 , dt2 , Ptau , Px , Py , sq2
      REAL*8 :: Tau , X , Y
      sq2 = 2.d0**(1.D0/3.D0)
      alpha = 1.D0/(2.d0-sq2)
      beta = sq2/(2.d0-sq2)
      dt1 = Dt*alpha
      dt2 = -Dt*beta
      CALL SYM2(X,Y,Tau,Px,Py,Ptau,dt1)
      CALL SYM2(X,Y,Tau,Px,Py,Ptau,dt2)
      CALL SYM2(X,Y,Tau,Px,Py,Ptau,dt1)
      END

现在 IFORT 和 GFORTRAN 之间的编译差异很小但不等于零。 是否可以通过其他方式对代码进行更多改进,例如:更改调用或函数、拆分子程序或引入其他模块?

非常感谢!

【问题讨论】:

  • 在两个编译器上运行 F77 版本有什么不同吗?
  • 在我看来,这两个文件都像是从(0,0) 到大约(48000,13000) 的直线。我应该看到什么样的“非常不同”的东西?
  • 我当然不会运行你的代码并仔细研究它的内部来发现问题。你自己做了什么来找到它?如果你真的认为是 common 块,为什么不简单地用每个范围内的参数替换它,它只包含两个变量?
  • 这里的common 看起来很安全,因为它出现在主程序中。采用添加调试写入的旧方法并跟踪实际问题所在,而不是根据猜测进行更改。
  • 如果您要解决微妙的数字问题,我建议您明确指定文字的精度,例如。 mu=0.001D0

标签: fortran fortran90 gfortran intel-fortran fortran77


【解决方案1】:

我建议插入中间输出语句并查看结果首先出现分歧的位置。可能性:仅在一个编译器中显示的错误。您可能会看到突然的、离散的变化。尝试找出最先发生变化的地方,以此作为问题的线索。或者差异可能是算法中数值不稳定的结果。在这种情况下,差异将开始非常小并增长。两个编译器生成的可执行文件的数值运算顺序可能不完全相同,这可能会在某些计算中产生差异。

我发现将旧版 FORTRAN 77 代码移植到现代编译器的一个常见问题是,许多旧版 FORTRAN 77 程序假定所有局部变量都是 saveed。语言标准过去和现在都不能保证这是一种常见的行为。您可以使用编译器选项恢复该行为。见Are local variables in Fortran 77 static or stack dynamic?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2016-01-29
    • 1970-01-01
    相关资源
    最近更新 更多