What can I do with Fortran 95

Fortran: Fortran 95: subroutines


If programs are more extensive and complex or if individual program sections are used more often, then it makes sense to use subroutines (procedures). Fortran 95 knows two types of subroutines:

  • Functions ()
  • Subroutines ()

In addition, there is the possibility in Fortran to include subroutines and data in the program by means of modules.

The subroutine [edit]

A function is a subroutine that returns exactly one value. What kind of data type the value is is achieved by an assignment to the function name (e.g.).

The general function declaration is:

data type function function name ([formal parameters]) declaration part statement part function name = value [return] end function function name

If the data type is not specified in the function declaration, the data type of the function must be specified in the declaration section:

function function-name ([formal parameters]) declaration part data type :: function-name statement part function-name = value [return] end function function-name

You can use to return to the calling program unit. An immediately before the statement is not absolutely necessary because the program jumps back to the calling program unit when the statement is reached. Therefore it should be avoided with all newer programs. The instruction for alternative returns to the calling program unit is important.

A function is usually called by the executing program unit using the following general instruction:

variable = function name (current parameters)

This subprogram technique is based directly on mathematical functions. In the following example, the program calls the function, executes the subroutine and returns the corresponding return value to the program:

file e.g. f95:

Fortran 90/95 code (free source form)
program test! implicit none real :: funk real :: x, y write (*, *) 'x ->' read (*, *) xy = funk (x) write (*, *) 'funk ->', y end program test real function funk (a)! implicit none real :: a funk = a ** 2 end function funk

The subroutine can be found directly under the calling program unit in the the same Text file or in a separate File. If the subroutine is in a separate file, it and the calling program unit must be compiled together:

Translation with gfortran in the present case:

gfortran -o ex ex f95

Translation with gfortran with separate files (e.g.):

gfortran -o ex ex f95 funk.f95

But it is also possible to call a function by name only. The return value of the function is then output directly:

file e.g. f95:

Fortran 90/95 code (free source form)
program test! implicit none real :: funk real :: x write (*, *) 'x ->' read (*, *) x write (*, *) 'funk ->', funk (x) end program test real function funk (a)! implicit none real :: a funk = a ** 2 end function funk

The subroutine [edit]

One is a subroutine that can return more than one value. In contrast to a function, a subroutine has no data type and no return value.

The general declaration of a subroutine is:

subroutine subroutine name ([formal parameters]) declaration part statement part [return] end subroutine subroutine name

You can use to return to the calling program unit. An immediately before the instruction is not absolutely necessary, since the program jumps back to the calling program unit when it reaches the. Therefore it should be avoided with all newer programs. The instruction for alternative returns to the calling program unit is important.

A subroutine is called from the calling program unit using the instruction:

call subroutine name [([current parameters])]


The following example calls the subroutine. This then returns two values:

file e.g. f95

Fortran 90/95 code (free source form)
program ex! implicit none real :: x, y, z write (*, *) 'x ->' read (*, *) x call sub (x, y, z) write (*, *) 'y ->', y , 'z ->', z end subroutine sub (a, b, c)! implicit none real :: a, b, c b = a ** 2 c = a ** 2 + b end subroutine sub

Further instructions for the subprogram technique [edit]

The attribute [edit]

In the declaration part of the function, the parameter declaration is given the keyword.

data type, intent (in) :: var

With indicates that the parameter will not be changed in the function and that the information will not flow back into the calling program unit. One or as with subroutines would mostly also be possible, but contradicts the basic idea of ​​the Fortran function concept and the structured programming. With a function, the information return should take place via the return value and not via parameters.


When passing parameters, a subroutine offers the following options:

  • data type, intent (in) :: var ... flow of information from the calling program unit into the function
  • data type, intent (out) :: var ... flow of information from the subroutine to the calling program unit
  • data type, intent (inout) :: var ... two-way flow of information

Example:

Fortran 90/95 code (free source form)
program bsp implicit none real :: a, b, c a = 1.0 b = 2.0 c = 3.0 call sub (a, b, c) write (*, *) 'main program:', a, b, c! Output: 1.000000 22.20000 33.30000 end subroutine sub (x, y, z) implicit none real, intent (in) :: x real, intent (out) :: y real, intent (inout) :: z write (*, *) 'Subroutine:', x, y, z! Output: 1.000000 2.000000 3.000000 y = 22.2 z = 33.3 end subroutine sub

The current and formal parameters must match in terms of data type, number and order.

The instruction [edit]

A subroutine which has no side effects is a mere or pure subroutine. A subroutine does not produce any side effects if it neither changes its input data nor the data that lie outside the subroutine, unless it is its output data. In a pure subroutine, the local variables have no attributes, nor are the local variables initialized in the data declaration.

Pure subroutines are necessary for the construct: the construct was designed for parallel computing, which is why the computer decides here how the construct is to be processed. For this, however, it is necessary that it does not matter in which order the construct is processed. If this does not apply - i.e. if the subroutine has side effects - the -construct cannot be used.

Every input and output argument in a pure subroutine must be declared using the attribute. In addition, every subroutine that is to be called from a pure subroutine must also be a pure subroutine. Otherwise the calling subroutine is no longer a pure subroutine.

The instruction [edit]

A subroutine is elementary if it accepts scalars as well as fields as input values. If the input value is a scalar, an elementary subroutine supplies a scalar as an output value. If the input value is a field, the output value is also a field.

The instruction [edit]

An instruction may only be used in the scope of subroutines. It causes the subroutine execution to be aborted and a return to the call point, where the next statement is continued.

Example:

