pyfplo.common

This module contains a collection of usefull objects related to FPLO band/bandweights routines. You can easily write these files and read them into numpy.ndarrays for further processing. Have a look at ..../FPLO18.00-53/DOC/pyfplo/Examples/bandplot/model.py for better understanding.

BandFileContext

class BandFileContext

This class wraps data to easily manage the creation of FPLO band/bandweight files. This class cannot be instantiated directly. It only is produced and returned via a call to BandPlot.openBandFile()

Example:

# A simple band structure plotting using low level routines
# based on slabify.
import pyfplo.slabify as sla
import numpy as np
import numpy.linalg as LA

s=sla.Slabify()
s.dirname='.'
s.object='3d'
hamdata='+hamdata'
s.prepare(hamdata)


bp=sla.BandPlot()
bp.points=[
        ['$~G',[0,  0,0]],
        ['X'  ,[0.5,0,0]]
]
bp.ndiv=100
bp.calculateBandPlotMesh(s.dirname)
dists=bp.kdists
kpts=bp.kpnts


with bp.openBandFile(s.dirname+'/+b',s.nspin,len(kpts),\
                       progress='bandplot') as fb:

    # now fb is an instance of `BandFileContext`

    for ik,k in enumerate(kpts):
        for ms in range(s.nspin):
            Hk=s.hamAtKPoint(k*s.kscale,ms)
            (EV,C)=LA.eigh(Hk)
            fb.write(ms,dists[ik],k,EV)
close()

Explicitely close the file. Usefull, if multiple files are used in the same loop, in which case the with-statement is not usefull. The underlying file gets closed when this object gets garbage collected (after it’s scope is exited). For cleanliness it is a good measure to always close files.

Method1:

with bp.openBandFile(...) as f:
   doseomthing with f
# here f is closed

Method2:

f=bp.openBandFile(...):
do something with f
f.close()
# here f is closed
write(ispin, dk, k, energies, weights=None)

Write the energies for spin component ispin and k-vector k and scalar path-length variable dk to the file. ispin must be 0 if there is only one spin. It must loop over [0,1] if there are two spins. See the nspin argument in BandPlot.openBandFile(). The spin loop must be inside the k-loop!

If a weight file is writen (weightlabels argument in BandPlot.openBandFile()) a matrix like argument (e.g. a numpy.ndarray) must be given as last argument to write() whose rows correspond to the weights and the columns to the bands.

BandPlot

class BandPlot

This is a helper class for data which control the path through the BZ for routines creating band structure or energy distribution cut plots. After setting the data (points and ndiv) calculateBandPlotMesh() must be called before using BandPlot. Alternatively readBandPlotMesh() can be called to import from =.kp.

This class is used by certain methods of pyfplo.slabify.Slabify.

Usage:

import pyfplo.slabify as sla
import pyfplo.common as com
s=sla.Slabify()

bp=com.BandPlot()
bp.points=[ ['$~G',[0,0,0]],... ]
bp.ndiv=100
bp.calculateBandPlotMesh(s.dirname)

s.calculateBandStructure(bp)

This class also allows to read +band type files for further processing:

bp=com.BandPlot()
[bh,kdists,kptns,erg]=bp.readBands('+band')
print 'bandheader +b: nkp={0} nband={1} nspin={2}'\
    .format(bh.nkp,bh.nband,bh.nspin)
print 'kdists2 shape :',dists2.shape
print 'kptns2 shape :',kptns2.shape
print 'erg shape :',erg.shape
# now do something with the information

Create a new BandPlot instance via:

import pyfplo.slabify as sla
bp=sla.BandPlot()

or:

import pyfplo.common as com
bp=com.BandPlot()
calculateBandPlotMesh(pointsfileoutputdir)

Finalize the bandplot definition. This actually calculates the k-points for the BZ-path from the input settings (points and ndiv). pointsfileoutputdir usually should be Slabify.dirname:

import pyfplo.slabify as sla
s=sla.Slabify()
...
bp.points=[...]
bp.calculateBandPlotMesh(s.dirname)
...

It serves to put the file +points in the right place.

readBandPlotMesh(kpfilename)

