Fortran How can I properly use function calls in Fortran 90?

  • Thread starter Thread starter JellyKing
  • Start date Start date
  • Tags Tags
    Fortran Function
AI Thread Summary
The discussion focuses on the challenges of using function calls in Fortran 90, particularly when integrating a six-dimensional ODE with a fourth-order Runge-Kutta method. The user encounters errors related to array ranks and function declarations, specifically needing an explicit interface for array-valued functions. Solutions suggested include using an interface block or defining the function as an internal procedure. Another user shares a toy example to illustrate the correct implementation of array-valued functions, emphasizing the importance of explicit interfaces. The conversation also touches on the complexities of passing dimensions as arguments in functions, with users seeking ways to simplify their function calls.
JellyKing
Messages
2
Reaction score
0
Hi all,

I'm new to Physics Forums, but not to physics, since I'm now doing my MSc. I've had a persistent problem in a segment of my Fortran code that I've worked around, but would like to fix.

The long and short is that I'm integrating a six-dimensional ODE with a fourth-order Runge-Kutta method.* I've tried to do it with function calls as follows. In the main program body, there will be a line to iterate the solution one step, using some function I call rk. I'd like the line of code to be something like
Code:
output = rk(input, parameters)
Sure enough, after the END program, I have the function, initiated by
Code:
FUNCTION rk(inputx,parametersx)
REAL(6) :: rk,...
...
rk = ...
END FUNCTION
In the opening lines, I'll declare that rk is a six-dimensional real (REAL(6)). That's fine. However, when I try to call it as above, I get an error like

Error: FUNCTION 'rk' is of rank (1) at {function declaration} and rank (0) and {function call}.

Okay, so I figure I need to tell the program that rk is going to be a REAL(6). But now the compiler tries to parse the arguments as array indices, so I'll get an error like


v = rk(w,E,L,Q,a,dtau)
...1
Error: Array index at (1) must be of INTEGER type


I haven't had this problem with functions that return scalars. For now, I've worked around the function calls by using routines, so that instead of a line like

Code:
output = rk(input,parameters)

I use

Code:
CALL rk(input,parameters,output)

Sorry this is a long post, and if there are any other details that will help find a solution just ask. Thanks in advance for any help you can provide. This has been bugging me for a while.

JK

*I can't for the life of me work out how one is supposed to import other people's modules, but that's another story.
 
Technology news on Phys.org
Hi JellyKing,

There's not much program in your code to go on, but I guess my first question is do you have an explicit interface to the function? That could be the source of the error.

If not, probably the easiest thing is to show you a working case in case it's helpful; here is a trivial program that uses an array-valued function as an internal procedure (just takes an array and adds 1 to each element):

Code:
PROGRAM array_valued_functions
implicit none
integer::i
integer,dimension(5)::a,b

b=(/ (i,i=1,5) /)
a=addone(b)
print*,a

contains

function addone(x)
implicit none
integer,dimension(:),intent(in)::x
integer,dimension(size(x))::addone

addone=x+1
end function addone

end program array_valued_functions

Here is the same example with an interface block which might be better for your case:

Code:
PROGRAM array_valued_functions
implicit none
integer::i
integer,dimension(5)::a,b


interface
function addone(x)
integer,dimension(:),intent(in)::x
integer,dimension(size(x))::addone
end function addone
end interface


b=(/ (i,i=1,5) /)
a=addone(b)
print*,a

end program array_valued_functions


function addone(x)
implicit none
integer,dimension(:),intent(in)::x
integer,dimension(size(x))::addone

addone=x+1
end function addone


If you still have trouble, could you perhaps write a toy program that shows the behavior you're talking about and post it here?
 
Okay, here's something that reproduces the error.

Code:
PROGRAM toy
	REAL, DIMENSION(2) :: z
	
	z(1) = 1
	z(2) = 2
	
	z = array_valued_function(z)
	PRINT *, z
	
END PROGRAM toy

FUNCTION array_valued_function(x)
	REAL, DIMENSION(2) :: array_valued_function,x
	
	array_valued_function = x+1
END FUNCTION

I already notice you making use of a couple of structures I had no idea about. I've never seen interface or contains before. I am fairly new to Fortran, from a smattering of Java, C++, a bit more Python, and a lot of MATLAB. If I include IMPLICIT NONE, I'm told array_valued_function has no implicit type. If I supplant

Code:
REAL :: array_valued_function(2)

I get back to my error of the compiler wanting the argument of the function to be an index of the array (described in my first post).

I'll look up those interface and contains structures when I get back to this particular problem. Thanks for the help though! :)

JK
 
Then that would be the error; array-valued function require an explicit interface, which can be given in three ways: putting the function in a module and using a corresponding USE statement, making the function an internal subprogram with a CONTAINS statement, or using an interface block in the main (calling) program.

To get your toy program running you might use:

Code:
PROGRAM toy
	REAL, DIMENSION(2) :: z

