Fortran Fortran external functions vs subroutines

  • Thread starter Thread starter Vrbic
  • Start date Start date
  • Tags Tags
    Fortran Functions
AI Thread Summary
The discussion centers on a beginner's challenges with defining and calling functions and subroutines in Fortran, particularly while working on a routine file for numerical methods. Key points include the appropriateness of collecting functions in an external file, the possibility of having both functions and subroutines in the same file, and the ability to call functions from subroutines within that file. The user is following "Numerical Recipes in Fortran 77" and is struggling with implementing a Runge-Kutta 4 subroutine, encountering multiple compiler errors related to variable declarations and executable statements. The errors stem from incorrect ordering of declaration and executable statements, as declarations must precede any executable code. Suggestions include keeping all code in one file for simplicity as a beginner and gradually learning to use libraries for more advanced organization. Additionally, there is a discussion about the differences between program-specific functions and those suitable for a library, emphasizing the importance of testing when modifying library functions.
Vrbic
Messages
400
Reaction score
18
Hello, I'm fortran beginner. I have problem with calling or definition of functions and subroutines. I decided to establish my routine file, where I collect all functions and subroutines who I code (for now I have there function for derivative, only this works).
My first question, is it good way, to colect all in external file and call from it?
May I have functions and subroutins in same file?
May I call function from same routine file into subroutine in same file?
I'm following Numerical recipes in fortran 77 from Shapiro at all. Now I'm struggeling with runge-kutta 4 subroutine. I just write it into my routine file and don't call. To main program I call only derivative function above. But compiler reports many errors:
1)
INTEGER :: i
1
Error: Unexpected data declaration statement at (1)

2)
DOUBLE PRECISION :: h6,hh,xh,dym(NMAX),dyt(NMAX),yt(NMAX)
1
Error: Unexpected data declaration statement at (1)

3) atc.

atc. but I followed recipies...
Can you advice me?

My code
Main
Fortran:
DOUBLE PRECISION FUNCTION X2(a)
    DOUBLE PRECISION  :: a,OUT
    OUT=sin(a)
    RETURN
 END FUNCTION X2
DOUBLE PRECISION FUNCTION DDX2(a)
    DOUBLE PRECISION :: a,OUT
    OUT=cos(a)
    RETURN
 END FUNCTION DDX2
 
 PROGRAM HLAVNI
    IMPLICIT NONE
    INTEGER :: i
    DOUBLE PRECISION :: X, DX2, h
    DOUBLE PRECISION, EXTERNAL :: X2, DDX2
    h=10.0**(-5)

    WRITE(*,*) 'Zadejte ve kterem bode chcete derivovat'
    READ(*,*) X

    wRITE(*,*) 'Hodnota v bode x', X2(X)
    CALL derivs(X,X2,DX2)
    wRITE(*,*) 'Derivace v bode x', DX2
    wRITE(*,*) 'Opravdova derivace v bode x', DDX2(X)

    READ(*,*) X
 END PROGRAM
routines
Fortran:
!*********************************!
!****** Derivative function ******!
!*********************************!

DOUBLE PRECISION FUNCTION derivs(x,y,dydx)
  DOUBLE PRECISION :: x,y,dydx,h
  h=10.0**(-10)
  dydX=(y(x+h)-y(x-h))/(2*h)return
END FUNCTION derivs
!*********************************!
!***** Runge-Kutta 4th order *****!
!*********************************!

SUBROUTINE rk4(y,dydx,n,x,h,yout)
INTEGER :: n,NMAX
DOUBLE PRECISION :: h,x,dydx(n),y(n),yout(n)
!DOUBLE PRECISION, EXTERNAL :: derivs
NMAX=50                          !Maximum number of equation

INTEGER :: i
DOUBLE PRECISION :: h6,hh,xh,dym(NMAX),dyt(NMAX),yt(NMAX)
hh=h*0.5
h6=h/6.
xh=x+hh
                  !I move calls to cycle and add (i) to dyt(i) atc.
                               !First step
do i=1,n                     
   yt(i)=y(i)+hh*dydx(i)
   call derivs(xh,yt,dyt(i))
end do

                               !Second step
do i=1,n                     
   yt(i)=y(i)+hh*dyt(i)
   call derivs(xh,yt,dym(i))
end do

                                !Third step
do i=1,n
   yt(i)=y(i)+hh*dym(i)
   dyn(i)=dyt(i)+dym(i)
   call derivs(x+h,yt,dyt(i))
end do

                                !Fourth step
do i=1,n
   yout(i)=y(i)+h6*(dydx(i)+dyt(i)+2.*dym(i))