Fortran 90/95 code (free source form)
program main implicit none call xyz (-2) write (*, *) "UP end" stop write (*, *) "program end" contains subroutine xyz (n) integer, intent (in) :: n integer :: k do k = n, n + 20 write (*, *) k if (k == 5) return end do write (*, *) "k_max =", k end subroutine xyz! Output: ! -2! -1 ! 0! 1 ! 2! 3! 4! 5! UP end end program main

Some compilers allow a program to abort instead of the one in the main program. But that does not conform to the standard. Other compilers would reject such code with an error message, so the program would no longer be fully portable.

An in the loop instead of the statement would only abort the loop pass and the subroutine execution would continue after the loop.

Fields as parameters [edit]

Example: Transfer of an entire field

file e.g. f95:

Fortran 90/95 code (free source form)
program e.g. implicit none integer, dimension (3,3) :: field integer :: cnt, i, j cnt = 1 do i = 1, 3 do j = 1, 3 field (j, i) = cnt cnt = 1 + cnt end do end do! Subroutine call call sub (field)! Output: 1 2 3 4 5 6 7 8 9 end program ex


file sub.f95

Fortran 90/95 code (free source form)
subroutine sub (arr) implicit none integer, dimension (3,3), intent (in) :: arr write (*, *) arr end subroutine sub


Example: Transfer of a field substring

file e.g. f95:

Fortran 90/95 code (free source form)
program e.g. implicit none integer, dimension (3,3) :: field integer :: cnt, i, j cnt = 1 do i = 1, 3 do j = 1, 3 field (j, i) = cnt cnt = 1 + cnt end do end do! Subroutine call call sub (field (1: 2.2: 3))! Output: 4 5 7 8 end program ex


file sub.f95

Fortran 90/95 code (free source form)
subroutine sub (arr) implicit none integer, dimension (0: 1, 0: 1), intent (in) :: arr write (*, *) arr end subroutine sub


Example: Transfer of a single field element

file e.g. f95:

Fortran 90/95 code (free source form)
program e.g. implicit none integer, dimension (3,3) :: field integer cnt, i, j cnt = 1 do i = 1, 3 do j = 1, 3 field (j, i) = cnt cnt = 1 + cnt end do end do! Subroutine call call sub (field (1,2))! Output: 4 end program ex


file sub.f95

Fortran 90/95 code (free source form)
subroutine sub (arr) implicit none integer, intent (in) :: arr write (*, *) arr end subroutine sub

Procedures as parameters [edit]

Procedures can also be passed as parameters.

Standard functions (intrinsic functions) are identified as follows in the agreement section:

or

data type, intrinsic :: name list


Own sub-programs or sub-programs from libraries with:

or

data type, external :: name list


Example:

Fortran 90/95 code (free source form)
program e.g. real, parameter :: PI = 3.1415927! intrinsic functions intrinsic sin, cos! Subroutine calls call sub (sin, PI)! Output: 0.000000 call sub (cos, PI)! Output: -1.000000 end program e.g. subroutine sub (funk, x) implicit none real :: funk, x write (*, *) nint (funk (x) * 1000) /1000.0 end subroutine sub

Optional parameters [edit]

As of Fortran 90, optional parameters for subroutines are also allowed. Such parameters are to be identified by the attribute. This parameter option must also be made known to the calling program unit, e.g. via an interface. The current presence of a parameter marked as optional when the subroutine is called can be checked in the subroutine itself using the function.


Example:

Fortran 90/95 code (free source form)
program bsp implicit none interface subroutine ab (a, b) integer, intent (in) :: a integer, intent (in), optional :: b end subroutine ab end interface call ab (1) call ab (8, 12)! Output: ! Only given a 1! Both parameters given 8 12 end program bsp subroutine ab (a, b) integer, intent (in) :: a integer, intent (in), optional :: b if (present (b)) then write (*, *) " Both parameters given ", a, b else write (*, *)" Only given a ", a end if end subroutine off

Modules [edit]

In Fortran 95, modules replace the FORTRAN 77 blocks. Variables, constants and subroutines can be stored in a module. These can then be addressed by different program units.

module module name [implicit none] [save] Declaration of variables, constants [contains subroutines] end module module name


A module is integrated into a program unit by means of the instruction

use module name [, only list]

indicates that only the variables or constants specified in should be used.


Example:

Fortran 90/95 code (free source form)
module m1 implicit none save real, parameter :: PI = 3.1415 real :: a end module m1 program bsp use m1 implicit none a = 1.5 write (*, *) 'main program 1:', PI, a! Output: Main program 1: 3.141500 1.500000 call sub write (*, *) 'Main program 2:', PI, a! Output: Main program 2: 3.141500 2.500000 end program bsp subroutine sub use m1 implicit none write (*, *) 'Subprogram:', PI, a! Output: Subroutine: 3.141500 1.500000 a = 2.5 end subroutine sub

The statement in modules ensures that the current values ​​of module variables are safely retained when changing between the various program units.

Recursive subroutine call [edit]

In Fortran 95, subroutines (functions, subroutines) can also be called recursively. Recursion means that a subroutine calls itself again (Latin. Recurrere or en. Recur ... to return, to come back).

Example: calculation of n! (simplified)

Fortran 90/95 code (free source form)
program eg implicit none integer :: number, result, fac write (*, *) "Enter an integer:" read (*, *) number result = fac (number) write (*, *) "result is:", result end program e.g. recursive function fac (n) result (zerg) implicit none integer, intent (in) :: n integer :: zerg! Simplified: No check for overflow, negative number, etc. zerg = n if (n> 1) then zerg = n * fac (n-1) end if return end function fac


In this example, the functional head is designed somewhat differently than usual. While the Intel Fortran compiler is also a

recursive integer function fac (n)

or a

integer recursive function fac (n)

accepted without any problems, he throws gfortran-Compiler a syntax error with these variants.