writing VASP calculations to ase.db formats
Posted March 26, 2014 at 01:22 PM | categories: ase, vasp | tags:
Table of Contents
The ase development team has created a new database module (https://wiki.fysik.dtu.dk/ase/ase/db/db.html ). In this post, we will examine how to use that in conjunction with jasp
to save calculations to a database. To use this you need the latest version of jasp from http://github.com/jkitchin/jasp .
The idea here is to use the code from http://kitchingroup.cheme.cmu.edu/blog/2014/03/20/Finding-VASP-calculations-in-a-directory-tree/ to add each calculation in that subtree to an ase database. We will use the json format for the database.
import os from jasp import * from ase.db import connect c = connect('vaspdb.json') def vasp_p(directory): 'returns True if a finished OUTCAR file exists in the current directory, else False' outcar = os.path.join(directory, 'OUTCAR') if os.path.exists(outcar): with open(outcar, 'r') as f: contents = f.read() if 'General timing and accounting informations for this job:' in contents: return True return False total_time = 0 for root, dirs, files in os.walk('/home-research/jkitchin/research/rutile-atat'): for d in dirs: # compute absolute path to each directory in the current root absd = os.path.join(root, d) if vasp_p(absd): # we found a vasp directory, so we can do something in it. # here we get the elapsed time from the calculation with jasp(absd) as calc: atoms = calc.get_atoms() calc.results['energy'] = atoms.get_potential_energy() calc.results['forces'] = atoms.get_forces() # it is important that this line not be inside the jasp # context-manager, because c.write writes in the local # dir. print c.write(atoms, ['atat']), absd
1 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/0 2 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/1 3 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/10 4 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/11 5 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/12 6 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/13 7 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/14 8 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/15 9 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/16 10 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/17 11 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/2 12 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/3 13 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/4 14 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/5 15 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/59 16 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/6 17 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/66 18 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/7 19 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/73 20 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/74 21 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/78 22 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/8 23 /home-research/jkitchin/research/rutile-atat/RuTi_O_rutile/9
The result is in this file: vaspdb.json .
We can see the contents of that database like this:
import os from jasp import * from ase.db import connect c = connect('vaspdb.json') g = c.select() # g is a generator print g.next()
{u'username': u'jkitchin', u'calculator_name': u'vasp', u'tags': array([0, 0, 0, 0, 0, 0]), u'positions': array([[ 1.382, 1.382, 0. ], [ 3.145, 3.145, 0. ], [ 3.646, 0.881, 1.548], [ 0.881, 3.646, 1.548], [ 0. , 0. , 0. ], [ 2.263, 2.263, 1.548]]), u'energy': -44.251496, u'calculator_parameters': {u'incar': {u'doc': u'INCAR parameters', u'prec': u'high', u'nbands': 43, u'sigma': 0.1, u'encut': 350.0}, u'doc': u'JSON representation of a VASP calculation.\n\nenergy is in eV\nforces are in eV/\\AA\nstress is in GPa (sxx, syy, szz, syz, sxz, sxy)\nmagnetic moments are in Bohr-magneton\nThe density of states is reported with E_f at 0 eV.\nVolume is reported in \\AA^3\nCoordinates and cell parameters are reported in \\AA\n\nIf atom-projected dos are included they are in the form:\n{ados:{energy:data, {atom index: {orbital : dos}}}\n', u'potcar': [[u'Ru', u'potpaw_PBE/Ru/POTCAR', u'dee616f2a1e7a5430bb588f1710bfea3001d54ea'], [u'O', u'potpaw_PBE/O/POTCAR', u'9a0489b46120b0cad515d935f44b5fbe3a3b1dfa']], u'input': {u'kpts': array([ 6, 6, 10]), u'reciprocal': False, u'xc': u'PBE', u'kpts_nintersections': None, u'setups': {}, u'txt': u'-', u'gamma': True}, u'atoms': {u'cell': array([[ 4.527, 0. , 0. ], [ 0. , 4.527, 0. ], [ 0. , 0. , 3.095]]), u'symbols': [u'O', u'O', u'O', u'O', u'Ru', u'Ru'], u'tags': array([0, 0, 0, 0, 0, 0]), u'pbc': array([ True, True, True], dtype=bool), u'positions': array([[ 1.382, 1.382, 0. ], [ 3.145, 3.145, 0. ], [ 3.646, 0.881, 1.548], [ 0.881, 3.646, 1.548], [ 0. , 0. , 0. ], [ 2.263, 2.263, 1.548]])}, u'data': {u'stress': array([ 0.088, 0.088, 0.06 , -0. , -0. , -0. ]), u'doc': u'Data from the output of the calculation', u'volume': 63.43221074143486, u'total_energy': -44.251496, u'forces': array([[-0.024, -0.024, 0. ], [ 0.024, 0.024, 0. ], [-0.024, 0.024, 0. ], [ 0.024, -0.024, 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ]]), u'fermi_level': 5.0374}, u'metadata': {u'date.created': 1395241327.477995, u'uuid': u'7081ee4a-af77-11e3-a6e6-003048f5e49e', u'date.created.ascii': u'Wed Mar 19 11:02:07 2014', u'user.username': u'jkitchin', u'atoms.resort': array([2, 3, 4, 5, 0, 1]), u'user.email': u'jkitchin@andrew.cmu.edu', u'user.fullname': u'John Kitchin', u'O.potential.git_hash': u'9a0489b46120b0cad515d935f44b5fbe3a3b1dfa', u'atoms.tags': array([0, 0, 0, 0, 0, 0]), u'O.potential.path': u'potpaw_PBE/O/POTCAR', u'Ru.potential.path': u'potpaw_PBE/Ru/POTCAR', u'Ru.potential.git_hash': u'dee616f2a1e7a5430bb588f1710bfea3001d54ea'}}, u'cell': array([[ 4.527, 0. , 0. ], [ 0. , 4.527, 0. ], [ 0. , 0. , 3.095]]), u'numbers': array([ 8, 8, 8, 8, 44, 44]), u'pbc': array([ True, True, True], dtype=bool), u'timestamp': 14.23343757848325, u'keywords': [u'atat'], u'forces': array([[-0.024, -0.024, 0. ], [ 0.024, 0.024, 0. ], [-0.024, 0.024, 0. ], [ 0.024, -0.024, 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ]]), 'id': 1, u'unique_id': u'123901e31734f14418381a23d1ee1072'}
The data stored there comes from the calc.todict() function written for jasp.
We can do some searches like this. Say we want to find all the calculations where there are four oxygen atoms.
import os from jasp import * from ase.db import connect c = connect('vaspdb.json') g = c.select(O=4) # g is a generator for entry in g: print c.get_atoms(entry['id']), '\n'
Atoms(symbols='O4Ru2', positions=..., tags=..., cell=[4.526933343669885, 4.526933343669885, 3.095292162609941], pbc=[True, True, True], calculator=SinglePointCalculator(...)) Atoms(symbols='O4Ti2', positions=..., tags=..., cell=[4.614336091353763, 4.614336091353763, 2.9555779409837473], pbc=[True, True, True], calculator=SinglePointCalculator(...)) Atoms(symbols='O4RuTi', positions=..., tags=..., cell=[[-0.0151920891931803, -4.604112035041115, 0.0], [-4.604112035041115, -0.0151920891931803, 0.0], [0.0, 0.0, -3.0110141191854245]], pbc=[True, True, True], calculator=SinglePointCalculator(...))
You can see there are three calculations with that criterion.
1 The command-line interface
There is also a command-line interface.
ase-db --help
usage: ase-db [-h] [-n] [-c COLUMNS] [--explain] [-y] [-i INSERT_INTO] [-k ADD_KEYWORDS] [-K ADD_KEY_VALUE_PAIRS] [--delete-keywords DELETE_KEYWORDS] [--delete-key-value-pairs DELETE_KEY_VALUE_PAIRS] [--delete] [-v] [-q] [-s SORT] [-r] [-l] [--limit LIMIT] [-p PYTHON_EXPRESSION] name [selection] positional arguments: name selection optional arguments: -h, --help show this help message and exit -n, --count -c COLUMNS, --columns COLUMNS short/long+row-row --explain -y, --yes -i INSERT_INTO, --insert-into INSERT_INTO -k ADD_KEYWORDS, --add-keywords ADD_KEYWORDS -K ADD_KEY_VALUE_PAIRS, --add-key-value-pairs ADD_KEY_VALUE_PAIRS --delete-keywords DELETE_KEYWORDS --delete-key-value-pairs DELETE_KEY_VALUE_PAIRS --delete -v, --verbose -q, --quiet -s SORT, --sort SORT -r, --reverse -l, --long --limit LIMIT -p PYTHON_EXPRESSION, --python-expression PYTHON_EXPRESSION
It is not obvious all those options are actually supported. For example, it is not clear there is a function that actually deletes keywords in the source code. You can add keywords, but I cannot figure out the syntax to add to one entry.
Below are some examples that do work. We can list details of the calculation with id=1.
ase-db vaspdb.json id=1
id|age|user |formula|calc| energy| fmax|pbc| size|keywords| mass 1|9m |jkitchin|O4Ru2 |vasp|-44.251|0.033|111|63.432|atat |266.138
Get calculations with four oxygen atoms:
ase-db vaspdb.json O=4
id|age|user |formula|calc| energy| fmax|pbc| size|keywords| mass 1|9m |jkitchin|O4Ru2 |vasp|-44.251|0.033|111|63.432|atat |266.138 2|9m |jkitchin|O4Ti2 |vasp|-52.970|0.033|111|62.930|atat |159.758 11|9m |jkitchin|O4RuTi |vasp|-48.115|0.157|111|63.826|atat |212.948
Get all calculations tagged with atat
ase-db vaspdb.json atat
id|age|user |formula |calc| energy| fmax|pbc| size|keywords| mass 1|9m |jkitchin|O4Ru2 |vasp| -44.251|0.033|111| 63.432|atat |266.138 2|9m |jkitchin|O4Ti2 |vasp| -52.970|0.033|111| 62.930|atat |159.758 3|9m |jkitchin|O8Ru2Ti2 |vasp| -96.601|0.086|111|126.719|atat |425.895 4|9m |jkitchin|O8RuTi3 |vasp|-100.842|0.075|111|126.846|atat |372.705 5|9m |jkitchin|O8Ru3Ti |vasp| -92.376|0.133|111|127.420|atat |479.085 6|9m |jkitchin|O8Ru2Ti2 |vasp| -96.594|0.184|111|127.176|atat |425.895 7|9m |jkitchin|O8RuTi3 |vasp|-100.959|0.176|111|126.924|atat |372.705 8|9m |jkitchin|O8Ru3Ti |vasp| -92.314|0.084|111|127.377|atat |479.085 9|9m |jkitchin|O8Ru2Ti2 |vasp| -96.612|0.086|111|126.542|atat |425.895 10|9m |jkitchin|O8RuTi3 |vasp|-100.816|0.080|111|126.557|atat |372.705 11|9m |jkitchin|O4RuTi |vasp| -48.115|0.157|111| 63.826|atat |212.948 12|9m |jkitchin|O8Ru3Ti |vasp| -92.429|0.163|111|127.291|atat |479.085 13|9m |jkitchin|O8Ru2Ti2 |vasp| -96.770|0.166|111|126.870|atat |425.895 14|9m |jkitchin|O8RuTi3 |vasp|-101.014|0.222|111|126.881|atat |372.705 15|9m |jkitchin|O12Ru4Ti2|vasp|-140.969|0.114|111|190.614|atat |692.033 16|9m |jkitchin|O8Ru3Ti |vasp| -92.323|0.125|111|127.541|atat |479.085 17|9m |jkitchin|O12Ru2Ti4|vasp|-149.516|0.241|111|190.070|atat |585.653 18|9m |jkitchin|O8Ru2Ti2 |vasp| -96.661|0.064|111|127.038|atat |425.895 19|9m |jkitchin|O12Ru4Ti2|vasp|-140.472|0.138|111|190.640|atat |692.033 20|9m |jkitchin|O12Ru3Ti3|vasp|-144.667|0.166|111|190.604|atat |638.843 21|9m |jkitchin|O12Ru2Ti4|vasp|-148.813|0.055|111|190.084|atat |585.653 22|9m |jkitchin|O8RuTi3 |vasp|-100.874|0.051|111|126.690|atat |372.705 23|9m |jkitchin|O8Ru3Ti |vasp| -92.246|0.102|111|127.383|atat |479.085
2 Summary thoughts
This is a nice addition to ase. I think it needs some thorough, production work testing to find out exactly how useful it is. We may need to reconsider the calc.todict() function in jasp to remove redundancy, but overall this is a good idea.
Copyright (C) 2014 by John Kitchin. See the License for information about copying.
Org-mode version = 8.2.5h