How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

16
How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont

Transcript of How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Page 1: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

How to Write a Fortran Jiffy

(C)2005 Mark RouldUniversity of Vermont

Page 2: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

• Lines with a "C" or "!" in column 1 are comments (ignored)

• Lines which start with something in column 6 are continuations of the previous line

• All other lines should begin in column 7 or later

Fortran has a few idiosyncrasies...

123456789012345678901234567890123456789012345678901234567890...c This line is a comment! This line is too. write( 6, *) 'This is a normal line (aka, a statement)' do i = 1, 3 write( 6, *) 'This statement continues ', & 'on the next line.' end do end123456789012345678901234567890123456789012345678901234567890...

Page 3: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Programs Play with Data;Data is stored in Variables

3 types of variables will get you far in Fortran:

• INTEGER for holding whole numbers: 43, -9843, 0

• REAL for holding numbers with decimal fractions and/or exponents: 43.546, 3.14159, -1.6180339, 6.0221E23

• CHARACTER for holding anything alphanumeric: "I love Fortran!", "Nothing from nothing leaves 0"

Other notables:• LOGICAL variables hold values of either TRUE or FALSE• COMPLEX variables are really two REALs (a real part and an imaginary part)• Any of these variables can be used in arrays• All of the numeric variables are also available as DOUBLE PRECISION (at least twice as many significant digits)

Page 4: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Do you have any variables to declare?

implicit none

integer Hin, Kin, Lin, & Hout, Kout, Lout, & m11, m12, m13, m21, m22, m23, m31, m32, m33, determinant, & endOfFileFlag, & nreflectionsRead, nreflectionsWritten, nsysAbsencesTossed

character filename*200, headerLine*100, restOfReflectionLine*32

real detector_width, wavelength, & min_xtl_detector_dist, max_xtl_detector_dist, & xtl_detector_dist_increment, xtl_detector_dist, & twoTheta_max_radians, twoTheta_max_degrees, highest_resolution

It's always a good idea to have an implicit nonestatement as the first line of your program -- It forces you to declare your variables at the beginning of the program, but it also helps catch a lot of typos.

All of these variables aredeclared to be integers

These are declared as character variables;the # after the * indicates how many characters long they are.

These variables will hold real numbers.

Page 5: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Getting Data In and Out

write( 6, *) 'Width of detector (in mm)?'

read( 5, *) detector_width

Display on the terminal

Take input from the user and store it in this variable

Page 6: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Could you get me that file?

write( 6, *) 'Input .sca file:' read( 5, '(a)') filename

open( unit=1, file=filename, status='old')

read( 1, '(i4,i4,i4,a32)', iostat = endOfFileFlag ) Hin, Kin, Lin, restOfReflectionLine

Open an existing (old) file whose name is stored in the character variable filename

Read a line from that file, take the integer number in the first 4 columns and store it in variable Hin, take the number in the next 4 columns and store it in Kin, the next 4 in Lin, and store the next 32 columns as alphanumeric data in the character variable restOfReflectionLine.

If we run out of data while trying to read from this file, then the variable endOfFileFlag will be set to a non-zero value; otherwise it will be set to 0.

Page 7: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

File This Away

write( 6, *) 'Output .sca file:' read( 5, '(a)') filename

open( unit=2, file=filename, status='unknown')

write( 2, '(i4,i4,i4,a32)') Hout, Kout, Lout, restOfReflectionLine

Open this file, regardless of whether or not it already exists.

Write the values in these variables to the file in the specified format.

Section of output file: 9 5 12 2259.5 138.0 2355.5 108.8 9 5 13 679.9 134.7 766.4 68.5 9 5 14 1477.4 119.0 1237.8 78.5 9 5 15 2163.2 149.2 2511.8 171.4 9 5 16 544.5 138.7 480.1 131.1

Page 8: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Data Games

nreflectionsRead = 0

Store a 0 in this variable

nreflectionsRead = nreflectionsRead + 1

Take the amount stored in this variable,add 1 to it, and store the result back inthe same variable.

Page 9: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

More Fun with Variables

Hout = m11 * Hin + m12 * Kin + m13 * Lin

