Source code for gpaw.bfield

from typing import Any, Dict

import numpy as np
from ase.units import Ha

from gpaw.density import Density
from gpaw.external import NoExternalPotential
from gpaw.pw.hamiltonian import ReciprocalSpaceHamiltonian
from gpaw.typing import Array1D, Array2D, ArrayLike1D


[docs]class BField(NoExternalPotential): def __init__(self, field: ArrayLike1D): """Constant magnetic field. field: B-field vector in units of eV/bohr-magnoton. """ self.name = 'BField' self.field_v = np.array(field) / Ha assert self.field_v.shape == (3,) def get_potential(self, gd): raise NotImplementedError('BField can only be used in PW-mode!') def update_potential_pw(self, ham: ReciprocalSpaceHamiltonian, dens: Density) -> float: magmom_v, _ = dens.estimate_magnetic_moments() eext = -self.field_v.dot(magmom_v) if dens.collinear: ham.vt_sG[:] = ham.pd2.ifft(ham.vt_Q) ham.vt_sG[0] -= self.field_v[2] ham.vt_sG[1] += self.field_v[2] else: ham.vt_xG[0] = ham.pd2.ifft(ham.vt_Q) ham.vt_xG[1:] = -self.field_v.reshape((3, 1, 1, 1)) return eext def paw_correction(self, Delta_p: Array1D, dH_sp: Array2D) -> None: if len(dH_sp) == 2: c = (4 * np.pi)**0.5 * self.field_v[2] dH_sp[0] -= c * Delta_p dH_sp[1] += c * Delta_p else: c_vp = (4 * np.pi)**0.5 * self.field_v[:, np.newaxis] dH_sp[1:] -= c_vp * Delta_p def todict(self) -> Dict[str, Any]: return {'name': self.name, 'field': tuple(self.field_v * Ha)}