Usage

Here you can find the source code of the main WfBase module.

The main WfBase module consists of these two main parts:

wfbase.download_data_if_needed(silent=False)[source]

Downloads the latest version of the WfBase database (file data.zip) and unpacks it in the data/ folder. Will not erase previous data/ folder if it already exists.

You can manually download the same database by following these instructions.

The database can be in any folder, it doesn’t need to be in a folder called data (which is the default used in this documentation). You might also want to place this folder at a fixed place on your machine and then simply load it by providing an absolute path to the file when you use the load function. This way you don’t need to have multiple copies of the database on your machine.

Parameters:

silent – If set to True will not print an error message if unable to download, or unzip, the database, or the database was already downloaded. The default is False.

Example usage:

import wfbase as wf

# download the database
wf.download_data_if_needed()

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# you can also open the database file by providing
# absolute path.
db = wf.load("~/work/calculations/data/fe_bcc.wf")
wfbase.load(*args, **kwargs)[source]

This is the function used to open a database file containing information about one of the DFT calculations.

Parameters:
  • data_path – Path to the database .wf file containing information about a calculation. The user should download database .wf file by following these instructions.

  • perform_consistency_check – A flag specifying whether the code should check that the computation of various physical quantities is done correctly. The default is True. Set to False only if you are really sure what is going on. It is strongly advised to keep this parameter as is.

Returns:

  • db – database object of type DatabaseWf. This object can be used next to create computators of various physical quantities.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()
wfbase.load_from_wannierberri(*args, **kwargs)[source]

Loads calculation directly using Wannier Berri package without using a .wf database file from WfBase.

See documentation of Wannier Berri for more details on creation of object System_w90.

Parameters:
  • system – This is System_w90 object from Wannier Berri.

  • global_fermi_level_ev – This is the Fermi level in eV. You can get this number at the end of your self-consistent DFT calculation. WfBase will later shift all band energies by this number, so that new Fermi level is zero.

Returns:

  • db – database object of type DatabaseWf. This object can next be used to create computators of various physical quantities.

Example usage:

import wfbase as wf
import wannierberri as wberri

def main():
    system = wberri.System_w90("run_dft_output/x", berry = True, spin = False)
    db = wf.load_from_wannierberri(system, global_fermi_level_ev = 18.3776)

if __name__ == "__main__":
    main()
class wfbase.DatabaseWf[source]

Object of this class contains information about the DFT calculations. Use function load create object of this class.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()
info(print_to_screen=True, full=False)[source]

Returns information about the computation stored in the database .wf file. This information here could be used by the user to redo the DFT calculation from scratch, as shown in this example.

Note that there is a function with the same name that provides information about the computator, not about the database .wf file. See here for more information on how to use this other function info.

Parameters:
  • print_to_screen – Whether the code should print the information to the screen. The default is True. If set to False, nothing is printed but instead this function returns a string.

  • full – Whether output should be cut to 50 lines per entry or the entire information should be shown.

Returns:

  • txt – string of the text with the information. This is returned only if print_to_screen is set to False.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# print information about the database
db.info()
create_dft_input_files(folder, ncpu=16)[source]

Recreates input files for the DFT calculation used in the construction of the database. Stores all of these input files in folder a named folder. Stops if the folder already exists.

Parameters:
  • folder – the name of the folder in which to store input files.

  • ncpu – integer specifying how many processors to use in the calculation. The default is 16.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# will store all input files in a folder called run_dft
db.create_dft_input_files("run_dft")
do_mesh(k_mesh=None, shift_k=[0.0, 0.0, 0.0], to_compute=['psi', 'A', 'S', 'dEdk'], formatted_output_latex=True, doublet_indices=False, reorder_orbitals=False)[source]

Compute various quantities on a regular k-mesh in the Brillouin zone. By default, it will compute the following quantities,

Quantity

Short description

How to get more information?

E

Electron band energy.

Call function comp.info(“E”). Example output.

psi

Electron wavefunction.

Call function comp.info(“psi”). Example output.

A

Berry connection.

Call function comp.info(“A”). Example output.

S

Electron spin magnetic moment.

Call function comp.info(“S”). Example output.

dEdk

Electron Fermi velocity (times hbar).

Call function comp.info(“dEdk”). Example output.

Code will also compute some other quantities, not listed here. For example, it will construct the default range of energies hbaromega, choose a default smearing parameter eta, etc. These can be changed by the user. See the examples below.

A complete list of all computed quantities can be obtained by calling the info function on the object returned by this function. Example output of the function info can be found here.

Note

For more details on the computator object returned by this function, see the description of the computator class _ComputatorWf.

Parameters:
  • k_mesh – Size of the uniform k-mesh on which you want to compute these quantities. This should be a vector with three components, one for the number of k-points in each direction. The default is the coarse mesh used to construct the Wannier functions, but you may want to use a denser mesh. Note that the code will precompute all the quantities here on the mesh you specify, and this might take up a lot of your RAM. If you wish to save RAM, you could instead compute several smaller grids, one at a time. For example, this can be achieved by randomly shifting the k-grid. See this example for more details.

  • shift_k – Shift of the uniform k-mesh. The coordinates for the shift are given as dimensionless, reduced, coordinates. Therefore, this parameter expects a set of three numbers between 0 and 1. If you specify numbers outside of this range, then the code will automatically reduce them to the range from 0 to 1 by removing the integer part. If you set shift_k to a string “random” then the code will shift the k-mesh by a random amount in all three directions. This might be useful for sampling the k-points.

  • to_compute – Quantity “E” is always computed. Here you can list additional quantities that you want to compute. These are any combination of “psi”, “A”, “S”, “dEdk”. The default is to use all of them: [“psi”, “A”, “S”, “dEdk”]. See here for more information. If you don’t need some of these quantities, don’t list them here, so they will not be computed, and the code will use less resources.

  • formatted_output_latex – Boolean value of True or False. The default is True. If set to False then any quantity evaluated from this computator will have a less formatted latex output. For example, the latex output will not use bra and ket notation, etc.

  • doublet_indices – The default is False. If set to True then the code will check if your band-structure is (at least) two-fold degenerate at each k-point. (This happens when a product of inversion and time-reversion symmetry is present, such as in inversion symmetric non-magnetic systems, for example.) If the band structure is (at least) two-fold degenerate at each k-point, and this parameter is set to True, then the band indices of all quantities will be changed, as follows. If you initially had, for example, 18 bands, then band index “n” would normally go over those 18 bands. But if this parameter is set to True then this same system will now have two indices, call them “a” and “A”. Index “a” now goes over 9 values while index “A” goes over 2 values. Therefore, “a” corresponds to the index of a doublet, and “A” indexes states in the doublet. The choice of the two states in the doublet is randomized by the diagonalizer in the Wannier Berri, and there is no special meaning to it. Also, if your band structure at some point is 4-fold degenerate, this routine will still use the doublet notation, and there is again no special meaning in the choice of those two doublets out of the 4 degenerate states. If you want to avoid these high-symmetry points then set shift_k to “random”, as that will guarantee that you can’t have more than doubly degenerate bands at every uniform mesh.

  • reorder_orbitals – The default is False. If set to True it will reorder orbitals in quantities wfc and orbitallabels so that the spin index of the orbital is the slow index. All other quantities are left unchanged.