Read file =.kp (from xfplo) for mesh definition. BandPlot restrictions (see setOutputRestrictions()) are still applied and restrictions inside =.kp are ignored.

IMPORTANT: do not use =.in... files from the Slabify output in context of visualizing the Fermi surface with xfplo. It will not work! Use the =.in files from the underlying FPLO calculation instead.

openBandFile(filename, nspin, nkpts, weightlabels=None, progress=None)

Low level routine. Return an object of type BandFileContext for creation of FPLO band files.

The returned object will open the file and organizes the proper file format. It’s BandFileContext.write() method can be used to write the actual data. If the object gets deleted (automatic if the scope is left) the file gets closed. The BandFileContext.close() method can be called explicitly.

The best way to use it is in a with-statement. Then it is closed automatically after the with-block is exited:

with bp.openBandFile(...) as f:
  for ...:
    f.write(...)
pass # now the file is closed.

If multiple files are written at the same time one can do the following:

f1=bp.openBandFile(filename1,...)
f2=bp.openBandFile(filename2,...)
for ...:
  f1.write(data1,...)
  f2.write(data2,...)
f1.close()
f2.close()
pass # now the files are closed.

nspin is the number of effective spins:

not full relativistic:

  • nspin=1 for non spin polarized
  • nspin=2 for spin polarized

full relativistic:

  • nspin=1

nkpts is the number of k-points.

If weightlabels is given and is a list of weight lables the resulting file will be a bandweight file.

If progress is set to a string a progress message is written in subsequent calls to BandFileContext.write().

see help of BandFileContext.

readBands(filename)

Read the bandfile (NOT bandweight file) called filename and return (bh, kdists, kpnts, erg) where

bh is an instance of BandHeader

kdists is a 1d numpy.ndarray containing the k-path variable.

kpnts is a C-ordered 2d numpy.ndarray containing the k-vectors with dimension [nkp,3].

erg is a 3d numpy.ndarray of energies, which is C-orderd, meaning that the last dimension is the innermost dimension. The three dimensions are BandHeader.nspin, BandHeader.nband and BandHeader.nkp.

active

Make band structure routines active.

ndiv

Maximum number of points between two high symmetry points along the path in the Brillouin zone. The actual number in a path segment is adjusted such that the individual points are placed as equidistant as possible.

lowerdepthdatalimit

Limit the weight data written to files to the layers with depth<=lowerDepthDataLimit measured from the lower end of the finite (two-sided) slab. Beware that the default for both (lower/upper) limits is 1.0e30. So, if only one side’s datalimit is set the other side’s limit likely will still be big enough to enable all layers. Simply put, define both limits unless it is a semislab.

upperdepthdatalimit

Limit the weight data written to files to the layers with depth<=upperDepthDataLimit measured from the upper end of the finite (two-sided) slab or semi-finite (one-sided) semislab. Beware that the default for both (lower/upper) limits is 1.0e30. So, if only one side’s datalimit is set the other side’s limit likely still will be big enough to enable all layers. Simply put, define both limits unless it is a semislab. For semislabs the upperdepthdatalimit determins which layers are used for the spectral density.

outputpartoccubands

See setOutputRestrictions()

partoccuoffset

See setOutputRestrictions()

ewindow

See setOutputRestrictions()

points

A list of high symmetry points. Example:

bp.points=[
    ['$~G' , [0,0,0] ],
    ['X' , [0.5,0,0] ],
     ... ]
print bp.points
kpnts

Return a numpy.ndarray of the k-points along the path. The first index runs over the k-points. The number of points in each segment is proportional to the length of the intervall. The max number is ndiv.

kdists

Return a numpy.ndarray of the scalar path-length variable along the path.

on()

Activate bandstructure creation.

off()

Deactivate bandstructure creation.

setOutputRestrictions(active, ewindow=[], offset=[0, 0])

Convenience function: To reduce the size of the resulting files output restrictions can be set. If active (outputpartoccubands) is True, ewindow determines the energy interval of bands which are considered for output. This is a relatively crude algorithm, which usually only checks the band energies at the first point of the path. If more bands are needed it is often easier to additionally define a lower and upper band index offset which widens the interval of considered band indices. Positive numbers for both lower and upper offset make the interval wider. Negative numbers make it narrower. Be carefull with these restrictions you might remove bands from the output without realizing it!

