dftbutils sub-package

Run BS (skpar.dftbutils.runBS)

Query DFTB (skpar.dftbutils.queryDFTB)

class skpar.dftbutils.queryDFTB.BandsOut(*args, **kwargs)[source]

A dictionary initialised with the bands from dp_bands or similar tool.

Useage:

destination_dict = BandsOut.fromfile(file)
classmethod fromfile(fp, enumeration=True)[source]
class skpar.dftbutils.queryDFTB.Bandstructure(*args, **kwargs)[source]

A dictionary initialised with the bands and some analysis of the bands.

It requires two files: detailed.out from dftb+, and bands_tot.dat from dp_bands. It reads the bands via BandsOut; obtains the number of electrons via DetailedOut. It returns a dictionary with all that is in DetailedOut plus: ‘bands’: energy bands (excluding k-point enumeration) ‘Ecb’ : LUMO ‘Evb’ : HOMO ‘Egap’ : Ecb - Evb

Useage:

destination_dict = Bandstructure.fromfiles(detailed.out_file, bands_file)
classmethod fromfiles(fp1, fp2, enumeration=True)[source]

Read the output of dftb+ and dp_bands and return a dictionary with band-structure data.

class skpar.dftbutils.queryDFTB.DetailedOut(*args, **kwargs)[source]

A dictionary initialised from file with the detailed output of dftb+.

Useage:

destination_dict = DetailedOut.fromfile(filename)
conv_tags = [('iSCC', ('nscc', 'scc_err')), ('SCC converged', True), ('SCC is NOT converged', True)]
energy_tags = [('Fermi energy:', 'Ef'), ('Fermi level:', 'Ef'), ('Band energy:', 'Eband'), ('TS:', 'Ets'), ('Band free energy (E-TS):', 'Ebf'), ('Extrapolated E(0K):', 'E0K'), ('Energy H0:', 'Eh0'), ('Energy SCC:', 'Escc'), ('Energy L.S:', 'Els'), ('Total Electronic energy:', 'Eel'), ('Repulsive energy:', 'Erep'), ('Total energy:', 'Etot'), ('Total Mermin free energy:', 'Emermin')]
classmethod fromfile(fp)[source]
nelec_tags = [('Input/Output electrons (q):', ('nei', 'neo')), ('Input / Output electrons (q):', ('nei', 'neo'))]
skpar.dftbutils.queryDFTB.calc_masseff(bands, extrtype, kLineEnds, lattice, meff_tag=None, Erange=0.008, forceErange=False, ib0=0, nb=1, usebandindex=False, **kwargs)[source]

A complex wrapper around meff(), with higher level interface.

Calculate parabolic effective mass at the specified extrtype of given bands, calculated along two points in k-space defined by a list of two 3-tuples - kLineEnds. lattice is a lattice object, defining the metric of the kspace.

Parameters:
  • bands – an array (nb, nk) energy values in [eV], or a 1D array like
  • extrtype – type of extremum to search for: ‘min’ or ‘max’, handled by np.min()/max()
  • kLineEnds – two 3-tuples, defining the coordinates of the endpoints of the k-line along which band is obtained, in terms of k-scace unit vectors, e.g. if band is obtained along a number of points from Gamma to X, of the BZ of a cubic lattice, then kLineEnds should read ((0, 0, 0), (1, 0, 0))
  • lattice – lattice object, holding mapping to kspace.
  • meff_name – the name to be featured in the logger
  • Erange – Energy range [eV] over which to fit the parabola [dflt=8meV], i.e. ‘depth’ of the assumed parabolic well.
Return meff:

the value of the parabolic effective mass [m_0] at the extrtype of the given E-kline, if the extremum is not at the boundary of the given k-line.

skpar.dftbutils.queryDFTB.expand_meffdata(meff_data)[source]
skpar.dftbutils.queryDFTB.get_Ek(bsdata, sympts)[source]
skpar.dftbutils.queryDFTB.get_bandstructure(implargs, database, source, model, detailfile='detailed.out', bandsfile='bands_tot.dat', hsdfile='dftb_pin.hsd', latticeinfo=None, *args, **kwargs)[source]

Get bandstructure and related data from dftb+.

