Source code for ase2sprkkr.asr.borncharges

"""Effective Born charges."""
from asr.core import command, option, ASRResult, prepare_result
import numpy as np
import typing


[docs] def webpanel(result, row, key_descriptions): import numpy as np def matrixtable(M, digits=2, unit='', skiprow=0, skipcolumn=0): table = M.tolist() shape = M.shape for i in range(skiprow, shape[0]): for j in range(skipcolumn, shape[1]): value = table[i][j] table[i][j] = '{:.{}f}{}'.format(value, digits, unit) return table columns = [[], []] for a, Z_vv in enumerate( row.data['results-asr.borncharges.json']['Z_avv']): table = np.zeros((4, 4)) table[1:, 1:] = Z_vv rows = matrixtable(table, skiprow=1, skipcolumn=1) sym = row.symbols[a] rows[0] = [f'Z<sup>{sym}</sup><sub>ij</sub>', 'u<sub>x</sub>', 'u<sub>y</sub>', 'u<sub>z</sub>'] rows[1][0] = 'P<sub>x</sub>' rows[2][0] = 'P<sub>y</sub>' rows[3][0] = 'P<sub>z</sub>' for ir, tmprow in enumerate(rows): for ic, item in enumerate(tmprow): if ir == 0 or ic == 0: rows[ir][ic] = '<b>' + rows[ir][ic] + '</b>' Ztable = dict( type='table', rows=rows) columns[a % 2].append(Ztable) panel = {'title': 'Born charges', 'columns': columns, 'sort': 17} return [panel]
[docs] @prepare_result class Result(ASRResult): Z_avv: np.ndarray sym_a: typing.List[str] key_descriptions = {'Z_avv': 'Array of borncharges.', 'sym_a': 'Chemical symbols.'} formats = {"ase_webpanel": webpanel}
@command('asr.borncharges', dependencies=['asr.gs@calculate'], requires=['gs.gpw'], returns=Result) @option('--displacement', help='Atomic displacement (Å)', type=float) def main(displacement: float = 0.01) -> Result: """Calculate Born charges.""" from gpaw import GPAW from ase.units import Bohr from asr.core import chdir, read_json from asr.formalpolarization import main as formalpolarization from asr.setup.displacements import main as setupdisplacements from asr.setup.displacements import get_all_displacements, get_displacement_folder if not setupdisplacements.done: setupdisplacements(displacement=displacement) calc = GPAW('gs.gpw', txt=None) atoms = calc.atoms cell_cv = atoms.get_cell() / Bohr vol = abs(np.linalg.det(cell_cv)) sym_a = atoms.get_chemical_symbols() Z_avv = [] phase_ascv = np.zeros((len(atoms), 2, 3, 3), float) for ia, iv, sign in get_all_displacements(atoms): folder = get_displacement_folder(ia, iv, sign, displacement) with chdir(folder): if not formalpolarization.done: formalpolarization() polresults = read_json(folder / 'results-asr.formalpolarization.json') phase_c = polresults['phase_c'] isign = [None, 1, 0][sign] phase_ascv[ia, isign, :, iv] = phase_c for phase_scv in phase_ascv: dphase_cv = (phase_scv[1] - phase_scv[0]) mod_cv = np.round(dphase_cv / (2 * np.pi)) * 2 * np.pi dphase_cv -= mod_cv phase_scv[1] -= mod_cv dP_vv = (np.dot(dphase_cv.T, cell_cv).T / (2 * np.pi * vol)) Z_vv = dP_vv * vol / (2 * displacement / Bohr) Z_avv.append(Z_vv) Z_avv = np.array(Z_avv) data = {'Z_avv': Z_avv, 'sym_a': sym_a} return data if __name__ == '__main__': main.cli()