[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ next ]
Fortran 90
Lessons for Computational Chemistry
The main aims of this lesson are the following:
presenting the advantages of using functions, subroutines and modules.
presenting the function concept in Fortran
.
showing the different types of functions: intrinsic, generic, elemental, transformational, and internal.
making possible the definition of new functions by the user.
evinving the difference beyween external and internal functions.
The use of subporgrams allows a more structured and efficient programming owing to
the possibility of developing and testing different subtasks in an independent manner.
it makes possible to recycle subprograms in different programs, diminishing the necessary time for coding.
the isolation in different subtasks of possible errors and the minimization of unexpected side effects, due to variable encapsulation.
We first focus in functions and will follow with subroutines and modules.
General characteristics of functions.
The main characteristics of a function are:
May require the input of one or several arguments.
Arguments can take the form of an expression.
In general, a function produces a single output, which is a function of the arguments, and this output is of scalar type though in some cases it also can be of an array type.
The arguments can be of different types.
There are more than one hundred predefined functions in Fortran
,
highly tested, and of easy usage. E.g. we need trigonometric functions we can
make use of the following:
Y = SIN(X)
Y = COS(X)
Y = TAN(X)
where X and Y are real variables[10]
This predefined functions are called intrinsic functions. In this
link URL
you can find a complet list of the intrinsic functions at your disposal with
the gfortran
compiler.
In general intrinsic functions are also generic, which means that they can admit different argument types, with the exception of the functions LGE, LGT, LLE, and LLT.
Elemental functions may have as an argument both scalars or vectors. The example source codes excode_8_1.f90, Section 8.3.1 and excode_8_2.f90, Section 8.3.2 show the elemental and generic character of some intrinsic functions. When an elemental function is applied to an array the fucntions is applied to each array element.
Other type of functions are of inquiry type, giving information about the characterictics of an array, e.g. the SIZE and ALLOCATED functions. Examples of the latter are found in excode_6_7.f90, Section 6.3.7 and excode_9_3.f90, Section 9.3.3.
Transformational functions transform between different data types, e.g. REAL and TRANSPOSE, or functions that work with time data variables as SYSTEM_CLOCK and DATE_AND_TIME.
Conversion between data types:
REAL(i): integer i is converted to a float. The argument i can be an integer, a double precision real or a complex number.
INT(x): transforms the real variable x to an integer, truncating the decimal part. No rounding is performed. The x variable can be a real, double precision real, or a complex variable.
The functions that follow allow to transform from real to integer values with an adequate control:
CEILING(x): real value x to the minimum integer value larger than or equal than x.
FLOOR(x): real value x to the maximum integer value less than or equal than x.
NINT(x): round the real value x to the nearest integer.
DBLE(a): transforms a to double precision. The argument can be integer, real, or complex.
CMPLX(x) or CMPLX(x,y): transform to complex values, where the second argument is the imaginary part.
Apart from the intrinsic functions, user defined functions can also be added. The definition of a function requires, apart from the function definition, the way the function is invoked from a program.
A user defined function is created according to the following scheme.
FUNCTION fun_name(argument_list) IMPLICIT NONE Declaration section (including arguments and fun_name) .... Local variables declaration .... fun_name = expr RETURN ! Optional END FUNCTION fun_name
The example Programa ejemplo_8_3.f90, Section 8.3.3 shows how to define and invoke a function computing the greatest common divisor of two integers. The following considerations should be taken into account:
This example is built with two blocks, the main program and the function definition. bloque con el programa principal y un segundo bloque donde se define la función. The function definition can be carried out in a separate file. In such case both filenames should be provided to the compiler.
The variables defined in a function are local with respect to the main program variables.
The MCD function is of INTEGER type. Therefore, in principle, the function output should be of integer type.
The INTENT(IN) attribute characterizing the A and B variables:
INTEGER , INTENT(IN) :: A,B
marks these two as input variables, whose values cannot be modified in the body of the function.
Every function argument needs to be difined with the INTENT(IN) attribute to avoid the modification of their values with unforeseen consequences.
It is possible to define internal functions, restrained to certain code segment. Such functions cannot be called from any program unit but the one that defines them. This is achieved with the CONTAINS statement (e.g. Programa ejemplo_8_4.f90, Section 8.3.4 and excode_8_5.f90, Section 8.3.5).
PROGRAM ex_8_1 IMPLICIT NONE ! Variable Definition INTEGER, PARAMETER :: Long=SELECTED_REAL_KIND(18,310) ! REAL (KIND=Long), PARAMETER :: DPI = ACOS(-1.0_Long) ! Pi number double precision REAL (KIND=Long) :: DANGLE, DANGLERAD ! REAL, PARAMETER :: PI = ACOS(-1.0) ! Pi number single precision REAL :: ANGLERAD ! PRINT*, 'ANGLE INPUT (Degrees)' READ*, DANGLE PRINT* ! Transform to RAD DANGLERAD = DPI*DANGLE/180.0_Long ANGLERAD = PI*DANGLE/180.0 ! PRINT 20, DANGLE, DANGLERAD PRINT 21, DANGLE, ANGLERAD PRINT* PRINT* ! PRINT 22, DANGLERAD, SIN(DANGLERAD), COS(DANGLERAD), SIN(DANGLERAD)**2+COS(DANGLERAD)**2,& 1.0_Long-(SIN(DANGLERAD)**2+COS(DANGLERAD)**2) PRINT* PRINT 22, ANGLERAD, SIN(ANGLERAD), COS(ANGLERAD), SIN(ANGLERAD)**2+COS(ANGLERAD)**2,1.0 - (SIN(ANGLERAD)**2+COS(ANGLERAD)**2) ! 20 FORMAT (1X, 'An angle of ',F14.8,' degrees = ', F14.8, ' rad. (dp)') 21 FORMAT (1X, 'An angle of ',F14.8,' degrees = ', F14.8, ' rad. (sp)') 22 FORMAT (1X, 'ANGLE ',F14.8,', SIN = ', F13.9, ', COS =',F13.9,/'SIN**2+COS**2 = ', F18.14, ', 1 - SIN**2+COS**2 = ', F18.14) END PROGRAM EX_8_1
PROGRAM ex_8_2 IMPLICIT NONE ! VARIABLE DEFINITION INTEGER , PARAMETER :: NEL=5 REAL, PARAMETER :: PI = ACOS(-1.0) ! Pi number REAL, DIMENSION(1:NEL) :: XR = (/ 0.0, PI/2.0, PI, 3.0*PI/2.0, 2.0*PI/) INTEGER , DIMENSION(1:NEL):: XI = (/ 0, 1, 2, 3, 4/) ! PRINT*, 'Sin ', XR, ' = ', SIN(XR) PRINT*, 'LOG10 ', XR, ' = ', LOG10(XR) PRINT*, 'REAL ', XI, ' = ', REAL(XI) END PROGRAM ex_8_2
PROGRAM ex_8_3 IMPLICIT NONE INTEGER :: I,J,Result INTEGER :: MCD EXTERNAL MCD PRINT *,' INTRODUCE TWO INTEGERS:' READ *,I,J RESULT = MCD(I,J) PRINT *,' THE GREATEST COMMON DIVISOR OF ',I,' AND ',J,' IS ',RESULT END PROGRAM ex_8_3 ! INTEGER FUNCTION MCD(A,B) IMPLICIT NONE INTEGER , INTENT(IN) :: A,B INTEGER :: Temp IF (A < B) THEN Temp=A ELSE Temp=B ENDIF DO WHILE ((MOD(A,Temp) /= 0) .OR. (MOD(B,Temp) /=0)) Temp=Temp-1 END DO MCD=Temp END FUNCTION MCD
PROGRAM ex_8_4 IMPLICIT NONE ! Internal function example: ! E(v) = we (v+1/2) - wexe (v+1/2)**2. INTEGER :: V, VMAX REAL :: we, wexe, Energy PRINT *,' Vmax?:' READ *, VMAX PRINT *,' we and wexe?' READ *,we, wexe DO V = 0, VMAX Energy = FEN(V) PRINT 100, V, Energy ENDDO 100 FORMAT(1X,'E(',I3,') = ',F14.6) CONTAINS ! REAL FUNCTION FEN(V) IMPLICIT NONE INTEGER , INTENT(IN) :: V FEN = we*(V+0.5)-wexe*(V+0.5)**2 END FUNCTION FEN ! END PROGRAM EX_8_4
PROGRAM ex_8_5 ! ! Simple program to compute the prime divisors of a given integer number. ! IMPLICIT NONE INTEGER :: NUMVAL INTEGER :: NUM ! READ*, NUMVAL ! input ! DO NUM = QUOT(NUMVAL) IF (NUM == NUMVAL) THEN PRINT*, NUM EXIT ELSE PRINT*, NUMVAL/NUM, NUM NUMVAL = NUM ENDIF ENDDO ! CONTAINS ! INTEGER FUNCTION QUOT(NUM1) ! INTEGER, INTENT(IN) :: NUM1 INTEGER :: I ! QUOT = NUM1 ! DO I = 2, NUM1-1 IF (MOD(NUM1,I) == 0) THEN QUOT = NUM1/I EXIT ENDIF ENDDO ! END FUNCTION QUOT ! END PROGRAM ex_8_5
PROGRAM ex_8_6 ! ! Program to evaluate a 1D potential function on grid points ! IMPLICIT NONE ! REAL, DIMENSION(:), ALLOCATABLE :: X_grid, Pot_grid ! REAL :: X_min, X_max, Delta_X REAL :: V_0 = 10.0, a_val = 1.0 INTEGER :: Index, X_dim INTEGER :: Ierr ! ! INTERFACE Potf ELEMENTAL FUNCTION Potf(Depth, Inv_length, X) ! IMPLICIT NONE ! REAL, INTENT(IN) :: Depth, Inv_length, X REAL :: Potf ! END FUNCTION Potf END INTERFACE Potf ! ! READ(*,*), X_min, X_max, X_dim ! input minimum and maximum values of X and number of points ! ALLOCATE(X_grid(1:X_dim), STAT = Ierr) IF (Ierr /= 0) THEN STOP 'X_grid allocation failed' ENDIF ! ALLOCATE(Pot_grid(1:X_dim), STAT = Ierr) IF (Ierr /= 0) THEN STOP 'Pot_grid allocation failed' ENDIF ! ! Delta_X = (X_max - X_min)/REAL(X_dim - 1) ! X_grid = (/ (Index, Index = 0 , X_dim - 1 ) /) X_grid = X_min + Delta_X*X_grid ! Pot_grid = Potf(V_0, a_val, X_grid) ! DO Index = 1, X_dim PRINT*, X_grid, Pot_grid ENDDO ! DEALLOCATE(X_grid, STAT = Ierr) IF (Ierr /= 0) THEN STOP 'X_grid deallocation failed' ENDIF ! DEALLOCATE(Pot_grid, STAT = Ierr) IF (Ierr /= 0) THEN STOP 'Pot_grid deallocation failed' ENDIF ! ! END PROGRAM ex_8_6 ! ELEMENTAL FUNCTION Potf(Depth, Inv_length, X) ! IMPLICIT NONE ! REAL, INTENT(IN) :: Depth, Inv_length, X ! REAL :: Potf ! Potf = -Depth/(COSH(Inv_length*X)**2) ! END FUNCTION Potf
PROGRAM ex_8_7 ! ! Program to characterize an array making use of inquiry functions ! IMPLICIT NONE ! REAL, DIMENSION(:,:), ALLOCATABLE :: X_grid INTEGER :: Ierr ! ! ALLOCATE(X_grid(-20:20,0:50), STAT = Ierr) IF (Ierr /= 0) THEN STOP 'X_grid allocation failed' ENDIF ! WRITE(*, 100) SHAPE(X_grid) 100 FORMAT(1X, "Shape : ", 7I7) ! WRITE(*, 110) SIZE(X_grid) 110 FORMAT(1X, "Size : ", I7) ! WRITE(*, 120) LBOUND(X_grid) 120 FORMAT(1X, "Lower bounds : ", 7I6) ! WRITE(*, 130) UBOUND(X_grid) 130 FORMAT(1X, "Upper bounds : ", 7I6) ! DEALLOCATE(X_grid, STAT = Ierr) IF (Ierr /= 0) THEN STOP 'X_grid deallocation failed' ENDIF ! END PROGRAM ex_8_7
[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ next ]
Fortran 90
Lessons for Computational Chemistry
mailto:francisco.perez@dfaie.uhu.es