Volume optimization of Ag

Volume optimization is a simple case of an aggregation property. This example shows how to set up the inputs for the data points with the help of a template and how to determine the optimal volume by fitting the corresponding total energies.

We are going to use a simple inputxml template to generate the input files for the total-energies calculations.


Experiment description

In order to vary the scale of the unit cell by +/- 5% we need a description of our experiment:

File: scale.xml

<?xml version="1.0" encoding="UTF-8" ?>
    <set unicellscaling="0.95" path="unicellscaling_0.95"/>
    <set unicellscaling="0.975" path="unicellscaling_0.975" />
    <set unicellscaling="1" path="unicellscaling_1"/>
    <set unicellscaling="1.025" path="unicellscaling_1.025"/>
    <set unicellscaling="1.05" path="unicellscaling_1.05"/>

This quasi format is referred to as experiment-list and used in various other examples.

The template

In order to generate the input files we use XSLT templating-tools. The corresponding template:


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
<xsl:output method="xml" />
<xsl:template match="/">
<!-- Authors: chm, jus, sag -->
<!-- Loop over all elements named "set" from reference xml-file -->
<xsl:for-each select = "/experiment/set">
<xsl:variable name="path">
<xsl:value-of select="@path"/>
 <!-- Write document at Path $path -->
 <xsl:document href="{$path}" method="xml" indent="yes">
 This file is generated with XSLTPROC using a template file and a reference file
<!-- ////////////////////////////////////////////////////////////////////////-->
<!-- /// The input file begins here /////////////////////////////////////////-->
<!-- ////////////////////////////////////////////////////////////////////////-->
<input xsi:noNamespaceSchemaLocation="excitinginput.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsltpath="../../../xml/"
  <title>Ag Energy-Volume</title>
  <structure speciespath="../../../species/">
    <crystal >
    <xsl:attribute name="scale">
    <xsl:value-of select="3.86*@unicellscaling"/>
      <basevect>1.0 1.0 0.0</basevect>
      <basevect>1.0 0.0 1.0</basevect>
      <basevect>0.0 1.0 1.0</basevect>
    <species speciesfile="Ag.xml">
      <atom coord="0.0  0.0  0.0" />
  <groundstate ngridk="8 8 8" rgkmax="8" />
<!-- ////////////////////////////////////////////////////////////////////////-->
<!-- /// The input file ends here ///////////////////////////////////////////-->
<!-- ////////////////////////////////////////////////////////////////////////-->

It looks quite complicated, but it consists only of a generic part (which can be used for all cases with a similar experiment description) and the Ag input file, where in the latter the @scale attribute of the <crystal> element is expressed in XSLT:

    <xsl:attribute name="scale">
    <xsl:value-of select="3.86*@unicellscaling"/>

To apply this template, execute:

xsltproc  evTemplate.xsl  scales.xml

Then xsltproc will create the five directories with the proper input file therein.


Here we have to run 5 self-consistent calculations. You may start them by hand. For more complex examples one could use templates to create scripts of all kind like: loadleveler-multistep-job-template


In order to get the energy-volume curve we have to collect the data, which are the volumes and corresponding total-energy values. They are saved among many other values in info.xml. To collect them into one file we use getev.xsl to get:

<?xml version="1.0"?>
<graph xmlns:math="http://exslt.org/math" xmlns:str="http://exslt.org/strings">
  <point volume="139.469011682385" scale="3.667" totalEnergy="-5312.439270664138"/>
  <point volume="150.772020410909" scale="3.7635" totalEnergy="-5312.4416556378"/>
  <point volume="162.669790561172" scale="3.86" totalEnergy="-5312.440895946467"/>
  <point volume="175.177572426039" scale="3.9565" totalEnergy="-5312.437999079701"/>
  <point volume="188.310616298377" scale="4.053" totalEnergy="-5312.433397077082"/>
xsltproc getev.xsl scales.xml >eV.xml

The script EV.py fits the data points, gets the minimum and plots the corresponding graphics:

import numpy as nm
import libxml2
from array import *
from libxml2 import xmlAttr
import matplotlib.pyplot as plt
# read data
eVdoc = libxml2.parseFile("./eV.xml")
ctxt = eVdoc.xpathNewContext()
# make parabular fit
# find root of derivative to get minimum
# x values for plotting polynomial
xa = nm.linspace(Volume[0],Volume[-1],100)
plt.ylabel(r'Total energy $[Ha]$')
plt.xlabel(r'Volume $[bohr]^3$')
plt.annotate('optimal volume '+str(min[0]), xy=(min,curve(min)), xycoords='data' ,
              xytext=(min-10,curve(min)+0.002) ,  arrowprops=dict(arrowstyle="->"))
print 'optimal volume '+str(min[0])

To execute this script, call:

python EV.py


Additional excercises

  • Improve the accuracy of the fit by adding an additional data point.
  • Calculate the lattice constant of the optimal volume.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License