Assume that source is the execution directory where detailed.out, and bands_tot.dat can be found. Additionally, the parsed input of dftb+ – dftb_pin.hsd is also checked if lattice info is given, in order to analyse k-paths and provide data for subsequent plotting.

skpar.dftbutils.queryDFTB.get_dftbp_data(implargs, database, source, model, datafile='detailed.out')[source]

Get whatever data can be obtained from detailed.out of dftb+.

Assume source is the directory where dftb+ was executed and that datafile is the detailed output file, along with dftb_pin.hsd, etc.

Parameters:
  • implargs (dict) – implicit key-word arguments passed by caller
  • database (obj) – a database object that has a .update(dict) method
  • source (str) – directory name where dftb+ has been executed
  • model (str) – name of the model whose data is updated
  • datafile (str) – base-name of the detailed output from dftb+
skpar.dftbutils.queryDFTB.get_dftbp_evol(implargs, database, source, model, datafile='detailed.out', *args, **kwargs)[source]

Get the data from DFTB+ SCC calculation for all models.

This is a compound task that augments the source path to include individual local directories for different cell volumes, based on the assumption that these directories are named by 3 digits. Similar assumption applies for the model, where the name of the base model is augmented by the 3-digit directory number.

Parameters:
  • workroot (string) – base directory where model directories are found.
  • source (string) – model directory
  • model (str) – name of the model whose data is updated
  • datafile (string) – optional filename holding the data.
skpar.dftbutils.queryDFTB.get_effmasses(implargs, database, source, model=None, directions=None, carriers='both', nb=1, Erange=0.04, usebandindex=False, forceErange=False, *args, **kwargs)[source]

Get effective masses along select directions for select carrier types.

Obtain the effective masses for the given carriers for the first nb bands in the VB and/or CB, along the given directions, as well as the values of the extrema and their position along these directions. Label the effective masses by band index (starting from 0, within the band for the select carrier type), if usebandindex is True. Carrier types (carriers) could be ‘e’, ‘h’, ‘both’. Erange is the energy range over which parabolic expansion is attempted

skpar.dftbutils.queryDFTB.get_labels(ss)[source]

Return two labels from a string containing “-” or two words starting with a capital.

For example, the input string may be ‘G-X’, ‘GX’, ‘Gamma-X’, ‘GammaX’. The output is always: (‘G’, ‘X’) or (‘Gamma’, ‘X’).

skpar.dftbutils.queryDFTB.get_special_Ek(implargs, database, source, model=None, sympts=None, extract={'cb': [0], 'vb': [0]}, align='Ef', usebandindex=True, *args, **kwargs)[source]

Query bandstructure data and yield the eigenvalues at k-points of high-symmetry.

skpar.dftbutils.queryDFTB.greek(label)[source]

Change Greek letter names to single Latin capitals, and vice versa.

Useful for some names of high-symmetry points inside the BZ, to shorten the names of Gamma, Sigma and Delta. Note that Lambda cannot be made into L, as it will make automatic L to Lambda as well, which is wrong since L is a standard point on the BZ surface.

skpar.dftbutils.queryDFTB.is_monotonic(x)[source]

Return True if x is monotonic (either never increases or never decreases); False otherwise.

skpar.dftbutils.queryDFTB.meff(band, kline)[source]

Return the effective mass, in units of m_0, given a band a k-line.

The mass is calculated as as the inverse of the curvature of bands, assuming parabolic dispersion within kline, working in atomic units: bands and kline are in Hartree and 1/Bohr, h_bar = 1, m_0 = 1

meff = (h_bar**2) / (d**2E/dk**2), [m0]
skpar.dftbutils.queryDFTB.plot_fitmeff(ax, xx, x0, extremum, mass, dklen=None, ix0=None, *args, **kwargs)[source]

Plot the second order polynomial fitted to E(k) dispersion on top of ax axes of a matplotlib figure object. mass is the fitted effective mass extremum is extremal energy, E0 x0 is the relative position of the extremum along the given kline xx.

Assumed is that around the extremum at k0:

E”(k) = 1/mass => E(k) = E(x) = c2*x^2 + c1*x + c0.

Since E”(x) = 2*c2 => c2 = 1/(2*mass). Since E’(x) = 2*c2*x + c1, and E’(x=x0) = 0 and E(x=x0) = E0 => knowing E0 and x0, we can obtain c1 and c2:

c1 = -2*c2*x0 c0 = E0 - c2*x0^2 - c1*x0

Query k-Lines (skpar.dftbutils.querykLines)

Module for k-Lines extraction and k-Label manipulation

Recall that bands contains NO information of the k-points. So we must provide that ourselves, and reading the dftb_pin.hsd (the parsed input) seems the best way to do so. We also need to figure out what to do with equivalent points, or points where a new path starts. Finally, points internal to the Brilloin Zone are labeled with Greek letters, which should be rendered properly.

skpar.dftbutils.querykLines.get_klines(lattice, hsdfile='dftb_pin.hsd', workdir=None, *args, **kwargs)[source]

This routine analyses the KPointsAndWeights stanza in the input file of DFTB+ (given as an input argument hsdfile), and returns the k-path, based on the lattice object (given as an input argument lattice). If the file name is not provided, the routine looks in the default dftb_pin.hsd, i.e. in the parsed file!

The routine returns a list of tuples (kLines) and a dictionary (kLinesDict) with the symmetry points and indexes of the corresponding k-point in the output band-structure.

kLines is ordered, as per the appearence of symmetry points in the hsd input, e.g.:

  • [(‘L’, 0), (‘Γ’, 50), (‘X’, 110), (‘U’, 130), (‘K’, 131), (‘Γ’, 181)]

therefore it may contain repetitions (e.g. for ‘Γ’, in this case).

kLinesDict returns a dictionary of lists, so that there’s a single entry for non-repetitive k-points, and more than one entries in the list of repetitive symmetry k-points, e.g. (see for ‘Γ’ above):

  • {‘X’: [110], ‘K’: [131], ‘U’: [130], ‘L’: [0], ‘Γ’: [50, 181]}
skpar.dftbutils.querykLines.get_kvec_abscissa(lat, kLines)[source]

Return abscissa values for the reciprocal lengths corresponding to the k-vectors derived from kLines.

skpar.dftbutils.querykLines.greekLabels(kLines)[source]

Check if Γ is within the kLines and set the label to its latex formulation. Note that the routine will accept either list of tupples (‘label’,int_index) or a list of strings, i.e. either kLines or only the kLinesLabels. Could do check for other k-points with greek lables, byond Γ (i.e. points that are inside the BZ, not at the faces) but in the future.

Lattice (skpar.dftbutils.lattice)

This module lists the component vectors of the direct and reciprocal lattices for different crystals. It is based on the following publication: Wahyu Setyawan and Stefano Curtarolo, “High-throughput electronic band structure calculations: Challenges and tools”, Comp. Mat. Sci. 49 (2010), pp. 291–312.

class skpar.dftbutils.lattice.BCC(param, setting='curtarolo')[source]

This is Body Centered Cubic lattice (cF)

class skpar.dftbutils.lattice.CUB(param, setting=None)[source]

This is CUBic, cP lattice

class skpar.dftbutils.lattice.FCC(param, setting='curtarolo')[source]

This is Face Centered Cubic lattice (cF)

class skpar.dftbutils.lattice.HEX(param, setting='curtarolo')[source]

This is HEXAGONAL, hP lattice

class skpar.dftbutils.lattice.Lattice(info)[source]

Generic lattice class.

get_kcomp(string)[source]

Return the k-components given a string label or string set of fraction.

Example of string:

s = ‘X’ s = ‘1/2 0 1/2’ s = ‘1/2, 0, 1/2’ s = ‘0.5 0 0.5’
get_kvec(kpt)[source]

Return the real space vector corresponding to a k-point.

class skpar.dftbutils.lattice.MCL(param, setting='curtarolo')[source]

This is simple Monoclinic MCL_* (mP) lattice, set via a, b <= c, and alpha < 90 degrees, beta = gamma = 90 degrees as in W. Setyawan, S. Curtarolo / Computational Materials Science 49 (2010) 299-312. Setting=ITC should work for the standard setting (angle>90) of ITC-A, but is not currently implemented. Note that conventional and primitive cells are the same.

class skpar.dftbutils.lattice.MCLC(param, setting='ITC')[source]

