General Programming Practices, Fortran Language, Fortran Compiler, Unix, General Computing, Numerical Methods, Class Procedures
The bytes and accuracy of an Unformatted type number is determined by type declaration for the variable containing the number. On most workstations an number contained in a variable declared REAL takes up 4 bytes and represent a real number to 6 or 7 decimal digits of precision. Write that variable to a file as and Unformatted number, and you take up 4 bytes and get the same 6-7 decimal digits of precision. If you write that number to a file as a Formatted number, the number of bytes and decimal precision depend on the edit descriptor used for the format. If I write the number with an "e12.3"edit descriptor, the "12" says it will occupy 12 bytes (some may just be "blank", but the space is used). The 3 tells you that you get 3 decimal digits of precision (unless the "e12.3" is preceded by "1p", then you get 4 decimal digits of precision. If I write the number with an "f8.3" edit descriptor, the "8" says it will occupy 8 bytes. The "3" give 3 digits after the decimal, but there is also one before the decimal for a total of 4 digits of precision.
What are some important uses of character variables?
One of them is given to you in Homework 10. Character variables are very handy for obtaining and storing the names of files that you will need to open in your program. This gives you the flexibility to keep several different input files in the same directory, and to generate output with names related to your input. Another major use is for generating more readable and meaningful error message. You gather pieces of information about the code failure and concatenate them into a meaningful sentence. A third use is for graphical interfaces. When you fire up a Word Processor or spread sheet, all those nice menu headings and labels exist in the program somewhere as the content of character variables. Good scientific and engineering applications contain the ability to generate various graphs of the results. The labels for the axes, axis labels, graph title, etc. are all stored and passed as character variables.
I would like to know more on array applications.
We will be using arrays extensively for the rest of the semester. Watch the applications that are presented in class, the text, and homework.
If the statement "real a(:)" appears directly in the subroutine, you should deallocate before returning, and the information is not available to other parts of the program ("a" can not be included in the subroutines dummy argument list). Failure to deallocate the array before the RETURN from the subroutine does not kill the program, it just results in extra memory required to run the program that you can't reuse.
If the statement "real a(:)" appears in a MODULE that is used by a subroutine, then space created by an ALLOCATE statement in the subroutine is available to any portion of the program that uses the same MODULE. In this case you should not deallocate the array before a RETURN, unless you really don't need the contents of array "a" again.
I'm Confused about the general abilities of arrays. What must be programmed to produce a complete array and what outcomes are then available for a relatively simple array?
An array is just a way of grouping together information that has very similar characteristics. You've seen me group a bunch of temperature values as elements of a single array named "t". I could put all the names of class members into an array called "name", one class member in each element. This process is just like filling in columns box by box on a spreadsheet.
Two steps are necessary in programming an array. First you must declare a given variable name to be an array, and allocate memory space (number of elements or data values). The easy way to do this is with a type statement. To create an array with space for 100 temperatures:
real t(100)These are generally not a random set of temperatures. For physical information, you usually build your program so that the position in the array has some relation to location of the data. For example these might be temperatures at 100 altitudes above some weather station. I would couple the temperatures to location by creating a second array named "z" to contain altitudes.
real t(100), z(100)The altitude at which the 3rd temperature was obtained would be stored in the 3rd element of the array "z".
Remember that the other way to allocate space for an array is through the allocate statement, you then declare a variable as an array and allocate its space in two separate statements. First declare the arrays with
real t(:), z(:)Note that the ":" is required here to say "this is an array, but I don't know how large it is". Later in the program you allocate the space:
allocate( t(n), z(n))where the variable n contains the result of some test or prompt to the user to determine the number of array elements needed.
Once you have the array space, the next step is to put something there. You might get the initial data from a read statement:
read (11,*) (t(i),i=1,100)Think how much easier this is than if you had used an individual variable for each of your temperatures (say t1, t2, t3, ..., t100). You would need a much longer read statement
read (11,*) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, & t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, & t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, & t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, & t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, & t51, t52, t53, t54, t55, t56, t57, t58, t59, t60, & t61, t62, t63, t64, t65, t66, t67, t68, t69, t70, & t71, t72, t73, t74, t75, t76, t77, t78, t79, t80, & t81, t82, t83, t84, t85, t86, t87, t88, t89, t90, & t91, t92, t93, t94, t95, t96, t97, t98, t99, t100One thing worth noting is that you are not required to fill or use all of the space that you initially allocate for the array.
Once you have values in your array, you can do anything with the array elements that you can with individual variables. If the measurements are in Fahrenheit and you need Kelvin, you can convert simple temperature with:
tk1 = 5./9.*( t1 - 32.) +273.16or you can convert an array element loading the result into a new array:
tk(i) = 5./9*(t(i) -32.) + 273.16With the array construct you can now embed the statement in a DO loop and convert all temperatures with 3 lines:
do i=1,100tk(i) = 5./9*(t(i) -32.) + 273.16
enddoor even easier, you can use range operators to do the whole job in one line:
tk(1:100) = 5./9*(t(1:100) -32.) + 273.16
If you allocate space for an array in a subroutine, do you have to deallocate before you leave that subroutine? Once an array is allocated in the subroutine, is that good for the rest of the program?
The answer to these questions depends on whether the array is declared in a MODULE. If the statement:
real a(:)is part of the coding of the subroutine, then the contents of the array are not available to the rest of the program (you can't pass it through the argument list), and you should deallocate it before exiting the subroutine (or function). The compiler won't complain if a DEALLOCATE statement is not included, but when you leave the subroutine, it loses track to the allocated memory. If you enter the subroutine again you can't access the values in the previous allocation, and using ALLOCATE again just picks up new memory, adding to the size of the program with each call to the subroutine. Deallocating the array before a RETURN, frees the memory, so your program's memory size is the same after the call as it was before the call to the subroutine.
The situation changes if the statement "real a(:)", actually appears in a MODULE, and you use that module in your subroutine. Then when you allocate the array in the subroutine, the space can always be found and is available to any other part of the program that uses the same MODULE.
Can you go over SUM, MINVAL, MINLOC etc. again and is this important?
This class of functions is important because it improves the speed of your program, while making it shorter and easier to interpret. Usually you use them with a single argument, the name of an array. For example
tsum = sum (t)adds all of the elements in the array "t". You can also include the range of elements to be summed:
tsum = sum ( t(1:20) )which sums elements 1 through 20. There is also an optional argument that you need to know, "MASK =". Think of it as a way of activating IF tests within the function. For example a simple minded Fortran representation for what goes on in a reference to "minval(a(1:n))" is:
aminval=1.e38 do i =1,n aminval=min(aminval,a(i)) enddo minval=aminvalIf instead I include the "mask" argument, for example as "minval(a(1:n),mask=a.gt.0)", then the action in minval could be represented as:
aminval=1.e38 do i =1,n if(a(i).gt.0) aminval=min(aminval,a(i)) enddo minval=aminval
Yes. I recommend that you use FTP to move them from the Unix machine to the floppy drive on a PC. However, if you are very ambitions, there is a floppy drive hidden behind a swing down door on the front of the Hammond machines. Use man to learn how to use the dosread and doswrite commands on the Hammond machines.
GENERAL PROTECTION Fault in MODULE
xxxx in xxx.exe
What is a General Protection fault? Is the MODULE like the MODULE in F77?
General Protection fault means that the program is trying to access a portion of memory that it shouldn't be using. Generally this is the result of a code bug in some sort of array operation, or a reference to a function that wasn't defined in program xxx.exe. In this context "MODULE" is analogous to a Subroutine not a Fortran MODULE.
Maintained by John Mahaffy : firstname.lastname@example.org