Skip to main content

BandUPpy: Python interface of the BandUP code

Project description

BandUP/BandUPpy: Band Unfolding code for Plane-wave based calculations

BandUPpy - Python version of BandUP code (not to be confused with bandupy - the interface and plotting tool of BandUP)

This is a Python version to the BandUP code, made in order to restore support for modern versions of QuantumEspresso and other codes. In order ot read the wavefunctions stored by ab-initio codes, the routines of irrep are used.

Unfolded band structure - flatband mode (Si0.5Ge0.5) Unfolded band structure - density mode (Si0.5Ge0.5) Band structures overlay (Si0.5Ge0.5: Red, pure Si: black, pure Ge: blue) Band centers and band width (Si0.5Ge0.5)

Developers and contributors

Developer of BandUPpy :

BandUPpy Package is Restructured by (maintainer):

Developer of original BandUP :

  • Paulo V. C. Medeiros, Linköping University, (at present: SMHI, the Swedish Meteorological and Hydrological Institute)

  • Jonas Björk, Linköping University

  • Stepan S. Tsirkin, (in 2015: Donostia International Physics Center)

BandUPpy Contributors: Contributors

  • We sincerely thank each and every contributor for their valuable input and support.

Contact us: Email developer/maintainer team

  • If you would like to contribute to the development of BandUPpy or request new functionality, please get in touch with us or open a pull request. We will be happy to support your request ASAP.

Installation

1. Requirements

    1. python>=3.7
    2. collections
    3. numpy
    4. pickle
    5. scipy>=1.0
    6. irrep>=1.6.2
    7. matplotlib

2. Installation using pip

    pip install banduppy

3. Installation from github repository

    git clone https://github.com/band-unfolding/banduppy.git
    cd banduppy
    pip install .  

Or, without cloning

    pip install git+https://github.com/band-unfolding/banduppy.git #@specific_branch

4. Installation using setup.py [deprecated]

Alternatively you can clone the repository and run setup.py in the usual manner:

    git clone https://github.com/band-unfolding/banduppy.git
    cd banduppy
    python setup.py install

Plane-wave codes currently supported by BandUPpy

At the moment, BandUPpy can parse wavefunctions generated by:

Usage

Explore the tutorial folder for detailed examples. Below are quick snippets showcasing what you can achieve with BandUPpy:

banduppy package:
    1. Unfolding class 
        1.1 propose_maximum_minimum_folding()
        1.2 generate_SC_Kpts_from_pc_kpts()
        1.3 generate_SC_Kpts_from_pc_k_path()
        1.3 Unfold()
        1.4 plot_ebs() [Note: Similar in Plotting class but can not plot band centers]
    2. BandStructure class
        2.1 BandStructure()
    3. Properties class
        3.1 collect_bandstr_data_only_in_energy_window()
        3.2 band_centers_broadening_bandstr()
        3.3 calculate_effecfive_mass()
        3.4 fit_functions()
    4. SaveBandStructuredata class
        4.1 save_unfolded_pc_kpts()
        4.2 save_unfolded_bandstucture()
        4.3 save_unfolded_bandcenter()
    5. Plotting class
        5.1 plot_ebs()
        5.2 plot_scf()

1. Lat's start

---------------------------- Import modules ---------------------------------
    import numpy as np
    import pickle
    import banduppy
------------------------ Define variables ---------------------------------
Note: Only the VASP KPOINTS file format is implemented so far.
    # supercell : 4X4X2 supercell == np.diag([4,4,2]) or
    super_cell_size = [[-1,  1, 1], [1, -1, 1], [1,  1, -1]] 
    # k-path: L-G-X-U,K-G. If the segmant is skipped, put a None between nodes.
    PC_BZ_path = [[1/2,1/2,1/2], [0,0,0],[1/2,0,1/2], [5/8,1/4,5/8], None, [3/8,3/8,3/4], [0,0,0]] 
    # Number of k-points in each path segments. or, one single number if they are same.
    npoints_per_path_seg = (23,27,9,29) 
    # Labels of special k-points: list or string. e.g ['L','G','X','U','K','G'] or 'LGXUKG'
    special_k_points = "LGXUKG"
    # Weights of the k-points to be appended in the final generated k-points files
    kpts_weights = 1 
    # Save the SC kpoints in a file
    save_to_file = True 
    # Directory to save file
    save_to_dir = '<directory to save files>' 
    # File format of kpoints file that will be created and saved
    kpts_file_format = 'vasp' # This will generate vasp KPOINTS file format

