Introduction

            The class PHZ 6156, computer methods in physics, is about using computers to solve physics problems such as interpolation, integration, transforms, and differential equations.  Since computers are constantly evolving and at present there are many different flavors available to members of the physics department, the course concentrates on the lowest common denominator which works with modifications on all computers.  More user friendly editors and routines exist and I do not object to their use, but such users will have to be semi-independent.

            At the beginning of the course, I hand out a CD containing Watfor.  This is Fortran 77 restricted to 640K which was once thought to be the most that anyone would ever need.  It is also the best debugger that I have ever found.  It is adequate for the course.  Openwatcom is an open-source version of the combination Fortran and C compiler that Watcom was working on when it went bankrupt.  It contains a reasonably friendly IDE (editor/compiler) and allows a reasonably easy mixing of Fortran and C in windows.  It chief virtue is that it is free.  The programming part of the course is natural in Unix/Linux.  These come with open-source f77 and gcc, and Fortran and C mix easily.  Debugging is a little harder than with Watfor and the word processing is not as easy. 

            To display the results of codes, it is necessary to have plotting routines.  On the PC's the locally written GPLOT which is available from the website enables this.   On Unix/Linux machines, gnuplot is available (and much more complete) for this same purpose.

            Fortran is the most evolved language.  Methods for compilers to test the code in debugging mode provide very desirable error checking.  It's rather rigid rules began at a time when codes were submitted as decks of cards and many things that are desirable for file control, directory structure, the incorporation of other codes, screen displays or controlling equipment are either not possible or are possible only in very awkward ways.  The Unix operating system is "essentially" written in C.  It is a recent language with access to most machine operations through a large set of callable functions.  It is not easy to debug.  Even the compiler error messages frequently are wrong in their guess at the mistake.  There is no checking that the array element a[100] is not actually part of the code.  In the class, routines will usually be written first in fortran and then in C. 

Variable types

                In C each variable needs to be individually typed.  The three types of concern in the beginning are double precision reals, integers and character variables.

double x;

 int i,j,nl=100 ;

 char string[80];

                In fortran the typing is by default that all variables are single precision reals except those beginning with I,j,k,l,m, and n.  Single precision is inadequate, so all main codes must begin with

                IMPLICIT REAL*8 (A-H,O-Z)

And this needs to be the second line of all functions and subroutines.

 

Input Output

                The codes written for the class will need to read from the keyboard and write to the screen.  In fortran the commands needed to read and write the integer I and double precision X  are.

                PRINT*,' ENTER I, X'

                READ(*,*)I,X

                PRINT*,I,X

The input from the screen could be

17, 32.5

or equally well

17 32.5

or even

17 32

                In C the Input is a bit more complex.  First I need an address to go to

again:

 printf("enter a value for i,x ");

 j=scanf("%d %lf",&i,&x);

 if(j != 2)

  {printf(" incorrect input probably a ,\n");

   printf("Input a string:\n");

   gets(string);

   printf("The erroneous input was: %s\n", string);

   goto again;}

which is the again:.  Then I need the format %d to tell scanf that the first variable is an integer, and the format %lf to tell it that the second variable is double precision.  Note that i, j, and x were defined in the previous section.  The code runs correctly with a space delimeter

enter a value for i,x 1 3.7

 i = 1 x=3.700000

The decimal point is not needed in the 3.7, but the standard fortran comma delimeter causes

enter a value for i,x 1,3

 incorrect input probably a ,

Input a string:

The erroneous input was: ,3

enter a value for i,x

 

                The gets(string) command is necessary to clear the input buffer.  Otherwise all subsequent calls to scanf will not work.  This problem with scanf is so bad that some authors recommend avoiding it for a string read followed by scanning the string.  The above, however, does seem to be an innocuous fix to the problem. 

File opens

Fortran

                In order to plot output using GPLOT or gnuplot, it is necessary to put the data in file.  In fortran, this involves associating a unit number with the file

      IMPLICIT REAL*8 (A-H,O-Z)

     DIMENSION F(137)

      DO I=1,137

  F(I)=I*I

      ENDDO

      OPEN(1,FILE='test.out')

      WRITE(1,'(I5,G20.6)')(I,F(I),I=1,137)

      END

Note that the format in the write statement allows for 5 digit intgers and 6 digit reals taking up 20 spaces.  The G format basically tells the computer to figure it out.  

                A useful variant of this is

      DIMENSION R(256000)

      DO I=1,256000

        R=I

      ENDDO

      OPEN(1,STATUS=’SCRATCH’)

      WRITE(1)R

      DO I=1,256000

        R=I*I

      ENDDO

      …

      REWIND(1)

      READ(1)R

In the interval marked by … all sorts of things could happen, R is free for use.  After the rewind and read, R is again equal to I.  The scratch file is handled by the system.  If it is written to the disk, it is erased at then end of the file.  A set of open parameters are in Open.txt.

 

C opens

                In C the open is a bit more openly mysterious.  The name of the file is a special type enabling the computer to keep track of all sorts of details.

#include <stdio.h>

#include <stdlib.h>

void main(void)

{

    FILE *fp;

    double f[137];

    int i;

    for(i=0;i<137;++i)

     {f[i]=i*i;}

    if((fp=fopen("test.out","w+"))==NULL){printf(" cannot open file\n");

        return;}

    for(i=0;i<137;++i)

     {fprintf(fp, "%d %lf \n", i, f[i]);}

    fclose(fp);

}

                The w+ opens the file for reading and writing.  A w or an r would restrict the file to writing only or reading only.  Details about this parameter are in CfileModes.htm.  As might be expected in a modern computer oriented language there are many other ways of reading and writing files.  The addition of C++ especially provides for very flexible I/O.

                The Fortran scratch object is somewhat meaningless to C since it has the call remove to delete any file.

#include <stdio.h>

void main()

  { remove( "vm.tmp" );  }

 

The file is however written to the disk and then removed, while the Fortran scratch at the operating systems discretion can be left in memory or swap space.  I have found C binary reads from the disk to be very efficient.

 

 

 

The hello code in C.

 The following is mostly from  The C Programming Language, Brian W. Kernighan and  Dennis M. Ritchie, Prentice Hall (1988) Chapter 1 a tutorial introduction.

enter emacs with the command emacs hello.c

note ^K kills lines in order of its use, ^Y yanks the lines back to where the cursor is

the ^^ makes a mark, ^W kills text from the mark to the cursor.  ^Y yanks it back

neptune[~] emacs hello.c

 

For information about the GNU Project and its goals, type C-h C-p.

C-x C-c

(No files need saving)

enter the c code to say hello

#include <stdio.h>                          the standard input output

main()                                             a special subroutine with no args  

{                                                     function statements begin

  printf("hello, world\n");                \n advances to the next line after the print

}                                                     function statements end

 

 

 

 

 

 

 

exit emacs by entering ^x ^c

 

 

 

 

 

 

 

 

 

-----Emacs: hello.c           (C)--All------------------------------------------

compile the c code

neptune[~] cc hello.c

run the c code

neptune[~] a.out

hello, world

leave neptune

neptune[~] exit

logout

A more complex code comparing Fortran and C

The following is a Fortran code for Fahrenheit to Celsius conversion.

<beginning of file>

      LOWER=0                                       note that by starting the name

      IUPPER=300                                    with an I,J,K,L,M. or N it is

      ISTEP=20                                                 a 4byte integer

      DO IFAHR=LOWER,IUPPER,ISTEP

        PRINT'(I4,F6.1)',IFAHR,(5./9.)*(IFAHR-32)   The format is in     

      ENDDO                                                      ‘( )’, The math is floating

      END                                                            point because of the 5.

<end of file>

WATFOR-77 V3.0 Copyright WATCOM Systems Inc. 1984, 1988

 

F1:Pg_ 2:Pg_ 3:L_ 4:L_ 5:LIns 6:LDel 7:Select/Deselect 8:Cut 9:Scrn/Cmd 10:Help

fcconv.for (8,1,36853) WATFOR-77 V3.0 PC/DOS

The command RUN produces the following output

RUN

   0 -17.8

  20  -6.7

  40   4.4

  60  15.6

  80  26.7

 100  37.8

 120  48.9

 140  60.0

 160  71.1

 180  82.2

 200  93.3

 220 104.4

 240 115.6

 260 126.7

 280 137.8

 300 148.9

                                                                       <hold>
The c version of the same code is

#include <stdio.h>

 

#define    LOWER  0      /* lower limit of table */  these are symbolic names

#define    UPPER  300    /* upper limit */         they go into code exactly as

#define    STEP   20     /* step size */           is and are strings not numbers

 

/* print Fahrenheit-Celsius table */

main()

{

      int fahr;

      for (fahr=LOWER; fahr <= UPPER; fahr = fahr + STEP )  a do loop

        printf("%3D %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

}

it is saved as fahr2cel.c and compiled with the command

cc fahr2cel.c

a.out

 

  0  -17.8

 20   -6.7

 40    4.4

 60   15.6

 80   26.7

100   37.8

120   48.9

140   60.0

160   71.1

180   82.2

200   93.3

220  104.4

240  115.6

260  126.7

280  137.8

300  148.9

neptune[~] exit

logout

CLI: Connection closed.

port2@annex: hangup

the following code results from the fortran code above when run on quark with the command

f2c fahr2cel.f

/* fahr2cel.f -- translated by f2c (version 19950105).

   You must link the resulting object file with the libraries:

                -lf2c -lm   (in that order)

*/

 

#include "f2c.h"

 

/* Table of constant values */

 

static integer c__1 = 1;

 

/* Main program */ MAIN__()

{

    /* System generated locals */

    integer i__1, i__2;

    real r__1;

 

    /* Builtin functions */

    integer s_wsfe(), do_fio(), e_wsfe();   start, do fortran io, end

 

    /* Local variables */

    static integer ifahr, istep, lower, iupper;

 

    /* Fortran I/O blocks */

    static cilist io___5 = { 0, 6, 0, "(I4,F6.1)", 0 };

 

 

    lower = 0;

    iupper = 300;

    istep = 20;

    i__1 = iupper;

    i__2 = istep;

    for (ifahr = lower; i__2 < 0 ? ifahr >= i__1 : ifahr <= i__1; ifahr +=   same for loop

                    i__2) {

                s_wsfe(&io___5);                         starts wsfe                                 

                do_fio(&c__1, (char *)&ifahr, (ftnlen)sizeof(integer));     outputs integer

int r        r__1 = (ifahr - 32) * (float).55555555555555558;            double precision

                do_fio(&c__1, (char *)&r__1, (ftnlen)sizeof(real));          outputs real

                e_wsfe();                                     end wsfe

    }

} /* MAIN__ */

The code is compiled on quark with the command

cc fahr2cel.c -I/usr/local/include -lf2c -lm

                                            f2c library                       

                   seach this dir for includes      normal math library