MD++ Tutorial
An Example Tcl File
Saad Bhamla and Wei Cai
This tutorial walks you through a complete .tcl file that performs an MD simulation.
Before reading this document, the reader is advised to read the primer of using TCL for MD++ here.
In this document, we will demonstrate how the example script file in the | previous wiki page can be easily converted to a Tcl file to give the add more flexibility and functionality to the code.
Contents |
Overall Structure of *.tcl files
In general, a tcl file for MD++ will have the following parts:
- Definition of procedures
- Main program that calls the procedures
The definition of procedures is similar to defining routines or functions in Matlab or C++. This makes it easier perform certain calculations multiple times by just invoking the previously defined function.
The main program in the Tcl file is then able to call the procedures defined above it.
Suppose you have installed MD++ in your $HOME/Codes/MD++ folder.
export MDPP=$HOME/Codes/MD++ cd $MDPP
In this example, we will use the following Tcl file:
$MDPP/scripts/Examples/example02a-si-md.tcl
Using this tcl file, we can perform the same simulation as defined in the example02a-si-md.script file. In addition, this Tcl enables MD++ to carry out a few more related tasks easily.
All characters following the # (pound) sign are comments. They will be ignored by the Tcl parser (and the MD++ program) and we will not discuss them here either.
Defining procedures
Pretty much every Tcl file used in MD++ simulations begins with the definition of procedures. The syntax for procedure definition in Tcl is
proc name { args } { body }
Output set up
To illustrate this with an example,
proc initmd { } { MD++ { setnolog setoverwrite dirname = runs/si-example } }
In this example, the procedure name is initmd and it doesn't accept any arguments. The body begins with a MD++ { to indicate that each of the following statements that follow are MD++ commands and variable assignments. These statements will be passed to the script parser of MD++.
This procedure will be called later in the main Tcl program as
initmd
At that time, three MD++ commands will be executed, which set up the output directory, as described in the previous wiki page.
Initialize atoms positions
The next procedure that is defined instructs MD++ how to create the initial configuration of the atoms. The order in which these procedures are defined is not important as long as they are defined before they are called.
proc makecrystal { nx ny nz } { MD++ crystalstructure = diamond-cubic MD++ latticeconst = 5.4309529817532409 MD++ latticesize = \[ 1 0 0 $nx 0 1 0 $ny 0 0 1 $nz \] MD++ makecrystal finalcnfile = perf.cn writecn }
Here, the procedure name is makecrystal and it accepts three arguments, which are the number of repeats of the lattice vectors in the x, y, and z directions.
This procedure would be called later called in the main program below as
makecrystal 4 4 4
which would create an atomic configuration of a perfect crystal structure with 4 repeats along the [100], [010] and [001] directions, as discussed in the previous wiki page.
There are a few subtle points one should notice in this procedure:
- makecrystal is both a Tcl and MD++ variable. This illustrates that one can use the same variable names for a Tcl file. In a Tcl file, the MD++ command must be called with the keyword MD++ in front of it, where as makecrystal by itself is a call to the Tcl procedure defined above.
- Here we put MD++ in front of all four lines inside this procedure, instead of enclosing all of them within MD++ { ... } as in the definition of initmd. This is done intentionally to allow $nx, $ny, $nz to be replaced by the value of arguments passed when procedure makecrystal is called (i.e. 4 4 4).
- There are \ symbols (backslashes) before the [ and ] symbos so that Tcl doesn't interpret them as commands special Tcl commands.
Visualization and simulation set up
The remaining procedures are similarly defined. They encapsulate different sections of the script file described in the previous wiki page.
- Plotting setup: setup_window and openwindow
- Relaxation: relax_fixbox and relax_freebox
- MD simulation setup: setup_md
Main Program
Unlike a script file, a tcl file can be called with an argument. For e.g. this tcl file could be called in the following ways.
\\\\
\fcolorbox{black}{gray!20}{\parbox{\linewidth}{
\tt{\$bin/sw\_mac scripts/ME346\/example02a-si-md.tcl\\ or \\ \$bin/sw\_mac scripts/ME346\/example02a-si-md.tcl 1 \\ or \\ \$bin/sw\_mac scripts/ME346\/example02a-si-md.tcl 2 \\
} }}\\\\
The argument at the end of the line is read by the tcl file in the following way:
\\\\
\fcolorbox{black}{gray!20}{\parbox{\linewidth}{
\tt{if \{ \$argc == 0 \} \{ \\
set status 0\\
\} elseif \{ \$argc > 0 \} \{ \\
set status [lindex \$argv 0]
\} \\ puts "status = \$status" \\
} }}\\\\
What happens in this part of the code is the following: \begin{itemize} \item \tt{argc} \rm is an in-built Tcl command which stores the value of the argument. If none is supplied by the user, then it defaults to 0. \item The statement \tt{set status 0} \rm sets the value of the variable \tt{status } \rm to 0. This is the default case. \item Supposing the user did supply an argument (e.g. 1 or 2) when executing the tcl script, then the value of the variable \tt{status} \rm is set to that. \item \tt{ \$argv} \rm is an array into which the user input (e.g. 1 or 2) is stored and \tt{[lindex \$argv 0} \rm retrieves the first element of that array. \end{itemize}
The rest of the code is calling of the procedures defined above. The reader is encouraged to notice the different cases defined in this part of the code for each argument specified by the user. This highlights one of the advantages of using a Tcl file over a .script file since multiple cases can be defined in one tcl file and depending on the argument, the specific case is executed. Whereas if a script file were used, then for each case, a separate script file would be needed. Thus, Tcl makes coding easier and eliminates redundancy in the script.