Source code for pylada.vasp
###############################
# This file is part of PyLaDa.
#
# Copyright (C) 2013 National Renewable Energy Lab
#
# PyLaDa is a high throughput computational platform for Physics. It aims to make it easier to submit
# large numbers of jobs on supercomputers. It provides a python interface to physical input, such as
# crystal structures, as well as to a number of DFT (VASP, CRYSTAL) and atomic potential programs. It
# is able to organise and launch computational jobs on PBS and SLURM.
#
# PyLaDa is free software: you can redistribute it and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# PyLaDa is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along with PyLaDa. If not, see
# <http://www.gnu.org/licenses/>.
###############################
""" Module providing an interface to VASP code.
The interface is separated into 4 conceptual areas:
- VASP parameterization: mostly contained within :py:mod:`incar <pylada.vasp.incar>` submodule
- Launching vasp: a single-shot run is performed with a :py:class:`Vasp` object
- Extracting data from vasp output: to be found in :py:mod:`extract <pylada.vasp.extract>` submodule
- Methods: One can chain vasp runs together for more complex calculations
The :py:class:`Vasp <pylada.vasp.functional.Vasp>` class combines the first
three concepts together. It allows us to launch vasp and retrieve
information from the output. It checks for errors and avoids running the
same job twice. Hence data retrieval and vasp calculations can be performed
using the same class and script.
`version` tells for which version of VASP these bindings have been
compiled.
"""
__docformat__ = "restructuredtext en"
__all__ = ['Vasp', 'Extract', 'Specie', 'MassExtract', 'relax', 'emass', 'read_input', 'exec_input']
from .extract import Extract, MassExtract
from .specie import Specie
from .functional import Vasp
from . import relax, emass
def exec_input( script, global_dict=None, local_dict=None,
paths=None, name=None ):
""" Specialized exec_input function for vasp. """
from ..misc import exec_input
# names we need to create input.
if global_dict is None: global_dict = {}
for k in __all__:
if k != 'read_input' and k != 'exec_input': global_dict[k] = globals()[k]
return exec_input(script, global_dict, local_dict, paths, name)
def parse_incar(path):
""" Reads INCAR file and returns mapping (keyword, value). """
from os.path import isdir, join
from ..error import ValueError
from ..misc import RelativePath
from ..tools.input import Tree
if isinstance(path, str):
if path.find('\n') == -1:
dummy = RelativePath(path).path
if isdir(dummy): dummy = join(dummy, 'INCAR')
with open(dummy) as file: return parse_incar(file)
else:
return parse_incar(path.split('\n').__iter__())
lines = []
for line in path:
if line.find('#') != -1: line = line[:line.find('#')]
dummy = [u.lstrip().rstrip() for u in line.split(';')]
dummy = [u for u in dummy if len(u) > 0]
if len(dummy) and len(lines) == 0: lines.append(dummy.pop(-1))
while len(dummy):
if lines[-1][-1] == '\\':
lines[-1] = lines[-1][:-1] + dummy.pop(-1)
else: lines.append(dummy.pop(-1))
result = Tree()
for line in lines:
if line.find('=') == -1: continue
keyword, value = [u.rstrip().lstrip() for u in line.split('=')]
if len(keyword) == 0: raise ValueError('Found empty keword in INCAR.')
if keyword in result: raise ValueError('Found duplicate keyword {0} in INCAR'.format(keyword))
result[keyword] = value
return result
[docs]def read_incar(filename='INCAR'):
""" Reads a functional from an INCAR.
:param filename:
It can be one of the following:
- An iterable object: each iteration should yield a line in the
INCAR.
- A string (single line): path to a directory containing an INCAR_ or
to an INCAR_ file itself.
- A string (multi-line): should be the content of an INCAR_.
Defaults to 'INCAR'.
:returns: A vasp functional equivalent to the INCAR_.
:rtype: :py:class:`~pylada.vasp.functional.Vasp`
"""
from .functional import Vasp
parsed = parse_incar(filename)
result = Vasp()
result.read_input(parsed)
return result