How to Write a Fortran Jiffy (C)2005 Mark Rould University of Vermont.
-
Upload
iris-little -
Category
Documents
-
view
219 -
download
0
Transcript of 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
• 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...
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)
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.
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
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.
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
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.
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
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.
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
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
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
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.
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.
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