Source code for pymatgen.io.shengbte

# coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License
import warnings

from monty.dev import requires
from monty.json import MSONable

try:
    import f90nml
except Exception:
    f90nml = None

"""
This module defines IO ShengBTE for reading, updating, and writing the
CONTROL input file
"""

__author__ = "Rees Chang"
__copyright__ = "Copyright 2019, The Materials Project"
__version__ = "0.1"
__email__ = "rc564@cornell.edu"
__date__ = "June 27, 2019"


[docs]class Control(dict, MSONable): """ Class for reading, updating, and writing ShengBTE CONTROL files. See https://bitbucket.org/sousaw/shengbte/src/master/ for more detailed description and default values of CONTROL arguments. Args: ngrid (size 3 list): number of grid planes along each axis in reciprocal space lfactor (float): unit of measurement for lattice vectors (nm) scalebroad (float): scale parameter for Gaussian smearing. A value of 1.0 is theoretically guaranteed to work, but significant speedups can sometimes be achieved by reducing it with negligible loss of precision. t (int or float): temperature (Kelvin) **kwargs: Other ShengBTE parameters. Several parameters are required for ShengBTE to run - we have listed these parameters below: - nelements (int): number of different elements in the compound - natoms (int): number of atoms in the unit cell - lattvec (size 3x3 array): real-space lattice vectors, in units of lfactor - types (size natom list): a vector of natom integers, ranging from 1 to nelements, assigning an element to each atom in the system - elements (size natom list): a vector of element names - positions (size natomx3 array): atomic positions in lattice coordinates - scell (size 3 list): supercell sizes along each crystal axis used for the 2nd-order force constant calculation """ required_params = ["nelements", "natoms", "ngrid", "lattvec", "types", "elements", "positions", "scell"] allocations_keys = ["nelements", "natoms", "ngrid", "norientations"] crystal_keys = ["lfactor", "lattvec", "types", "elements", "positions", "masses", "gfactors", "epsilon", "born", "scell", "orientations"] params_keys = ["t", "t_min", "t_max", "t_step", "omega_max", "scalebroad", "rmin", "rmax", "dr", "maxiter", "nticks", "eps"] flags_keys = ["nonanalytic", "convergence", "isotopes", "autoisotopes", "nanowires", "onlyharmonic", "espresso"] @requires(f90nml, "ShengBTE Control object requires f90nml to be installed. " "Please get it at https://pypi.org/project/f90nml.") def __init__(self, ngrid=None, lfactor=0.1, scalebroad=0.5, t=300, **kwargs): if ngrid is None: ngrid = [25, 25, 25] self["ngrid"] = ngrid self["lfactor"] = lfactor self["scalebroad"] = scalebroad self["t"] = t self.update(kwargs)
[docs] @classmethod def from_file(cls, filepath): """ Read a CONTROL namelist file and output a 'Control' object Args: filepath (String): Path of the CONTROL file. Returns: 'Control' object with parameters instantiated. """ nml = f90nml.read(filepath) sdict = nml.todict() all_dict = {} all_dict.update(sdict["allocations"]) all_dict.update(sdict["crystal"]) all_dict.update(sdict["parameters"]) all_dict.update(sdict["flags"]) return cls.from_dict(all_dict)
[docs] @classmethod def from_dict(cls, sdict): """ Write a CONTROL file from a Python dictionary. Description and default parameters can be found at https://bitbucket.org/sousaw/shengbte/src/master/. Note some parameters are mandatory. Optional parameters default here to None and will not be written to file. Args: dict: A Python dictionary of ShengBTE input parameters. """ return cls(**sdict)
[docs] def to_file(self, filename='CONTROL'): """ Writes ShengBTE CONTROL file from 'Control' object """ for param in self.required_params: if param not in self.as_dict(): warnings.warn( "Required parameter '{}' not specified!".format(param)) alloc_dict = {k: self[k] for k in self.allocations_keys if k in self and self[k] is not None} alloc_nml = f90nml.Namelist({"allocations": alloc_dict}) control_str = str(alloc_nml) + "\n" crystal_dict = {k: self[k] for k in self.crystal_keys if k in self and self[k] is not None} crystal_nml = f90nml.Namelist({"crystal": crystal_dict}) control_str += str(crystal_nml) + "\n" params_dict = {k: self[k] for k in self.params_keys if k in self and self[k] is not None} params_nml = f90nml.Namelist({"parameters": params_dict}) control_str += str(params_nml) + "\n" flags_dict = {k: self[k] for k in self.flags_keys if k in self and self[k] is not None} flags_nml = f90nml.Namelist({"flags": flags_dict}) control_str += str(flags_nml) with open(filename, "w") as file: file.write(control_str)
[docs] def as_dict(self): return dict(self)