1. Estimate the best choice of number of kpoints to use in effective band structure each k-path segments considering maximizing or minimizing folding in the supercell.

Motivation: Maximizing folding helps minimizing computational resource.

Definition: $\text{Folding percent} = \frac{\text{no. of unique PC kpoints} \ -\ \text{no. of folded SC Kpoints}}{\text{no. of unique PC kpoints}}\times100$

------------------ Initiate Unfolding method -----------------------------
    band_unfold = banduppy.Unfolding(supercell=super_cell_size,
                                     print_log='high')
------------- Propose degree of unfolding --------------------------------
    propose_folding_results = \
    band_unfold.propose_maximum_minimum_folding(PC_BZ_path, min_num_pts=10, max_num_pts=50,
                                                serach_mode='brute_force', draw_plots=True, 
                                                save_plot=False, save_dir='.', 
                                                save_file_name=None)

2. Create SC kpoints from PC band path

------------ Creating SC folded kpoints from PC band path -----------------

Note: band_unfold.generate_SC_Kpts_from_pc_kpts() can be used to generate SC Kpoints from PC kpoints list.

    kpointsPBZ_full, kpointsPBZ_unique, kpointsSBZ, \
        SBZ_PBZ_kpts_mapping, special_kpoints_pos_labels \
        = band_unfold.generate_SC_Kpts_from_pc_k_path(pathPBZ = PC_BZ_path,
                                                      nk = npoints_per_path_seg,
                                                      labels = special_k_points,
                                                      kpts_weights = kpts_weights,
                                                      save_all_kpts = save_to_file,
                                                      save_sc_kpts = save_to_file,
                                                      save_dir = save_to_dir,
                                                      file_name_suffix = '',
                                                      file_format=kpts_file_format)

3. Unfold band structure

    read_dir = '<path where the vasp output files are>'
------------------------ Read wave function file --------------------------
    bands = banduppy.BandStructure(code="vasp", spinor=False,
                                   fPOS = f"{read_dir}/POSCAR",
                                   fWAV = f"{read_dir}/WAVECAR")
----------------- Unfold the band structures ------------------------------
    # save2file : Save unfolded kpoints or not? 
    # fdir : Directory path where to save the file.
    # fname : Name of the file.
    # fname_suffix : Suffix to add to the file name.

Option 1: Continue with previous instance.

    unfolded_bandstructure_, kpline \
    = band_unfold.Unfold(bands, kline_discontinuity_threshold = 0.1, 
                        save_unfolded_kpts = {'save2file': True, 
                                              'fdir': save_to_dir,
                                              'fname': 'kpoints_unfolded',
                                              'fname_suffix': ''},
                        save_unfolded_bandstr = {'save2file': True, 
                                                'fdir': save_to_dir,
                                                'fname': 'bandstructure_unfolded',
                                                'fname_suffix': ''})

Option 2: If this part is used independently from the above instances re-initiate the Unfolding module.

    # --------------------- Initiate Unfolding method --------------------------
    band_unfold = banduppy.Unfolding(supercell=super_cell_size, print_info='high')

    # ----------------- Unfold the band structures ------------------------------
    unfolded_bandstructure_, kpline \
    = band_unfold.Unfold(bands, PBZ_kpts_list_full=kpointsPBZ_full, 
                         SBZ_kpts_list=kpointsSBZ, 
                         SBZ_PBZ_kpts_map=SBZ_PBZ_kpts_mapping,
                         kline_discontinuity_threshold = 0.1, 
                         save_unfolded_kpts = {'save2file': True, 
                                              'fdir': save_to_dir,
                                              'fname': 'kpoints_unfolded',
                                              'fname_suffix': ''},
                         save_unfolded_bandstr = {'save2file': True, 
                                                'fdir': save_to_dir,
                                                'fname': 'bandstructure_unfolded',
                                                'fname_suffix': ''})

4. Determine band centers and band width