+ - * /sin( ) asin( )cos( ) acos( )tan( ) atan( )mod( a, b) -- remainder of a/b

highest_resolution = wavelength / ( 2. * sin( 0.5 * twoTheta_max_radians))

Use parentheses liberally toforce the order of evaluation

Calculate the sine ofthe following expression in parentheses

Variables

Page 10: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Decisions Decisions

if ( min_xtl_detector_dist .le. 0.0 ) then

write( 6, *) 'This distance must be greater than 0.0 mm.'

stop

end if

.eq. =

.lt. <

.gt. >

.le. < or =

.ge. > or =

.ne. not =

Only if the expression in parentheses is true will the statements in between be executed.

Page 11: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

if ( ( Hout .eq. 0 ) .and. ( Kout .eq. 0 ) .and. ( mod( Lout, 2) .ne. 0 ) ) then

write( 6, '( " ** Tossed ** ", 3i4, a32)' ) Hout, Kout, Lout, restOfReflectionLine

nsysAbsencesTossed = nsysAbsencesTossed + 1

else

write( 2, '(3i4,a32)') Hout, Kout, Lout, restOfReflectionLine

nreflectionsWritten = nreflectionsWritten + 1

end if

.and.

.or.

.not.

Only if all 3 of these conditions are met will the statements between the then and else be executed;else if not, the statements between the else and end ifwill be executed

Tough Decisions

Page 12: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Loop-de-Loop

do i = 10, 20, 2 write( 6, *) iend do

A simple loop: "Begin by setting the variable i to 10. Execute all statements up to the end do, then go back up to the beginning of the loop, increment i by 2, and repeat until i exceeds 20."

101214161820

Page 13: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

do xtl_detector_dist = min_xtl_detector_dist, max_xtl_detector_dist, xtl_detector_dist_increment

twoTheta_max_radians = atan( 0.5 * detector_width / xtl_detector_dist)

twoTheta_max_degrees = twoTheta_max_radians * 180. / 3.14159

highest_resolution = wavelength / ( 2. * sin( 0.5 * twoTheta_max_radians))

write( 6, '(5x, f6.1, 19x, f5.2, 21x, f5.1)') xtl_detector_dist, highest_resolution, twoTheta_max_degrees

end do

When this loop is reached, the variable xtl_detector_dist will be set to the value in variable min_xtl_detector_dist.

Do (execute) all statements up to the end of the loop, indicated by end do.

At the bottom of the loop, xtl_detector_dist_increment is added to xtl_detector_dist. As long as xtl_detector_dist does not exceed max_xtl_detector_distance, the loop repeats.

Loop-de-Loop, part Deux

Page 14: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

endOfFileFlag = 0

do while ( endOfFileFlag .eq. 0 )

read( 1, '(3i4,a32)', iostat = endOfFileFlag ) Hin, Kin, Lin, restOfReflectionLine

if ( endOfFileFlag .eq. 0 ) then

nreflectionsRead = nreflectionsRead + 1

Hout = m11 * Hin + m12 * Kin + m13 * Lin

Kout = m21 * Hin + m22 * Kin + m23 * Lin

Lout = m31 * Hin + m32 * Kin + m33 * Lin

. . .

end if

end do

Repeat this loop as long as the condition in parentheses is true

How long do I have to keep doing this?

Note: The indenting is not required,but helps make the program more legible.

Page 15: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

write( 6, '(a)') ' Xtl-Det Dist (mm) Highest Resolution (A) 2theta_max (deg)' write( 6, '(a)') ' ----------------- ---------------------- ----------------'! '.....####.#...................##.##.....................###.#'

write( 6, '(5x, f6.1, 19x, f5.2, 21x, f5.1)') xtl_detector_dist, highest_resolution, twoTheta_max_degrees

5x -- skip 5 spacesf6.1 -- write a real value in a total of 6 spaces, with 1 decimal digiti5 -- write an integer value in 5 spacesa7 -- write 7 characters of a character variable

How do you want that written?

The same format specifiers can be used for reading too.

Page 16: How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.

Compiling and Running your Jiffy

g77 yourProgam.f -o yourProgram -ffixed-line-length-255

To compile (ie, convert your program into the computer's native tongue)

To run:

yourProgram