Source code for ase2sprkkr.asr.magnetic_anisotropy

"""Magnetic anisotropy."""
from asr.core import command, read_json, ASRResult, prepare_result
from math import pi


[docs] def get_spin_axis(): anis = read_json('results-asr.magnetic_anisotropy.json') return anis['theta'] * 180 / pi, anis['phi'] * 180 / pi
[docs] def get_spin_index(): anis = read_json('results-asr.magnetic_anisotropy.json') axis = anis['spin_axis'] if axis == 'z': index = 2 elif axis == 'y': index = 1 else: index = 0 return index
[docs] def spin_axis(theta, phi): import numpy as np if theta == 0: return 'z' elif np.allclose(phi, 90): return 'y' else: return 'x'
[docs] def webpanel(result, row, key_descriptions): from asr.database.browser import table if row.get('magstate', 'NM') == 'NM': return [] magtable = table(row, 'Property', ['magstate', 'magmom', 'dE_zx', 'dE_zy'], kd=key_descriptions) panel = {'title': 'Basic magnetic properties (PBE)', 'columns': [[magtable], []], 'sort': 11} return [panel]
params = '''asr.gs@calculate:calculator +{'mode':'lcao','kpts':(2,2,2)}''' tests = [{'cli': ['ase build -x hcp Co structure.json', f'asr run "setup.params {params}"', 'asr run asr.magnetic_anisotropy', 'asr run database.fromtree', 'asr run "database.browser --only-figures"']}]
[docs] @prepare_result class Result(ASRResult): spin_axis: str E_x: float E_y: float E_z: float theta: float phi: float dE_zx: float dE_zy: float key_descriptions = { "spin_axis": "Magnetic easy axis", "E_x": "Soc. total energy, x-direction [eV/unit cell]", "E_y": "Soc. total energy, y-direction [eV/unit cell]", "E_z": "Soc. total energy, z-direction [eV/unit cell]", "theta": "Easy axis, polar coordinates, theta [radians]", "phi": "Easy axis, polar coordinates, phi [radians]", "dE_zx": "Magnetic anisotropy energy between x and z axis [meV/unit cell]", "dE_zy": "Magnetic anisotropy energy between y and z axis [meV/unit cell]" } formats = {"ase_webpanel": webpanel}
@command('asr.magnetic_anisotropy', tests=tests, returns=Result, dependencies=['asr.gs@calculate', 'asr.magstate']) def main() -> Result: """Calculate the magnetic anisotropy. Uses the magnetic anisotropy to calculate the preferred spin orientation for magnetic (FM/AFM) systems. Returns ------- theta: Polar angle in radians phi: Azimuthal angle in radians """ from asr.core import read_json from gpaw.spinorbit import soc_eigenstates from gpaw.occupations import create_occ_calc from gpaw import GPAW magstateresults = read_json('results-asr.magstate.json') magstate = magstateresults['magstate'] # Figure out if material is magnetic results = {} if magstate == 'NM': results['E_x'] = 0 results['E_y'] = 0 results['E_z'] = 0 results['dE_zx'] = 0 results['dE_zy'] = 0 results['theta'] = 0 results['phi'] = 0 results['spin_axis'] = 'z' return Result(data=results) calc = GPAW('gs.gpw') width = 0.001 occcalc = create_occ_calc({'name': 'fermi-dirac', 'width': width}) Ex, Ey, Ez = (soc_eigenstates(calc, theta=theta, phi=phi, occcalc=occcalc).calculate_band_energy() for theta, phi in [(90, 0), (90, 90), (0, 0)]) dE_zx = Ez - Ex dE_zy = Ez - Ey DE = max(dE_zx, dE_zy) theta = 0 phi = 0 if DE > 0: theta = 90 if dE_zy > dE_zx: phi = 90 axis = spin_axis(theta, phi) results.update({'spin_axis': axis, 'theta': theta / 180 * pi, 'phi': phi / 180 * pi, 'E_x': Ex * 1e3, 'E_y': Ey * 1e3, 'E_z': Ez * 1e3, 'dE_zx': dE_zx * 1e3, 'dE_zy': dE_zy * 1e3}) return Result(data=results) if __name__ == '__main__': main.cli()