Returns:

  • comp – computator object of type _ComputatorWf. This object can next be used to evaluate various physical quantities.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a uniform mesh
comp = db.do_mesh()

# create a different computator object, from the same database db
# but now use a different k-mesh.  There is no need to load
# the database object again using load function!
comp_alter = db.do_mesh([4, 4, 4])

# print information about all quantities in the computator
comp.info()

# print information about one of the quantities in the computator
comp.info("A")

# change the energy range
comp.compute_photon_energy("hbaromega", 0.0, 5.0, 51)

# change the value of the smearing parameter
comp.replace("eta", "0.2 eV")

# different way to change the value of the smearing parameter
comp["eta"] = 0.25

# you can also do more complex operations on quantities
comp["S"] = comp["S"][:, :, :, 0]

db = wf.load("data/au_bcc.wf")
comp = db.do_mesh()
print("Shape of matrix A without doubling: ", comp.get_shape("A"))
comp_new = db.do_mesh(doublet_indices = True)
print("Shape of matrix A with doubling   : ", comp_new.get_shape("A"))
do_list(k_list, to_compute=[], formatted_output_latex=True, doublet_indices=False, reorder_orbitals=False)[source]

Similar to do_mesh with the difference that now the returned computator contains information on an arbitrary list of k-vectors.

Use do_path for a simple way to generate a path between the special k-points in the Brillouin zone.

Parameters:
  • k_list – List of k-vectors on which you want to do a computation. These vectors are specified as dimensionless reduced coordinates of the reciprocal vectors.

  • to_compute – List of additional quantities that you want to compute. You can take any of these: “psi”, “A”, “S”, “dEdk”. The default is to compute none of them. See here for more information about these quantities.

  • formatted_output_latex – Boolean value of True or False. The default is True. If set to False then any quantity evaluated from this computator will have a less formatted latex output. For example, the latex output will not use bra and ket notation, etc.

  • doublet_indices – Same meaning as in do_mesh.

  • reorder_orbitals – The default is False. If set to True it will reorder orbitals in quantities wfc and orbitallabels so that the spin index of the orbital is the slow index. All other quantities are left unchanged.

Returns:

  • comp – computator object of type _ComputatorWf. This object can next be used to evaluate various physical quantities.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a list of two k-points
comp = db.do_list([[0.2, 0.4, 0.2], [0.1, 0.9, 0.4]])
do_path(k_str, to_compute=[], num_steps_first_segment=30, latex_tick_labels=True, formatted_output_latex=True, doublet_indices=False, reorder_orbitals=False)[source]

Similar to do_mesh with the difference that now the returned computator contains information on a list of k-vectors between special k-points.

Parameters:
  • k_str – String describing the path between the special k-points for the given symmetry of the system. Conventions here follow that from the Bilbao Crystallographic server.

  • to_compute – List of additional quantities that you want to compute. You can take any of these: “psi”, “A”, “S”, “dEdk”. The default is to compute none of them. See here for more information about these quantities.

  • num_steps_first_segment – The number of points between two first special k-points in the list. The number of points between other special k-points is computed so that the density of k-points in the Brillouin zone is nearly constant. The default is 30.

  • latex_tick_labels – True or False. The default is True. If False, then labels of special points will not use LaTeX. For example, Gamma point will simply be rendered as “GM” instead of using “$\Gamma$”.

  • formatted_output_latex – Boolean value of True or False. The default is True. If set to False then any quantity evaluated from this computator will have a less formatted latex output. For example, the latex output will not use bra and ket notation, etc.

  • doublet_indices – Same meaning as in do_mesh.

  • reorder_orbitals – The default is False. If set to True it will reorder orbitals in quantities wfc and orbitallabels so that the spin index of the orbital is the slow index. All other quantities are left unchanged.

Returns:

  • comp – computator object of type _ComputatorWf. This object can next be used to evaluate various physical quantities.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a path between these special points
comp = db.do_path("GM--H--N")

# plot the band structure
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
comp.plot_bs(ax)
ax.set_title("Band structure of Fe bcc")
fig.tight_layout()
fig.savefig("a.pdf")
class wfbase._ComputatorWf(quantities={}, formatted_output_latex=True, doublet_indices=False, loaded_from_wannierberri=False)[source]

This is a class for an object that stores various quantities and then parses mathematical expressions to compute various other physical quantities. It has a funny archaic name so that it is not confused with “calculators” from Wannier Berri.

In most cases, you will not need to create computator object on your own using a constructor. Instead, after loading a database you should use do_mesh, do_path, or do_list to create the object from this class. See the example below.

Each quantity has a “value”, physical “unit”, and sometimes other data, such as information about how the quantity was constructed, etc.

The “value” of the quantity is simply a numpy array and it can be modified by the user with any numpy operation, such as transpose or reshape or by slicing using the [] operator.

Quantities stored in the computator are constructed in one of these three ways.

  • First, the quantity could be precomputed by the code. For example, if you construct this object using do_mesh the code will precompute various quantities such as electron band energies, Berry connection, and so on.

  • Second, quantities could be added to the computator by the user by calling the new function. These added quantites are added as ordinary numpy arrays, along with some additional information sent to the new function.

  • Third, quantities can be evaluated using the evaluate function. This function parses a mathematical expression using currently available quantities and it then stores the resulting quantity in the computator. For example, one can use precomputed band energy and Berry connection to compute the optical conductivity, and so on.

