Fortran 90 : return error - fortran

Hello I am a new user in fortran.
I try to use a subroutine for my project. The code is quite simple and below is the code
subroutine initial_data(f, x, y, z)
implicit none
REAL :: f, x, y, z
! Adding function
#include "func_expr.h"
return
end subroutine
func_expr.h is separate file that I created because expression of f is really complicated. And I got the following error messages:
error #5082: Syntax error, found IDENTIFIER 'RETURN' when expecting one of: * ) :: , ; . (/ + - : ] /) ' ** / // > .LT. < ...
return
----^
and
error #6404: This name does not have a type, and must have an explicit type. [RETURN]
return
----^
compilation aborted for initial.f90.f (code 1)
I am not sure which part is wrong and why return has the problem of it.
Any help is really appreciated!

Related

Return type missmatch calling function

I have a fortran.f file and whant to compile it in Linux. I dont't know what I am doing wrong. I get the following error in my subroutine:
VHImpUmat.f:476:20:
sv%Fm = get_Fm(T) ! $F_M(\Tb)$ limit stress obliquity (depends on $\theta$)
1
Error: Return type mismatch of function ‘get_fm’ at (1) (UNKNOWN/REAL(8))
AVHImpUmat.f:476:14:
sv%Fm = get_Fm(T) ! $F_M(\Tb)$ limit stress obliquity (depends on $\theta$)
1
Error: Function ‘get_fm’ at (1) has no IMPLICIT type
My subroutine:
subroutine stiffness_and_derivatives(T,sv,mat,d,msg)
use tools_lt
use constitutive_names
implicit none
type (MATERIALCONSTANTS),intent(in) :: mat
type (STATEVARIABLES),intent(inout) :: sv
type (DERIVATIVES), intent(inout) :: d
type (MESSAGE),intent(inout) :: msg
character*40 :: whereIam
real(8), intent(in) :: T(3,3)
real(8), dimension(3,3,3,3,3,3) :: c,ctransp
real(8) :: trT3,fac
sv%Fm = get_Fm(T) ! $F_M(\Tb)$ limit stress obliquity (depends on $\theta$)
sv%That = hated(T) ! $\hat {\Tb} = \Tb / \tr \Tb$
sv%LLhat= sv%Fm*sv%Fm*Idelta+mat%az2*(sv%That .out. sv%That) ! linear hp stiffness $ \hat{\cE} = a^2 \left[ \left(\Frac{F_M}{a}\right)^2 \cI + \hTb \hTb \right] $
sv%LL = -( sv%trT/(3.0d0*mat%Cs) )* sv%LLhat ! $ \cE = \frac{-\tr\Tb}{3 \kappa} \hat{\cE}$
!----- dLLhatdT ----------
trT3 = sv%trT**3 ! $\tr^3 \Tb$
fac = mat%az2 / trT3
c = (Idelta .out. T) ! $c_{ijmnkl}= I_{ijmn}T_{kl}$
ctransp = tpose35i46(c) ! $c^T= c_{ijklmn}$
d%dLLhatdT = fac * ( sv%trT*ctransp + sv%trT*(T .out. Idelta)
& - 2.0d0*( T .out. ( T .out. delta) ) ) ! $ \hat E_{ijklmn}'=a^2\left(\dfrac{ T_{rr} I_{ijmn}T_{kl} + T_{rr} T_{ij}I_{klmn}-2 T_{ij}T_{kl} \delta_{mn} }{ (T_{rr})^3} + 2 \dfrac{F_M}{a} I_{ijkl}F'_{M\, mn} \right)$
! $F'_M \approx 0$ is assumed
d%dLLdT = -(1.0d0/(3.0d0*mat%Cs) )*((sv%LLhat .out. delta) ! $\cE_{ }' = \frac{-1}{3 \kappa} \hat\cE \oneb + \dfrac{-\tr \Tb}{3\kappa}\hat\cE'$
& + sv%trT*d%dLLhatdT )
end subroutine stiffness_and_derivatives
In your subroutine, you have the statement implicit none. This is very good and is considered good programming practice.
With this, you must specifically declare any user functions with their return type just like you declare your variables.
We really cannot see what kind of variable sv%Fm is since it is likely defined in one of those modules you use. For the sake of answering, lets say the Fm component of sv is a real(8) (hint in the error message): You would declare the function like this:
real(8) :: get_fm
You would do this at the top with the rest of the variable declarations.
The second error message Error: Function ‘get_fm’ at (1) has no IMPLICIT type essentially tells you you did not declare the return type of your function when there is no implicit typing.
The first error message Error: Return type mismatch of function ‘get_fm’ at (1) (UNKNOWN/REAL(8)) always lists 2 types. The first type is in the using program unit and the second type is the return value type in the function itself. Since you did not declare the function in your subroutine, it reports 'unknown' for that one. If, for example, you accidentally declared it as an integer function, it would have (integer/real(8)) there and that is a little more self-explanatory about the type mismatch.
So adding the 1 declaration makes both errors go away.

