Fortran 90 Notebook

Table of Contents

This notes were possible by reading from several sources, but the book Introduction to Programming with Fortran1 was specifically useful because it has a large set of examples and progressive definitions. My first approach to Fortran 90 relies on the manual Physique Numérique2 that I recommend to those people interested in an introduction to Computational Physics based in Fortran.

Terminology

Arrays

explicit-shape array: declared with explicit values for the bounds in each dimension of the array. For this we can have automatic arrays, when the array is a local variable, and adjustable array when it is a dummy argument to a subprogram or procedure.

assumed-shape array: it is a non-pointer(!) dummy argument array that takes its shape from the associated actual argument array (by actual I mean the array that is introduced or demanded by the main program when it is called the subprogram or procedure). It is interesting to combine this approach with the size() instrinc procedure that gives the actual size of an array. We then can obtain within the procedure the size of the array and use this integer value inside the subprogram. For example to allocate an intent(out) array with the correct dimensions.

deferred-shape array: is an allocatable array (it has the ALLOCATABLE attribute and a specified rank but their bounds are set by allocation or argument association) or array pointer.

automatic array: it is explicit-shape and local. It is usually in subprograms and the bounds are set when the subprogram is called

Note here that how the arrays are implemented and defined in a specific programming language is crucial, as it is the main basic piece used to build all the scientific computations. It is illustrative to compare the evolution of the several arrays on the different languages: Fortran, Python, C. In particular, the several libraries on Haskell due to the central role that the type system has in this functional programming language. {.smallblock}

Examples

An example with a subprogram (a subroutine) with arguments x and n will be:

Here x is a dummy argument declared with specific bounds therefore it is a explicit-shape dummy array. However we could use an assumed-shape dummy array because in Fortran 90 and later versions the actual array size and the associated dummy arguments have the same rank and the same size in each dimension. In this situation a different approach will be:

programexample_mainimplicitnoneinteger::nreal,allocatable,dimension(:)::a! The interface part is optional and not mandatory ! it is useful when we have external subprograms! and we can help the compiler to a full consistence! checking. It is recomended its use.interfacesubroutineexample(x)implicitnoneinteger::mreal,intent(in),dimension(:)::xendsubroutineexampleendinterface! n can be read from a file for exampleread*,nallocate(x(1:n))CALLexample(x)endexample_mainsubroutineexample(x)implicitnoneinteger::nreal,intent(in),dimension(:)::xn=size(x)

Procedures

They are very important for break the code in smaller problems, to don’t repeat code within a program, to allow a better testing strategy.

In general the procedures communicate with the main program or other procedure by the arguments, inside the procedure they are named dummy arguments.Because Fortran is an strongly type code, we have to define the type of each argument both in the main program and in the procedures and they have to be consistent (this is for instance ensured by the definition of an interface).

Inside the procedures, specifically in the subroutines, we have the possibility of define if the dummy argument is an input, an output or both, by the intent sentence in the type definition block at the beginning of the sentence. The internal local variables are simple not included in the list of arguments of the procedure and they are destroyed once the procedure end.

Functions

Subroutines

A very interesting case is when the subroutine is including a procedure as argument this means that we have to define an interface for the function that is consistent with the actual procedure argument

subroutinemy_own(a,ext_sub,b,c,d)implicitnonereal,intent(in),dimension(:)::areal,intent(out),dimension(:)::binteger::c,dinterfacesubroutineext_sub(a,b,c)implicitnonereal,intent(in),dimension(:)::areal,intent(out),dimension(:)::binteger,intent(inout)::creal::parm1,parm2endsubroutineext_subendinterface! now we have operations including call ext_sub(a,b,c) and using the arguments b and c ! ..endsubroutinemy_own

In this situation we have to include information on a main program using this subroutine as