BandHeader

class BandHeader

The class is returned by BandPlot.readBands or BandWeights.readBandWeights and contains information about the header information in fplo +band and +bweights like files.

nkp

The number of k-points.

nband

The number of bands.

nspin

The number of spins (full-relativistic – 1, otherwise – 1 or 2).

norb

The number of weights (if present)

ilower

The index of the lowest band present in the data.

iupper

The index of the highest band present in the data.

labels

A list of labels.

BandWeights

class BandWeights(infile)

Use this to sum up weights contained in a bandweigths file or to read the content of a weights file into numpy arrays. The resulting weigths will be written to another bandweights file.

Example:

import pyfplo.common as com
wds=com.WeightDefinitions()
# add a new state (a single sum of certain weights)
w=wds.add(name="all")
# add labels
w.addLabels(labels=["Al(001)3s+0","Al(001)3p-1","Al(001)3p+0",
                    "Al(001)3p+1"],fac=1)
# or add via orbital info, if the bandweights file contains
# default weight labels.
w.addAtoms(atom='Al',sites=[1],orbitals=['3s','3p'],fac=1)

print wds # want see what we did

# read a bandweights file (more general file example)
bw=com.BandWeights("+bweights")
# add weights and write to +bwsum
bw.addWeights(wds,'+bwsum')

For further information see: WeightDefinitions and WeightDefinition

BandWeights(infile) creates a new BandWeights object with the input bandweights file’s name set to the string infile.

header()

Return the header information of the underlying file.

addWeights(weightdefs, outfile, ewindow=[], vlevel=100)

weightdefs (instance of WeightDefinitions): the definitions for the resulting weights.

outfile (str): the name of the output file with resulting weights.

ewindow (optional,list of two float: [emin,emax]): the energy interval to which to restrict the output bands

vlevel (optional,int): verbosity level.

Take state definitions for resulting weights from the weightdefs (instance of WeightDefinitions) which is similar to the definitions in the file =.addwei for faddwei... and create a new weights file outfile, with the weights added up according to the weightdefs.

Restrict number of bands in outfile according to the energywindow ewindow.

readBandWeights()

Read the bandweights file given as argument to BandWeights and return (bh, kdists, erg, wei) where

bh is an instance of BandHeader

kdists is a 1d numpy.ndarray containing the k-path variable.

erg is a 3d numpy.ndarray of energies, which is C-orderd, meaning that the last dimension is the innermost dimension. The three dimensions are BandHeader.nspin, BandHeader.nband and BandHeader.nkp.

wei is a 4d numpy.ndarray of energies, which is C-orderd, meaning that the last dimension is the innermost dimension. The four dimensions are BandHeader.nspin, BandHeader.nband, BandHeader.norb and BandHeader.nkp.

This function does not return the list of k-vectors, since these are not part of the weights file. If you need them and have a corresponding band file you could get them from there via BandPlot.readBands.

WeightDefinitions

class WeightDefinitions

Helper class to collect input for BandWeights.addWeights() or for usage in some Slabify routines. This is the python equivalent of faddwei...

Example:

import pyfplo.common as com
wds=com.WeightDefinitions()
# get a new state
w=wds.add(name='all')
# add labels
w.addLabels(labels=['Al(001)3s+0','Al(001)3p-1','Al(001)3p+0','Al(001)3p+1'],fac=1)
# or add via orbital info
w.addAtoms(atom='Al',sites=[1],orbitals=['3s','3p'],fac=1)

print wds
bw=com.BandWeights('+bweights')
bw.addWeights(wds,'+bwsum')


#fictitious more efficient example

wds=com.WeightDefinitions()
w=wds.add('plaquette')\
   .addAtoms('Cu',[9,10],['3d'])\
   .addAtoms('O',[1,2],['2p'])

For further information see WeightDefinition and BandWeights

WeightDefinitions() creates a new WeightDefinitions object.

add(name)

Add a new state definition (weight sum) called name to the collection of states and return an instance of WeightDefinition, which can be used to add specific input weights.