Here is an example of the structure of the computator object comp. Two quantities (E and A) in this computator were created using function do_mesh. The third quantity (sigma) was computed using evaluate. See examples page for various examples that use computators with these quantites. For example, you could take a look at this example. Each quantity below contains several keys, such as value or units. Third column below shows you how to access these these keys.

Quantity

Key

How to access?

E

value

comp[“E”]
comp.get(“E”, “value”)

units

comp.get_units(“E”)
comp.get(“E”, “units”)

A

value

comp[“A”]
comp.get(“A”, “value”)

units

comp.get_units(“A”)
comp.get(“A”, “units”)

sigma

value

comp[“sigma”]
comp.get(“sigma”, “value”)

units

comp.get_units(“sigma”)
comp.get(“sigma”, “units”)

latex

comp.get_latex(“sigma”)
comp.get(“sigma”, “latex”)

To get a list of all quantites in the computator, use function all_quantities. To get all keys stored for a specific quantity, use function all_quantity_keys. You can get more information about the quantites in the computator using function info. Here you can find an example output of function info.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create a computator object called "comp"
# the type of this object is _ComputatorWf
comp = db.do_mesh(formatted_output_latex = False)

# add new quantity "sigma" to the object comp,
# evaluate this quantity from the expression below
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# add new quantity called "omicron" to the object comp
comp.new("omicron", "0.7 * eV")

# change value of one of the previously stored quantity
comp.replace("eta", "0.05 * eV")

# print information about all quantities in this computator
comp.info()
# print information about quantity "sigma"
comp.info("sigma")

# access some of the stored quantities
print(comp["omicron"])
print(comp["sigma"])

# change the value stored for quantity "sigma"
# Now sigma is no longer a 3x3 matrix, but a
# vector.  Also, we multiplied it with 10.
comp["sigma"] = 10.0 * comp["sigma"][0, :]

# print information about quantity "sigma"
# Now a warning will be printed that quantity sigma
# has been modified.
comp.info("sigma")

# since [] returns a copy of the stored object,
# the following will NOT change the value stored for quantity "sigma"
# but it will only change the copy of hte array.
cpy = comp["sigma"]
cpy = 20.0 * cpy
print(comp["sigma"]) # --> unchanged by the previous line

# the following also does not change the value of sigma
comp["sigma"][:] = 1.0

# the following, on the other hand, does change the value of sigma
comp["sigma"] = 1.0

# list all quantities stored in this computator
print(comp.all_quantities())
get_initialization_time()[source]

Returns time, in seconds, it took to initialize this computator. Most of this time is spent in calls to Wannier Berri to get all required quantities, such as band energy, Berry connection, etc.

all_quantities()[source]

Returns a list of all quantities stored in the computator object.

Returns:

  • lst – list containing all quantities stored in the object.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a mesh
comp = db.do_mesh()

# get a list of all quantities stored in comp
lst = comp.all_quantities()

# access one of the quantities in comp
print(comp["E"])
all_quantity_keys(core)[source]

Returns a list of keys for all data stored about the single quantity core.

Returns:

  • lst – list containing keys for quantity core

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a mesh
comp = db.do_mesh()

# get a list of all quantities stored in comp
keys = comp.all_quantity_keys("E")

# access one of the keys (units) stored about quantity "E"
print(str(comp.get("E", "units")))
get(core, key='value')[source]

Returns value of the specified quantity core. This returned value (typically an array of numbers) is a copy of the value stored in the computator object. Therefore, if you change the copy of this value, the one stored in the computator object will not be changed. If you want to actually change the value of the quantity stored in the computator use the [] operator, as shown in the example below, or use the replace function.

Parameters:
  • core – name of the quantity you wish to get

  • key – Which part of the quantity you want to get. The default is “value” which returns the value of the quantity (typically an array of numbers, for example). This could also be “units” to get the physical unit of the quantity.

Returns:

  • val – returned value of the specified quantity.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# now "energy" is a shallow copy of quantity "E"
energy = comp.get("E")

units = comp.get("E", "units")

print("Energy of the first band at the first kpoint is", energy[0, 0], "in units of", units)

# this will change array "energy" but not quantity "E" stored in the comp!
energy = energy + 10.0

# this will change the quantity "E" stored in the comp
comp["energy"] = energy * 3.4
get_shape(core)[source]

Returns the shape of the specified quantity core.

Parameters:

core – name of the quantity whose shape you want to get.

Returns:

  • shp – shape of the quantity

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

print("Band energy is stored in array of this shape: ", comp.get_shape("E"))
get_ndim(core)[source]

Returns the dimensionality of the specified quantity core.

Parameters:

core – name of the quantity whose dimensionality you want to get.

Returns:

  • ndim – dimensionality. 0 for single number. 1 for vector, etc.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

print("Band energy is stored in array of this dimensionality: ", comp.get_ndim("E"))
get_latex(core)[source]

This returns an object that stores information about LaTeX’ed definition of core. Here core is a quantity that was computed using the evaluate function.

Parameters:

core – Name of the quantity.

Returns:

  • lat – object that contains information about LaTeX’ed definition of core.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# now get LaTeX'ed data about this object
lat = comp.get_latex("sigma")

wf.render_latex(lat, "test.png")
wf.display_in_separate_window("test.png")
wf.display_in_terminal("test.png")
get_units(core)[source]

Returns units of quantity core. This is a product of arbitrary power of Angstroms, electron-volts, and Bohr’s magneton.

Parameters:

core – Name of the quantity.

Returns:

  • unit – object that contains information about units.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

print("Units of sigma are: ", comp.get_units("sigma"))
compute_in_SI(core, prefactor=None)[source]

Internally in WfBase all quantities are specified in units of eV, Angstrom, and Bohr magneton. This function will return the numerical value of the physical quantity core in SI units. If prefactor is not None (default), then the returned numerical value will be multiplied by prefactor.

Here prefactor is a string that consists of various constants of nature (hbar, electron charge, etc, as listed below). If prefactors are specified then this function will return an additional object that contains LaTeX expression for the product of the prefactor and core.

This function does not change any property of the quantity core itself. Everything in the computator, and all cores, are always specified in eV, Angstrom, and Bohr magneton. The only numbers in SI units are those returned by this function.

