Kris's Research Notes

December 8, 2010

KMC Code Description

Filed under: GaAs Simulations — Kris Reyes @ 1:40 am

This note briefly explains how I get the KMC code up and running. To run the simulation, we must generate 6 files, which we describe below.

  1. Energy file — contains pairwise bonding energy between extended species, desorption potentials and diffusion coefficients;
  2. Profile file — the atom configuration used to initialize the simulation;
  3. Graph file — the underlying lattice (more generally, graph) the atoms occupy;
  4. Species file — how an extended species of an atom is determined from its local neighborhood;
  5. Legal Neighborhoods file — lookup tables that specify whether an event is legal for a given local neighborhood;
  6. Trial File — points to the other files as well as specifying the remaining parameters of the simulation.

The KMC program is easy to run once all the appropriate files are generated:

$ ./kmc trial_file

The Trial File

A trial file describes the parameters to be used in a simulation. It is a text file consisting of several lines. The lines in a trial file are:

  1. Output Interval (how often, in simulation seconds, to output an atom configuration).
  2. NUM_LABELS = The number of labels (colors of atoms).
  3. A descriptive name (no spaces) of the trial
  4. Location of the graph file
  5. Location of the profile file
  6. Location of the species file
  7. Location of the energy file
  8. Location of legal neighborhoods file
  9. Folder to place output

Then the file contains one or more lines of the form:

Temperature    Time    r_{\downarrow 0} \hdots r_{\downarrow S-1}    L_0 \hdots L_{S-1}    description of this part of experiment

where:

  • the time describes the simulation time (cumulative) up to which to perform that part of the experiment;
  • S is the number of species — a power of 2 where species 0 is always vacuum;
  • r_{\downarrow i} is the deposition rate (in monolayers/second) of species i;
  • L_i is the label (a number from 0 to NUM_LABELS-1) to give an atom of species i deposited during this part of the experiment;
  • the description at the end doesn’t contain any spaces

Here is an example trial file

0.70
3
a4g2_1.00__g0g0_0.29__T_0600__DEPTH_4.00__GA_FLUX_0.10__TRIAL_16
/nobackup/kgre/kmc/kmc_graph_files/out.graph
/nobackup/kgre/kmc/kmc_profile_files/out.profile
/nobackup/kgre/kmc/kmc_species_files/out.species
/nobackup/kgre/kmc/kmc_energy_files/a4g2_1.00__g0g0_0.29.energy
/nobackup/kgre/kmc/kmc_legal_neighborhoods_files/out.legal_neighborhoods
/nobackup/kgre/kmc/kmc_runs/a4g2_1.00__g0g0_0.29
600 40.0 0 0.1 0 0 0 1 2 0 deposition.at.0.1.ML.per.second
650 70.0 0 0 0 0 0 1 2 0 anneal

This simulation will place output in the folder

/nobackup/kgre/kmc/kmc_runs/a4g2_1.00__g0g0_0.29/trial_a4g2_1.00__g0g0_0.29__T_0600__DEPTH_4.00__GA_FLUX_0.10__TRIAL_16_SEED/

where SEED is the seed used by the simulation to initialize the random number generator. This simulation deposits atoms of species 1 at a rate of 0.1 monolayers per second for 40 seconds at temperature 600K. The deposition is then turned off, and the system is allowed to anneal at temperature 650K for the next 30 seconds. Output is given every 0.70 seconds.

The Energy File

The energy file describes parameters used to determine rates for all events besides deposition (those rates are simply specified in the trial file). Specifically, the energy file contains pairwise bonding energies and diffusion coefficients between extended species and desorption potentials for each species. The number of extended species NUM_EXTENDED_SPECIES and normal species NUM_SPECIES are specified in params.h.

The format of the energy file consists of 5 parts:

  1. Desorption potentials — a list of NUM_SPECIES desorption potentials
  2. Bonding energies — the matrix \gamma(S_i, S_j) of bonding energies between extended species in row-major order.
  3. Next-nearest neighbor bonding energies — the matrix \gamma_{NN}(S_i, S_j) of next-nearest bonding energies between extended species in row-major order.
  4. Diffusion coefficients — the matrix \omega(S_i, S_j) of diffusion coefficients between extended species, in row-major order.
  5. Next-nearest neighbor diffusion coefficients — the matrix \omega_{NN}(S_i, S_j) of next-nearest neighbor diffusion coefficients between extended species, in row-major order.