interface
     FUNCTION array_valued_function(x)
     implicit none
     REAL, DIMENSION(2) :: array_valued_function,x
     end function array_valued_function
end interface


	
	z(1) = 1
	z(2) = 2
	
	z = array_valued_function(z)
	PRINT *, z
	
END PROGRAM toy

FUNCTION array_valued_function(x)
	REAL, DIMENSION(2) :: array_valued_function,x
	
	array_valued_function = x+1
END FUNCTION
 
Last edited:
Hello and thanks for your info about use of INTERFACE in fortran.

I have a question:

I have a main code within which I have used an external extrinsic function. I have coped and pasted both here:
THIS IS THE MAIN CODE
program matrix
implicit none
double precision, dimension(3,3) :: A
double precision, dimension(3,1) :: B
double precision :: X(3)

integer :: m ! SEE HERE PLEASE

interface
function X_Part_Piv(A,B,n)
double precision, allocatable :: AUG(:,:),AUGP(:,:),AUX1(:,:),AUX2(:,:)
integer :: n,p,k,r,m,o,s
double precision :: big,factor,matrmultip,X_Part_Piv(n),A(n,n),B(n,1)
end function X_Part_Piv
end interface

A(1,1)=9
A(1,2)=33
A(1,3)=-3
A(2,1)=0
A(2,2)=9
A(2,3)=11
A(3,1)=.2
A(3,2)=23
A(3,3)=15
B(1,1)=0
B(2,1)=4
B(3,1)=6

m=size(A,2)! SEE HERE PLEASE

X=X_Part_Piv(A,B,m)

end program matrix

THIS IS THE FUNCTION

function X_Part_Piv(A,B,n)
implicit none

double precision, allocatable :: AUG(:,:),AUGP(:,:),AUX1(:,:),AUX2(:,:)
integer :: n,p,k,r,m,o,s
double precision :: big,factor,matrmultip,X_Part_Piv(n),A(n,n),B(n,1)

n=size(A,2)
p=n+1
allocate (AUG(n,n+1))
do m=1,n
AUG(m,n+1)=B(m,1)
do o=1,n
AUG(m,o)=A(m,o)
end do
end do

allocate (AUGP(n,n+1))

do k=1,n-1

big=maxval(abs(AUG(k:n,k)))
s=maxloc(abs(AUG(k:n,k)),dim=1)!dim=1 enforces the max loc of a an (n,1) matrix to be found
r=s+k-1

if (r/=k) then
AUGP=AUG
AUG(k,:)=AUGP(r,:)
AUG(r,:)=AUGP(k,:)
end if

do m=k+1,n

factor=AUG(m,k)/AUG(k,k)
AUG(m,k:p)=AUG(m,k:p)-factor*AUG(k,k:p)

end do

end do

X_Part_Piv(n)=AUG(n,p)/AUG(n,n)

do m=n-1,1,-1
allocate (AUX1(1,n-m))
allocate (AUX2(n-m,1))
AUX1(1,1:n-m)=AUG(m,m+1:n)
AUX2(1:n-m,1)=X_Part_Piv(m+1:n)
matrmultip=0
do o=1,n-m
matrmultip=matrmultip+AUX1(1,o)*AUX2(o,1)
end do
X_Part_Piv(m)=(AUG(m,p)-matrmultip)/AUG(m,m)
deallocate(AUX1)
deallocate(AUX2)
end do
end function X_Part_Piv


My function has three arguments A,B, and n. n is basically the size of A, so it depends on A.

I cannot omit n from my function`s argument. I have done many try and errors to be able to have X_Part_Piv(A,B) instead of X_Part_Piv(A,B,n)

Can anybody help me with that?
 
Dear Peeps I have posted a few questions about programing on this sectio of the PF forum. I want to ask you veterans how you folks learn program in assembly and about computer architecture for the x86 family. In addition to finish learning C, I am also reading the book From bits to Gates to C and Beyond. In the book, it uses the mini LC3 assembly language. I also have books on assembly programming and computer architecture. The few famous ones i have are Computer Organization and...
What percentage of programmers have learned to touch type? Have you? Do you think it's important, not just for programming, but for more-than-casual computer users generally? ChatGPT didn't have much on it ("Research indicates that less than 20% of people can touch type fluently, with many relying on the hunt-and-peck method for typing ."). 'Hunt-and-peck method' made me smile. It added, "For programmers, touch typing is a valuable skill that can enhance speed, accuracy, and focus. While...
I had a Microsoft Technical interview this past Friday, the question I was asked was this : How do you find the middle value for a dataset that is too big to fit in RAM? I was not able to figure this out during the interview, but I have been look in this all weekend and I read something online that said it can be done at O(N) using something called the counting sort histogram algorithm ( I did not learn that in my advanced data structures and algorithms class). I have watched some youtube...

Similar threads

Replies
25
Views
3K
Replies
4
Views
2K
Replies
3
Views
2K
Replies
8
Views
4K
Replies
12
Views
3K
Replies
17
Views
6K
Replies
3
Views
2K
Back
Top