Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Type mismatch problem FORTRAN 77

  1. Jul 20, 2012 #1
    Hi all,

    I am trying to run a long FORTRAN 77 code in my laptop. Document contains a makefile and it is instructed to use 'make pgi' command to compile. Beside many warnings, each time I enter that command, it returns me ' Return type mismatch of function 'cmod' at (1) (REAL(4)/REAL(8))
    analsubs.f90:766.13'

    The relevant part of the code is:
    REAL*8 FUNCTION ERREV(NN,QR,QI,MS,MP,ARE,MRE)
    REAL*8 QI(NN), QR(NN),MS,MP,ARE,MRE,E
    E =CMOD(QR(1),QI(1))*MRE/(ARE+MRE)
    DO 10 I=1,NN
    E = E*MS+CMOD(QR(I),QI(I))
    10 CONTINUE
    ERREV = E*(ARE+MRE)-MP*MRE
    END FUNCTION errev

    and part for 'cmod' is:

    REAL*8 FUNCTION CMOD(R,I)
    REAL*8 R,I,AR,AI,DABS,DSQRT
    AR = DABS(R)
    AI = DABS(I)
    IF (AR .GE. AI) GO TO 10
    CMOD = AI*DSQRT(1.0D0+(AR/AI)**2)
    RETURN
    10 IF (AR .LE. AI) GO TO 20
    CMOD = AR*DSQRT(1.0D0+(AI/AR)**2)
    RETURN
    20 CMOD = AR*DSQRT(2.0D0)
    END FUNCTION cmod

    I don't understand the reason of the error since I believe that both AR and AI in cmod are defined in type REAL*8. Is there anyone who has an idea about it?

    Thanks in advance,
    Batu
     
  2. jcsd
  3. Jul 20, 2012 #2
    Stop using "D" as a prefix in the intrinsic functions and tell me what happens.

    Also, please post the entire error message...I am sure that "1" is strategically placed under some line to indicate exactly where fortran thinks the problem is.
     
  4. Jul 20, 2012 #3

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    I don't thinkg gsal's advaice is relevant. (the D prefixes might not be necessary, but that doesn't make them wrong!)

    You need to add the line
    REAL*8 CMOD
    in function ERREV. Each function or subroutine of a Fortran program is compiled independet of everyting else. You didn't declare the type of CMOD in ERREV, so the compiler assumes it is REAL*4. Later, when all the functions are linked together to make the executable program, that turns out to be wrong and you get the error.
     
  5. Jul 21, 2012 #4
    I admit, maybe the removal of "D" is not quite the best thing to do...I forgot that you are using Fortran77....I think in Fortran90 (and beyond), the "D" would be unnecessary since Fortran90 can choose the correct function for you automatically.

    By the way, how long is you code? I don't know about you but, after a better look at the source, I wouldn't resist the urge to modernize it. You might be using Fortran77, but it looks like this code was written in Fortran66 at most...that spaghetti code with the GOTO's gives it away...it's confusing to figure out what's supposed to be done when. I would also stop using uppercase all over, it's just make the screen so crowded.

    You can start by explicitly writing it out and THEN optimize a bit. For example, first shot:
    Code (Text):

    real*8 function cmod(r,i)
        real*8 r,i,ar,ai,dabs,dsqrt
       
        ar = dabs(r)
        ai = dabs(i)
       
        if (ar .lt. ai) then
            cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
            return
        end if
       
        if (ar .gt. ai) then
            cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
            return
        end if

        if (ar .eq. ai) then
            cmod = ar*dsqrt(2.0d0)
            return
        end if    
       
    end function cmod    
     
    Then again, the "if (ar .eq. ai) then" is not quite necessary since both of the previous equations would turn into this one for the case when ar.eq.ai; so, we could turn one of the other two into ".le." or ".ge."

    Code (Text):

    real*8 function cmod(r,i)
        real*8 r,i,ar,ai,dabs,dsqrt
       
        ar = dabs(r)
        ai = dabs(i)
       
        if (ar .le. ai) then
            cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
            return
        end if
       
        if (ar .gt. ai) then
            cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
            return
        end if
       
    end function cmod    
     
    Now, the two "IF" statements lend themselves to be put into a single "IF-THEN-ELSE" block

    Code (Text):

    real*8 function cmod(r,i)
        real*8 r,i,ar,ai,dabs,dsqrt    
       
        ar = dabs(r)
        ai = dabs(i)
       
        if (ar .le. ai) then
            cmod = ai*dsqrt(1.0d0+(ar/ai)**2)
        else
            cmod = ar*dsqrt(1.0d0+(ai/ar)**2)
        end if
       
        return
    end function cmod
     
    ...now, that's a nice looking function :-)

    my 2 cents
     
  6. Jul 21, 2012 #5
    Adding the line REAL*8 CMOD solved the problem and this time I didn't get any error message. I thank you very much for the advice AlephZero.

    gsal, the file is about 1500 lines long and worse is that I didn't write the code. This is a part of my project and I am trying to make it run first. Fortran 77, says the manual:) I do appreciate your help and will most probably change the parts as the way you have suggested if there will be no license issues.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Type mismatch problem FORTRAN 77
  1. Fortran 77 problem! (Replies: 7)

  2. Fortran 77 (Replies: 1)

Loading...