def test_ewald(): """ Ewald Rydberg test """ from numpy import all, abs, sqrt from pylada.crystal import Structure from pylada.ewald import ewald from quantities import angstrom, a0, Ry structure = Structure([[1, 0, 0], [0, 1, 0], [0, 0, 1] ], scale=50 ) \ .add_atom(0, 0, 0, 'A', charge=1e0) \ .add_atom(float(a0.rescale(angstrom) / 50.0), 0, 0, 'A', charge=-1e0) result = ewald(structure, cutoff=80) assert abs(result.energy + 2e0 * Ry) < 1e-3 assert all(abs(abs(result[0].force) - [2e0, 0, 0] * Ry / a0) < 1e-3) assert all(abs(abs(result[1].force) - [2e0, 0, 0] * Ry / a0) < 1e-3) a = float(a0.rescale(angstrom) / 50.0) / sqrt(2.) structure = Structure([[1, 0, 0], [0, 1, 0], [0, 0, 1] ], scale=50 ) \ .add_atom(0, 0, 0, 'A', charge=1e0) \ .add_atom(0, a, a, 'A', charge=-1e0) result = ewald(structure, cutoff=80) assert abs(result.energy + 2e0 * Ry) < 1e-3 assert all( abs(abs(result[0].force) - [0, 2. / sqrt(2), 2. / sqrt(2)] * Ry / a0) < 1e-3) assert all( abs(abs(result[1].force) - [0, 2. / sqrt(2), 2. / sqrt(2)] * Ry / a0) < 1e-3)
def test(): from numpy import all, abs, sqrt from pylada.crystal import Structure from pylada.ewald import ewald from quantities import angstrom, a0, Ry structure = Structure( [ [1,0,0], [0,1,0], [0,0,1] ], scale=50 ) \ .add_atom(0, 0, 0, 'A', charge=1e0) \ .add_atom( float(a0.rescale(angstrom)/50.0), 0, 0, 'A', charge=-1e0 ) result = ewald(structure, cutoff = 80) assert abs(result.energy + 2e0*Ry) < 1e-3 assert all(abs(abs(result[0].force) - [2e0, 0, 0]*Ry/a0) < 1e-3) assert all(abs(abs(result[1].force) - [2e0, 0, 0]*Ry/a0) < 1e-3) a = float(a0.rescale(angstrom)/50.0) / sqrt(2.) structure = Structure( [ [1,0,0], [0,1,0], [0,0,1] ], scale=50 ) \ .add_atom(0, 0, 0, 'A', charge=1e0) \ .add_atom(0, a, a, 'A', charge=-1e0 ) result = ewald(structure, cutoff = 80) assert abs(result.energy + 2e0*Ry) < 1e-3 assert all(abs(abs(result[0].force) - [0, 2./sqrt(2), 2./sqrt(2)]*Ry/a0) < 1e-3) assert all(abs(abs(result[1].force) - [0, 2./sqrt(2), 2./sqrt(2)]*Ry/a0) < 1e-3)
def get_madelungenergy(latt_vec_array, charge, epsilon, cutoff): """ Function returns leading first order correction term, i.e., screened Madelung-like lattice energy of point charge Reference: M. Leslie and M. J. Gillan, J. Phys. C: Solid State Phys. 18 (1985) 973 Parameters defect = pylada.vasp.Extract object charge = charge of point defect. Default 1e0 elementary charge epsilon = dimensionless relative permittivity, SKW: isotropic average of dielectric constant cutoff = Ewald cutoff parameter Returns Madelung (electrostatic) energy in eV Note: 1. Units in this function are either handled by the module Quantities, or\ defaults to Angstrom and elementary charges 2. Function is adopted from Haowei Peng's version in pylada.defects modules """ ewald_cutoff = cutoff * Ry cell_scale = 1.0 # SKW: In notebook workflow cell parameters are converted to Cartesians and units of Angstroms # SKW: Create point charge in pylada.crystal.structure class (used for charge model) # http://pylada.github.io/pylada/userguide/crystal.html struc = Structure() struc.cell = latt_vec_array struc.scale = cell_scale struc.add_atom(0., 0., 0., "P", charge=charge) #Anuj_05/22/18: added "cutoff" in ewald syntax result = ewald(struc, cutoff=ewald_cutoff).energy / epsilon return -1 * result.rescale(eV)
def first_order_charge_correction(structure, charge=None, epsilon=1e0, cutoff=20.0, **kwargs): """ First order charge correction of +1 charge in given supercell. Units in this function are either handled by the module Quantities, or defaults to Angstroems and elementary charges. :Parameters: structure : `pylada.crystal.Structure` Defect supercell, with cartesian positions in angstrom. charge Charge of the point-defect. Defaults to 1e0 elementary charge. If no units are attached, expects units of elementary charges. epsilon dimensionless relative permittivity. cutoff Ewald cutoff parameter. :return: Electrostatic energy in eV. """ from quantities import elementary_charge, eV from pylada.crystal import Structure from pylada.physics import Ry from pylada.ewald import ewald if charge is None: charge = 1 elif charge == 0: return 0e0 * eV if hasattr(charge, "units"): charge = float(charge.rescale(elementary_charge)) ewald_cutoff = cutoff * Ry struc = Structure() struc.cell = structure.cell struc.scale = structure.scale struc.add_atom(0e0, 0, 0, "A", charge=charge) result = ewald(struc, ewald_cutoff).energy / epsilon return -result.rescale(eV)
def get_madelungenergy(defect, charge=None, epsilon=1e0, cutoff=100.0): """ Function returns leading first order correction term, i.e., screened Madelung-like lattice energy of point charge Reference: M. Leslie and M. J. Gillan, J. Phys. C: Solid State Phys. 18 (1985) 973 Parameters defect = pylada.vasp.Extract object charge = charge of point defect. Default 1e0 elementary charge epsilon = dimensionless relative permittivity cutoff = Ewald cutoff parameter Returns Madelung (electrostatic) energy in eV Note: 1. Units in this function are either handled by the module Quantities, or\ defaults to Angstrom and elementary charges 2. Function is adopted from Haowei Peng's version in pylada.defects modules """ from quantities import elementary_charge, eV from pylada.crystal import Structure from pylada.physics import Ry from pylada.ewald import ewald if charge is None: charge = 1 elif charge == 0: return 0e0 * eV if hasattr(charge, "units"): charge = float(charge.rescale(elementary_charge)) ewald_cutoff = cutoff * Ry structure = defect.structure struc = Structure() struc.cell = structure.cell struc.scale = structure.scale struc.add_atom(0., 0., 0., "P", charge=charge) #Anuj_05/22/18: added "cutoff" in ewald syntax result = ewald(struc, cutoff=ewald_cutoff).energy / epsilon return -1 * result.rescale(eV)