Bill TP
Bill TP

Reputation: 1097

Fortran 90, function, array

I am a novice in Fortran programming. I have two .f90 files.

fmat.f90

function fmat(t,y)
 implicit none
 real::t
 real::y(2)
 real::fmat(2)
 fmat(1) = -2*t+y(1)
 fmat(2) = y(1)-y(2)
end function fmat

And, main.f90 looks like:

program main
 implicit none
 real::t
 real::y(2)
 real::fmat(2)
 real::k(2)
 t=0.1
 y(1)=0.5
 y(2)=1.4
 k=fmat(t,y)
 write(*,*) k
end program main

So, I am expecting 0.3 -0.9. But I keep getting the following error messages:

ifort fmat.f90 main.f90

main.f90(13): error #6351: The number of subscripts is incorrect.   [FMAT]
k=fmat(t,y)
--^
compilation aborted for main.f90 (code 1)

Any help is appreciated!

!==== EDIT ====

I thank Mark for his answers. I could actually compile the separate files without any error using a "subroutine" approach.

main.f90

program main
  implicit none
  real::t
  real::y(2)
  real::k(2)
  t=0.1
  y(1)=0.5
  y(2)=1.4
  call fmat_sub(t,y,k)
  write(*,*) k
end program main

fmat_sub.f90

subroutine fmat_sub(t,y,k)
  implicit none
  real::t
  real::y(2),k(2)
  k(1) = -2*t+y(1)
  k(2) = y(1)-y(2)
end subroutine fmat_sub

Upvotes: 1

Views: 3779

Answers (1)

High Performance Mark
High Performance Mark

Reputation: 78316

Your declaration, in main, of real::fmat(2) tells the compiler that fmat is an array of reals with rank 1 and length 2. It does not tell it anything about the function fmat written in your other file.

One good way to avoid such issues is to use the capabilities of modern Fortran. Put your subroutines and functions into modules and use-associate them. So, change fmat.f90 to something like

module useful_functions

contains
function fmat(t,y)
 implicit none
 real::t
 real::y(2)
 real::fmat(2)
 fmat(1) = -2*t+y(1)
 fmat(2) = y(1)-y(2)
end function fmat

end module useful_functions

and modify main.f90 to something like

program main
 use useful_functions
 implicit none
 real::t
 real::y(2)
 real::k(2)
 t=0.1
 y(1)=0.5
 y(2)=1.4
 k=fmat(t,y)
 write(*,*) k
end program main

This approach lets the compiler generate explicit interfaces for the module functions and allows it to check, at compile time, the match between dummy arguments and actual arguments.

Since you are a novice I've put some key terms in italics, read about them in your compiler manual or other favourite Fortran documentation.

Another way to solve your problem would be to edit main.f90 to include the source for function fmat, like this:

program main
 implicit none
 real::t
 real::y(2)
 real::k(2)
 t=0.1
 y(1)=0.5
 y(2)=1.4
 k=fmat(t,y)
 write(*,*) k

contains

function fmat(t,y)
 implicit none
 real::t
 real::y(2)
 real::fmat(2)
 fmat(1) = -2*t+y(1)
 fmat(2) = y(1)-y(2)
end function fmat
end program main

I favour the first approach, it scales much better when your programs and projects get large and the benefits of modularisation start to become necessities rather than nice-to-have, but the second approach is OK for small programs while you are learning the language.

Upvotes: 5

Related Questions