Source code for ase2sprkkr.asr.deformationpotentials

"""Deformation potentials."""
from typing import List
from asr.core import command, option, ASRResult, prepare_result
import numpy as np


[docs] def webpanel(result, row, key_descriptions): data = row.data.get('results-asr.deformationpotentials.json') defpot = data['deformation_potentials'] vbmdef = (defpot[0, 0] + defpot[1, 0]) / 2 cbmdef = (defpot[0, 1] + defpot[1, 1]) / 2 rows = [['Uniaxial deformation potential at VBM', f'{cbmdef:0.2f} eV'], ['Uniaxial deformation potential at CBM', f'{vbmdef:0.2f} eV']] panel = {'title': 'Basic electronic properties (PBE)', 'columns': [[{'type': 'table', 'header': ['Property', ''], 'rows': rows}]], 'sort': 11} return [panel]
[docs] @prepare_result class Result(ASRResult): formats = {"ase_webpanel": webpanel}
@command(returns=Result) @option('--strains', help='Strain percentages', type=float) @option('--ktol', help='Distance in k-space that extremum is allowed to move.', type=float) def main(strains: List[float] = [-1.0, 0.0, 1.0], ktol: float = 0.1) -> Result: """Calculate deformation potentials. Calculate the deformation potential both with and without spin orbit coupling, for both the conduction band and the valence band, and return as a dictionary. """ from asr.setup.strains import (get_strained_folder_name, get_relevant_strains) from asr.core import read_json from ase.io import read strains = sorted(strains) atoms = read('structure.json') ij = get_relevant_strains(atoms.pbc) ij_to_voigt = [[0, 5, 4], [5, 1, 3], [4, 3, 2]] # Edges have dimension (3, 6, 2) = # (#strains_percentages, #strains, (vbm, cbm)) # Because np.polyfit likes that edges_pin = np.zeros((3, 6, 2), float) edges_nosoc_pin = np.zeros((3, 6, 2), float) gsresults = read_json('results-asr.gs.json') k0_vbm_c = gsresults['k_vbm_c'] k0_cbm_c = gsresults['k_cbm_c'] for i, j in ij: for ip, strain in enumerate(strains): folder = get_strained_folder_name(strain, i, j) gsresults = read_json(folder / 'results-asr.gs.json') k_vbm_c = gsresults['k_vbm_c'] k_cbm_c = gsresults['k_cbm_c'] difference = k_vbm_c - k0_vbm_c difference -= np.round(difference) assert (np.abs(difference) < ktol).all(), \ (f'{folder}: i={i} j={j} strain={strain}: VBM has ' f'changed location in reciprocal space upon straining. ' f'{k0_vbm_c} -> {k_vbm_c} (Delta_c={difference})') difference = k_cbm_c - k0_cbm_c difference -= np.round(difference) assert (np.abs(difference) < ktol).all(), \ (f'{folder}: i={i} j={j} strain={strain}: CBM has ' f'changed location in reciprocal space upon straining. ' f'{k0_cbm_c} -> {k_cbm_c} (Delta_c={difference})') evac = gsresults['evac'] edges_pin[ip, ij_to_voigt[i][j], 0] = gsresults['vbm'] - evac edges_nosoc_pin[ip, ij_to_voigt[i][j], 0] = \ gsresults['gaps_nosoc']['vbm'] - evac edges_pin[ip, ij_to_voigt[i][j], 1] = gsresults['cbm'] - evac edges_nosoc_pin[ip, ij_to_voigt[i][j], 1] = \ gsresults['gaps_nosoc']['cbm'] - evac results = {'edges': edges_pin, 'edges_nosoc': edges_nosoc_pin} for soc in (True, False): if soc: edges_pin = edges_pin else: edges_pin = edges_nosoc_pin deformation_potentials = np.zeros(np.shape(edges_pin)[1:]) for idx, band_edge in enumerate(['vbm', 'cbm']): D = np.polyfit(strains, edges_pin[:, :, idx], 1)[0] * 100 deformation_potentials[:, idx] = D results[['deformation_potentials_nosoc', 'deformation_potentials'][soc]] = \ deformation_potentials.tolist() return results if __name__ == '__main__': main.cli()