How do I compile this Fortran code with new 2017 ifort?

I have the following fortran code that compiles with pre 2017 ifort:
program parallel_m
contains
character(500) function PARALLEL_message(i_ss)
character(50) :: Short_Description = " "
integer :: i_s =0
integer :: n_threads = 0
!
PARALLEL_message=" "
!
if (i_s>0) then
if (len_trim("test this ")==0) return
endif
!
if (i_s==0) then
PARALLEL_message=trim("10")//"(CPU)"
if (n_threads>0) PARALLEL_message=trim(PARALLEL_message)//"-"//trim("200")//"(threads)"
else
PARALLEL_message=trim("a")//"(environment)-"//&
& trim("a")//"(CPUs)-"//&
& trim("a")//"(ROLEs)"
endif
!
end function
end program parallel_m
Going through the preprocessor :
icc -ansi -E example.F > test.f90
Which produces:
# 1 "mod.F"
program parallel_m
contains
character(500) function PARALLEL_message(i_ss)
character(50) :: Short_Description = " "
integer :: i_s =0
integer :: n_threads = 0
!
PARALLEL_message=" "
!
if (i_s>0) then
if (len_trim("test this ")==0) return
endif
!
if (i_s==0) then
PARALLEL_message=trim("10")
if (n_threads>0) PARALLEL_message=trim(PARALLEL_message)
else
PARALLEL_message=trim("a")
& trim("a")
& trim("a")
endif
!
end function
end program parallel_m
This unfortunately with intel 2017 does not compile, the same
output compiles without complaint on 2016 and 2015 ifort releases.
this is the error that I get:
mod.F(19): error #5082: Syntax error, found '&' when expecting one of: <LABEL> <END-OF-STATEMENT> ; TYPE INTEGER REAL COMPLEX BYTE CHARACTER CLASS DOUBLE ...
& trim("a")
------------------------^
mod.F(20): error #5082: Syntax error, found '&' when expecting one of: <LABEL> <END-OF-STATEMENT> ; TYPE INTEGER REAL COMPLEX BYTE CHARACTER CLASS DOUBLE ...
& trim("a")
------------------------^
compilation aborted for test.f90 (code 1)
Your program is illegal Fortran after the preprocessing because the // is interpretted as a C comment.
Simply do not use icc but ifort. Ifort is for Fortran, icc is for C. Ifort uses a different preprocessor fpp which does not discard //.

Line truncated, Syntax error in argument list

When I compile the program below, I have an error and a warning in the call Coor_Trans command line as
Warning: Line truncated
Error: Syntax error in argument list
I compile the program several times, but it does not work. Maybe there is something wrong with my call command.
program 3D
implicit none
integer :: i,j,k
integer, parameter :: FN=2,FML=5,FMH=5
integer, parameter :: NBE=FN*FML*FMH
real, parameter :: pi = 4*atan(1.0)
real(kind=4), dimension(1:FN,1:FML+1,1:FMH+1) :: BEXL,BEYL,BEZL
real(kind=4), dimension(1:FN,1:FML,1:FMH) :: BEXC,BEYC,BEZC,BE2A,BE2B,ANGLE
real(kind=4), dimension(1:NBE,1:1,1:1) :: BEXC1,BEYC1,BEZC1,BE2A1,BE2B1,ANGLE1
real(kind=4), dimension(1:NBE,1:NBE) :: LOC_PTS1,LOC_PTS2,LOC_PTS3
real :: LOC_1,LOC_2,LOC_3
do i=1,FN
do j=1,FML
do k=1,FMH
BEXC(i,j,k) = 0.5*(BEXL(i,j,k) + BEXL(i,j+1,k))
BEYC(i,j,k) = 0.5*(BEYL(i,j,k) + BEYL(i,j+1,k))
BEZC(i,j,k) = 0.5*(BEZL(i,j,k) + BEZL(i,j,k+1))
BE2A(i,j,k) = FL(i)/FML + j*0 + k*0
BE2B(i,j,k) = FH(i)/FMH + j*0 + k*0
ANGLE(i,j,k) = BETA(i) + j*0 + k*0
end do
end do
end do
BEXC1 = reshape(BEXC,(/NBE,1,1/))
BEYC1 = reshape(BEYC,(/NBE,1,1/))
BEZC1 = reshape(BEZC,(/NBE,1,1/))
BE2A1 = reshape(BE2A,(/NBE,1,1/))
BE2B1 = reshape(BE2B,(/NBE,1,1/))
ANGLE1 = reshape(ANGLE,(/NBE,1,1/))
do i=1,NBE
do j=1,NBE
call Coor_Trans(BEXC1(i,1,1),BEYC1(i,1,1),BEZC1(i,1,1),BEXC1(j,1,1),BEYC1(j,1,1),BEZC1(j,1,1),ANGLE1(j,1,1),LOC_1,LOC_2,LOC_3)
LOC_PTS1(i,j) = LOC_1
LOC_PTS2(i,j) = LOC_2
LOC_PTS3(i,j) = LOC_3
end do
end do
end program 3D
subroutine Coor_Trans(GLOB_PTSX1,GLOB_PTSY1,GLOB_PTSZ1,GLOB_PTSX2,GLOB_PTSY2,GLOB_PTSZ2,BETA,LOC_PTS1,LOC_PTS2,LOC_PTS3)
implicit none
real(kind=4), intent(in) :: GLOB_PTSX1,GLOB_PTSY1,GLOB_PTSZ1,GLOB_PTSX2,GLOB_PTSY2,GLOB_PTSZ2,BETA
real(kind=4), intent(out) :: LOC_PTS1,LOC_PTS2,LOC_PTS3
real, parameter :: pi = 4*atan(1.0)
real :: E1,E2
E1 = cos(BETA/180*pi)
E2 = sin(BETA/180*pi)
LOC_PTS1 = (GLOB_PTSX1-GLOB_PTSX2)*E1 + (GLOB_PTSY1-GLOB_PTSY2)*E2
LOC_PTS2 = (GLOB_PTSZ1-GLOB_PTSZ2)
LOC_PTS3 = -(GLOB_PTSX1-GLOB_PTSX2)*E2 + (GLOB_PTSY1-GLOB_PTSY2)*E1
!return
end subroutine Coor_Trans
The length of your call statement is too long. The default maximum width of a line is 132.
The compiler will truncate input lines at that width [as it did--and said so with the warning]. After that, you had an incomplete line (e.g. call foo(a,b that was missing the closing )) which generated the second warning message.
The best solution is to break up the long line with a continuation character, namely &:
call Coor_Trans(BEXC1(i,1,1),BEYC1(i,1,1),BEZC1(i,1,1), &
BEXC1(j,1,1),BEYC1(j,1,1),BEZC1(j,1,1), &
ANGLE1(j,1,1),LOC_1,LOC_2,LOC_3)
Most C-style guides recommend keeping lines at <= 80 chars. IMO, that's a good practice even with fortran.
Note, with GNU fortran, you can increase the limit with the -ffree-line-length-<n> command line option. So, you could try -ffree-line-length-512, but, I'd do the continuation above
Historical footnote: 132 columns was the maximum width that a high speed, chain driven, sprocket feed, fanfold paper, line printer could print.
The Fortran standard imposes a limit on the length of line that compilers are required to deal with, these days it's 132 characters. You can break the line at a suitable place and use a continuation line. Something like this:
call Coor_Trans(BEXC1(i,1,1),BEYC1(i,1,1),BEZC1(i,1,1),BEXC1(j,1,1), &
BEYC1(j,1,1),BEZC1(j,1,1),ANGLE1(j,1,1),LOC_1,LOC_2,LOC_3)
Notice the & at the end of the continued line.
Once the line is truncated arbitrarily it is syntactically erroneous, which explains the second part of your compiler's complaint.
Your compiler probably has an option to force it to read longer lines.

Fortran Coding Advice

