[ 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 consist of:
presenting the use of FORMAT in reading operations.
considering basic techniques about the reading of files in
Fortran
.
presenting possible alternatives to the standard I/O: here documents and the NAMELIST type input.
presenting internal files.
This chapter is very much linked with the previous one, having an emphasis in reading data instead of writing them. We present interesting options for providing input data to a program. Formatted input is seldom used with the keyboard, though it is very important when reading data stored in a file.
The FORMAT statement acts in a completely equivalent way to the one explained in INPUT/OUTPUT (I), Chapter 6.
A useful option of the READ command is IOSTAT. It allows to detect if the read process has reached the end-of-file:
READ(UNIT=unit_number, FMT=format_label, IOSTAT=integer_var) variable_list
Thus, if if we read a set of data, e.g. coordinates in space as (var_X,var_Y,var_Z) from a file and we do not know the total number of coordinates included we can proceed as follows
num_data = 0 readloop: DO ! READ(UNIT=33, FMT=100, IOSTAT=io_status) var_X, var_Y, var_Z ! ! Check reading IF (io_status /= 0) THEN ! Error in the input or EOF EXIT ENDIF num_data = num_dat + 1 ! work with the coordinates ! ...... ! ! Format statement 100 FORMAT(1X, 3F25.10) ! ENDDO readloop
The integer variable num_data is a counter that indicates the number of points read and the integer io_status check if the reading has been correct.
The example Programa ejemplo_7_1.f90, Section 7.3.1 presents how to read array slices from a file were students' grades are indicated in rows (students) and columns (subjects).
A convenient way to convey the input to a Fortran
program is
making use of a here documents from the bash shell
.
A here document is a brief script[8], such that apart from compiling (if necessary) and running the program, the input is given in a way that comments can also be included. Example excode_7_2.f90, Section 7.3.2 is a program that computes the roots of a second order algebraic equation y = A*x**2 + B*x + C and ej_here_file included in Script ej_here_file, Section 7.3.3, is an application of a here document. In order to run this program proceed as follows
. ej_here_file
The namelist format is quite informative, consisting in a list of values assigned to variables labeled with their names. The command NAMELIST syntax is
NAMELIST/var_group_name/ var1 [var2 var3 ... ]
This statement define a set of variables assigned to the var_group_name and should appear in the program prior to any executable statemnt. The reading of variables included in a NAMELIST is done with a READ statement where, instead of specifying a format with the FMT option, is used the option NML as follows[9]
READ(UNIT=unit_number, NML=var_group_name, [...])
The NAMELIST file with the variable information must start each line with the "&" character, followed by the variable group name, var_group_name, ending the line with the character "/". The values in the file can be in different lines but always between the two mentioned characters.
Program excode_7_3.f90, Section 7.3.4 is almost identical to program excode_7_2.f90, Section 7.3.2 but it has been modified to make use of a namelist file, called sec_order.inp, included as namelist input file, Section 7.3.5.
In the example excode_7_4.f90, Section 7.3.6 you can find an internal file, where the I/O takes place in an internal buffer instead than in a file. This is rather handy to treat data of unknowkn format, reading them first in a character variable and treating them later, or to handle data mixing variables of different types, like character and integer. This is the case in the example excode_7_4.f90, Section 7.3.6 where a series of different numbered files are defined and data saved in them. sucesivamente. In this example the intrinsic function TRIM is used to remove trailing spaces from the variable pref.
PROGRAM EJEMPLO_7_1 IMPLICIT NONE !Definicion de variables INTEGER , PARAMETER :: NROW=5 INTEGER , PARAMETER :: NCOL=6 REAL , DIMENSION(1:NROW,1:NCOL) :: RESULT_EXAMS = 0.0 REAL , DIMENSION(1:NROW) :: MEDIA_ESTUD = 0.0 REAL , DIMENSION(1:NCOL) :: MEDIA_ASIGN = 0.0 INTEGER :: R,C ! ! Abrir fichero para lectura OPEN(UNIT=20,FILE='notas.dat',STATUS='OLD') ! DO R=1,NROW READ(UNIT=20,FMT=100) RESULT_EXAMS(R,1:NCOL),MEDIA_ESTUD(R) ! Lectura de notas y luego de promedio 100 FORMAT(6(2X,F4.1),2X,F5.2) ! Se leen 6 numeros seguidos y luego un septimo ENDDO READ (20,*) ! Saltamos una linea con esta orden READ (20,110) MEDIA_ASIGN(1:NCOL) ! 110 FORMAT(6(2X,F4.1)) ! ! IMPRESION DE LAS NOTAS EN LA SALIDA ESTANDAR DO R=1,NROW PRINT 200, RESULT_EXAMS(R,1:NCOL), MEDIA_ESTUD(R) 200 FORMAT(1X,6(1X,F5.1),' = ',F6.2) END DO PRINT *,' ==== ==== ==== ==== ==== ==== ' PRINT 210, MEDIA_ASIGN(1:NCOL) 210 FORMAT(1X,6(1X,F5.1)) END PROGRAM EJEMPLO_7_1
PROGRAM ex_7_2 ! Second degree equation solver ! y = A*x**2 + B*x + C IMPLICIT NONE ! Variables REAL :: A = 0.0 REAL :: B = 0.0 REAL :: C = 0.0 REAL, DIMENSION(2) :: SOL REAL :: TEMP INTEGER :: I ! ! Input: A, B, C READ*, A READ*, B READ*, C ! ! Calculations TEMP = SQRT(B*B-4.0*A*C) ! SOL(1) = (-B+TEMP)/(2.0*A) SOL(2) = (-B-TEMP)/(2.0*A) ! ! ! DO I=1, 2 PRINT 200, I, SOL(I) 200 FORMAT(1X,'SOLUTION ', I2,' = ',F18.6) END DO ! END PROGRAM EX_7_2
# Compile.. gfortran -o second_order excode_7_2.f90 # And Run... ./second_order <<eof 2.0 # A 1.0 # B -4.0 # C eof
PROGRAM ex_7_3 ! Solving second order algebraic equation ! y = A*x**2 + B*x + C IMPLICIT NONE ! Variables REAL :: A = 0.0 REAL :: B = 0.0 REAL :: C = 0.0 REAL, DIMENSION(2) :: SOL REAL :: TEMP INTEGER :: I ! ! NAMELIST DEFINITION NAMELIST/INP0/ A, B, C ! NAMELIST FILE OPEN(UNIT=10,FILE='sec_order.inp',STATUS='OLD') ! Inpot of A, B, C READ(10,INP0) ! ! Calculations TEMP = SQRT(B*B-4.0*A*C) ! SOL(1) = (-B+TEMP)/(2.0*A) SOL(2) = (-B-TEMP)/(2.0*A) ! ! ! OUTOPUT DO I=1, 2 PRINT 200, I, SOL(I) 200 FORMAT(1X,'SOLUTION ', I2,' = ',F18.6) END DO ! END PROGRAM EX_7_3
# # INPUT FILE FOR excode_7_3.f90 # &INP0 A=2.0, B=1.0, C=-4.0 /
PROGRAM ex_7_4 ! ! Internal file example ! IMPLICIT NONE ! Variables REAL :: x_var INTEGER :: unit_n, index_X CHARACTER(LEN=65) :: filename CHARACTER(LEN=56) :: pref ! PRINT*, "Introduce file name preffix: " READ(*,*) pref ! DO unit_n = 10, 20 ! WRITE(filename, '(A, "_", i2,".dat")') TRIM(pref), unit_n OPEN(UNIT = unit_n, FILE = filename, STATUS = "UNKNOWN", ACTION = "WRITE") ! DO index_X = 0, 100 x_var = REAL(index_X)*0.01 WRITE(unit_n, '(1X,2ES14.6)') x_var, SIN(REAL(unit_n)*x_var) ENDDO ! CLOSE(UNIT = unit_n) ! ENDDO ! END PROGRAM ex_7_4
[ 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