This is base-centered Monoclinic MCLC_* mS, lattice Primitive lattice defined via: a <> b <> c, and alpha <> 90 degrees, beta = gamma = 90 degrees

class skpar.dftbutils.lattice.ORC(param, setting='curtarolo')[source]

This is ORTHOROMBIC, oP lattice

class skpar.dftbutils.lattice.RHL(param, setting=None)[source]

This is Rhombohedral RHL, hR lattice Primitive lattice defined via: a = b = c, and alpha = beta = gamma <> 90 degrees Two variations exists: RHL1 (alpha < 90) and RHL2 (alpha > 90)

class skpar.dftbutils.lattice.TET(param, setting='curtarolo')[source]

This is TETRAGONAL, tP lattice

skpar.dftbutils.lattice.getSymPtLabel(kvec, lattice)[source]

Return the symbol corresponding to a given k-vector, if named.

This routine returns the symbol of a symmetry point that is given in terms of reciprocal cell-vectors (kvec – a 3-tuple) of the lattice object.

skpar.dftbutils.lattice.get_dftbp_klines(lattice, delta=None, path=None)[source]

Print out the number of points along each segment of the BZ path (default for the lattice chosen if None) of a given lattice object

skpar.dftbutils.lattice.get_kvec(comp_rc, recipr_cell)[source]

comp_rc are the components of a vector expressed in terms of reciprocal cell vectors recipr_cell. Return the components of this vector in terms of reciprocal unit vectors.

skpar.dftbutils.lattice.get_recipr_cell(A, scale)[source]

Given a set of set of three vectors A, assumed to be that defining the primitive cell, return the corresponding set of vectors that define the reciprocal cell, B, scaled by the input parameter scale, which defaults to 2pi. The B-vectors are computed as follows: B0 = scale * (A1 x A2)/(A0 . A1 x A2) B1 = scale * (A2 x A0)/(A0 . A1 x A2) B2 = scale * (A0 x A1)/(A0 . A1 x A2) and are returnd as a list of 1D arrays. Recall that the triple-scalar product is invariant under circular shift, and equals the (signed) volume of the primitive cell.

skpar.dftbutils.lattice.getkLineLength(kpt0, kpt1, Bvec, scale)[source]

Given two k-points in terms of unit vectors of the reciprocal lattice, Bvec, return the distance between the two points, in terms of reciprocal length.

skpar.dftbutils.lattice.len_pathsegments(lattice, scale=None, path=None)[source]

Report the lenth in terms of _scale_ (2pi/a if None) of the BZ _path_ (default for the lattice chosen if None) of a given _lattice_ object

skpar.dftbutils.lattice.repr_lattice(lat)[source]

Report cell vectors, reciprocal vectors and standard path

Plot (skpar.dftbutils.plot)

skpar.dftbutils.plot.magic_plot_bs(xval, yval, filename=None, **kwargs)[source]

A magic-wrapper around the fundamental back-end plot_bs function.

The magic is that if yval is a list of [Egap, VBand, CBand,…] the data is modified so that a band-gap, Egap, is open between cband and vband, even if they are not properly aligned, e.g. if CB bottom is 0 at the same time as VB top is 0. Note that the CB is moved, not the VB. NOTABENE: the order must be Egap, VB, CB!

We do this here, so that we don’t burden the PlotTask elsewhere with knowledge of what band structure and band-gap is, and keep it independent of what it is plotting. However, somewhere, the gap need to be opened, if we’ve specified CB and VB as independent objectives, and certainly the band-end plot_bs is not such a place due to its intended generality (of plotting band-structures unrelated to objectives, optimisation etc.).

The magic happens only if yval contains an array shaped (1,), which is taken as a band-gap. If no such array is discovered, no shifts are applied to the bands.

Parameters:
  • filename (str) – valid filename to save the plot
  • xval (arr) – k-points (1D array or a list of values and 1D arrays)
  • yval (arr) – bands (2D-array or a list values and 2D arrays)
Kwargs:
Check plot_bs for details as kwargs are passed directly to it.
Returns:matplotlib figure and axes objects containing the plot
Return type:fig, ax
skpar.dftbutils.plot.plot_bs(xx, yy, colors=None, linelabels=None, title=None, figsize=(6, 7), xticklabels=None, yticklabels=None, xlim=None, ylim=None, xlabel=None, ylabel='Energy (eV)', filename=None, legendloc=0, **kwargs)[source]