Profile file

The profile file describes the initial atom configuration to use in a simulation. The atom sites are ordered linearly in some fashion (determined in the graph file). The number of sites N and number of species NUM_SPECIES is specified in params.h. The profile file consists of two parts

  1. Atom species — a list of N integers from 0 to NUM_SPECIES-1 describing the initial species of each site.
  2. Atom label — a list of N integers from 0 to NUM_LABELS-1 describing the initial label of each site.

Graph File

The graph file describes the underlying lattice of atom sites by specifying the (linear) indices nearest and next-nearest neighbors for each atom site. The number of atom sites N and the regularity of the graph(the number of neighbors each site has) REGULARITY is specified in params.h The graph file consists of 4 parts:

  1. Nearest neighbors — an N\times REGULARITY matrix A = (a_{i,j}) where a_{i,j} is the index of the i-th site’s j-th nearest neighbor, in row-major order. Equivalently it is a list of  REGULARITY-tuples, one for each site, that lists the indices of that site’s nearest neighbors.
  2. Next-nearest neighbors — similar to the matrix above, but lists the indices of an site’s next-nearest neighbors.
  3. Fixed sites — a list of length N, where each entry is either 1 or 0 to indicate whether that position is fixed or not, respectively.
  4. Coordinates — a list of length N of triples x_i \quad y_i \quad z_i describing the (x,y,z) coordinates of site i.

Species File

The species file gives the projection from a local neighborhood (the tuple of species for a site and its nearest and next-nearest neighbors) to it’s extended species (which may e.g. only care about the count of each species and not the actual location of them). It also gives the projection from  extended species to species. The number of local neighborhoods NUM_NEIGHBORHOODS, the number of extended species NUM_EXTENDED_SPECIES and the number of species NUM_SPECIES are specified in params.h. The species file consists of 2 parts:

  1. Extended Species — a list of length NUM_NEIGHBORHOODS consisting of integers between 0 and NUM_EXTENDED_SPECIES-1 that assigns an extended species to each neighborhood.
  2. Extended Species to Species — a list of NUM_EXTENDED_SPECIES consisting of integers between 0 and NUM_SPECIES-1 that assigns a species to each extended species.

Note: the way the neighborhoods are linearly ordered is specific to the code in kmc_core.

Legal Neighborhoods File

The legal neighborhoods file consists of lookup tables that indicate whether, for a given local neighborhood, a particular swap, deposition or desorption even can happen at a site. The number of neighborhoods NUM_NEIGHBORHOODS and the regularity of the graph REGULARITY is given in params.h .The legal neighborhoods file has 3 parts:

  1. Swappable Neighbors — a NUM_NEIGHBORHOOD-long list of 2\times REGULARITY tuples with entries being 1 or 0 depending on whether an exchange between an atom site and its neighbor (or next nearest neighbor) is legal. The first REGULARITY entries of the tuple correspond to the nearest neighbors and the last REGULARITY entries correspond to the next nearest neighbors.
  2. Desorbable Neighborhood — a list of length NUM_NEIGHBORHOODS consisting of 1 or 0 depending on whether the particular neighborhood of a site allows for a desorption at that site.
  3. Depositable Neighborhood — a list of length NUM_NEIGHBORHOODS consisting of 1 or 0 depending on whether the particular neighborhood of a site allows for a deposition at that site.

Scripts to Generate Files

The code includes scripts to generate these files for the settings we have described in previous post. These scripts are located in

kmc_utilities/generate_trial_files/

Many of the scripts located in kmc_utilities/ require setting several environment variables to indicate the locations of certain components of the code. The easiest way to set these environments it to change the kmc.source file located in the root KMC directory. Here is an example of how I set up my kmc.source file:

#!/bin/bash
# This source file sets up some environment variables used throughout the code.
KMC_CORE='/nobackup/kgre/kmc/kmc_core'
KMC_ENERGY_FILES='/nobackup/kgre/kmc/kmc_energy_files'
KMC_GRAPH_FILES='/nobackup/kgre/kmc/kmc_graph_files'
KMC_PROFILE_FILES='/nobackup/kgre/kmc/kmc_profile_files'
KMC_SPECIES_FILES='/nobackup/kgre/kmc/kmc_species_files'
KMC_LEGAL_NEIGHBORHOODS_FILES='/nobackup/kgre/kmc/kmc_legal_neighborhoods_files'
KMC_TRIAL_FILES='/nobackup/kgre/kmc/kmc_trial_files'
KMC_PBS_FILES='/nobackup/kgre/kmc/kmc_pbs_files'
KMC_RUNS_FOLDER='/nobackup/kgre/kmc/kmc_runs'
KMC_UTILITIES_FOLDER='/nobackup/kgre/kmc/kmc_utilities'
export KMC_CORE
export KMC_ENERGY_FILES
export KMC_GRAPH_FILES
export KMC_PROFILE_FILES
export KMC_SPECIES_FILES
export KMC_TRIAL_FILES
export KMC_PBS_FILES
export KMC_RUNS_FOLDER
export KMC_UTILITIES_FOLDER
export KMC_LEGAL_NEIGHBORHOODS_FILES

These variables would be modified depending on where you would like the files to be. To source, we run the command

$ source kmc.source

which will set up the environment variable so that we may use them in the scripts that follow.

Most of the code probably doesn’t need to be changed besides the code to generate energy files and profile files, and so we focus only on these two files.

generate_trial_files/generate_energy_file/generate_energy_file.c:

The most relevant part of this file  are the tables located in the beginning:

double Ga_Ga_bonds[5][5] = {
    /*           G0    G1    G2    G3    G4 */
    /* G0 */ { G0G0, 0.25, 0.25, 0.25, 0.00 },
    /* G1 */ { 0.25, 0.25, 0.25, 0.25, 0.00 },
    /* G2 */ { 0.25, 0.25, 0.25, 0.25, 0.00 },
    /* G3 */ { 0.25, 0.25, 0.25, 0.25, 0.00 },
    /* G4 */ { 0.00, 0.00, 0.00, 0.00, 0.00 }
}; 
double Ga_As_bonds[5][5] = {
    /*           A0          A1          A2          A3    A4 */
    /* G0 */ { 0.00,       0.00,       0.00,       0.00, 0.00 },
    /* G1 */ { 0.00, G1A(1)+0.1, G1A(2)+0.1, G1A(3)+0.1, 0.05 },          /* numbers set to encourage diffusion through droplet */
    /* G2 */ { 0.00,       0.05,       0.25,       G2A4, G2A4 },
    /* G3 */ { 0.00,       0.05,       0.25,       0.95, 0.95 },
    /* G4 */ { 0.00,       0.05,       0.95,       0.95, 1.00 }
};
double As_As_bonds[5][5] = {
    /*           A0    A1    A2    A3    A4 */
    /* A0 */ { 0.10, 0.10, 0.10, 0.10, 0.00 },
    /* A1 */ { 0.10, 0.10, 0.10, 0.10, 0.00 },
    /* A2 */ { 0.10, 0.10, 0.10, 0.10, 0.00 },
    /* A3 */ { 0.10, 0.10, 0.10, 0.10, 0.00 },
    /* A4 */ { 0.00, 0.00, 0.00, 0.00, 0.00 }
};

These tables assume extended species defined in earlier post, e.g. G(i) is a Gallium atom with exactly i Arsenic neighbors. These three tables describe G(i)G(j), G(i)A(j), A(i)A(j) bonds, respectively. These energies can be changed depending on what phenomena we wish to observe. For example, I had run experiments to see how droplet size changes with respect to (among other things) the G0G0, G2A4 bonds. To do this automatically, I had introduced constants G0G0 and G2A4 in the code, which are then specified at compile-time with appropriate flags to the compiler. If those flags are not present, the compiler will default to values specified earlier in the code:

#ifndef G0G0
#warning using default G0G0 bond strength 0.3 eV
#define G0G0 0.3
#else
#warning using specified G0G0 bond strength
#endif

#ifndef G2A4
#warning using default G2A4 bond strength 1.0 eV
#define G2A4 1.0
#else
#warning using specified G2A4 bond strength
#endif

If we are interested in varying other bond-strengths, similar constants could be placed in the code in an identical way. The G1A(i) macro in the table is also specified earlier in the file:

#define G1A(i) (( 3.0*SMALL_DIFFUSION_COEFFICIENT/( 4.0*((1.0-SMALL_DIFFUSION_COEFFICIENT)*i-SMALL_DIFFUSION_COEFFICIENT) ) ) )
generate_trial_files/generate_profile_file/generate_profile_file.c:

This program generates an initial 2D profile. It uses the width of the lattice WIDTH, the height of the lattice HEIGHT and a macro atom_index(i,j), which gives the 2-dimensional lattice indexing into the linear atom indexing used in the program. These are all specified in params.h. Here is the code (located in main) to generate 5 layers of GaAs substrate and a hemispherical Ga drop:

// initial layers of GaAs
for(j=0; j < 5; j++){
    for(i=0; i < WIDTH; i++){
        atoms[atom_index(i,j)].type = 1+(j%2);
        atoms[atom_index(i,j)].label = 1+(j%2);
    }
} 

// Ga sphere
for(i=(WIDTH/2)-DROPLET_RADIUS; i < (WIDTH/2) +DROPLET_RADIUS; i++){
    for(j=5; j < sqrt(pow(DROPLET_RADIUS,2)-pow(i-WIDTH/2, 2))+ 5; j++){
        atoms[atom_index(i,j)].type = 1;
        atoms[atom_index(i,j)].label = 6;
    }
}

We see that to form the substrate, we the atom type for the atom at position (i,j), is

1 + (j \mod 2) = \begin{cases} 1 & j \text{ even} \\ 2 & j \text{ odd} \end{cases}

Here we assigned Gallium to be of type 1 and Arsenic to be of type 2. The substrate atoms are given a label equal to their type. We make a hemispherical droplet by varying the height variable j from 5 to

\sqrt{r^2-\left(i-\frac{W}{2}\right)^2} + 5,

i.e. the top half of a circle of radius r centered at (\frac{W}{2}, 5). The atoms in this region are given type 1 (Gallium), but are given a label 6 to indicate they should be colored differently than the other Gallium atoms. Here 6 corresponds to Cyan in gnuplot.

Varying Several Parameters

The script kmc_utilities/scripts/droplet_trials is an example of how to set up a bash script to generate trial files while varying various parameters.  In this script, we vary A4G2 and G0G0 bond strengths, temperature, depth and Gallium deposition rates.

#!/bin/bash

# generate trial files
cd $KMC_UTILITIES_FOLDER/generate_trial_files
./generate_trial_files

for A4G2 in 1.0; do
    for G0G0 in 0.29 0.30 0.40; do
        PREFIX=`printf a4g2_%4.2f__g0g0_%4.2f $A4G2 $G0G0`
        mkdir $KMC_RUNS_FOLDER/$PREFIX

        # create energy file
        cd $KMC_UTILITIES_FOLDER/generate_trial_files/generate_energy_file/
        gcc *.c ${KMC_CORE}/energy.c ${KMC_CORE}/species.c -lm -O3 -o generate_energy_file -I${KMC_CORE} -DG2A4=$A4G2 -DG0G0=$G0G0
        ./generate_energy_file $KMC_SPECIES_FILES/out.species $KMC_UTILITIES_FOLDER/generate_trial_files/extended_species_neighbor_counts
        mv out.energy $KMC_ENERGY_FILES/$PREFIX.energy

        for DEPTH in 4.0; do
            for GA_FLUX in 0.1 0.2 0.3 0.4; do
                for TEMP in 350 375 400 425 450 475 500 525 550 575 600; do
                    for TRIAL in {1..16}; do
                        TRIAL_NAME=`printf %s__T_%04d__DEPTH_%4.2f__GA_FLUX_%4.2f__TRIAL_%02d $PREFIX $TEMP $DEPTH $GA_FLUX $TRIAL`

                       # generate trial file
                       DEPOSIT_TIME=`echo $DEPTH/$GA_FLUX | bc -l`
                       ANNEAL_TIME=`echo $DEPOSIT_TIME+30 | bc -l`
                       DT=`echo $ANNEAL_TIME/100.0 | bc -l`
                       echo $DT > $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo 3 >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$TRIAL_NAME" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_GRAPH_FILES/out.graph" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_PROFILE_FILES/out.profile" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_SPECIES_FILES/out.species" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_ENERGY_FILES/$PREFIX.energy" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_LEGAL_NEIGHBORHOODS_FILES/out.legal_neighborhoods" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$KMC_RUNS_FOLDER/$PREFIX" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$TEMP $DEPOSIT_TIME 0 $GA_FLUX 0 0 0 1 2 0 deposition.at.$GA_FLUX.ML.per.second" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial
                       echo "$TEMP $ANNEAL_TIME 0 0 0 0 0 1 2 0 anneal" >> $KMC_TRIAL_FILES/$TRIAL_NAME.trial

                       # generate pbs file
                       echo "#!/bin/sh" > $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -N $TRIAL_NAME" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -A screms_flux" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -l walltime=1200:00,qos=screms_flux" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -M kgre@umich.edu" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -m a" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -joe" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -V" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "#PBS -q flux" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "cd $KMC_CORE" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                       echo "./kmc $KMC_TRIAL_FILES/$TRIAL_NAME.trial" >> $KMC_PBS_FILES/$TRIAL_NAME.pbs
                    done;
                done;
            done;
        done;
    done;