Parameters:
  • core – name of the quantity you wish to get.

  • prefactor – optional parameter. If specified then the returned quantity will be multiplied by this prefactor. The prefactor provided to this function is a string of the form “e^2 / (hbar * epszero)” or similar. The allowed constants are “e” for electron charge, “epszero” for vacuum permittivity, “c” for speed of light “me” for electron mass, and “hbar” for reduced Planck’s constant.

Returns:

  • val – returned value of the specified quantity.

  • lat – object that contains LaTeX expression for the product of core and prefactor. Returned only if prefactor is not None (default).

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# get units of this object
print("Units of sigma are: ", comp.get_units("sigma"))

# convert units to SI and multiply with e^2/hbar
result, result_latex = comp.compute_in_SI("sigma", "e^2 / hbar")
print("result = ", result)

wf.render_latex(result_latex, "latex.png")
wf.display_in_separate_window("latex.png")
wf.display_in_terminal("latex.png")
get_as_dictionary(want_cores_in, key='value')[source]

Returns values of multiple quantities at once in form of a dictionary.

Parameters:
  • want_cores_in – A string or a list of strings. Each string is either a name of the quantity you want to return, or it contains an asterisk or question mark to match possibly multiple quantities at once. See the example below.

  • key – Which part of the quantity you want to get. The default is “value” which returns the values of the quantities (typically an array of numbers, for example).

Returns:

  • dic – dictionary containing values of all quantities that match.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# this will return all quantities that match
dic = comp.get_as_dictionary(["atom*", "A", "num?"])

print(dic["numk"])
new(core, data, units_as=None)[source]

Adds a new quantity to the computator.

Parameters:
  • core – This is the name of the new quantity.

  • data

    This is the data associated with the new quantity. This can be one of three things.

    • First option – is that data can be a dictionary that contains key “value” that is a number or a numpy array. The dictionary can also contain key “units” (defaults to dimensionless). The key “units” should be of type Units as shown in the example below. User can also specify key “format” and “format_conjugate” which give a way to format this quantity in LaTeX. See the example below how to use “format”. In short, one needs to specify *0 at the place in the LaTeX expression where the first index of the quantity goes, *1 for the second, etc. Another entry in the dictionary could be “origin_story” which is a string describing the quantity core.

    • Second option – is that data is a string, such as “3.0 eV * muB^2 / Ang” or similar. Allowed units are eV, Ang, and muB, for electronvolt, angstrom, and bohr radius. You must use multiplication signs between units, such as “eV * muB”. (You are not allowed to use “eV muB” or “3.0 eV”.) You can use parentheses, division, and power operator (^).

    • Third option – is to simply make data a number or a numpy array. The units will be set to dimensionless by default (unless you specified those with parameter units_as).

  • units_as – Ignored if set to None (default). Otherwise, units of the new quantity will be equal to the units of quantity units_as. Stops if units were specified through parameter data (either first or second option above).

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# create new quantity with dimensionless value of 3.0
comp.new("alpha", 3.0)

# create new quantity with value of 3.0 * eV^2 * muB^2 / Ang
# (notice that below there must be a multiplication sign after "3.0")
comp.new("beta", "3.0 * (eV * muB)^2 / Ang")

# different way to achieve the same thing
comp.new("gamma", {"value": 3.0, "units": wf.Units(eV = 1)})

# adding extra information about the quantity
comp.new("delta", {"value": 3.0,
                   "units": wf.Units(eV = 1),
                   "origin_story": "Give here some information about delta."})

# information about how to display this quantity
comp.new("epsilon", {"value": np.array([[ 10.0       ,  9.0 + 3.0j,  1.0 + 2.0j],
                                        [  9.0 - 3.0j, 12.0       , 22.0 - 8.0j],
                                        [  1.0 - 2.0j, 22.0 + 8.0j, 45.0       ]]),
                     "units": wf.Units(eV = 1),
                     "format": r"\langle v_{*0} \lvert X \rvert v_{*1} \rangle",
                     "format_conjugate": r"\langle v_{*1} \lvert X \rvert v_{*0} \rangle"})

# one can also define quantities that are vectors, or tensors in general
comp.new("zeta", [3.0, 4.0, 5.0, 6.0])

# units of new quantity eta will be copy-pasted from gamma
comp.new("eta", 3.0, units_as = "gamma")

comp.info("alpha")
comp.info("beta")
comp.info("gamma")
comp.info("delta")
comp.info("epsilon")

# evaluate new quantity using quantity defined earlier
comp.evaluate("kappa_ik <= epsilon_ij * #epsilon_kj")

# expression for kappa should be formatted using the bra-ket notation for epsilon
comp.info("kappa", display = True)
replace(core, data, units_as=None)[source]

Removes previously existing quantity core and replaces it with new quantity core with data provided in data.

Parameters:
  • core – This is the name of the quantity that you want to replace.

  • data – This is the data associated with the new quantity. Same as data parameter used in new.

  • units_as – Same as units_as parameter used in new.

Example usage:

import wfbase as wf

db = wf.load("data/fe_bcc.wf")
comp = db.do_mesh()
comp.new("beta", "3.0 * (eV * muB)^2 / Ang")
comp.replace("beta", "4.0 * (eV * muB)^2 / Ang")
remove(core)[source]

Removes previously existing quantity core.

Parameters:

core – This is the name of the quantity that you want to remove.

Example usage:

import wfbase as wf

db = wf.load("data/fe_bcc.wf")
comp = db.do_mesh()
comp.new("beta", "3.0 * (eV * muB)^2 / Ang")
comp.remove("beta")
compute_occupation(out_core='f', energy='E', fermi='ef', kbtemp=None)[source]

Computes a quantity that has entries close to 1 at all places where energy is less than fermi and 0 otherwise. Uses a Fermi-Dirac distribution if temperature is specified. Otherwise, temperature is zero.

Note

This quantity can be used to enforce occupations of states while evaluating physical quantities. The same effect can be achieved using the conditions tag while calling evaluate function. The benefit of using conditions tag is that it reduces the number of operations needed to do the computation. See examples below

Parameters:
  • out_core – Name of the occupation factor quantity. Defaults to “f”. (This function will remove previously existing quantity with the same name.)

  • energy – Name of the energy quantity. Defaults to “E”.

  • fermi – Name of the fermi level quantity (or a float). Defaults to “ef”.

  • kbtemp – The default is None, which means zero temperature. You can also specify a quantity, or give a floating point number in units of eV.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

comp.compute_occupation("f", "E", "ef")

# computes band energy of occupied states
comp.evaluate("sumA <= E_nk * f_nk")

