Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Simple incompatible rank problem

Status
Not open for further replies.

dsal

Instructor
Jun 27, 2011
2
US
Hello, I have programmed in Fortran in the past, but it is safe to say that I am very much a novice. My current goal is to write a function, or subroutine for that matter, that accepts an array of rank one as its argument, and determines it's size from within the function/subroutine. I figure that this way I wont have to pass the dimensions as arguments, making the function/subroutine more general.

It seems simple enough, however, I am getting rank mismatch issues when compiling with gfortran. More specifically, it complains at n = lbound(vec), saying that n has rank 0 while lbound(vec) has rank 1. I don't understand why these two would have different ranks? Do they have different ranks, or is this a gfortran-specific problem? Any and all help is much appreciated. Below is the code that I'm working with.

PROGRAM arrayarg

REAL, DIMENSION(10):: a

DO i = 1, 10
a(i) = i
END DO

CALL showsize(a)

END PROGRAM arrayarg


SUBROUTINE showsize(vec)
REAL, DIMENSION:))::vec
INTEGER n
n = lbound(vec)
END SUBROUTINE showsize


Thanks,
Daniel
 
First of all, put your subroutine into a module and USE the module in the main program.

Indeed, you need an explicit interface to call a subroutine which has an argument vector declared with ":))". The use of a module is the easiest way to define this interface.

From a more general point of view, define always all your subroutines of functions within modules. They are very nice containers.

Code:
      MODULE my_module
      IMPLICIT NONE
      CONTAINS
      SUBROUTINE showsize(vec)
      REAL, DIMENSION(:)::vec
      WRITE(*,*) SIZE(vec)
      END SUBROUTINE showsize
      END MODULE

      PROGRAM arrayarg

      USE my_module
      IMPLICIT NONE

      REAL, DIMENSION(10):: a
      INTEGER :: i

      DO i = 1, 10
         a(i) = i
      END DO

      CALL showsize(a)
      
      END PROGRAM arrayarg

Notice also that I have replaced the function LBOUND by SIZE. LBLOUND will return 1 in general (the lowest bound of a dummy array declared ":))"). SIZE, on the contrary, will return 10 in your case.

You have apparently chosen a fixed format (each instruction starts at the column 7). I would prefer a free format (file suffix .f90), the fixed format being usually associated to the suffixes ".f" and ".for".

François Jacq
 
Thank you for your reply, FJacq. I figured it was only a matter of time before I needed to start using modules, but I'm not sure I understand their role within the programming language. Could you or anyone out there direct me to a good place to learn the language along with good programming practices? I plan to use fortran to solve equations that arise from computational fluid dynamics, if it makes any difference.

-Daniel
 
Few advices :
- put everything in modules except the main program which is normally in its own source file
- a module is a container well suited to group together related things like derived type definitions, data and procedures (subroutines or functions)
- try to limit the size of a module... A module of 10000 instruction is too large (2000 instructions is OK). Inside a module, try also to limit the size of a procedure (500 instructions is already quite large).
- put at the top of the module the needed USE statements (a module may use modules). But the circular use is forbidden (A uses B and B uses C => C cannot use A). It is very convenient to precise, in each USE statement, the list of symbols you want to import (keyword ONLY)
- just after, add the instruction IMPLICIT NONE. USE and IMPLICIT statements are automatically valid for all the procedures within the module (no need to repeat inside the procedures).
- it may be useful to declare symbols you want to make public from the current module, but only when the software becomes large enough. For that, I start by the instruction PRIVATE and I continue by the declaration of public symbols (procedure names, data, types) (PUBLIC instructions).

They are books available like "Fortran 95/2003 explained" by Michael Metcalf, John Ker Reid, Malcolm Cohen.

Have also a look in the website which presents many things about Fortran.

François Jacq
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top