Hex, Bugs and More Physics | Emre S. Tasci

a blog about physics, computation, computational physics and materials…

POSCAR2Cif

May 23, 2009 Posted by Emre S. Tasci

Converts POSCAR files to CIF format. Uses Octave (latvec2par) to convert the unit cell vectors to lattice cell parameters. It is assumed (compulsory) that the atom coordinates in the POSCAR file are in fractional (direct) coordinates.

Parameters

f         : input file  (Default = POSCAR)
o         : output file (Default = <inputfilename>.cif)
t         : if set (t=1), then the output is written to the screen
speclist  : Define the name of the species, seperated by 'xx' or ',' to be used
            with neighbour listing (Default = AxxBxxCxx...)
            (Labels can also be seperated via [space] as long as speclist is given
            in quotation -- Example: ... speclist=\"Au Si\" )

Example

sururi@husniya OUTCARs_final_structures $ cat POSCAR_Pd3S
Pd3S
   1.00000000000000
     4.7454403619558345    0.0098182468538853    0.0000000000000000
    -1.4895902658503473    4.5055989020479856    0.0000000000000000
     0.0000000000000000    0.0000000000000000    7.2191545483192190
   6   2
Direct
  0.1330548697855782  0.5102695954022698  0.2500000000000000
  0.4897304045977232  0.8669451452144267  0.7500000000000000
  0.5128136657304309  0.1302873334247993  0.2500000000000000
  0.8697126665752007  0.4871863042695738  0.7500000000000000
  0.0013210250693640  0.9986789749306360  0.0000000000000000
  0.0013210250693640  0.9986789749306360  0.5000000000000000
  0.6856021298170862  0.6825558526447357  0.2500000000000000
  0.3174442073552622  0.3143978111829124  0.7500000000000000

sururi@husniya OUTCARs_final_structures $ php POSCAR2CIF.php f=POSCAR_Pd3S t=1 speclist=Pd,S
data_
loop_
_symmetry_equiv_pos_as_xyz
x,y,z
_cell_length_a  4.745451
_cell_length_b  4.745451
_cell_length_c  7.219155
_cell_angle_alpha       90.000000
_cell_angle_beta        90.000000
_cell_angle_gamma       108.175792
loop_
_atom_site_label
_atom_site_type_symbol
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
Pd01    Pd        0.1330548697855782  0.5102695954022698  0.2500000000000000
Pd02    Pd        0.4897304045977232  0.8669451452144267  0.7500000000000000
Pd03    Pd        0.5128136657304309  0.1302873334247993  0.2500000000000000
Pd04    Pd        0.8697126665752007  0.4871863042695738  0.7500000000000000
Pd05    Pd        0.0013210250693640  0.9986789749306360  0.0000000000000000
Pd06    Pd        0.0013210250693640  0.9986789749306360  0.5000000000000000
S01     S         0.6856021298170862  0.6825558526447357  0.2500000000000000
S02     S         0.3174442073552622  0.3143978111829124  0.7500000000000000

Code

#!/usr/bin/php
<?PHP
/* Emre S. Tasci <e.tasci@tudelft.nl>                    *
 * Script name: POSCAR2CIF.php                           *
 * Converts the specified POSCAR file to CIF format      *
 * Uses octave to convert the unit cell vectors          *
 * to lattice parameters.                                *
 *                                              23/05/09 */
 
 
//require("/code/toolbox/commandline.inc.php"); # Equivalent handling of $_GET / $_POST
# ============/code/toolbox/commandline.inc.php========================================
// Enables the same treat for command line parameters
// as those of GET parameters.
// Also sets the $first, $last ranges including the gall parameter
 
//Support for command line variable passing:
for($i=1;$i<sizeof($_SERVER["argv"]);$i++)
{
  list($var0,$val0) = explode("=",$_SERVER["argv"][$i]);
  $_GET[$var0] = $val0;
}
 
$first = -2; //disabled by default
$last  = -3;
 
if($_GET["gfirst"]) $first = $_GET["gfirst"];
if($_GET["glast"] ) $last  = $_GET["glast"];
if($_GET["gall"] ) {$first = $_GET["gall"]; $last = $first;}
# ============/code/toolbox/commandline.inc.php========================================
 
 
if($_GET["h"]||$_GET["help"])
{
$help = <<<lol
 * Script name: POSCAR2CIF.php                           *
 * Converts the specified POSCAR file to CIF format      *
 * Uses octave to convert the unit cell vectors          *
 * to lattice parameters.                                *
 
 * Emre S. Tasci <e.tasci@tudelft.nl>                    *
 *                                              23/05/09 *
 
 Usage:
 f         : input file  (Default = POSCAR)
 o         : output file (Default = <inputfilename>.cif)
 t         : if set (t=1), then the output is written to the screen
 speclist  : Define the name of the species, seperated by 'xx' or ',' to be used
             with neighbour listing (Default = AxxBxxCxx...)
             (Labels can also be seperated via [space] as long as speclist is given
             in quotation -- Example: ... speclist=\"Au Si\" )
 
 Example : php POSCAR2CIF.php f=POSCAR_RhBi4 speclist=Bi,Rh
lol;
 echo $help."\n";
 exit;
}
 
 
if($_GET["file"])$inputfile = $_GET["file"];
else if($_GET["f"])$inputfile = $_GET["f"];
else $inputfile="POSCAR";
 
$outfile = $inputfile.".cif";
if($_GET["o"]) $outfile=$_GET["o"];
if($_GET["t"]) $outfile = "php://stdout";
 
$species_type_template = Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
if($_GET["speclist"])$species_type_template = split("xx| |,",$_GET["speclist"]);
 
//echo sizeof($_GET["speclist"])."\n";
exec('sed -n "3,6p" '.$inputfile.'|awk \'{print $1"\t"$2"\t"$3}\'',$out);
$octfp = fopen("octrungetvolnpar.m","w");
 
fwrite($octfp,"kini=[\n");
for ($i=0;$i<3;$i++)
    fwrite($octfp,$out[$i]."\n");
fwrite($octfp,"];\n\n");
 
fwrite($octfp,"numatom = [".$out[3]."];\n\n");
$numatoms = split("[ \t]+",trim($out[3]));
 
// Write the octave operations
fwrite($octfp,"k1 = latvec2par (kini);totatom=sum(numatom );\n");
fwrite($octfp,"for i=1:6;printf(\"%f\\n\",k1(i));endfor;\nprintf(\"%d\\n\",totatom)\n");
 
fclose($octfp);
 
// Execute the octave file to find the lattice parameters and volume
exec('octave -q '.$thisdir.'octrungetvolnpar.m',$out3);
unlink("octrungetvolnpar.m");
//echo $out3[0]."\n";
 
/*
for ($i=0;$i<sizeof($out3);$i++)
    echo $i."\t".$out3[$i]."\n";
 */
 
exec('grep "Direct" '.$inputfile.' -n|sed "s:^\([0-9]\+\).*:\1:"',$start);# Line number of the Direct prompt
$start = $start[0];
$start++;
$finish = $start+$out3[sizeof($out3)-1]-1;
exec('sed -n "'.$start.','.$finish.'p" '.$inputfile,$outr);
$fpo = fopen($outfile, "w");
fwrite($fpo, "data_\nloop_\n_symmetry_equiv_pos_as_xyz\nx,y,z\n");
fwrite($fpo, "_cell_length_a\t".$out3[0]."\n");
//echo $out3[0];
fwrite($fpo, "_cell_length_b\t".$out3[1]."\n");
fwrite($fpo, "_cell_length_c\t".$out3[2]."\n");
fwrite($fpo, "_cell_angle_alpha\t".$out3[3]."\n");
fwrite($fpo, "_cell_angle_beta\t".$out3[4]."\n");
fwrite($fpo, "_cell_angle_gamma\t".$out3[5]."\n");
fwrite($fpo, "loop_\n_atom_site_label\n_atom_site_type_symbol\n_atom_site_fract_x\n_atom_site_fract_y\n_atom_site_fract_z\n");
$k = 0;
for($specie=0;$specie<sizeof($numatoms);$specie++)
    for($i=1;$i<=$numatoms[$specie];$i++)
    {
        fwrite($fpo, $species_type_template[$specie].sprintf("%02d",$i)."\t".$species_type_template[$specie]."\t".$outr[$k]."\n");
        $k++;
    }
 
 
fclose($fpo);
?>

POSCAR2findsymm

March 24, 2009 Posted by Emre S. Tasci

A very simple code I wrote while studying the Python language that fetches the information from a VASP POSCAR file and prepares (and feeds) the input for Harold Stokes’ findsym (you should actually download the executable included in the ISOTROPY package instead of the referred web version) program to find the unit cell symmetry.

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
POSCAR2findsym.py
/* Emre S. Tasci <e.tasci@tudelft.nl>                    *
   A simple python code that parses the POSCAR file,
   prepares an input file for Harold Stokes' findsym
   (http://stokes.byu.edu/isotropy.html)
   executable.

   Then, checks the current system to see if findsym is
   accessible: if it is, then feeds the prepared file 
   and directly outputs the result; if findsym is not 
   executable then outputs the generated input file.

   If you are interested only in the results section of 
   the findsymm output, you should append "| grep "\-\-\-\-\-\-" -A1000"
   to the execution of this code.

   Accepts alternative POSCAR filename for argument
   (default = POSCAR)

   If a second argument is proposed then acts as if
   findsym is not accessible (ie, prints out the input
   file instead of feeding it to findsymm)

                                             10/03/09 */
"""

import sys
import re
from numpy import *
from os import popen
import commands

force_output = False

if len(sys.argv)<2:
    filename="POSCAR"
elif len(sys.argv)<3:
    filename=sys.argv[1]
else:
    filename=sys.argv[1]
    force_output = True

f = open(filename,'r')

title = f.readline().strip()
tolerance = 0.00001
latt_vec_type = 1 # We will be specifying in vectors

f.readline() # Read Dummy
lat_vec = array([])
for i in range(0,3):
    lat_vec = append(lat_vec,f.readline().strip())

# Read atom species
species_count = f.readline()
species_count = re.split('[\ ]+', species_count.strip())
species_count = map(int,species_count)
number_of_species = len(species_count)
total_atoms = sum(species_count)

initial_guess = "P" # For the centering

species_designation = array([])
for i in range(1,number_of_species+1):
    for j in range(0,species_count[i-1]):
        species_designation = append(species_designation,i)

species_designation = map(str,map(int,species_designation))
# print species_designation
sep = " "
# print sep.join(species_designation)

# Read Coordinates
f.readline() # Read Dummy
pos_vec = array([])
for i in range(0,total_atoms):
    pos_vec = append(pos_vec,f.readline().strip())

# print pos_vec

findsym_input = array([])
findsym_input = append(findsym_input, title)
findsym_input = append(findsym_input, tolerance)
findsym_input = append(findsym_input, latt_vec_type)
findsym_input = append(findsym_input, lat_vec)
findsym_input = append(findsym_input, 2)
findsym_input = append(findsym_input, initial_guess)
findsym_input = append(findsym_input, total_atoms)
findsym_input = append(findsym_input, species_designation)
findsym_input = append(findsym_input, pos_vec)
# print findsym_input
sep = "\n"
findsym_input_txt = sep.join(findsym_input)
# print findsym_input_txt

# Check if findsym is accessible:
status,output =  commands.getstatusoutput("echo \"\n\n\"|findsym ")
if(output.find("command not found")!=-1 or force_output):
    # if it is not there, then just output the input
    print findsym_input_txt
elif(status==6144):
    # feed it to findsym
    pipe = popen("echo \""+findsym_input_txt+"\" | findsym").readlines()
    for line in pipe:
        print line.strip()
quit()

Example Usage:

sururi@husniya POSCAR2findsym $ cat POSCAR
Si(S)-Au(Pd) -- Pd3S
   1.00000000000000
     4.7454403619558345    0.0098182468538853    0.0000000000000000
    -1.4895902658503473    4.5055989020479856    0.0000000000000000
     0.0000000000000000    0.0000000000000000    7.2191545483192190
   6   2
Direct
  0.1330548697855782  0.5102695954022698  0.2500000000000000
  0.4897304045977232  0.8669451452144267  0.7500000000000000
  0.5128136657304309  0.1302873334247993  0.2500000000000000
  0.8697126665752007  0.4871863042695738  0.7500000000000000
  0.0013210250693640  0.9986789749306360  0.0000000000000000
  0.0013210250693640  0.9986789749306360  0.5000000000000000
  0.6856021298170862  0.6825558526447357  0.2500000000000000
  0.3174442073552622  0.3143978111829124  0.7500000000000000

sururi@husniya POSCAR2findsym $ python POSCAR2findsym.py
FINDSYM, Version 3.2.3, August 2007
Written by Harold T. Stokes and Dorian M. Hatch
Brigham Young University
 
Si(S)-Au(Pd) -- Pd3S
Tolerance:    0.00001
Lattice vectors in cartesian coordinates:
4.74544   0.00982   0.00000
-1.48959   4.50560   0.00000
0.00000   0.00000   7.21915
Lattice parameters, a,b,c,alpha,beta,gamma:
4.74545   4.74545   7.21915  90.00000  90.00000 108.17579
Centering: P
Number of atoms in unit cell:
8
Type of each atom:
1  1  1  1  1  1  2  2
Position of each atom (dimensionless coordinates)
1   0.13305   0.51027   0.25000
2   0.48973   0.86695   0.75000
3   0.51281   0.13029   0.25000
4   0.86971   0.48719   0.75000
5   0.00132   0.99868   0.00000
6   0.00132   0.99868   0.50000
7   0.68560   0.68256   0.25000
8   0.31744   0.31440   0.75000
------------------------------------------
Space Group  40  C2v-16    Ama2
Origin at    0.00000   0.00000   0.50000
Vectors a,b,c:
0.00000   0.00000   1.00000
-1.00000  -1.00000   0.00000
1.00000  -1.00000   0.00000
Values of a,b,c,alpha,beta,gamma:
7.21915   5.56683   7.68685  90.00000  90.00000  90.00000
Atomic positions in terms of a,b,c:
Wyckoff position b, y = -0.17834, z =  0.31139
1   0.75000   0.17834   0.31139
2   0.25000   0.82166   0.31139
Wyckoff position b, y =  0.32155, z =  0.19126
3   0.75000   0.17845   0.69126
4   0.25000   0.82155   0.69126
Wyckoff position a, z =  0.00132
5   0.50000   0.00000   0.00132
6   0.00000   0.00000   0.00132
Wyckoff position b, y = -0.31592, z =  0.00152
7   0.75000   0.81592   0.50152
8   0.25000   0.18408   0.50152

LaTeX to PNG and all that equations..

March 23, 2009 Posted by Emre S. Tasci

After migrating this blog to a new server, I had some difficulties in writing up the equations. It was due to the fact that on this server, I wasn’t able to execute the necessary commands to parse the latex code and convert it to PNG format.

Last week, some need arouse for this and I finally coded the necessary way around to be able to convert LaTeX definitions to their PNG counterparts. Before I start to quote the necessary code and explanations, let me tell that, this method only will work if you can successfully manage to produce this conversation at your -local- computer since what the code does is to generate the image on your local computer and then copy it to the server where your blog (/or whatever you have) resides. So, make sure:

  • You can convert LaTeX code to PNG on your -own- computer.
  • You are running a httpd server so that the code can copy the output PNG file from your local computer

What the code does:
It has 3 seperate processes. Let’s designate them A, B & C.

  • Part A is called on the remote server. It presents a form with textbox in it where you can type the LaTeX code. The form’s target is the same file but this time on your local server, so when you submit the data —
  • Part B is called on your local server. Using the texvc code, an open source software that also comes packed with mediawiki, it converts the LaTeX code into a PNG image and places it under the relative math/ directory of your local server. After doing this, via the META tag ‘refresh’ it causes the page to refresh itself loading its correspondence in the remote server, hence initiating —
  • Part C where the generated image identified by the MD5 hashname is fetched from the local server and copied unto the relative math/ directory on the remote server. The LaTeX code that was used is also passed in the GET method and it is included in the generated code as the title of the image, so if necessary, the equation can be modified in the future.

The code is as follows:

<?PHP if($_GET["com"]||(!$_POST["formula"] && !$_GET["file"])){?>
<body onload="document.postform.formula.focus();">
<form action="http://yourlocalserver.dns.name/tex/index.php" method="post" name=postform id=postform>
<textarea name="formula" cols=40 rows=5 id=formula>
</textarea><br>
<input type="submit" value="Submit" />
<?PHP
}
if($_POST["formula"])
{
    // NL
    $lol = './texvc  ./mathtemp ./math "'.$_POST["formula"].'" iso-8859-1';
    exec($lol,$out);
    $file = substr($out[0],1,32);
    $formula = base64_encode($_POST["formula"]);
    $html = '<HTML>
<HEAD>
<META http-equiv="refresh" content="0;URL=http://remoteserver.dns.name/tex/index.php?formula='.$formula.'&file='.$file.'">
</HEAD>';
    echo $html;
}
else if($_GET["file"])
{
    // COM
    $file = "math/".$_GET["file"].".png";
    if(!copy("yourlocalserver.dns.name/tex/".$file, $file)) exit( "copy failed<br>");
    $formula = base64_decode($_GET["formula"]);
?>
<form action="http://yourlocalserver.dns.name/tex/index.php" method="post">
<textarea name="formula" cols=40 rows=5><?PHP echo $formula; ?>
</textarea><br>
<input type="submit" value="Submit" />
<?
 
    echo "<br><br><img src=\"".$file."\" title=\"".$formula."\"><br>";
    echo "&lt;img src=\"/tex/".$file."\" title=\"".$formula."\"&gt;<br>";
}
?>

To apply this:

1. Create a directory called ‘tex’ on both servers.
2. Create subdir ‘math’ on both servers
3. Create subdir ‘mathtemp’ on the local server
4. Modify the permissions of these subdirs accordingly
5. Place the executable ‘texvc’ in the ‘tex’ directory
6. Place the code quoted above in the ‘tex’ directories of both servers in a file called ‘index.php’

If everything well up to this point, let’s give it a try and you shall have some output similar to this:

For an input LaTeX code of:
\sum_{n=0}^\infty\frac{x^n}{2n!}

where you can immediately see the resulting image, modify the code if there’s something wrong or copy the IMG tag and put it to your raw HTML input box in your text…

Two bash scripts for VASP

October 20, 2008 Posted by Emre S. Tasci

It’s of great importance to have sufficient number of k-points when doing DFT calculations. The most practical (but CPU time costly) way is to check energies for different number of k-points until some kind of "convergence" is reached.

Here are the two scripts I’ve recently written for VASP to check for suitable k-point values.

The first code runs the calculation with increasing k-points (I have a cubic cell, so using same number of k-points for the 3 lattice axes).

Before running this code, make sure that the essential files (KPOINTS POSCAR POTCAR INCAR) are in the directory, also copy your KPOINTS file to a file named "KP" which has KPOINTS mesh defined as 2x2x2:

sururi@husniya Al3Li $ cat KP
Automatic
0
Gamma
2 2 2
0 0 0

The following script will then run the calculations, incrementing the number of K-Points by 1 per each axis. It will store the output (and the 4 input files) in archive files in the format k{%03d}.tar.bz2 where the value in the curly brackets is actually the number of k-points per axis. As you can easily see, it runs from k= 1x1x1 (silly but since this is tutorial) to k=13x13x13.

#!/bin/bash

# A script file to run the system for various k-points in order to find the optimal setting
# Emre S. Tasci, 20/10/2008

for (( i = 1; i <= 13; i++ )) 
do  
    date
    echo $i

    # change the KPOINTS (KP is a copy of the KPOINTS with k=2:
    cat KP|sed s/"2 2 2"/"$i $i $i"/ > KPOINTS

    # run the vasp
    vasp > vasp.out

    # archive the existing files (except the archive files):
    tar -cvjf $(printf "k%02d.tar.bz2" $i) $(ls |grep -v "\(.bz2\)\|\(runrunrun.sh\)\|\(KP$\)\|\(work\)")

    # remove the output files:
    rm $(ls *|grep -v "\(.bz2\)\|\(KPOINTS\)\|\(POSCAR\)\|\(POTCAR\)\|\(INCAR\)\|\(runrunrun.sh\)\|\(KP$\)") -f
    date
    echo "=================================================="
done

After it ends, you should see something like

-rw-r----- 1 sururi users 299K 2008-10-20 10:14 POTCAR
-rw-r--r-- 1 sururi users  283 2008-10-20 10:14 POSCAR
-rw-r--r-- 1 sururi users  604 2008-10-20 10:14 INCAR
-rw-r--r-- 1 sururi users   31 2008-10-20 11:06 KP
-rw-r--r-- 1 sururi users   34 2008-10-20 14:33 KPOINTS
-rw-r--r-- 1 sururi users 195K 2008-10-20 11:08 k01.tar.bz2
-rw-r--r-- 1 sururi users 196K 2008-10-20 11:08 k02.tar.bz2
-rw-r--r-- 1 sururi users 193K 2008-10-20 11:08 k03.tar.bz2
-rw-r--r-- 1 sururi users 195K 2008-10-20 11:08 k04.tar.bz2
-rw-r--r-- 1 sururi users 195K 2008-10-20 11:08 k05.tar.bz2
-rw-r--r-- 1 sururi users 197K 2008-10-20 11:09 k06.tar.bz2
-rw-r--r-- 1 sururi users 197K 2008-10-20 11:09 k07.tar.bz2
-rw-r--r-- 1 sururi users 200K 2008-10-20 11:10 k08.tar.bz2
-rw-r--r-- 1 sururi users 201K 2008-10-20 11:10 k09.tar.bz2
-rw-r--r-- 1 sururi users 205K 2008-10-20 11:11 k10.tar.bz2
-rw-r--r-- 1 sururi users 205K 2008-10-20 11:12 k11.tar.bz2
-rw-r--r-- 1 sururi users 211K 2008-10-20 11:13 k12.tar.bz2
-rw-r--r-- 1 sururi users 211K 2008-10-20 11:14 k13.tar.bz2
-rwxr--r-- 1 sururi users  732 2008-10-20 14:02 runrunrun.sh

Now, it’s time for the second script. Create a new directory (say “work”) and then type the following into a script file (don’t forget to set it as executable (or you can also always “sh ” 😉 ) )

#!/bin/bash
 
# Script name: energy_extract_from_OUTCAR.sh
# Emre S. Tasci, 20/10/2008
 
# Reads the OUTCAR files from the archive files in the parent directory
# Stores the energies in corresponding ENE files.
 
# (Assuming filenames are given like "k05.tar.bz2")
 
k=00
 
for i in ../k*.bz2
do
    kpre=$k
    enepre="0.00000000"
 
    # Extract OUTCAR
    tar -xjf $i OUTCAR
 
    # Parse file counter from filename 
    k=$(echo $(basename $i)|sed "s:k\([0-9]*\).*:\1:")
 
    # write the energies calculated in this run 
    cat OUTCAR | grep "energy without"|awk '{print $8}' > $(printf "%s_ENE" $k)
 
    #calculate the energy difference between this and the last run
    if [ -e "$(printf "%s_ENE" $kpre)" ] 
    then
        enepre=$(tail -n1 $(printf "%s_ENE" $kpre));
    fi
 
    enethis=$(tail -n1 $(printf "%s_ENE" $k));
 
    # Using : awk '{ print ($1 >= 0) ? $1 : 0 - $1}' : for absolute value
 
    echo -e $(printf "%s_ENE" $kpre) " :\t" $enepre "\t" $(printf "%s_ENE" $k) ":\t" $enethis "\t" $(echo $(awk "BEGIN { print $enepre - $enethis}") | awk '{ print ($1 >= 0) ? $1 : 0 - $1}')
 
    rm -f OUTCAR
done;

when runned, this script will produce an output similar to the following:

sururi@husniya work $ ./energy_extract_from_OUTCAR.sh
00_ENE  :        0.00000000      01_ENE :        -6.63108952     6.63109
01_ENE  :        -6.63108952     02_ENE :        -11.59096452    4.95988
02_ENE  :        -11.59096452    03_ENE :        -12.96519853    1.37423
03_ENE  :        -12.96519853    04_ENE :        -13.20466179    0.239463
04_ENE  :        -13.20466179    05_ENE :        -13.26411934    0.0594576
05_ENE  :        -13.26411934    06_ENE :        -13.26528991    0.00117057
06_ENE  :        -13.26528991    07_ENE :        -13.40540825    0.140118
07_ENE  :        -13.40540825    08_ENE :        -13.35505746    0.0503508
08_ENE  :        -13.35505746    09_ENE :        -13.38130280    0.0262453
09_ENE  :        -13.38130280    10_ENE :        -13.36356457    0.0177382
10_ENE  :        -13.36356457    11_ENE :        -13.37065368    0.00708911
11_ENE  :        -13.37065368    12_ENE :        -13.37249683    0.00184315
12_ENE  :        -13.37249683    13_ENE :        -13.38342842    0.0109316

Which shows the final energies of the sequential runs as well as the difference of them. You can easily plot the energies in the gnuplot via as an example “plot “12_ENE”“. You can also plot the evolution of the energy difference with help from awk. To do this, make sure you first pipe the output of the script to a file (say “energies.txt”):

./energy_extract_from_OUTCAR.sh > energies.txt

And then, obtaining the last column via awk

cat energies.txt |awk '{print $7}' > enediff.txt

Now you can also easily plot the difference file.

Hope this scripts will be of any help.

Miedema et al.’s Enthalpy code — 25 years after..

July 28, 2008 Posted by Emre S. Tasci

Yes, it’s been 25 years since A.K. Niessen, A.R. Miedema et al.’s "Model Predictions for the Enthalpy of Formation of Transition Metal Alloys II" titled article (CALPHAD 7(1) 51-70 1983) was published. It can be thought as a sequel to Miedema et al.’s 1979 (Calphad 1 341-359 1979) and 1980 dated (Physica 100 1-28 1980) papers with some update on the data as well as a computer code to calculate the enthalpies of formation written in ALGOL.

I have been currently working on these papers and by the way ported the code presented in CALPHAD 1983 to FORTRAN and here it is:

 

C      THE IMPLEMENTATION OF THE ALGOL CODE FROM
C      A.K. Niessen, F.R. de Boer, R. Boom, P.F. de Chatel
C      W.C.M. Mattens and A.R. Miedema
C      CALPHAD Vol.7 No.1 pp. 51-70, 1983
C      Model Predictions for the Enthalpy of Formation of Transition 
C        Metal Alloys II"
C
C      by Emre S. Tasci, TUDelft (2008)

      IMPLICIT DOUBLE PRECISION(A-H,N-Z)
C      DOUBLE PRECISION va,aa,p,r,x,dn,dg,ng,pq,xa,xm,csa,csm
C      DOUBLE PRECISION cas,cms,fam,dph,vm,am,fma,var,vmr
C      DOUBLE PRECISION vas, vms, xas, xms, xva,xvm, dgl,pqrs, pqrl
      INTEGER arrout, z1,z2,a,m,n,w,dh,ga,gm,gal,gml,nr,dHtrans
      LOGICAL detp, detr, bool
      CHARACTER(LEN=5) Symbol
      DIMENSION arrout(15)
      DIMENSION Phi(75), acf(75), dHtrans(75), Nws113(75), Rcf(75),
     + V213(75), xxx(9), Symbol(75)
      COMMON /CDH/ x, dh
      COMMON /CDPH/ dph, Phi, Nws113, ng, r, Rcf, p, pq, dn, pqrs, pqrl

      OPEN(UNIT=3,FILE='inpdata.txt',STATUS='OLD')
      DO I=1,75
        READ(3,*)nr,Symbol(nr),Phi(nr),Nws113(nr),V213(nr),
     +  acf(nr),Rcf(nr),dHtrans(nr)
C       WRITE(*,*)nr,Symbol(nr),Phi(nr),Nws113(nr),V213(nr),
C     + acf(nr),Rcf(nr),dHtrans(nr)
      END DO
      CLOSE(UNIT=3)

      xxx(1) = 0.001
      xxx(2) = 1.0/6.0
      xxx(3) = 1.0/4.0
      xxx(4) = 1.0/3.0
      xxx(5) = 1.0/2.0
      xxx(6) = 2.0/3.0
      xxx(7) = 3.0/4.0
      xxx(8) = 5.0/6.0
      xxx(9) = 0.999

      DO z1 = 1,46 
          WRITE(*,200)z1,Symbol(z1),Phi(z1),Nws113(z1)**3,
     +      V213(z1)**(3.0/2),dHtrans(z1)
200       FORMAT(I2," ",A5," Phi: ",F5.2,"V  Nws: ",F5.2,
     +     "d.u.  Vmole: "
     +     ,F5.2,"cm3  DeltaHtrans:",I3,"kJ/mole",/)
          WRITE(*,250)"M","AM5","AM3","AM2","AM",
     +     "MA2","MA3","MA5","AinM","AM","MinA"
250       FORMAT(A,"      ",9(A4,"  "),A4,/)
          DO z2 = 1, 75
             m = z2
             a = z1
             CALL PQRSL(a,m)

             va = V213(a)
             aa = acf(a)
             ga = dHtrans(a)
             gal = ga

             vm = V213(m)
             am = acf(m)
             gm = dHtrans(m)

             IF (m.EQ.67.OR.m.EQ.68) THEN
                 gml = 0
             ELSE
                 gml = gm
             END IF

             n = 1

             DO I = 1,9
              xa = xxx(I)
              IF(xa.EQ.0.001.OR.xa.EQ.0.999) THEN
                  bool = .TRUE.
              ELSE
                  bool = .FALSE.
              END IF

              xm = 1 - xa
              xva = xa * va
              xvm = xm * vm

              dgl = xa * gal + xm * gml
              dg = xa * ga + xm * gm
              csa = xva / (xva + xvm)

              csm = 1 - csa
              fam = csm * (1 + 8 * csa * csa * csm * csm)
              fma = fam * csa / csm

              var = va * (1 + aa * csm * dph)
              vmr = vm * (1 - am * csa * dph)

              vas = va * (1 + aa * fam * dph)
              vms = vm * (1 - am * fma * dph)

              xar = xa * var
              xas = xa * vas
              xmr = xm * vmr
              xms = xm * vms

              cas = xas / (xas+xms)
              cms = 1 - cas
              csa = xar / (xar + xmr)
              csm = 1 - csa

              fam = cms * (1 + 8 * cas * cas * cms * cms)
              fma = fam * cas / cms

              IF(bool) THEN
                  IF(n.EQ.1) THEN 
                      GOTO 292
                  ELSE
                      GOTO 392
                  END IF
              END IF
                  IF(xa.EQ.0.5) THEN
                      x = csm * xar * p * pqrl + dgl
                      CALL MAXI
                      arrout(n+5) = dh
                  END IF
                  x = fam * xas * p * pqrs + dg
                  CALL MAXI
                  arrout(n) = dh
                  arrout(11) = gml
                  GOTO 492
292               x = (csm * xar * p * pqrl + dgl) / xa
                  CALL MAXI
                  arrout(n) = dh
                  arrout(11) = gml
                  GOTO 492
392               x = (csm * xar * p * pqrl + dgl) / xm
                  CALL MAXI
                  arrout(n) = dh
                  arrout(12) = gal
492               n = n + 1
             END DO
C            DO J=1,15
C              WRITE(*,500) J, arrout(J)
C            END DO
             WRITE(*,600)Symbol(m),arrout(2),arrout(3),arrout(4),
     +        arrout(5),
     +        arrout(6),arrout(7),arrout(8),arrout(1),arrout(10),
     +        arrout(9)
             IF(Symbol(m).EQ."Ni".OR.Symbol(m).EQ."Pd".OR.Symbol(m).EQ.
     +       "Lu".OR.Symbol(m).EQ."Pt".OR.Symbol(m).EQ."Pu".OR.
     +       Symbol(m).EQ."Au".OR.Symbol(m).EQ."H".OR.Symbol(m).EQ.
     +       "Cs".OR.Symbol(m).EQ."Mg".OR.Symbol(m).EQ."Ba".OR.
     +       Symbol(m).EQ."Hg".OR.Symbol(m).EQ."Tl".OR.Symbol(m).EQ.
     +       "Pb".OR.Symbol(m).EQ."Bi")WRITE(*,*)""
          END DO
      WRITE(*,"(2A,/)")"-----------------------------------",
     + "----------------------------"
      END DO

C500   FORMAT("O[",I3,"] = ",I50)
600   FORMAT(A5,"  ",9(I4,"  "),I4)

      STOP
      END

      SUBROUTINE MAXI
      IMPLICIT DOUBLE PRECISION(A-H,N-Z)
      INTEGER dh
      COMMON /CDH/ x, dh
      IF(x.LT.-999.OR.x.GT.999) THEN
        dh = 999
      ELSE
        dh = NINT(x)
      END IF
C      WRITE(*,*)"x:",dh
      RETURN
      END

      SUBROUTINE PQRSL(a,b)
      IMPLICIT DOUBLE PRECISION(A-H,N-Z)
      INTEGER a,b
      LOGICAL detp,detr
      DIMENSION Phi(75), acf(75), dHtrans(75), Nws113(75), Rcf(75),
     + V213(75)
      COMMON /CDPH/ dph, Phi, Nws113, ng, r, Rcf, p, pq, dn, pqrs, pqrl

          dph = Phi(a) - Phi(b)
          dn = Nws113(a)-Nws113(b)
          ng = (1/Nws113(a) + 1/Nws113(b))/2

          IF (detr(a).EQV.detr(b)) THEN
              r = 0
          ELSE
              r = Rcf(a)*Rcf(b)
          END IF

          IF (detp(a).AND.detp(b)) THEN
              p = 1.15 * 12.35
C             BOTH TRUE
          ELSE IF (detp(a).EQV.detp(b)) THEN
              p = 12.35 / 1.15
C             BOTH FALSE
          ELSE
              p = 12.35
          END IF
          p = p / ng
          pq = -dph * dph + 9.4 * dn * dn
          pqrs = pq - r
          pqrl = pq - 0.73 * r

      RETURN
      END

      LOGICAL FUNCTION  detp(z)
      INTEGER z
      IF (z.LT.47.AND.(z.NE.23.AND.z.NE.31)) THEN
          detp = .true.
      ELSE
          detp = .false.
      END IF
      RETURN
      END

      LOGICAL FUNCTION  detr(z)
      INTEGER z
      IF (z.LT.47.OR.(z.GT.54.AND.z.LT.58)) THEN
          detr = .true.
      ELSE
          detr = .false.
      END IF
      RETURN
      END

Even though ALGOL doesn’t exist anymore, being a highly semantic language, it is still used in forms of pseudo-code to present algorithms and because of this reason, it didn’t take much to implement the code in FORTRAN. You can download the datafile from here. And also if you don’t want to run the code, here is the result file. And, as you can see, I haven’t trimmed or commented the code since I’ll feed it the updated values and move on forward, sorry for that!