# same but without using "f"
comp.evaluate("sumB <= E_nk", "E_nk < ef")

# same computation by directly using numpy operations
import numpy as np
sumC = np.sum(comp["E"][ comp["E"] < comp["ef"]])

print(comp["sumA"], comp["sumB"], sumC)
compute_occupation_derivative(out_core='dfdE', energy='E', fermi='ef', kbtemp=0.05)[source]

Computes a derivative of the Fermi-Dirac distribution.

Parameters:
  • out_core – Name of the occupation factor quantity. Defaults to “dfdE”. (This function will remove previously existing quantity with the same name.)

  • energy – Name of the energy quantity. Defaults to “E”.

  • fermi – Name of the fermi level quantity (or a float). Defaults to “ef”.

  • kbtemp – Quantity (or a floating point number) giving kb*temperature in eV. Defaults to 0.05 eV.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

comp.compute_occupation_derivative("dfdE", "E", "ef", 0.01)
compute_kronecker(out_core, core, ind, core2=None, ind2=None)[source]

Computes a Kronecker delta symbol that has one on diagonal and zero otherwise.

Parameters:
  • out_core – Name of the Kronecker delta quantity. No default. (This function will remove previously existing quantity with the same name.)

  • core – The Kronecker delta will have the first index the same shape as ind-th index of the quantity core.

  • ind – First index to use in the construction of the Kronecker delta.

  • core2 – The Kronecker delta will have the second index the same shape as ind2-th index of the quantity core2. The default is to use the same as ind.

  • ind2 – Second index to use in the construction of the Kronecker delta. The default is to have the same as ind.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# this will create kronecker with shape numwann * numwann
comp.compute_kronecker("d", "E", 1)

# this will include only diagonal parts
comp.evaluate("B_nm <= d_nm/(E_km - E_kn + j*eta)")

# this will exclude diagonal parts, where n == m
comp.evaluate("C_nm <= (1.0 - d_nm)/(E_km - E_kn + j*eta)")
compute_identity(out_core, size)[source]

Gives an identity matrix of shape (size, size). One on diagonal, zero off-diagonal.

Parameters:
  • out_core – Name of this quantity.

  • size – Size of the matrix.

Returns:

  • mat – The identity matrix.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# this will create 3x3 identity matrix
comp.compute_identity("one", 3)
compute_photon_energy(out_core='hbaromega', emin=0.5, emax=3.0, steps=31)[source]

Computes an array of photon energy in eV.

Parameters:
  • out_core – Name of the quantity for photon energy. Defaults to “hbaromega”. (This function will remove previously existing quantity with the same name.)

  • emin – Minimal energy in the range. Defaults to 0.5. Units are eV.

  • emax – Maximal energy in the range. Defaults to 3.0. Units are eV.

  • steps – The number of equidistant steps. Defaults to 31.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# this will create photon energies from 0.5 to 5 eV in 51 steps
comp.compute_photon_energy("omicron", 0.5, 5.0, 51)

# this achieves the same thing
import numpy as np
comp.new("delta", {"value": np.linspace(0.01, 5.0, 51, endpoint = True),
                   "units": wf.Units(eV = 1)})
compute_orbital_character(out_core)[source]

Computes approximate orbital character of the wavefunction.

|| < W_p | psi_kn > ||^2

(If you earlier used doublet_indices = True then the indices above on psi are are knN instead of kn.)

This is a dimensionless number. The sum of this number over index p is 1.0.

Parameters:

out_core – Name of the quantity for the orbital character. (This function will remove previously existing quantity with the same name.)

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# computes orbital character
comp.compute_orbital_character("O")
compute_optical_offdiagonal(out_core, hbaromega)[source]

Computes matrix elements for the off-diagonal (interband) interaction of electrons with electromagnetic waves.

< psi_kn | H_offdiagonal | psi_km >

(If you earlier used doublet_indices = True then the indices above are knN and kmM instead of kn and km.)

Units of this quantity are eV. This effectively assumes that the maximum electric field of the applied electromagnetic wave is 1 eV/Ang.

The exact computed quantity is

(1 / 2) (E_kn - E_km) * < u_kn | i del_k_d | u_km > / hbaromega_o

The diagonal elements (n = m) are set to zero. (When indices are doubled then matrix elements within the doublet are set to zero.)

Parameters:
  • out_core – Name of the quantity for the matrix element. (This function will remove previously existing quantity with the same name.)

  • hbaromega – Name of the quantity containing photon energies.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# compute interband optical matrix element for predefined
# photon energies "hbaromega"
comp.compute_optical_offdiagonal("L", "hbaromega")

# this will create photon energies from 0.01 to 5 eV in 51 steps
comp.compute_photon_energy("omicron", 0.01, 5.0, 51)

# recompute matrix elements for these new energies
comp.compute_optical_offdiagonal("L", "omicron")
compute_optical_offdiagonal_polarization(out_core, hbaromega, polarization)[source]

Similar to compute_optical_offdiagonal but now the matrix element is computed for a specified polarization only.

Parameters:
  • out_core – Name of the quantity for the matrix element. (This function will remove previously existing quantity with the same name.)

  • hbaromega – Name of the quantity containing photon energies.

  • polarization – String describing the polarization direction. For linearly polarized light use “x”, or “y”, or “z”. For circularly polarized light, use one of these “x + i y”, “x - i y”, “x + i z”, “x - i z”, “y + i z”, “y - i z”.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# compute interband optical matrix element for predefined
# photon energies "hbaromega"
comp.compute_optical_offdiagonal_polarization("L", "hbaromega", "x + i y")
compute_hbar_velocity(out_core)[source]

Computes matrix elements for the diagonal (intraband) and off-diagonal (interband) velocity operator times hbar,

< psi_kn | hbar * v_d | psi_km >

Units of this quantity are eV * Ang

The exact computed quantity for the diagonal is

(d E_kn / d k_d) delta_nm

for off-diagonal (n != m) it is

i (E_kn - E_km) * < u_kn | i del_k_d | u_km >

(If you earlier used doublet_indices = True then the indices above are knN and kmM instead of kn and km.)

Parameters:

out_core – Name of the quantity for the matrix element. (This function will remove previously existing quantity with the same name.)

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

comp.compute_hbar_velocity("hbarv")
evaluate(in_eqns, conditions='', brute_force_sums=False, optimize_divisions=True, optimize_recomputation=True, show_latex_with_div_opts=False)[source]

