# Copyright (c) 2020-2021 ETH Zurich
"""
Module with some utility methods.
"""
from typing import Union
import numpy as np
import scipy.constants as sc
num = Union[int, float, np.ndarray]
[docs]def velocity_from_energy(energy: num) -> num:
"""
Calculate the velocity norm of electrons, based on their kinetic energy.
Args:
energy: Energy of the electron (eV)
Returns: Velocity norm of the electrons (m.s-1)
"""
return np.sqrt(2 * energy * sc.elementary_charge / sc.electron_mass)
[docs]def energy_from_velocity(velocity: num) -> num:
"""
Calculate the kinetic energy of electrons, based on the norm of their velocity.
Args:
velocity: velocity norm of the electrons (m.s-1)
Returns: Energy of the electrons (eV)
"""
return 0.5 * sc.electron_mass * velocity ** 2 / sc.elementary_charge
[docs]def acceleration_from_electric_field(electric_field: num) -> num:
"""
Calculates the acceleration of electrons, based on the local electric field.
Args:
electric_field: local electric field strength (V.m-1)
Returns: acceleration (m.s-2)
"""
return electric_field * (sc.elementary_charge / sc.electron_mass)
[docs]def maxwell_boltzmann_eedf(points: num, temperature: Union[int, float]) -> num:
"""
Calculates the Maxwell-Boltzmann EEDF of the given points or point
Args:
points (Union[int, float, np.ndarray]): Scalar or vector of energies in eV
temperature (Union[int, float]): Temperature at which to calculate the
distribution
"""
kB = sc.k
me = sc.m_e
q0 = sc.e
T = temperature
v = np.sqrt(2 * points * q0 / me)
mb = np.sqrt(2/np.pi) * (me/(kB*T))**(3/2) * v**2 * np.exp(-me * v**2 / (kB*T))
return mb * np.sqrt(points)
[docs]def maxwell_boltzmann_random(num: int, temperature: Union[float, int]) -> list:
"""
Returns a list of `num` Maxwell Boltzmann distributed values (in eV) at
temperature `temperature`
Args:
num (int): Number of electrons
temperature (float): Temperature
"""
d = False
i = 0
last = -1
di = 0.0001
# determine the range for values
while not d or not np.isclose(last, 0):
now = maxwell_boltzmann_eedf(i, temperature)
if now < last:
d = True
last = now
i += di
# divide the range into subintervals
bins = np.arange(0, i, di)
vals = []
# for each subinterval associate a probability (the mean of the eedf value
# at the right and left side of the subinterval)
for b in bins:
left = maxwell_boltzmann_eedf(b, temperature)
right = maxwell_boltzmann_eedf(b+di, temperature)
m = left + right / 2
vals.append(m)
# sum all probabilities together (imagine putting them all on a line)
total = sum(vals)
e = []
# generate num values by choosing a random point the line and select a
# random energy in the corresponding energy interval. Both random numbers
# are chosen uniformly.
for i in range(0, num):
u = np.random.uniform(0, total)
s = 0
for b, v in zip(bins, vals):
s += v
if u <= s:
e.append(np.random.uniform(b, b + di))
break
return e