Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
610 views
in Technique[技术] by (71.8m points)

fortran - Function return type mismatch

I'm attempting to recode an old C++ program in Fortran to make use of LAPACK (I'm aware that C++ does have LAPACK++, but I'm having a lot of trouble installing it, so I gave up).

I originally didn't have any problems with compilation, but that was when I had all variables declared as REAL. When I started coding the section of the program that required LAPACK, I found that all parameters passed to DSYEV need to be DOUBLE PRECISION. So I tried to change everything to double precision (including changing all hard coded numbers to their double precision counterparts, i.e. 0.0 -> 0.0D0) Now when I try to compile, I get the following error for all of the functions and subroutines that I've written:

    Error: Return type mismatch of function <function> at (1) (REAL(4)/REAL(8))

I'm not sure where this is coming from, as everything in the program has been changed to double precision.

For example, I've declared the following:

double precision :: alpha(3),d(3),zeta1,zeta2
double precision :: A1(3),A2(3),D1(3),D2(3)
double precision :: PI
PI = 3.14159265359D0
alpha = (/0.109818D0, 0.405771D0, 2.22766D0/)
d = (/0.444635D0, 0.535328D0, 0.154329D0 /)

do 10 i=1,3

A1(i) = alpha(i)*zeta1**2.0D0
A2(i) = alpha(i)*zeta2**2.0D0
D1(i) = d(i)*(2.0D0*A1(i)/PI)**(3.0D0/4.0D0)
D2(i) = d(i)*(2.0D0*A2(i)/PI)**(3.0D0/4.0D0)

10  continue

And the function:

subroutine createS(S,A1,A2,D1,D2,r)
double precision A1(3),A2(3),D1(3),D2(3) 
double precision r
double precision S(2,2)
integer :: i,j
S(1,1) = 1.0D0
S(2,2) = 1.0D0
do 80 i=1,3
do 90 j=1,3

S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)

 90 continue
 80 continue
S(2,1) = S(1,2)
return
end

double precision function getS(a,b,r)
double precision :: PI
double precision a,b,r
double precision :: S
PI = 3.14159265359D0
S = (PI/(a+b))**1.5D0
S = S*dexp(-(a*b*r*r)/(a+b))
getS = S
return
end

And then I get the error

  HFSTO3G.f:85.28:

  S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)                 
                        1
  Error: Return type mismatch of function 'gets' at (1) (REAL(4)/REAL(8))

I'm using gfortran to compile. Could that be the issue? I'm not new to programming, but new to Fortran. Not programming this in Fortran is not an option.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Did you put your subroutines and functions into a module and use that module? Otherwise, probably what is occurring is that you are getting implicit typing of getS in subroutine createS as a single precision real but it actually returns a double precision. Another suggestion: always use implicit none to find undeclared variable. In case you forget to include implicit none in your source code, gfortran provides the compiler options -fimplicit-none. Implicit typing is pernicious and likely continued in Fortran to support legacy code.

P.S. double precision is also obsolete but much less risky than implicit typing. If you have a recent version of gfortran you can use the following:

use ISO_FORTRAN_ENV
real (real64) ::

See the gfortran manual.

EDIT: The implicit none changed the type of getS from real(4) (by implicit typing) to unknown (no type declared, implicit typing disabled). If you place the procedures into a module, they will "know" each others types: function returns and argument types. This will fix this bug. It also helps the compiler find other bugs but enabling it to check the consistency of arguments between the call and the arguments of the procedure. See Correct use of modules, subroutines and functions in fortran and Computing the cross product of two vectors in Fortran 90 for examples.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...