done;

This script does several things:

  • Generates the default species, legal neighborhoods and graph files. It also generates an initial profile file that gives some initial layers of GaAs subtrate — we have to edit  generate_profile_file.c to ensure this is the case.
  • It creates an output directory for each (A2G4, G0G0) pair that we loop over. This is done by the lines:
    PREFIX=`printf a4g2_%4.2f__g0g0_%4.2f $A4G2 $G0G0`
    mkdir $KMC_RUNS_FOLDER/$PREFIX
  • It creates the appropriate energy file for each (A2G4, G0G0) pair with the lines:
    cd $KMC_UTILITIES_FOLDER/generate_trial_files/generate_energy_file/
    gcc *.c ${KMC_CORE}/energy.c ${KMC_CORE}/species.c -lm -O3 -o generate_energy_file -I${KMC_CORE} -DG2A4=$A4G2 -DG0G0=$G0G0
    ./generate_energy_file $KMC_SPECIES_FILES/out.species $KMC_UTILITIES_FOLDER/generate_trial_files/extended_species_neighbor_counts
    mv out.energy $KMC_ENERGY_FILES/$PREFIX.energy

    In particular, the actual bonding energies for A2G4, G0G0 are set with the compile-time definitions, i.e. the flags -DG2A4=$A4G2 -DG0G0=$G0G0 in the gcc line.

  • It creates 16 trials for each (A4G2, G0G0, T, Depth, r_{\downarrow Ga}) tuple. For each such tuple and trial, we generate a trial name. It calculates the amount of simulation time to deposit Gallium via the DEPOSIT_TIME=`echo $DEPTH/$GA_FLUX | bc -l` line, and tacks on 30 extra seconds of annealing via the ANNEAL_TIME=`echo $DEPOSIT_TIME+30 | bc -l` line. It also calculates the output frequency for the simulation with DT=`echo $ANNEAL_TIME/100.0 | bc -l`, which results in 100 frames of output.
  • It creates the .trial file for each tuple above. It also creates a .pbs file, which is used to submit the job to the batch scheduler. If we choose not to use the batch scheduler, we would either have to run each trial manually, or add a line inside the for loop to call kmc with the trial file just created.

A Quick-Start Guide

Here is a quick-start guide to using the above droplet_trials script. It assumes the kmc files are located in a folder called /path/kmc/

  1. Edit the kmc.source file so that the folders point to the correct location. For example, we would have to edit the line
    KMC_CORE='/nobackup/kgre/kmc/kmc_core'

    to

    KMC_CORE='/path/kmc/kmc_core'

    and similarly for the other lines.

  2. Source the kmc.source file:
    $ source kmc.source
  3. Edit kmc_utilities/generate_trial_files/generate_profile_files/generate_profile_files.c so that the inital profile is just GaAs substrate.
  4. Edit kmc_utilities/scripts/droplet_trials to vary over the appropriate parameters
  5. Call droplet_trials:
    $ cd kmc_utilities/scripts
    $ ./droplet_trials

    This will create the appropriate energy and trial files, placing them in $KMC_ENERGY_FILES and $KMC_TRIAL_FILES, respectively.

  6. Make the kmc code:
    $ cd $KMC_CORE
    $ make
  7. Run kmc on each of the trail files either manually:
    $ ./kmc $KMC_TRIAL_FILES/some_trial_file

    or in a for-loop:

    $ for trial_file in `ls $KMC_TRIAL_FILES/*.trial`; do
    $ ./kmc $trial_file;
    $ done;
Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: