# Source code for pyMETHES.utils

```#  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
```