本文介绍了Fortran错误:(1)固有的'datan2'的'y'参数必须为REAL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to calculate z value as the coordinate in range of x:-50~50 and y:-50~50 like below code.

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)中.我应该如何更改这些代码?

But I couldn't make it work like below error. I think because i, j are in datan(i,j). How should I change these code?

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

推荐答案

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

Inspired by the comments of @Rodrigo Rodrigues, @Ian Bush, and @Richard, here is a suggested rewrite of the code segment from @SW. Kim

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

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

Specifically, the following changes were made with respect to the original code posted:

  • 对问题的最小更改:将integer变量ij转换为real值,以便在实值函数datandsqrt中使用它们.
  • 为内在过程使用通用名称,即sqrt代替dsqrtatan代替datansin代替dsin.这种方法的一个好处是,可以在一个地方更改工作精度wp的类型,而无需在代码中的其他地方进行显式更改.
  • 定义real变量的kind并将其命名为wp.可以在此站点上找到对该主题及其含义和后果的详细讨论,例如,此处此处. @Steve Lionel还在他的博客,他的一般建议是使用selected_real_kind.
  • pi定义为parameter一次,而不是在嵌套的for循环中重复计算相同的值.
  • Minimum change to answer the question: casting integer variables i and j to real values for using them in the real valued functions datan and dsqrt.
  • Using generic names for intrinsic procedures, i.e sqrt instead of dsqrt, atan instead of datan, and sin instead of dsin. One benefit of this approach, is that the kind of working precision wp can be changed in one place, without requiring explicit changes elsewhere in the code.
  • Defining the kind of real variables and calling it wp. Extended discussion of this topic, its implications and consequences can be found on this site, for example here and here. Also @Steve Lionel has an in depth post on his blog, where his general advice is to use selected_real_kind.
  • Defining pi as a parameter calculating its value once, instead of calculating the same value repeatedly within the nested for loops.

这篇关于Fortran错误:(1)固有的'datan2'的'y'参数必须为REAL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 01:39