This function can be used to evaluate a wide range of mathematical expressions. Einstein summation over repeating indices is assumed.

Quick example:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# calculate something
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")
Parameters:
  • in_eqns

    String containing mathematical expression(s) you wish to evaluate. This string can contain the following.

    • ”Numbers,” – either integer, real, or complex. For example, you can use numbers in these formats 2, 3.14, 3j, 4.3 + 2.0j, j.

    • ”Quantities” – defined in this computator. For example, “E_kn” corresponds to the band energy associated with k-point k and band n. This quantity can be anyone that is currently defined for the computator. You can use the function all_quantity_keys to get a list of all quantities currently in the computator. You can also use info to get extended information about all quantities in the computator. Note that you can use any set of letters as indices for quantities. For example, if your expression contains multiple sums over bands, you can use “E_kn” and “E_km”, or any other combination of indices such as “E_qw”. Quantities that are constants (not tensors with indices) you can simply refer to as “Q” or “QwR” or similar. For constants don’t use the underscore symbol, as these quantities don’t have indices.

      In the name of the quantity, you can use ~ symbol (once at most). When doing LaTeX rendering everything after ~ will be rendered as a superscript. For example “Abc~intra_knm” will be rendered in LaTeX as “Abc^{intra}_{knm}”.

    • ”Basic operators” – such as addition (+), subtraction (-), multiplication (*), division (/), exponentiation (^). Note that the multiplication symbol * is required. For example, you must use “A_ij * B_jk”. If you simply use “A_ij B_jk” you will get an error message. Certain potentially ambiguous expressions are not allowed, such as “A / B * C”. You should either use “A / (B * C)” or “(A / B) * C” depending on your intention. Similarly, you are not allowed to write “A^B^C” as that could be ambiguous. Instead, write “(A^B)^C” or “A^(B^C)”.

    • ”Plus and minus symbol” – can be used either in between two quantities, such as “A_ij - B_ij”, but you can also use it in front of a symbol, such as “-A_ij - B_ij”. This expression will change the sign of the quantity “A” relative to the former expression, as expected.

    • ”Parentheses.” – Only regular parentheses “(” and “)” are allowed.

    • ”Assignment operators” – are one of these three: <=, <+=, or <<=. The assignment operator assigns to the new quantity on the left the expression given on the right. For example, “A_ik <= B_ij * C_jk” would do a regular matrix multiplication of B and C and assign the result to a new quantity A. Related assignment operator “<+=” assumes that the quantity “A” on the left already exists. This operator will compute the value of the right hand side and add it to the value of the preexisting quantity “A”. This is similar to the behavior of “+=” operator in python. Finally, “<<=” operator will erase the previously existing quantity “A” on the left, and it will create a new quantity with the value of whatever is on the right of “<<=”.

      On the left of “<=” you can either have a tensor quantity “A_ik”, or a constant quantity “D”, or you can simply have “_ik”, or simply “_”. If you have something like “_ik” on the left of “<=” then this function will simply return a numerical value of the tensor and will not create any new quantity. Finally, if you simply write “A_ij * B_jk” without even using “<=” operator, you will again get a numerical value of the matrix product without creating a new quantity. The indices of the returned quantity in this case will be simply sorted in alphabetical order (“ik”) in the present case. To reduce ambiguity, it is therefore recommended to always use one of the assignment operators in your computations. (This option is not allowed when brute_force_sums is True. One must use one of the arrow operators (<=, <+=, <<=) if brute_force_sums is True.)

      Assignment operators can be used only once per expression.

    • ”Complex conjugation” – is done using the # operator. Note that this operator does not transpose any of the indices of the matrix, it only does complex conjugation. The # operator must appear before the quantity whose complex conjugation you are taking. For example, in this case, quantity B would be conjugated: “A_ij * #B_jl”. If you also wish to transpose B then you need to do so explicitly “A_ij * #B_lj” by swapping indices on B. (If quantity B_jl is a matrix element of operator O, “< j | O | l >” then #B_jl will refer simply to “conjugate(< j | O | l >)”. Now, if operator O happens to be a Hermitian operator, then this quantity is by definition equal to <l|O|j>. LaTeX parser will display in this case <l|O|j> instead of conjugate(<j|O|l>). In other words, #B_jl will be parsed into <l|O|j> instead of conjugate(<j|O|l>) which doesn’t look as pretty.)

    • ”Functions” – Real and Imag can also be used in the expression. These take real and imaginary parts of the complex numbers. For example, “Real(A_ij + B_ji)”

  • conditions

    This string contains all restrictions you wish to perform on the sums in your computation. The string can contain more than one condition. Conditions must be separated from each other by a comma. For example, “E_kn < ef , E_km > ef, n != m” would limit any sum containing indices k and n to only those for which E_kn is less than ef. An additional limitation would occur for the sum over k and m. The third condition would ensure that no sum over n and m includes the n==m term. Also, if n and m appear in the output indices, the diagonal terms are set to zero. (The code will also avoid dividing by n==m term of the tensors in the denominator. This is useful if you divide 1/(A_n - A_m) and then use the condition n!=m.) The lesser/greater conditions must be formatted so that on the left of < or > there is a single tensor quantity. The indices should not repeat.

    If one of the indices is summed over, the other index in the condition must appear in the same sum. Otherwise, the meaning of the condition is imprecise. (For example, this would occur if one has the condition “E_kn < ef” but in the expression we have a sum only over n, but not over k. For example, if the expression “B_k <= E_kn * E_kn” we have a sum over repeated index n but not over k.)

    On the right of < or > you must use either a constant (quantity without indices) or a number. No other formatting is allowed for conditions with lesser/greater. Only real parts of the left and right hand side are used in determining conditions.

    The formatting of conditions involving != is much simpler. On the left and right of != you can only have a single index.

  • brute_force_sums

    Boolean. The default is False. The code will use different algorithms to evaluate the quantity, depending on the value of this parameter. If False (default) then the code will evaluate quantity using numpy vectorization. If True, then the code will use brute-force for loops compiled via Numba. The two approaches should give numerically the same values. Depending on your machine, it is probably more optimal to use default (False) when you have moderately dense k-grids. If you need to sample denser k-grids, you should probably use random sampling and perform several calculations with a moderately dense k-grid unless you reach convergence. See this example for more details on how to do this. If you really have a need to do a single-shot calculation with very many k-points, you may want to set this flag to True and test if that makes your calculation faster. (Whether brute-force sums are faster or not will depend not only on the number of k-points but also the type of calculation you are evaluating.)

    (There is a slight difference in the two approaches (numpy vectorization vs Numba) since in certain edge cases numpy vectorization approach will stop, while Numba approach will still do the calculation. For example, this will happen in certain edge cases with conditions, if some condition is too restrictive on the sum, numpy vectorization will stop, but with this parameter set to True it will do the calculation. Another difference is that when brute_force_sums is True you must use one of the arrow operators (<=, <+=, or <<=) in all of your evaluation expressions.)

  • optimize_divisions – Boolean. The default is True. If True then the code will internally preoptimize the expression by replacing expressions such as A*B*C/(D*E) with something like A*B*C*(1/D)*(1/E). In many cases, this is faster to evaluate (less overhead) as this is now a single product of five quantities (A, B, C, 1/D, and 1/E). For debugging purposes, the user could set this flag to False, but True should give the same result faster in most cases. If in doubt, inspect the output of info (with the show_code flag set to True) to see what exact operation the code uses to evaluate your expression. (This parameter is ignored if brute_force_sums is True.)

  • optimize_recomputation – Boolean. The default is True. If True then the code will optimize certain computations. For example, if the expression (E_nk - E_mk) appears twice in the single call to this function (it could be either in the same line or in two different lines, as long as it is in the same call to this function), then in the second appearance of this expression code will reuse previously computed value. For debugging purposes, the user could set this flag to False, but True should give the same result faster. If in doubt, inspect the output of info (with show_code flag set to True) to see what exact operation the code uses to evaluate your expression. (This parameter is ignored if brute_force_sums is True.)

  • show_latex_with_div_opts – Boolean. The default is False. If True then the code will return LaTeX’d code that includes optimizations that were potentially used if the optimize_divisions flag is True.

