Fortran Error: 'y' argument of 'datan2' intrinsic at (1) must be REAL

后端 未结 1 2069
深忆病人
深忆病人 2021-01-26 21:03

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           


        
相关标签:
1条回答
  • 2021-01-26 21:21

    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:

    • 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.
    0 讨论(0)
提交回复
热议问题