I have to develop a linear interpolation program, but keep getting these errors.
Here is the source code:
!Interpolation program for exercise 1 of portfolio
PROGRAM interpolation
IMPLICIT NONE
!Specify table 1 for test of function linter
REAL, DIMENSION (5):: x,f
!Specify results for table 1 at intervals of 1
REAL, DIMENSION (10):: xd, fd
!Specify table 2 to gain linter results
REAL, DIMENSION (9):: xx,ff
!Specify results for table 2 of at intervals of 0.25
REAL, DIMENSION (36):: xxd, ffd
INTEGER :: i, j
!Write values for table dimensions
!Enter x values for Table 1
x(1)=-4.0
x(2)=-2.0
x(3)=0.0
x(4)=2.0
x(5)=4.0
f(1)=28.0
f(2)=11.0
f(3)=2.0
f(4)=1.0
f(5)=8.0
xd(1)=-4.0
xd(2)=-3.0
xd(3)=-1.0
xd(4)=0.0
xd(5)=1.0
xd(6)=2.0
xd(7)=3.0
xd(9)=4.0
!Print Table 1 Array
PRINT *,"Entered Table Values are", x,f
PRINT *,"Interpolation Results for Table 1", xd, fd
END PROGRAM
SUBROUTINE interpol(x,f, xd,fd)
DO i=1, 5
DO j=1, 5
IF (x(j) < xd(i) .AND. xd(i) <= x(j+1)) THEN
fd=linterp (x(j),x(j+1),f(j))
END IF
END DO
END DO
END SUBROUTINE interpol
!Linear Interpolation function
FUNCTION linterp(x(i),x(i+1),f(i),f(i+1),x)
linterp=f(i)+((x-x(i))/(x(i+1)-x(i)))*(f(i+1)-f(i))
END FUNCTION
With it giving these errors;
lin.f90:55:18: Error: Expected formal argument list in function definition at (1)
lin.f90:56:19:
linterp=f(i)+((x-x(i))/(x(i+1)-x(i)))*(f(i+1)-f(i))
1
Error: Expected a right parenthesis in expression at (1)
lin.f90:57:3:
END FUNCTION
1
Error: Expecting END PROGRAM statement at (1)
Could anyone please point me in the right direction?
It is exactly what the compiler complains about: you are missing a right parenthesis.
Either remove the superfluous left (:
linterp=f(i)+ ( x-x(i) ) / ( x(i+1)-x(i) )* ( f(i+1)-f(i) )
or add another )
linterp=f(i)+ ( (x-x(i)) ) / ( x(i+1)-x(i) )* ( f(i+1)-f(i) )
Note that I removed another miss-placed ) in the middle part.
Apart from that, your function declaration is broken! You cannot have x(i) in the declaration!
Try:
real FUNCTION linterp(xI,xIp1,fI,fIp1,x)
implicit none
real, intent(in) :: xI,xIp1,fI,fIp1,x
linterp = fI + (x-xI)/(xIp1-xI)*(fIp1-fI)
END FUNCTION
Alternatively, you can provide the whole arrays (including its length N) and the current index:
real FUNCTION linterp(x,f,N,i,xx)
implicit none
integer, intent(in) :: N
real, intent(in) :: x(N), f(N), xx
integer, intent(in) :: i
linterp = f(i) + (xx-x(i))/( x(i+1)-x(i) )*( f(i+1)-f(i) )
END FUNCTION
In addition to everything Alexander said. You also need to make sure that you have the same amount of inputs in your function declaration as you do when you call it:
fd=linterp (x(j),x(j+1),f(j))
has two less inputs than in your function declaration:
FUNCTION linterp(x(i),x(i+1),f(i),f(i+1),x)
Also, don't forget to add an index to fd, either i or j:
fd(i)=linterp (x(j),x(j+1),f(j))
otherwise you're replacing the entire array with the linterp result every time.

Syntax error, found .and. and .or.

I just wanted to modify a small part of a very old program and I can't for the life of me figure out what I've done to anger the Fortran gods.
The original code has the following line:
if (r.gt.rstep) xappad = xappad*fakm
which I have modified to:
if (r.gt.0.58*rstep .and. r.lt.1.42*rstep) .or. (r.gt.2.08*rstep
: .and. r.lt.2.92*rstep) xappad = xappad*fakm
Which gives me the errors:
sp-co-2-MODIFIED.for(785): error #5082: Syntax error, found '.OR.'
when expecting one of: BLOCK BLOCKDATA PROGRAM MODULE TYPE COMPLEX
BYTE CHARACTER DOUBLE DOUBLECOMPLEX ...
if (r.gt.0.58*rstep .and. r.lt.1.42*rstep) .or. (r.gt.2.08*rstep
-------------------------------------------------------------------------^
sp-co-2-MODIFIED.for(786): error #6090: An array-valued operand is required in this context.
: .and. r.lt.2.92*rstep) xappad = xappad*fakm
------^
sp-co-2-MODIFIED.for(786): error #6087: An array assignment statement
is required in this context.
: .and. r.lt.2.92*rstep) xappad = xappad*fakm
-------------------------------------------^
I really don't know much FORTRAN, but it looks to me like you're missing a pair of parentheses around the conditional:
if ((r.gt.0.58*rstep .and. r.lt.1.42*rstep) .or. (r.gt.2.08*rstep .and. r.lt.2.92*rstep)) xappad = xappad*fakm