Example usage:

import wfbase as wf
import numpy as np

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

comp.verbose_evaluate()

# This creates new quantity, called "test".
# This quantity depends on one index (k).
# The value of this quantity is the sum of squares
# of all band energies with that k.  The sum over *n* is implied as
# index *n* does not appear on the left of <=
comp.evaluate("test_k <= E_kn * E_kn")
print(comp["test"])

# direct way to compute the same thing using numpy
direct = np.sum(comp["E"]*comp["E"], axis = 1)
print(direct)

# this removes quantity "test"
comp.remove("test")

# same calculation as above, but using brute-forced sums and Numba
# instead of numpy vectorization
comp.evaluate("test_k <= E_kn * E_kn", brute_force_sums = True)
comp.remove("test")

# since now index *n* appears next to the tensor "test"
# on the left of <= we don't sum over n
comp.evaluate("test_kn <= E_kn * E_kn")

comp.remove("test")
# now we sum over both *k* and *n* as neither index
# appears next to the tensor "test" on the left of <=
comp.evaluate("test <= E_kn * E_kn")

comp.remove("test")
# this basically makes "test" be a copy of "E", as nothing
# is summed over
comp.evaluate("test_kn <= E_kn")

comp.remove("test")
# this makes "test" be a transpose of "E"
comp.evaluate("test_nk <= E_kn")

comp.remove("test")
# now the sum is performed only over occupied states
comp.evaluate("test <= E_kn * E_kn", "E_kn < ef")

comp.remove("test")
# now the sum is performed only over occupied states with energy above -2 eV.
comp.evaluate("test <= E_kn * E_kn", "E_kn < ef, E_kn > -2.0")

comp.remove("test")
# now the sum is performed only over occupied states with energy above -2 eV,
# the diagonal terms (n == m) are not included in the sum
comp.evaluate("test <= E_kn * E_kn", "E_kn < ef, E_kn > -2.0, n != m")

comp.remove("test")
# this will create a tensor with four indices.  Tensor "E" will be
# repeated over the missing indices.
comp.evaluate("test_knmi <= E_kn * A_kmni")

comp.remove("test")
# same thing, but now we perform sum over three of the indices
# so we are left with one index (k)
comp.evaluate("test_k <= E_kn * A_kmni")

comp.remove("test")
# this will create a tensor with three indices.  E_kn does
# not depend on m, so it will simply copy E_kn along m'th index.
comp.evaluate("test_knm <= E_kn - E_km")

comp.remove("test")
# this can be made more complicated as well...
comp.evaluate("test_ki <= (E_kn - E_km) * A_knmi * (E_kn + E_km)")

comp.remove("test")
# One is allowed to use numbers as well (but there must be a
# multiplication sign between any two quantities if you want them
# multiplied.  So, you must use ... 2 * E_kn ...  not simply ... 2 E_kn ...
comp.evaluate("test_ki <= (E_kn - E_km) * A_knmi * (E_kn + 2 * E_km)")

comp.remove("test")
# One can use "eV", "Ang", or "muB" to introduce quantities in the expression with units
comp.evaluate("test_ki <= (E_kn - E_km) * A_knmi * (E_kn + 2 * E_km + 0.1 * eV)")

comp.remove("test")
# ... division is also allowed, as well as complex numbers
comp.evaluate("test_ki <= (E_kn - E_km) * A_knmi / (E_kn + 2j * E_km)")

comp.remove("test")
# ... and multiple levels of parentheses
comp.evaluate("test_ki <= (E_kn - E_km) * A_knmi / ((E_kn + 2j * E_km) * A_knni)")

comp.remove("test")
# ... you can also raise to a power
comp.evaluate("test_ki <= (E_kn - E_km)^2 * A_knmi")

comp.remove("test")
# ... and take complex conjugate, or real, or imaginary part
# (note that complex conjugation does not transpose any indices!  It only
# complex conjugates each element of the tensor)
comp.evaluate("test_ki <= (E_kn - E_km) * #A_knmi * Real(1 / (E_kn - 2j* E_km)) * Imag(A_knni)")

# you can redefine quantity "test" that already exists, without the need to call "remove"
# notice how we use here <<= instead of <=
comp.evaluate("test_knm <<= E_kn - E_km")

# you can also add to the previously existing quantity using <+=
comp.evaluate("test_knm <+= E_kn + 3.0 * E_km")

