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.
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.
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.