__str__()

Return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:

print obj

WeightDefinition

class WeightDefinition

This collects information for a single weight (state) definition. This object cannot be created directly. Rather it is returned by WeightDefinitions.add().

addLabels(labels, fac=1.0)

labels (list of strings): a list of existing weight labels (being in the input bandweights file).

fac (float): the weights enter the weight sum with this factor.

This routine adds the labels to the current WeightDefinition and returns the current instance of WeightDefinition, in order to allow constructions like:

w.addLabels(...)\
 .addAtoms(...)
addAtoms(atom, sites, orbitals, fac=1.0, spin='')

atom (str): element name.

sites (list of int): list of site numbers.

orbitals (list of str): list of orbitals (e.g. ‘3d or ‘3d+1’ or ‘3d5/2-1/2’ or ‘all’)

fac (double): the weights enter the weight sum with this factor.

spin (str): ‘up’, ‘dn’, or ‘both’

Defines a set of single orbital weights to be added to this state. Note, that in the full relativistic case spin must be specified if the orbitals in the input weight file refer to pseudo non-relativistic symmetries (e.g. ‘Pt(001)5d+1 up’).

It returns the current instance of WeightDefinition, in order to allow constructions like:

w.addAtoms(...)\
 .addAtoms(...)\
 .addLabels(...)
__str__()

Return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:

print obj

OptionSet

class OptionSet

A collection of options for debugging output. This class cannot be instantiated directly. It only is returned from objects, which have an OptionSet member variable (see example) Example usage:

s=sla.Slabify()
op=s.options # a possible way to get an OptionSet object

print op # print the option list including their values
print op.names # print the available option names

for n in op.names:  # python loop for option print
    print n,op[n]

for n in op.names:  # python loop to set all options
    if n.startswith('prep'):
        op[n]=True

# or let's suppose there is an option called prep_pairs

op['prep_pairs']=True
__getitem__(self, n)

Return the value of the option n (string):

op=s.options # just an example
print op['some_option_name']
__setitem__(self, n, value)

Set the value of the option n (string):

op=s.options # just an example
op['some_option_name']=True
names

Return a list of available options:

s=sla.Slabify()
op=s.options # just an example
print op.names
__str__()

Return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:

print obj

Version

class Version

This class manages the version numbers of pyfplo. The easiest use is:

import pyfplo.common as com
...
print 'pyfplo version ',com.version
# one can protect scripts in the following way:
if com.version!='18.00': raise RuntimeError('pyfplo version is incorrect.')

version is also bound as a module variable in pyfplo, pyfplo.slabify and pyfplo.fploio such that the example above could read:

import pyfplo.slabify as sla
...
print 'pyfplo version '+str(sla.version)
# one can protect scripts in the following way:
if sla.version!='18.00': raise RuntimeError('pyfplo version is incorrect.')

Return a default Version object, which contains the version information of the package.

__eq__(mainversion)

Compare the main version (for code sanity purposes). Example:

if com.version!='18.00': raise RuntimeError('pyfplo version is incorrect.')
__ne__(mainversion)

Compare the main version (for code sanity purposes).

mainVersion()

Return the main version number as string.

release()

Return the release number as string.

__str__()

Return printable representation. You do not need to call this explicitly. An object obj with this function provides usefull info when printed:

print obj

Vlevel

class Vlevel

This class merely defines the verbosity level constants (Silent, Info,..., All). You can use any int where ever a vlevel is needed as an argument. For an arbitrary int N as argument the actual vlevel is set to the largest constant (defined below), which is <= N or to 0 (Silent) if int<0; One can use the constants:

print com.Vlevel.All
Silent = 0
Info = 100
More = 200
Many = 300
All = 1000

Constants

A collection of physical constants.

common.c_abtoang = Bohr radii / Angstroem
common.c_hatoev = Hartree / eV
common.c_speed_of_light_mpers = speed of light in m/s
common.c_hbar_Js = Planck constant/2pi in Js
common.c_me_kg = electron mass in Kg
common.c_angstroem_m = angstroem in m
common.c_echarge_C = electron charge in C