Source code for abtem.parametrizations.functions.lobato

from __future__ import annotations

import numpy as np
from ase import units
from numba import jit
from scipy.special import kn


[docs] @jit(nopython=True, nogil=True) def scattering_factor(k2, p): return ( (p[0, 0] * (2.0 + p[1, 0] * k2) / (1.0 + p[1, 0] * k2) ** 2) + (p[0, 1] * (2.0 + p[1, 1] * k2) / (1.0 + p[1, 1] * k2) ** 2) + (p[0, 2] * (2.0 + p[1, 2] * k2) / (1.0 + p[1, 2] * k2) ** 2) + (p[0, 3] * (2.0 + p[1, 3] * k2) / (1.0 + p[1, 3] * k2) ** 2) + (p[0, 4] * (2.0 + p[1, 4] * k2) / (1.0 + p[1, 4] * k2) ** 2) )
[docs] @jit(nopython=True, nogil=True) def potential(r, p): return ( p[0, 0] * (2.0 / (p[1, 0] * r) + 1.0) * np.exp(-p[1, 0] * r) + p[0, 1] * (2.0 / (p[1, 1] * r) + 1.0) * np.exp(-p[1, 1] * r) + p[0, 2] * (2.0 / (p[1, 2] * r) + 1.0) * np.exp(-p[1, 2] * r) + p[0, 3] * (2.0 / (p[1, 3] * r) + 1.0) * np.exp(-p[1, 3] * r) + p[0, 4] * (2.0 / (p[1, 4] * r) + 1.0) * np.exp(-p[1, 4] * r) )
[docs] @jit(nopython=True, nogil=True) def potential_derivative(r, p): dvdr = -( p[0, 0] * (2.0 / (p[1, 0] * r**2) + 2.0 / r + p[1, 0]) * np.exp(-p[1, 0] * r) + p[0, 1] * (2.0 / (p[1, 1] * r**2) + 2.0 / r + p[1, 1]) * np.exp(-p[1, 1] * r) + p[0, 2] * (2.0 / (p[1, 2] * r**2) + 2.0 / r + p[1, 2]) * np.exp(-p[1, 2] * r) + p[0, 3] * (2.0 / (p[1, 3] * r**2) + 2.0 / r + p[1, 3]) * np.exp(-p[1, 3] * r) + p[0, 4] * (2.0 / (p[1, 4] * r**2) + 2.0 / r + p[1, 4]) * np.exp(-p[1, 4] * r) ) return dvdr
[docs] @jit(nopython=True, nogil=True) def charge(r, p): n = ( 2 * np.pi**4 * units.Bohr * p[0, 0] / p[1, 0] ** (5 / 2) * np.exp(-2 * np.pi * r / np.sqrt(p[1, 0])) + 2 * np.pi**4 * units.Bohr * p[0, 1] / p[1, 1] ** (5 / 2) * np.exp(-2 * np.pi * r / np.sqrt(p[1, 1])) + 2 * np.pi**4 * units.Bohr * p[0, 2] / p[1, 2] ** (5 / 2) * np.exp(-2 * np.pi * r / np.sqrt(p[1, 2])) + 2 * np.pi**4 * units.Bohr * p[0, 3] / p[1, 3] ** (5 / 2) * np.exp(-2 * np.pi * r / np.sqrt(p[1, 3])) + 2 * np.pi**4 * units.Bohr * p[0, 4] / p[1, 4] ** (5 / 2) * np.exp(-2 * np.pi * r / np.sqrt(p[1, 4])) ) return n
[docs] @jit(nopython=True, nogil=True) def x_ray_scattering_factor(k, p): n = ( 2 * np.pi**2 * units.Bohr * p[0, 0] / (p[1, 0] * (1 + p[1, 0] * k**2) ** 2) + 2 * np.pi**2 * units.Bohr * p[0, 1] / (p[1, 1] * (1 + p[1, 1] * k**2) ** 2) + 2 * np.pi**2 * units.Bohr * p[0, 2] / (p[1, 2] * (1 + p[1, 2] * k**2) ** 2) + 2 * np.pi**2 * units.Bohr * p[0, 3] / (p[1, 3] * (1 + p[1, 3] * k**2) ** 2) + 2 * np.pi**2 * units.Bohr * p[0, 4] / (p[1, 4] * (1 + p[1, 4] * k**2) ** 2) ) return n
[docs] def projected_potential(r, p): v = 2 * ( 2 * p[0][:, None] / p[1][:, None] * kn(0, r[None] * p[1][:, None]) + p[0][:, None] * r[None] * kn(1, r[None] * p[1][:, None]) ).sum(0) return v.astype(np.float32)
[docs] @jit(nopython=True, nogil=True) def projected_scattering_factor(k2, p): pi = np.array(np.pi, dtype=np.float32) pi2 = np.array(np.pi**2, dtype=np.float32) k2 = 4 * pi2 * k2 f = ( 8 * pi * ( ( p[0, 0] / p[1, 0] / (k2 + p[1, 0] ** 2) + p[0, 0] * p[1, 0] / (k2 + p[1, 0] ** 2) ** 2 ) + ( p[0, 1] / p[1, 1] / (k2 + p[1, 1] ** 2) + p[0, 1] * p[1, 1] / (k2 + p[1, 1] ** 2) ** 2 ) + ( p[0, 2] / p[1, 2] / (k2 + p[1, 2] ** 2) + p[0, 2] * p[1, 2] / (k2 + p[1, 2] ** 2) ** 2 ) + ( p[0, 3] / p[1, 3] / (k2 + p[1, 3] ** 2) + p[0, 3] * p[1, 3] / (k2 + p[1, 3] ** 2) ** 2 ) + ( p[0, 4] / p[1, 4] / (k2 + p[1, 4] ** 2) + p[0, 4] * p[1, 4] / (k2 + p[1, 4] ** 2) ** 2 ) ) ) return f