Band ceneters are determined using the SCF algorithm of automatic band center determination from Paulo V. C. Medeiros, Sven Stafström, and Jonas Björk, Phys. Rev. B 89, 041407(R) (2014) paper.

    # -------------------- Initiate Properties method -----------------------------
    unfolded_band_properties = banduppy.Properties(print_log='high')
    #===================================
    min_dN = 1e-5 # get rid of small weights bands
    threshold_dN_2b_trial_band_center = 0.05 # initial guess of the band centers based on the threshold wights.
    min_sum_dNs_for_a_band = 0.05 # Cut off criteria for minimum weights that a band center should have.
    #===================================
    err_tolerance = 1e-8 # The tolerance to group the bands set per unique kpoints value.
    prec_pos_band_centers = 1e-5 # in eV # Precision when compared band centers from previous and current SCF
    #===================================
    unfolded_bandstructure_properties, all_scf_data = \
        unfolded_band_properties.band_centers_broadening_bandstr(unfolded_bandstructure_, 
                                                                 min_dN_pre_screening=min_dN,
                                                                 threshold_dN_2b_trial_band_center=
                                                                 threshold_dN_2b_trial_band_center,
                                                                 min_sum_dNs_for_a_band=min_sum_dNs_for_a_band, 
                                                                 precision_pos_band_centers=prec_pos_band_centers,
                                                                 err_tolerance_compare_kpts_val=err_tolerance,
                                                                 collect_scf_data=False)

5. Determine effective mass (parabolic and non-parabolic) from part of the band structure or band center data

    m_star, optimized_parameters, convergence_measure = \
    unfolded_band_properties.calculate_effecfive_mass(kpath, band_energy,
                                                      initial_guess_params=None,
                                                      params_bounds = (-np.inf, np.inf),
                                                      fit_weights=None, absolute_weights=False,
                                                      parabolic_dispersion=True,
                                                      hyperbolic_dispersion_positive=False,
                                                      hyperbolic_dispersion_negative=False,
                                                      params_name = ['alpha', 'kshift', 'cbm', 'gamma'])
    #===================================
    band_energy_fit = unfolded_band_properties.fit_functions(kpath, optimized_parameters,
                                                            parabolic_dispersion=True,
                                                            hyperbolic_dispersion_positive=False,
                                                            hyperbolic_dispersion_negative=False)

6. Determine alloy-scattering potential from part of the band structure or band center data

This is based on the ... paper.

    TBA

7. Save unfolded band structure and band center data

One can save the generated data within the function call for unfolding and band ceneter determination routines as shown above. [recommened]

However, you may want save the generated data (from the above function calls) after some post processing, for e.g., you want to save part of the data only. In such cases, you can use functions from SaveBandStructuredata class to save those data. Note that the data format should be compatible with the required data format for each functions.

8. Plot unfolded band structure (scatter plot/density plot/band_centers plot)

    # Fermi energy
    Efermi = 5.9740
    # Minima in Energy axis to plot
    Emin = -5
    # Maxima in Energy axis to plot
    Emax = 5
    # Filename to save the figure. If None, figure will not be saved
    save_file_name = 'unfolded_bandstructure.png'

Option 1: Continue with previous instance.

--------------------- Plot band structure ---------------------------------
    fig, ax, CountFig \
    = band_unfold.plot_ebs(save_figure_dir=save_to_dir, save_file_name=save_file_name, CountFig=None, 
                          Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, 
                          mode="density", special_kpoints=special_kpoints_pos_labels, 
                          plotSC=True, fatfactor=20, nE=100,smear=0.2, marker='o',
                          threshold_weight=0.01, show_legend=True,
                          color='gray', color_map='viridis')

Option 2: Using BandUPpy Plotting module.

    # --------------------- Initiate Plotting method ----------------------------
    plot_unfold = banduppy.Plotting(save_figure_dir=save_to_dir)
    
    # -------- Read the saved unfolded bandstructure saved data file ------------
    unfolded_bandstructure_ = np.loadtxt(f'{save_to_dir}/bandstructure_unfolded.dat')
    kpline = np.loadtxt(f'{save_to_dir}/kpoints_unfolded.dat')[:,1]
    with open(f'{save_to_dir}/KPOINTS_SpecialKpoints.pkl', 'rb') as handle:
        special_kpoints_pos_labels = pickle.load(handle)
--------------------- Plot band structure ----------------------------------
    
    fig, ax, CountFig \
    = plot_unfold.plot_ebs(kpath_in_angs=kpline, unfolded_bandstructure=unfolded_bandstructure_, 
                           save_file_name=save_file_name, CountFig=None, 
                           Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, 
                           mode="density", special_kpoints=special_kpoints_pos_labels, 
                           plotSC=True, fatfactor=20, nE=100,smear=0.2, marker='o',
                           threshold_weight=0.01, show_legend=True, 
                           color='gray', color_map='viridis')
