Fortran错误:(1)固有的'datan2'的'y'参数必须为REAL

时间:2018-12-20 05:21:03

标签: fortran fortran90

我想像下面的代码一样,将x值作为x:-50〜50和y:-50〜50范围内的坐标来计算。

program test
implicit none
! --- [local entities]
      real*8            :: rrr,th,U0,amp,alp,Ndiv
      real*8            :: pi,alpR,NR,Rmin,Rmax,z
      integer           :: ir, i, j

do i=0, 50
  do j=0, 50
      th=datan2(i,j)
      pi=datan(1.d0)*4.d0
!
      Ndiv= 24.d0            !! Number of circumferential division
      alp = 90.d0/180.d0*pi  !! phase [rad]
      U0  = 11.4d0           !! average velocity
      amp = 0.5d0            !! amplitude of velocity
      Rmin = 10              !! [m] 
      Rmax = 50              !! [m]
      NR = 6.d0              !! Number of radial division
!
      rrr=dsqrt(i**2+j**2)
      ir=int((rrr-Rmin)/(Rmax-Rmin)*NR)
      alpR=2.d0*pi/dble(Ndiv)*dble(mod(ir,2))
      z=U0*(1.d0+amp*dsin(0.5d0*Ndiv*th+alp+alpR))

  write(*,*) 'i, j, z'
  write(*,*) i, j, z 
 end do
end do

stop
end program test

但是我无法使它像下面的错误一样工作。我认为是因为i,j在datan(i,j)中。我应该如何更改这些代码?

test.f90:10.16:

      th=datan2(i,j)
                1
Error: 'y' argument of 'datan2' intrinsic at (1) must be REAL
test.f90:21.16:

      rrr=dsqrt(i**2+j**2)
                1
Error: 'x' argument of 'dsqrt' intrinsic at (1) must be REAL

1 个答案:

答案 0 :(得分:2)

受@Rodrigo Rodrigues,@ Ian Bush和@Richard的评论的启发,这里建议对@SW的代码段进行重写。金

program test
    use, intrinsic :: iso_fortran_env, only : real64
    implicit none
    ! --- [local entities]
    ! Determine the kind of your real variables (select one):
    !   for specifying a given numerical precision
    integer, parameter  :: wp = selected_real_kind(15, 307)  !15 digits, 10**307 range
    !   for specifying a given number of bits
    ! integer, parameter  :: wp = real64

    real(kind=wp), parameter    :: pi = atan(1._wp)*4._wp
    real(kind=wp)               :: rrr, th, U0, amp, alp, Ndiv
    real(kind=wp)               :: alpR, NR, Rmin, Rmax, z
    integer                     :: ir, i, j

    do i = 0, 50
        do j = 0, 50
            th = atan2(real(i, kind=wp), real(j, kind=wp))
    !
            Ndiv= 24._wp             !! Number of circumferential division
            alp = 90._wp/180._wp*pi  !! phase [rad]
            U0  = 11.4_wp            !! average velocity
            amp = 0.5_wp             !! amplitude of velocity
            Rmin = 10                !! [m]
            Rmax = 50                !! [m]
            NR = 6._wp               !! Number of radial division
    !
            rrr = sqrt(real(i, kind=wp)**2 + real(j, kind=wp)**2)
            ir = int((rrr - Rmin) / (Rmax - Rmin) * NR)
            alpR = 2._wp * pi / Ndiv * mod(ir, 2)
            z = U0 * (1._wp + amp * sin(0.5_wp * Ndiv * th + alp + alpR))
    !
            write(*,*) 'i, j, z'
            write(*,*) i, j, z
        end do
    end do

    stop
end program test

具体来说,对发布的原始代码进行了以下更改:

  • 对问题的最小更改:将integer变量ij转换为real的值,以便在实值函数datan和{中使用它们{1}}。
  • 为内在过程使用通用名称,即dsqrt代替sqrtdsqrt代替atandatan代替sin 。这种方法的一个好处是,可以在一个地方更改工作精度dsin的类型,而无需在代码的其他地方进行显式更改。
  • 定义wp变量中的kind并将其命名为real。可以在此站点上找到有关此主题及其含义和后果的扩展讨论,例如herehere。另外,@ Steve Lionel在他的blog上有一篇深入的文章,他的一般建议是使用wp
  • selected_real_kind定义为pi,一次计算其值,而不是在嵌套的for循环中重复计算相同的值。