Routine for plotting band-structure.

Accepts one or more sets of k-vector and corresponding bands, but the k-vector may be shared too. If you supply a set of ticks and labels for specific k-points, it will put them on X axis and will extend the xticks over all Y as thin lines; see xticklabels below.

Parameters:
  • xx – 1D array or a list of such; k-points.shape = nk
  • yy

    2D array or a list of such; bands.shape = nk, nE Notabene: each band is a column in its respective array

    so that the lowest band is leftmost.
  • colors – list of colors, one per 2D array of bands; if None, default matplotlib Vega/D3 set of colours is used.
  • linelabels – list of strings to label each set of bands in legend
  • title – figure title
  • figsize – tupple for figure dimensions, in inches; defaults to (6,7)
  • ylim (xlim,) – tupple of limits for X-axis, or Y-axis
  • ylabel (xlabel,) – axes labels
  • yticklabels (xticklabels,) – a list of explicit X- or Y-axis ticks and labels, e.g. [(‘label’,x), …]
  • filename (str) – filename (incl directory as needed); if present the figure is saved to that file.
Kwargs:
kticklabels: interpreted as xticklabels eticklabels: interpreted as yticklabels No other kwargs are interpreted, but no exception is generated if supplied.
Returns:matplotlib objects holding the plot
Return type:fig, ax
skpar.dftbutils.plot.set_axes(ax, xlabel, ylabel, xticklabels=None, yticklabels=None, extend_xticks=False, extend_yticks=False)[source]

Configure axes – labels and ticks/ticklabels.

Parameters:
  • ax – matplotlib axis object
  • ylabel (xlabel,) – labels for the x and y axis
  • yticklabels (xticklabels,) – list of [(value, ‘label’), ] for each explicit position of ticks and their labels
  • extend_yticks (extend_xticks,) – extend_x/yticks entire graph
skpar.dftbutils.plot.set_mplrcpar(**kwargs)[source]

Configure matplotlib rcParams.

skpar.dftbutils.plot.set_xylimits(ax, xval, yval, xlim=None, ylim=None, issetx=False, issety=False)[source]

Set x and y axis limits to exactly fit the data if not explicit.

ax: matplotlib axis object xval, yval: array (could be record array), lists of arrays xlim, ylim: tupple of (min,max) - explicit axis limits issetx, issety (bool): used if xlim or ylim is None, in which case

these flags serve to tell us to find min and max of the xval and yval even if these are record arrays where broadcasting won’t work. (e.g. yval is an array of two 1D arrays of different shape)

Unils (skpar.dftbutils.utils)

General utility functions

skpar.dftbutils.utils.configure_logger(name, filename=None, verbosity=20)[source]

Get parent logger: logging INFO on the console and DEBUG to file.

skpar.dftbutils.utils.execute(cmd, workdir='.', outfile='run.log', purge_workdir=False, **kwargs)[source]

Execute external command in workdir, streaming output/error to outfile.

Parameters:
  • cmd (str) – command; executed in workir; if it contains $ or *-globbing, these are shell-expanded
  • workdir (path-like) – execution directory relative to workroot
  • outfile (str) – output file for the stdout/stderr stream; continuously updated during execution
  • purge_workdir (bool) – if true, any existing working directory is purged
  • kwargs (dict) – passed directly to the underlying subprocess.call()
Returns:

None

Raises:
  • OSError – if cmd cannot be executed
  • RuntimeError – if cmd returncode is nonzero
  • SubprocessError – other possible circumstances
skpar.dftbutils.utils.get_logger(name, filename=None, verbosity=20)[source]

Return a named logger with file and console handlers.

Get a name-logger. Check if it is(has) a parent logger. If parent logger is not configured, configure it, and if a child logger is needed, return the child. The check for parent logger is based on name: a child if it contains ‘.’, i.e. looking for ‘parent.child’ form of name. A parent logger is configured by defining a console handler at verbosity level, and a file handler at DEBUG level, writing to filename.

skpar.dftbutils.utils.parse_cmd(cmd)[source]

Parse shell command for globbing and environment variables.