end do
return
END SUBROUTINE
 
Technology news on Phys.org
In general, programmers keep functions specific to a program with the program and functions have more general usage in a library of functions.

As an example, if you wrote functions for computing trig values then you’d place them in a library so they could used in other programs that might be written.

In contrast, if you write a function for a specific task needed only by this program then place it with the program.

Sometimes program specific functions are needed in other programs and so then it makes sense to promote those functions to a library for others to use.

Be aware that placing functions in a library comes at a cost ie you can’t just change them without testing them in other programs that rely on them.
 
  • Like
Likes FactChecker
jedishrfu said:
In general, programmers keep functions specific to a program with the program and functions have more general usage in a library of functions.

As an example, if you wrote functions for computing trig values then you’d place them in a library so they could used in other programs that might be written.

In contrast, if you write a function for a specific task needed only by this program then place it with the program.

Sometimes program specific functions are needed in other programs and so then it makes sense to promote those functions to a library for others to use.

Be aware that placing functions in a library comes at a cost ie you can’t just change them without testing them in other programs that rely on them.
Ok, I understand. So how may I create such library? Or what is different from my file of routines?
I mean, derivative functions is quite general also subroutine for solution of ODEs. I guess library should has different suffix like *.lib? And how should I call some function or subroutine from it?
Can you please check out errors? What is wrong? I feel that something very general but I don't have idea what.

Thank you.
 
You said your code is from Fortran 77 but what compiler are you using? Fortran has evolved over the years and you’ll need to find a howto document for upgrading the code to the newer syntax if that’s the case.
 
jedishrfu said:
You said your code is from Fortran 77 but what compiler are you using? Fortran has evolved over the years and you’ll need to find a howto document for upgrading the code to the newer syntax if that’s the case.
I believe it is not problem. I rewrite it. Maybe there can be some small buck but I can't see it. As I said. Calling function for derivative working. I just wrote subroutine bellow function I don't call it and it finds errors. In declaration, I have same declarations above and everything is alright...
May be a problem that I declared variables two times?
 
I saw an assignment where you used dydX and not dydx as you defined in your earlier statements.

That’s derivs function.

Also shouldn’t your return have a variable to return like return dydx ?
 
  • Like
Likes Vrbic
Vrbic said:
I'm following Numerical recipes in fortran 77 from Shapiro at all. Now I'm struggeling with runge-kutta 4 subroutine. I just write it into my routine file and don't call. To main program I call only derivative function above. But compiler reports many errors:
1)
INTEGER :: i
1
Error: Unexpected data declaration statement at (1)

2)
DOUBLE PRECISION :: h6,hh,xh,dym(NMAX),dyt(NMAX),yt(NMAX)
1
Error: Unexpected data declaration statement at (1)

Vrbic said:
Fortran:
!*********************************!
!***** Runge-Kutta 4th order *****!
!*********************************!

SUBROUTINE rk4(y,dydx,n,x,h,yout)
INTEGER :: n,NMAX
DOUBLE PRECISION :: h,x,dydx(n),y(n),yout(n)
!DOUBLE PRECISION, EXTERNAL :: derivs
NMAX=50                          !Maximum number of equation

INTEGER :: i
DOUBLE PRECISION :: h6,hh,xh,dym(NMAX),dyt(NMAX),yt(NMAX)
<snip>
@Vrbic, I believe that the two compiler errors you are seeing are due to your RK4 subroutine, quoted above.
You have an executable statement, NMAX = 50, followed by two declaration statements. If I'm remembering correctly, all declaration statements have to come before any executable statements. You should probably be able to fix the two compiler errors you listed by moving the NMAX assignment statement below the declaration for h, x, dydx(n), etc.
 
  • Like
Likes jedishrfu
Mark44 said:
@Vrbic, I believe that the two compiler errors you are seeing are due to your RK4 subroutine, quoted above.
You have an executable statement, NMAX = 50, followed by two declaration statements. If I'm remembering correctly, all declaration statements have to come before any executable statements. You should probably be able to fix the two compiler errors you listed by moving the NMAX assignment statement below the declaration for h, x, dydx(n), etc.
Fixed, thank you.
 
As a beginner developing new code, you may want to put everything in one file just to keep things as simple as possible and only worry about the FORTRAN syntax. But as soon as you get a little more experience, you should learn how to use libraries as described by @jedishrfu .
 

Similar threads

Replies
2
Views
2K
Replies
3
Views
2K
Replies
59
Views
11K
Replies
2
Views
3K
Replies
1
Views
3K
Replies
10
Views
10K
Replies
8
Views
2K
Back
Top