comp.remove("test")
# notice how the regular use of <= creates quantity "test"
comp.evaluate("test_knm <= E_kn - E_km")
# if you simply want to get the numerical array, and you
# don't want to create a new quantity, you can simply do:
value = comp.evaluate("_knm <= E_kn - E_km")
# if you don't use <= at all, then there will be no sums performed
# and the order of indices is alphabetical (kab in the case below)
value = comp.evaluate("E_kb - E_ka")
info(core=None, print_to_screen=True, display=False, full=False, show_code=False, allow_multiple_expressions=False)[source]

This function provides information about various quantities in the computator.

Note that there is a function with the same name that provides information about the database .wf file, not the computator. See here for more information on how to use this other function info.

Parameters:
  • core – If set to None then the function will return information about all quantities in the computator. Otherwise, it will give information only about the quantity core.

  • print_to_screen – Boolean. If set to True (default) then the information about the quantity will be printed on the screen by this function. If set to False nothing is printed on the screen. Instead, in this case function returns a string with the same information.

  • display

    Boolean. If set to True it will display inside the terminal LaTeX-ed equations if they are present in the description of the quantity. This feature works only in terminals that support imgcat. One such terminal is iTerm2 on OS X. You can find information about installing imgcat in iTerm2 here.

    If set to False (default) nothing is displayed in the terminal.

  • full – Boolean. If set to False (default) only some of the numerical values of the quantity are shown. If set to True, all values are shown.

  • show_code – Boolean. If set to True the function will show the python code used to compute the quantity. The default is False.

  • allow_multiple_expressions – Boolean. If set to True, and if show_code set to True, will display python code used to compute the quantity, even if multiple expressions were processed in a single call to evaluate and you are trying to access information for a quantity that is not the first one that was evaluated. The default is False.

Returns:

  • txt – String with information about the quantities. This string is returned only if print_to_screen is set to False.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# shows information about quantity "E"
comp.info("E")

# compute some quantity
comp.evaluate("sigma_oij <= (j / (numk * volume)) * (f_km - f_kn) * Real((E_km - E_kn) / (E_km - E_kn - hbaromega_o - j*eta)) * A_knmi * A_kmnj")

# shows information about newly computed quantity
comp.info("sigma")

# ... also displays LaTeX-ed equation defining this quantity
# This works only in terminals that support imgcat, such as iTerm2 on OS X.
# You can find information about installing imgcat in iTerm2 here:
#     https://iterm2.com/documentation-images.html>
comp.info("sigma", display = True)
verbose_evaluate(verbose=True)[source]

If verbose is set to True then the code will print information about each expression it evaluates.

Parameters:

verbose – whether to print information or not. If not specified, it defaults to True.

Example usage:

import wfbase as wf
import numpy as np

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

comp.verbose_evaluate()
report()[source]

This function returns a LaTeX equation for all quantities that were parsed by the user, in the order in which they were parsed. (The function skips quantities that were later modified by the user.)

Returns:

  • txt – String with LaTeX equation.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# compute some quantity
comp.evaluate("sigma_oij <= (j / (numk * volume)) * (f_km - f_kn) * Real((E_km - E_kn) / (E_km - E_kn - hbaromega_o - j*eta)) * A_knmi * A_kmnj")

# you can print the equation to the screen
print(comp.report())
# ... or, you can also render the equation
wf.render_latex(comp.report(), "latex.pdf")
plot_bs(ax, plot_bands=True, plot_spec=True, plot_fermi=True, plot_xticks=True)[source]

Plots the band structure.

Parameters:
  • ax – Matplotlib’s axes onto which you wish to plot the band structure.

  • plot_bands – If True, will plot the electron bands. (Default).

  • plot_spec – If True, will plot special k-points on the path. (Default).

  • plot_fermi – If True, will plot the Fermi level. (Default).

  • plot_xticks – If True, will plot the x-ticks of special points. (Default).

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# compute quantities on a path between these special points
comp = db.do_path("GM--H--N")

# plot the band structure
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
comp.plot_bs(ax)
ax.set_title("Band structure of Fe bcc")
fig.tight_layout()
fig.savefig("a.pdf")
class wfbase.Units(eV=0.0, Ang=0.0, muB=0.0)[source]

Class that stores information about a physical quantity’s units of electron volts (eV), angstroms (Ang), and Bohr magnetons (muB).

Parameters:
  • eV – Power associated with electron-volts. For example, if this parameter has value 2 then that represents units eV^2. The default is zero.

  • A – Same as eV but for angstrom.

  • muB – Same as eV but for Bohr magneton.

Example usage:

import wfbase as wf
import numpy as np

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# defines a new quantity, gamma, with value 3.0 in units of eV
comp.new("gamma", {"value": 3.0, "units": wf.Units(eV = 1)})

# defines a new quantity, delta, with value 2.5 in units of eV * A^2 / muB
comp.new("delta", {"value": 2.5, "units": wf.Units(eV = 1, Ang = 2, muB = -1)})
wfbase.render_latex(latex_str, fname, dpi=300)[source]

Renders mathematical LaTeX expression latex_str and saves it into file fname.

Parameters:
  • latex_str – mathematical LaTeX expression to be rendered.

  • fname – name of the output file. Either png or pdf format.

  • dpi – dots per inch for png file (ignored for pdf).

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# now get LaTeX'ed data about this object
lat = comp.get_latex("sigma")

wf.render_latex(lat, "test.png")
wfbase.display_in_terminal(fname)[source]

Displays image file fname in the terminal. Only supported on terminals that allow imgcat, such as iTerm2 on OS X. You can find information about installing imgcat in iTerm2 here.

Parameters:

fname – name of the file.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# now get LaTeX'ed data about this object
lat = comp.get_latex("sigma")

wf.render_latex(lat, "test.png")
wf.display_in_terminal("test.png")
wfbase.display_in_separate_window(fname)[source]

Displays image file fname in a separate window. The result will depend on your operating system and how it interacts with python’s PIL module.

Parameters:

fname – name of the file.

Example usage:

import wfbase as wf

# open a database file on bcc phase of iron
db = wf.load("data/fe_bcc.wf")

# create now a computator from the database
comp = db.do_mesh()

# evaluate some object
comp.evaluate("sigma_ij <= (j / (numk * volume)) * (f_km - f_kn) * A_knmi * A_kmnj")

# now get LaTeX'ed data about this object
lat = comp.get_latex("sigma")

wf.render_latex(lat, "test.png")
wf.display_in_separate_window("test.png")