--------- Plot and overlay multiple band structures ------------
    fig, ax, CountFig \
    = plot_unfold.plot_ebs(kpath_in_angs=kpline1, 
                            unfolded_bandstructure=unfolded_bandstructure_1, 
                            save_file_name=None, CountFig=None, threshold_weight=0.1,
                            Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, 
                            mode="fatband", special_kpoints=special_kpoints_pos_labels1, 
                            plotSC=True, fatfactor=20, nE=100, smear=0.2,
                            color='red', color_map='viridis', show_plot=False)
    
    fig, ax, CountFig \
    = plot_unfold.plot_ebs(ax=ax, kpath_in_angs=kpline1, 
                            unfolded_bandstructure=unfolded_bandstructure_2, 
                            save_file_name=save_file_name, CountFig=None, 
                            Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, 
                            mode="fatband", special_kpoints=None, marker='x',
                            smear=0.2, color='black', color_map='viridis')
----------------- Plot the band centers -----------------------------------
    fig, ax, CountFig \
        = plot_unfold.plot_ebs(kpath_in_angs=kpline, 
                               unfolded_bandstructure=unfolded_bandstructure_properties, 
                               save_file_name=save_file_name, CountFig=None, threshold_weight=min_dN,
                               Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, 
                               mode="band_centers", special_kpoints=special_kpoints_pos_labels, 
                               marker='x', smear=0.2, plot_colormap_bandcenter=True,
                               color='black', color_map='viridis')
-------------- Plot the band centers SCF cycles ---------------------
    plot_unfold.plot_scf(kpath_in_angs=kpline, unfolded_bandstructure=unfolded_bandstructure_,
                         al_scf_data=all_scf_data, plot_max_scf_steps=3, save_file_name=save_file_name,
                         Ef=Efermi, Emin=Emin, Emax=Emax, pad_energy_scale=0.5, threshold_weight=min_dN,
                         special_kpoints=special_kpoints_pos_labels, plot_sc_unfold=True, marker='o', 
                         fatfactor=20, smear=0.05, color=None, color_map='viridis', show_legend=False, 
                         plot_colormap_bandcenter=True, show_colorbar=True, colorbar_label=None, 
                         vmin=None, vmax=None, dpi=72)

Tips and tricks:

Problem: I am getting RuntimeError in one of my calculations using VASP. How can I resolve this?

RuntimeError: *** error - computed ncnt=18134 != input nplane=18133

Answer: VASP does not write which plane waves it uses to the WAVECAR file. Therefore, when banduppy (specifically IrRep) reads the band structure, it tries to mimic VASP's selection and ordering of plane waves that fall within the cut-off sphere. Occasionally, due to numerical errors, one code might consider a plane wave within the sphere while the other does not. This discrepancy can result in an extra vector, as seen in the above case. To address this, use a small correction coefficient (_correct_Ecut0) value. This slightly adjusts the Ecut to either exclude or include plane waves near the boundary of the cut-off sphere. In the example case, use small negative correction to exclude plane waves near the boundary of the cut-off sphere. Use small positive correction when computed ncnt < input nplane.

bands = banduppy.BandStructure(code="vasp", spinor=spinorbit, fPOS = "POSCAR", fWAV = "WAVECAR", _correct_Ecut0=-1e-7)

Citations and references:

If you use BandUPpy in your work, please:

  • State EXPLICITLY that you have used the BandUP code (or a modified version of it, if this is the case), for instance, adding a sentence like:

     "The unfolding has been performed using the BandUP(py) code"
    
  • Read and cite the following papers (and the appropriate references therein):

  1. Paulo V. C. Medeiros, Sven Stafström, and Jonas Björk, Phys. Rev. B 89, 041407(R) (2014)
  2. Paulo V. C. Medeiros, Stepan S. Tsirkin, Sven Stafström, and Jonas Björk, Phys. Rev. B 91, 041116(R) (2015)
  3. Mikel Iraola, Juan L. Mañes, Barry Bradlyn, Titus Neupert, Maia G. Vergniory, Stepan S. Tsirkin, "IrRep: Symmetry eigenvalues and irreducible representations of ab initio band structures", Comput. Phys. Commun. 272, 108226 (2022)

Bibliography file: Here is the bibliography (.bib) file for your convenience.

Further details

http://www.ifm.liu.se/theomod/compphys/band-unfolding
https://github.com/band-unfolding/bandup

Version release

Latest release: v0.3.2

Chekout out version release history here for the full list of updates and upgrades.

License

BandUPpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

BandUPpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with BandUP. If not, see http://www.gnu.org/licenses/.

Upcoming (TBD)

  1. Orbital contribution projection implementation
  2. Improve band center determination algorithm

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

banduppy-0.3.2.tar.gz (60.0 kB view hashes)

Uploaded Source

Built Distribution

banduppy-0.3.2-py3-none-any.whl (59.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page