0% found this document useful (0 votes)
9 views8 pages

Build simple Fortran Program

The document provides a comprehensive guide on using Fortran for molecular simulations, including basic programming concepts, compiling code, and handling input/output files. It details the steps to create a simple Fortran program, manipulate strings, and implement loops and conditional statements. Additionally, it covers formatting output and error handling in the context of a Monte Carlo simulation program.

Uploaded by

Matthew Ward
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views8 pages

Build simple Fortran Program

The document provides a comprehensive guide on using Fortran for molecular simulations, including basic programming concepts, compiling code, and handling input/output files. It details the steps to create a simple Fortran program, manipulate strings, and implement loops and conditional statements. Additionally, it covers formatting output and error handling in the context of a Monte Carlo simulation program.

Uploaded by

Matthew Ward
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

Molecular Simulations and Simple Fortran Programming

A. Molecular Dynamics and Monte Carlo simulations are often written in the computer
language Fortran, which stands for The IBM Mathematical Formula Translating System and was
first used in the 1950’s. The Monte Carlo program we’re going to work with is written in
Fortran, so we are going to first spend some time learning the basics of Fortran. There are many
resources on the internet; http://www.cs.umbc.edu/~squire/fortranclass/summary.shtml#Form
gives a long list of basics for the Fortran language, including formatting, and commands. The
commands deal with characters and strings, numbers, and logical true/false (Boolean) statements.

All computer programs, no matter what language they’re written in, need to be compiled by the
language’s compiler. This turns the code into instructions (machine language) that the
computer’s processor can understand. Different types of computers with different processors,
then, need different compilers to run the same Fortran program. The Fortran program itself is a
simple text file that can be edited in simple programs like Notepad or Wordpad. We will do
editing in the MS-DOS shell’s simple editing program. The other main part of writing and
running computer code besides the program and the compiler are input and output files. An
input file is another text file that contains parameters that are input into the program, telling it
specifically what we want it to do; we say that the program reads the input file. The program
outputs (or writes) data to output text files. These files contain the key results of the program.
One such type of output file we’ll be working with are the configuration files that give the xyz
coordinates of all the atoms in the simulation.

1. Get Command Prompt Window ( C:\) by searching for ‘command prompt.’


2. You won’t be in the right directory location (or “folder”), so navigate to the MinGW/bin
directory by typing “cd C:\MinGW\bin” at prompt and hit return (cd is the DOS command for
‘change directory’). If you’ve never used DOS, you can go backwards in the directory tree by
typing “cd ..”. Try this by going back to the MinGW directory, and then go to ..\bin again by
typing “cd bin”. Finally, in the MinGW\bin folder type “dir” and return to get a listing of all
the files there. “dir” is a much-used command to see what files are in the current folder.
3. Start your first fortran program just by typing at the prompt “notepad first.f”
This is calling your first fortran program first.f (the suffix .f is needed for all programs). The edit
window will replace the DOS screen and you can start adding text to first.f. Open the status bar
so that you can see the row and column location of the cursor.
4. Type in the following code, more or less as it appears, but not the bracketed < >
comments teaching you about the language. Spaces between lines don’t matter. NOTE: You
must start at the 7th space of the line with code; ‘c’ characters in the first column of input tell the
compiler that the line is a “comment” line, where you write notes to yourself and others who
might read the program. The comments are to help you understand what the program is doing.
Anything appearing in a comment line is ignored by the compiler and plays no role in the
function of the program. Brief comments on the purpose of each line are in brackets. The &
symbol can be used as a line continuation symbol (see the monte carlo code later in manual).

program first <names the program>


implicit none <fairly standard; it means all variables will be declared>
c **************************************************
c *This is just a simple first-time Fortran program*
c **************************************************

integer i,j <declaring integer variables to be used in code>


real h <declaring a real variable ‘h’>
character*10 name <declaring a character, which is a letter or symbol
c define constants other than a number. The *10 indicates ‘name’ is a
string of characters, but still called a character>
h = 6.62608d-34 <defining the value of h, Planck’s constant>
print *, 'What is your name?' <a ‘print’ statement writes to the screen>
read (*,*) name <the ‘read’ with the * reads from the
previously defined file or venue (screen in this
case);
what you typed in was assigned to ‘name’>
write (*,20) name, h <This and the next line write to the screen with a set
format given in line 20; print and write are similar, print is
20 format(A,' is',ES12.5,' years old!') usually just for the screen>
NOTE THE 20 MUST BE IN THE 2nd and 3rd COLUMN, NOT THE FIRST
end program <This is needed to end the program>

5. Now save the program as a text file, but include the full name in quotes to avoid having a
problematic .txt added to your file. After this, when you modify the program repeatedly you can
just ‘save’ it the quick way and it will preserve the right filename.
6. The next thing we have to do is compile the program. We will get out a file with the
suffix ‘.exe’ and then just type that filename (w/o the .exe suffix) to run the program. Loaded on
these computers is the ‘gfortran’ compiler, which is a more modern version of Fortran.
To compile our program, type “gfortran first.f –o first.exe” (you could
also choose your own executable filename, but it often makes sense to just stick with the same
name as the *.f program, which is first.f in our case). If you now search the directory (type
“dir”) you should see the new executable file. If there was a problem with your program, it
won’t compile and you’ll get an error message and possibly some help as to what is wrong.
7. Now you can see your program in action by typing “first” at the command prompt.
8. It is likely that there is too big a space between your name and the word ‘is.’ This is
because ‘name’ is given 10 character spaces due its definition as character*10 in the program.
So even if your name isn’t 10 letters, ‘name’ still contains extra spaces to make 10 characters.
We can fix this in a number of ways, each of which teaches you a bit more about programming.
So, we need to edit the program, so type in “notepad first.f”.

Hitting the up and down arrows on the keyboard will bring up recent DOS commands so you
don’t have to retype everything.

9. Let’s try using the ‘adjustr’ command. Add a line of code right after ‘name’ is read in:
name = adjustr(name)
This scoots your name to the end of the 10 character string, putting spaces in front. Resave and
exit your program (alt-F and ‘x’) and then recompile it. Use the arrow keys to get the gfortran
etc. command so you’re not always retyping it. It will overwrite the previous .exe file, so don’t
worry about renaming it.
10. Now run the program again and you should see the spacing taken care of. There is still an
issue, though, which we can see by going back to the code (notepad first.f) and adding
‘Did you know that ‘, to the format line:
20 format(‘Did you know that ’,A,' is ',ES12.5,' years old?!')

11. Save, recompile, and run the program again. You should now see a space issue between
‘that’ and your name. This is because the extra spaces got put on the other side of the ‘name’
character string. By the way, the ‘A’ that appears in the format line tells the computer that a
character is being printed where the ‘A’ is; that character is the first entry of the write line right
above, ‘name.’ The ES12.5 refers to the formatting in scientific notation of the real number, h.
The 12 sets the total width, including the d-23. The ‘d’ refers to ‘double precision’ which gives
the most significant figures by the computer for the number. The ‘5’ says only 5 decimal places
should be used.
12. Re-edit your program and comment out that ‘adjustr’ line (put a ‘c’ in the first column).
In the write (*,20) line replace ‘name’ with ‘trim(name)’. This will trim off an extra spaces.
Save, recompile, and run to see the improvement in formatting.
13. At the risk of belaboring the point, let’s use one other means of accomplishing the
formatting which also gives us a bit more information. We will find out how many characters
long your name is, and then have a variable format ready to go that incorporates the length. This
is slightly more complicated, but introduces some other programming tricks. Open up the
program (don’t forget the arrow keys to find the command you want) and add these lines:

Right after ‘h’ is defined as Plank’s constant, add a line defining ‘j’:
j = 5
Then, following the ‘read...name’ line and before the now-commented-out ‘adjustr’ line add:
i = len(name) <’len’ is a command that returns the length of the character in ( )>
print *, i,j <this just lets us know the values of i and j>
j = len_trim(name) <’len_trim’ removes the extra spaces before given the
length; this essentially gives the length of your
name>
print *, j <this will show the updated value of j>

You can save, recompile and run to see the effect of the new additions. Does it make sense?
The j was assigned to a value of 5 just to show how that is done and show that it changes after
being set equal to something else.
14. We have the length now, but this integer has to be incorporated somehow into the
formatting statement, which contains a string of characters. Open the program and add two
character*60 variables towards the top of the program, frmt and frmt2. You will also
need to add a character*1 variable called lengthA. (Again, you could call these anything
you want, but for now it’s probably easier if everyone in class uses the same words). The
formatting can work with a single character string, but that variable integer which is the length of
your name needs to be converted to a character. This is accomplished by writing the integer onto
the character. Type in the following line after the ‘print *, j’ line to do this:
write(lengthA,'(i1)') j <the ‘(i1)’ says to expect an integer of one number>
<also, be sure you typed the # 1 and not letter ‘l’>
15. Now we have to create a character string that we can use as one complete format
command. We will have to concatenate (splice) characters together. Type the following lines
after the ‘write(lengthA….’ line you just added:
frmt = "('Did you know that ',A"//lengthA//",' is',ES12.5"
frmt2 = trim(frmt)//",' years old?!')"
We couldn’t put it all in ‘frmt’ right away because the line was too long. Note that we had to
trim the frmt to get rid of any unwanted spaces. The // is the concatenate symbol and simply
joins two characters into one.
16. The last step in this reconfiguration of the formatting is easy. First, let’s put in a print
statement to make sure we’ve concatenated things correctly. After the ‘frmt2=…’ line add:
print *, frmt2
Then, we can comment out the ‘20 format….’ line (put a ‘c’ in front of the 20) and replace the
20 reference in the write line above with ‘frmt2’:
write (*,frmt2) name,h
Save, recompile, and run to make sure it works.
17. Before we leave the formatting nitty-gritty, one last thing to see. Switch the number
format for h to ES11.5 instead of ES12.5. Save, recompile, and run. You should see that we
lose that desired space in the output because it had been due just to 6.62608E-34 having only 11
characters instead of 12.

Do loops, if/then/else, subroutines


18. Type in the following in a line before the main write statement that we’ve been
formatting (write(*,frmt2) name,h) and indent it a bit from the other lines:
do k = 1,5 (You’ll have to define ‘k’ as an integer at the top of the program)
Now a brief line right after the write statement, indented the same amount as the ‘do’ statement:
enddo
This constitutes a ‘loop.’ The ‘do’ tells the computer to execute the commands that follow 5
times. It loops through the following commands (between the ‘do’ and the ‘enddo’ lines) adding
one to k each time until it gets to 5. Save, compile, run. Did it work?
19. To make it a bit more versatile, we can have the computer ask you how times you want to
print the message. Add a line before the do loop:
print *,’How many times do you want this printed?’
(You can use either ‘ or “ as long as you are consistent in beginning and closing with the same
type). Next, you add another read line like before with a new integer variable. You can name it
whatever you want, and be sure to add it to the integer list defined at the beginning of the
program. Last, replace the ‘5’ in the ‘do k = 1,5’ with your new integer variable. Save and
recompile the program to see if it works. Is it printing the number of times you tell it to? Do
you feel powerful?
20. Now we will add a little bit more to your program. Under the write command in the do
loop, add another line:
print *, k, k*[ending integer you defined]
(There is little difference between the write and print commands—print is just for the screen
output, whereas write is used for writing to other places, like files.) If you called your ending
integer ‘done’ than you would type ‘k*done’ in the above line. Compile and run.
You’ll see that you get calculated results very quickly.
21. Now let’s add an ‘if’ statement to make sure no one puts in too large a number. Type the
following in right after the line reading in the ending integer. I’m just going to call the ending
integer ‘endn’ but yours might be different. (Also, be careful you don’t exceed the maximum
characters in a line on the 1st print statement below) :

if (endn.gt.100) then
print*,’Your ending number is just too big…please try again.’
read(*,*) endn <this is a second ‘read’ line just like the one you already have>
else
print*,’That number should work just fine.’
end if

The ‘if’ statement is a conditional statement based on true/false logic. The ‘else’ that follows
should be self-explanatory. The ‘end if’ statement ends the whole ‘if’ deal. Compile and run.
22. You may realize that this still doesn’t work, because even if you initially put in too big a
number, on the second try you can do the same thing and it then accepts it. Verify that this is so.
Something more is needed to make sure you don’t get too big a number (if you really care about
that, which we do now only for teaching purposes).
Add in a ‘go to’ statement now after the second ‘read’ statement in the ‘if’ loop:
if (endn.gt.100) go to 20

Also, you need to put a ‘20’ in the 2nd and 3rd columns in front of the print statement 2 lines
above, so if the second input number is still too high, then the same statement gets printed again
telling you to input a new number. The ‘20’ labels the line so that the ‘go to’ statement tells the
program where to go. You may at this point wish to tell the program to go somewhere, also (ha).
Also, there is the possibility of an ‘else if’ line in an ‘if’ block of code. This allows for multiple
possibilities rather than just the two given by ‘if’ and ‘else’.
23. The last major piece to programming is the ‘subroutine’. This is just a little self-
contained program that services the main program. Different parts of the main program can
make ‘calls’ to the subroutine. The main program will pass variables to the subroutine, and the
subroutine returns those variables after having done a calculation or something with them. For
instance, in the Monte Carlo program there is a subroutine to calculate potential energy. That
routine could be incorporated in the main body of the program, but it is a bit lengthy and because
there are numerous places in the main program that require a calculation of the energy, than it
makes sense to only write it once and stick it in a subroutine.
We will write a short subroutine that modifies the ‘name’ that you input. Type the
following at the very end of your code (even after the ‘end program’ line):

c *** WE PUT SUBROUTINES HERE AFTER THE MAIN PROGRAM CODE***


subroutine demo(name) <This names the subroutine and says what variable is passed>

character gender <All variables used in the subroutine need to be defined>


character*10 name

print*,"Are you a male or a female? (type 'm' or 'f')"


read(*,*) gender <note that even if someone type ‘male’, gender would still be
If (gender.eq.'m') then ‘m’ because it is only one character and would take the
print*,"I've decided to change your name" first letter>
name = 'Vladimir'
else if (gender.eq.'f') then
print*,"I've decided to change your name"
name = 'Gertrude'
else
print*,"You thought you could fool me!" <in case ‘m’ or ‘f’ is not input>
end if
return
end
Next, find an appropriate spot in the main program to insert a “Call” statement that will run this
subroutine from that spot in the program. The line will be:
Call demo(name)
Now save, compile, and run. Does it make sense what happened to the program output?
24. This completes your quick introduction to Fortran programming; you have now seen and
used most of the key elements of programming, which in some form or another are common to
all computer languages. Later we will be exploring the Monte Carlo simulation code and you
now have the ability to understand most of what is going on in it. As a brief preview, flip
forward in this manual a few pages to where the entire program is printed (it’s 14 pages long).
The program is called MonteCarlo_gr.f and is the same as what is on the computer. Read the
opening comments. Note that two former students wrote this code with Dr. Eggimann’s help;
this was over half their Chem 475 experience when she taught that course one year. Also note
that two key input files are required for the program, the configuration file and the file of key
parameters. Open the input file, MCinput_gr, and see the list of various numbers included. Then
look to the beginning of the Monte Carlo code and see where these variables are read in by the
program. It begins with opening the file ‘MCinput_gr’ (or it may say something else; this is
easily changed depending on what the input file happens to be named). Every line, including
blank lines, is read by the program and assigned to a variable. All variables used are described in
the opening comments section, which is good practice in programming.

B. Using Free VMD Program and Calculating RDF’s


1. Dr. Eggimann was kind enough to generate 24 snapshots of equilibrated water on another
Monte Carlo program she has. (The Monte Carlo code we’ll be using later only deals with
monatomic substances like xenon—molecules are more complicated). The simulations were run
at 298K and 1 atm. They give a density of 0.991 +/- 0.004 g/mL. The box size is about 24.7
angstroms x 24.7 x 24.7. There are 24 of these xyz configuration files (snapshots) in the Chem
475 Simulations folder. Transfer these 24 files to the c:/temp folder on your computer. You can
do this most easily by opening each of these folders on the desktop and just highlighting them all
and moving them with the mouse.
2. Open one of these files and look at it. These are pretty straightforward; the first number
is the total number of atoms, and what follows are the x,y,z spatial coordinates locating each
atom in the 24.7 Å cube. You may see some negative values; this occurs when part of a water
molecule ends up outside the box due to the periodic boundary conditions. Rememeber, these
boundary conditions mean the cube is replicated on all 6 sides so that the molecules near the
edge of the real cube also interact with molecules in the nearby virtual cube. If one atom of the
water ends up outside the box, it just stays there because it is bonded to the rest of the molecule
inside the real box.
3. It is helpful to actually look at the box of water in addition to having programs churn
away with all the numbers. A program called VMD (visualize molecular dynamics) was
developed at U. of Illinois (a great school, by the way) and has now become widely used by
simulation researchers (all for free, of course!). (http://www.ks.uiuc.edu/Research/vmd/)
4. Open VMD from the chemistry section of the department-specific program list in the
Start menu. Three new windows will open up: one where the file will be displayed, one typical
windows “main” menu where there are many pull-down menus, and one window where script
commands can be entered at the prompt. Go to the File pull-down menu and open a ‘New
Molecule’ and Browse to find the first of the 24 configuration files, water-box-1.xyz. It should
determine this automatically to be of a ‘xyz’ file type. Load it and you should now see 500 water
molecules displayed in the display window.
5. Much of the power of this software comes from rendering the images in a wide-variety of
meaningful ways. Go to the Graphics pull-down menu and choose Representations. Go to the
Drawing Method menu towards the bottom and choose VDW (van der Waal’s). This will show
the atoms out to their vdw radius (the ‘b’ parameter of the vdw’s equation). Next, the default
Display option is ‘Perspective,’ but this is rather annoying so please choose the somewhat
cryptically named ‘Orthographic’ option instead in the Display pull-down menu. Next, try the
CPK Representation instead of van der Waal’s (which is a little congested).
6. You can move the display using the mouse, and the roller button zooms in and out.
Zoom into the middle of the water and observe its somewhat open structure due to the hydrogen
bonding network. You can also maximize the window to maximize your viewing enjoyment.
You can give the image a “spin” with your mouse; a gentle tap starts it rotating slowly, a
vigourous shove with the mouse starts it spinning quite quickly. Clicking again stops the
madness. At this point, take some time to collect yourself and wipe the tear from your eye as
you gaze at this stunning display of human achievement and natural wonder.
7. VMD like many software programs, accepts ‘scripts’ which are short chunks of code that
let the program go beyond features that are preset in pull-down menus. We will use two scripts.
The first is just used to draw a cube over our 500 water molecules. To enable this, transfer the
file box.script from the Chem 475 Simulations folder to the C:/temp directory (folder). Now, go
to the VMD window with the command prompt (not the display window). If there isn’t a
command prompt “vmd >” you can get one just by hitting ‘enter.’ Then, call the script from
your temp directory by typing: play c:/temp/box.script . This loads the program,
then you can run it by typing: box_molecule top . This draws the box on the top
configuration shown in the display window (we only have one configuration open now, so it is
the top one). You should get a nice red box that twirls along with your water.
8. Let’s load one more configuration, water-box-2.xyz. Go to the VMD Main window and
browse for a second configuration. We don’t want to add a new molecule, though, but rather add
a ‘frame’ to the current molecule by selecting ‘load data into molecule’ in the ‘file’ pull-down
menu. This means that it’s the same system (“molecule”) we’re loading but with different
configurations (frames). The reason it’s called a “molecule” is that VMD was mainly written for
bio-related simulations, so with protein conformations you would have many different
configurations (frames) of the same protein molecule.
9. Let’s do a radial distribution function on these 2 configurations. Go to the Extensions
pull-down menu and go to Analysis. Choose the Radial Pair Distribution Function and then go
to the window that pops up. First you need to select the ‘molecule’ you’re working with (there
should be only one choice). Then, go to the upper left “Utilities” and pick “set unit cell.” In the
new pop-up window you want to input 24.7 for all three edges (this is in angstroms) and hit “set
unit cell”. Select the ‘Use PBC’ box at the bottom left (this uses periodic boundary conditions
for the calculations which we have to do). Then, input “name O” into each of the Selection 1
and Selection 2 boxes. This tells the calculations to forget the hydrogens for now and just look
at average oxygen-oxygen distances. Last, hit “compute g(r)” and get a graph to pop up. You
should get a sharp peak close to 3 Å, and then more at ~4.5 and 7 Å. This shows the definite
structure of the water. Next do the same for H-H distances.
10. There is significant noise in these calculated results because we have only used 2 of the
24 configurations. We want to add all 24 configurations to make 24 frames of the same
“molecule.” Fortunately, there is a much easier way to load all these frames in instead of doing
it by hand. We can use another script called ‘multixyz.script’ which reads in multiple
configurations automatically as frames into ‘molecule 0’ (which should be the ID of your current
molecule). Find the multixyz.script file in the Chem 475 Simulations folder and put this into the
c:/temp folder. Now load the script in the VMD command window by typing:
play c:/temp/multixyz.script
Finally, run the script by typing at the vmd > prompt:
mxyz 3 24 c:/temp/water-box-%d.xyz
This loads the remaining 22 water configurations which have a generic filename water-box-
[integer].xyz. ‘mxyz’ is the command to run the multixyz script, 3 and 24 are the beginning and
ending file numbers, and the rest is the directory where to find the files, with the %d being an
integer that the script increases from 3 to 24 with each file it loads.
11. Now, you should see in the VMD Main window a molecule listed with 24 frames. Only
one frame is displayed at a time. You can scroll through the different configurations by sliding
the bar at the bottom, or hitting the left or right arrow box one in from the sides on the bottom
row. The arrow boxes at the edge of the window on the bottom row play a movie of the different
frames backwards and forwards. You can adjust the speed of the playback with the speed slider
bar on the bottom right.
12. Now, redo the rdf (radial distribution function) calculations. Go to the Extensions pull-
down menu and go to Analysis. Choose the Radial Pair Distribution Function and then go to the
window that pops up. First you need to select the ‘molecule’ you’re working with (there should
be only one choice). Then, go to the upper left “Utilities” and pick “set unit cell.” In the new
pop-up window you want to input 24.7 for all three edges (this is in angstroms) and hit “set unit
cell”. Select the Use PBC box at the bottom left (this uses periodic boundary conditions for the
calculations which we have to do). Then, input “name O” into each of the Selection 1 and
Selection 2 boxes. This tells the calculations to forget the hydrogens for now and just look at
average oxygen-oxygen distances. Last, hit “compute g(r)” and get a graph to pop up. You
should get a sharp peak close to 3 Å, and then more at ~4.5 and 7 Å. This shows the definite
structure of the water. Next do the same for H-H distances. Why is the shortest H-H peak closer
than the shortest O-O peak, and why is it so sharp? Next do the same for O-H distances. Again,
we have a very close, narrow peak. Why? Also, the g(r) dips well below one for a longer
distance than the other two rdf’s. Any ideas why this is? Save the O-O and O-H distributions
as .ps files. You can bring them up in a bit to compare to rdf’s made with only 2 configurations.
These rdf’s are definitely better signal-to-noise (S/N) than the rdf’s done with only 2
files. The lines are much smoother and we can be more confident of the results. Using just two
configurations, though, does give us a pretty good idea of what is going on.

You might also like