[ 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 session are:
introducing basic Fortran
syntax rules and the characters allowed
in source files.
Basic arithmetic operations and operator precedence rules.
The PARAMETER declaration.
Explain the different kinds of numerical variables and its use.
Basic syntax rules:
Maximum number of characters per line of code: 132.
Maximum length of a variable name string: 31.
'&' denotes that the statement continues in the next line. It is added at the end of the broken line[1]
'!' is the character that marks the rest of the line as a comment.
';' is the character that separates several statements in the same line.
Variable names can include the low hyphen ('_') and mix alphanumeric characters and digits, though variable names first character cannot be a number.
Fortran
character set:
A-Z Letters 0-9 Digits _ Underscore Blank = Equal + Plus - Minus * Asterisk / Slash or oblique ' Apostrophe ( Left parenthesis ) Right parenthesis , Comma . Period or decimal point : Colon ; Semicolon ! Exclamation mark "" Quotation mark % Percent & Ampersand < Less than > Greater than
Precedence of arithmetic operators:
Operators: {+,-,*,/,**}.
Precedence: (1) ** (right to left); (2) *,/ (compiler dependent); (3) +,- (compiler dependent).
Beware of floating point operations rounding, in particular when mixing different numeric variable types. Minimizing rounding errors is at times a complex and subtle task.
The compiler transform different type variables to a common type when performing a calculation. The priority ordering, from lower to higher is: INTEGER, REAL, DOUBLE PRECISION, and COMPLEX. Therefore, an operation involving an integer and a double precision float is performed transforming the integer value to double precision and the result is given in double precision too. The final result is the transformed to the type of the variable to which is assigned.
Integer types:
32 bits ::(2**31)-1 = 2,147,483,647 (~ 10**9)
64 bits :: (2**63)-1 = 9,223,372,036,854,774,807 (~ 10**19)
Floats types and precision:
Real 32 bits :: precision = 6-9 ~ 0.3E38 - 1.7E38
Real 64 bits :: precision = 15-18 ~ 0.5E308 - 0.8E308
Making use of the PARAMETER modifier in a variable definition we can define constant values in a program. See excode_2_4.f90, Section 2.3.4.
(*) Different kinds of floats and integers in Fortran
and the
intrinsic functions[2]
KIND, EPSILON, PRECISION, and
HUGE and how to define a variable in each of the existing types.
INTEGER VARIABLES: if we would like to define an integer variable i0 that could take values between -999999 y 999999 we should define a variable, called e.g. ki, making use of the intrinsic function SELECTED_INT_KIND() and make use of it in the variable definition.
INTEGER, PARAMETER :: ki = SELECTED_INT_KIND(6) INTEGER(KIND=ki) :: i0
The intrinsic function[3] SELECTED_INT_KIND(X) output is an integer that indicates the type (kind) of an integer variable capable of storing any integer in the range (-10E+X, 10E+X) where X is also an integer. If we want that any integer constant in our program to be treated with a particular type of integer this can be done as follows:
-1234_ki 2354_ki 2_ki
The error output of the SELECTED_INT_KIND(X) function is -1.
Real numbers are more involved. We make use a floating point
representation, and all the following are valid real numbers in
Fortran
:
-10.66E-20 0.66E10 1. -0.4 1.32D-44 2E-12 3.141592653
In this case the statement to control the type of float is SELECTED_REAL_KIND(p=X,r=Y), with two input parameters. The output is an integer associated with a float that complies with the following rules:
it has a precision at least equal to X and a range of decimal exponents given at least by Y. The argument labels are optional.
Among various possible results, the one with the minimum decimal precision will be chosen.
At least one of the two input parameter should be specified. Both X and Y are integers. If there is no variable type that fulfills the requested condiotions the output of the function will be -1 if the precision does not reach the requested level, -2 if the problem is in the exponent, and -3 if both requirements cannot be satisfied.
As an example, if we want to define a real variable called a0 with 15 digit precision and exponents in the range -306 to 307:
INTEGER, PARAMETER :: kr = SELECTED_REAL_KIND(15,307) REAL(KIND=kr) :: a0
Scalar floats can be addressed defining its particular kind as follows
-10.66E-20_kr 0.66E10_kr 142857._kr -0.4_kr 2E-12_kr 3.141592653_kr
Program excode_2_5.f90, Section 2.3.5 contains several examples of the use of the KIND statement and the default value of KIND for several variable types.
Program excode_2_6.f90, Section 2.3.6 contains examples of the different types of viariales, how to define them, and how to test them using the intrinsics KIND, DIGITS, EPSILON, TINY, HUGE, EXPONENT, MAXEXPONENT, MINEXPONENT, PRECISION , RADIX y RANGE.
In this program variables are defined using the functions SELECTED_INT_KIND and SELECTED_REAL_KIND This is correct though it is more appropriate to define the variables according to the process in the notes.
The used functions are
KIND(x): integer output, type of the variable x.
DIGITS(x): integer output, number of significant digits of x.
EPSILON(x): if the input x is a float the output is another float, of the same type (kind) than x. It is the smallest number of this type such that 1.0 + EPSILON(X) > 1.
TINY(x): for float x input the output is of the same kind than x, and it is the minimum positive value that can be defined for such variables.
HUGE(x): for float x input the output is of the same kind than x, and it is the maximum positive value that can be defined for such variables.
EXPONENT(x): x variable exponent. If x = 0 then EXPONENT(x)=0 too.
MAXEXPONENT(x): maximum exponent possible for x type variables.
MINEXPONENT(x): minimum exponent possible for x type variables.
PRECISION(x): if x is real or complex the output is an integer equal to the number of digits of precision of the variable x.
RADIX(x): integer result equal to the radix basis of x.
RANGE(x): integer result equal to the range of exponent for the variable x.
(*) Present how float arithmetic involves precision loss and how an appropriate use of the diferent data types can help to minimize this problem.
PROGRAM ex_2_1 IMPLICIT NONE ! ! Program computing the energy of a vibrational normal mode ! ! Ge(v) = we (v+1/2) - wexe (v+1/2)^2 ! ! ! Definicion de variables REAL :: energ_0, energ, delta_e ! deltae = energ-energ0 REAL :: we = 250.0, wexe = 0.25 ! Units: cm-1 INTEGER :: v = 0 CHARACTER*60 :: for_mol ! I/O PRINT *,'Formula de la molecula : ' READ *, for_mol PRINT *,'Num. de quanta de excitacion : ' READ *, v ! Calculations energ = we*(v+0.5) - wexe*(v+0.5)**2 energ_0 = we*(0.5) - wexe*(0.5)**2 delta_e = energ - energ_0 ! I/O PRINT * PRINT *,'Especie molecular: ', for_mol PRINT *,'num. de quanta: ', v PRINT *,'energ = ',energ,'cm-1' PRINT *,'energ_0 = ',energ_0,'cm-1' PRINT *,'energ - energ_0 = ',delta_e,'cm-1' END PROGRAM ex_2_1
PROGRAM ex_2_2 IMPLICIT NONE REAL :: A,B,C INTEGER :: I A = 1.5 B = 2.0 C = A / B I = A / B PRINT * PRINT *, 'Case (1), Float variable' PRINT *,A,'/',B,' = ',C PRINT *, 'Case (2), Integer variable' PRINT *,A,'/',B,' = ',I END PROGRAM ex_2_2
PROGRAM ex_2_3 IMPLICIT NONE INTEGER :: I,J,K REAL :: Answer I = 5 J = 2 K = 4 Answer = I / J * K PRINT *,'I = ',I PRINT *,'J = ',J PRINT *,'K = ',K PRINT *,'I / J * K = ',Answer END PROGRAM ex_2_3
PROGRAM ex_2_4 ! Program to compute the time that takes to light to travel ! a given distance in AU. ! 1 AU = 1,50E11 m ! !Definicion de variables IMPLICIT NONE ! a_u : astronomic unit in km REAL , PARAMETER :: a_u=1.50*10.0**8 ! y_l : year light --> distance travelled by light during a year REAL , PARAMETER :: y_l=9.46*10.0**12 ! m_l : minute light --> distance travelled by light during a minute REAL :: m_l ! dist : distance travelled in AUs (INPUT) REAL :: dist ! t_min : time in minutes needed to travel the distance dist REAL :: t_min ! ! min : integer part of t_min ! seg : seconds from the decimal digits of t_min INTEGER :: min, seg ! m_l = y_l/(365.25 * 24.0 * 60.0) ! m_l Calculation ! PRINT * PRINT *,'Distance in AUs' READ *, dist PRINT * ! t_min = (dist*a_u)/m_l min = t_min; seg = (t_min - min) * 60 ! PRINT *,' It takes light ' , min,' minutes and ', seg,' seconds' Print *,' to travel a distance of ',dist,' AU.' END PROGRAM ex_2_4
PROGRAM ex_2_5 INTEGER :: i REAL :: r CHARACTER(LEN=1) :: c LOGICAL :: l COMPLEX :: cp PRINT *,' Integer ',KIND(i) PRINT *,' Real ',KIND(r) PRINT *,' Char ',KIND(c) PRINT *,' Logical ',KIND(l) PRINT *,' Complex ',KIND(cp) END PROGRAM ex_2_5
PROGRAM ex_2_6 ! From Program ch0806 of Chivers & Sleightholme ! ! Examples of the use of the kind ! function and the numeric inquiry functions ! ! Integer arithmetic ! ! 32 bits is a common word size, ! and this leads quite cleanly ! to the following ! 8 bit integers ! -128 to 127 10**2 ! 16 bit integers ! -32768 to 32767 10**4 ! 32 bit integers ! -2147483648 to 2147483647 10**9 ! ! 64 bit integers are increasingly available. ! This leads to ! -9223372036854775808 to ! 9223372036854775807 10**19 ! ! You may need to comment out some of the following ! depending on the hardware platform and compiler ! that you use. INTEGER :: I INTEGER ( SELECTED_INT_KIND( 2)) :: I1 INTEGER ( SELECTED_INT_KIND( 4)) :: I2 INTEGER ( SELECTED_INT_KIND( 8)) :: I3 INTEGER ( SELECTED_INT_KIND(16)) :: I4 ! Real arithmetic ! ! 32 and 64 bit reals are normally available. ! ! 32 bit reals 8 bit exponent, 24 bit mantissa ! ! 64 bit reals 11 bit exponent 53 bit mantissa ! REAL :: R = 1.0 REAL ( SELECTED_REAL_KIND( 6, 37)) :: R1 = 1.0 REAL ( SELECTED_REAL_KIND(15,307)) :: R2 = 1.0 REAL ( SELECTED_REAL_KIND(18,310)) :: R3 = 1.0 PRINT *,' ' PRINT *,' Integer values' PRINT *,' Kind Huge' PRINT *,' ' PRINT *,KIND(I ),' ',HUGE(I ) PRINT *,' ' PRINT *,KIND(I1 ),' ',HUGE(I1 ) PRINT *,KIND(I2 ),' ',HUGE(I2 ) PRINT *,KIND(I3 ),' ',HUGE(I3 ) PRINT *,KIND(I4 ),' ',HUGE(I4 ) PRINT *,' ' PRINT *,' ----------------------------------- ' PRINT *,' ' PRINT *,' Real values' ! PRINT *,' Kind ', KIND(R ), ' Digits ', DIGITS(R ) PRINT *,' Huge = ',HUGE(R ), ' Tiny =', TINY(R) PRINT *,' Epsilon = ',EPSILON(R),' Precision = ', PRECISION(R) PRINT *,' Exponent = ',EXPONENT(R), 'MAXExponent = ', MAXEXPONENT(R), ' MINExponent = ',MINEXPONENT(R) PRINT *,' Radix = ', RADIX(R ), ' Range =', RANGE(R) PRINT *,' ' ! ! PRINT *,' Kind ', KIND(R1 ), ' Digits ', DIGITS(R1 ) PRINT *,' Huge = ',HUGE(R1 ), ' Tiny =', TINY(R1) PRINT *,' Epsilon = ',EPSILON(R1),' Precision = ', PRECISION(R1) PRINT *,' Exponent = ',EXPONENT(R1), 'MAXExponent = ', MAXEXPONENT(R1), ' MINExponent = ',MINEXPONENT(R1) PRINT *,' Radix = ', RADIX(R1 ), ' Range =', RANGE(R1) PRINT *,' ' ! ! PRINT *,' Kind ', KIND(R2 ), ' Digits ', DIGITS(R2 ) PRINT *,' Huge = ',HUGE(R2 ), ' Tiny =', TINY(R2) PRINT *,' Epsilon = ',EPSILON(R2),' Precision = ', PRECISION(R2) PRINT *,' Exponent = ',EXPONENT(R2), 'MAXExponent = ', MAXEXPONENT(R2), ' MINExponent = ',MINEXPONENT(R2) PRINT *,' Radix = ', RADIX(R2 ), ' Range =', RANGE(R2) PRINT *,' ' ! ! PRINT *,' Kind ', KIND(R3 ), ' Digits ', DIGITS(R3 ) PRINT *,' Huge = ',HUGE(R3 ), ' Tiny =', TINY(R3) PRINT *,' Epsilon = ',EPSILON(R3),' Precision = ', PRECISION(R3) PRINT *,' Exponent = ',EXPONENT(R3), 'MAXExponent = ', MAXEXPONENT(R3), ' MINExponent = ',MINEXPONENT(R3) PRINT *,' Radix = ', RADIX(R3 ), ' Range =', RANGE(R3) PRINT *,' ' ! END PROGRAM ex_2_6
[ 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