solrat.atom_model.multi_term_atom_model_legacy.statistical_equilibrium_equations_legacy module

class solrat.atom_model.multi_term_atom_model_legacy.statistical_equilibrium_equations_legacy.MultiTermAtomSEELegacy(level_registry: LevelRegistry, transition_registry: TransitionRegistry, disable_r_s: bool = False, disable_n: bool = False)[source]

Bases: BaseSEE

This is a legacy SEE implementation. It is not vectorized and therefore the new SEE implementation should be preferred for synthesis/inversion. This one is kept for reference and testing purposes. Also, for one-off calculations this one can actually be faster, as pre-computing time in the vectorized implementation is comparable to a couple of runs in this implementation.

classmethod from_model_config(config: MultiTermAtomConfig) Self[source]

Constructor from the model config.

fill_all_equations(atmosphere_parameters: AtmosphereParameters, radiation_tensor_in_magnetic_frame: RadiationTensor) None[source]

Loops through all equations. Reference: (7.38)

add_coherence_decay(term: Term, K: int, Q: int, J: float, : float, atmosphere_parameters: AtmosphereParameters)[source]

Reference: (7.38)

add_absorption(term: Term, K: int, Q: int, J: float, : float, radiation_tensor: RadiationTensor)[source]

Reference: (7.38)

add_emission(term: Term, K: int, Q: int, J: float, : float, radiation_tensor: RadiationTensor)[source]

Reference: (7.38)

add_relaxation(term: Term, K: int, Q: int, J: float, : float, radiation_tensor: RadiationTensor)[source]

Reference: (7.38)

r_a(term: Term, K: int, Q: int, J: float, : float, : int, : int, Jʹʹ: float, Jʹʹʹ: float, radiation_tensor: RadiationTensor)[source]
r_e(term: Term, K: int, Q: int, J: float, : float, : int, : int, Jʹʹ: float, Jʹʹʹ: float)[source]
r_s(term: Term, K: int, Q: int, J: float, : float, : int, : int, Jʹʹ: float, Jʹʹʹ: float, radiation_tensor: RadiationTensor)[source]
static gamma(term: Term, J: float, : float)[source]

(7.42)

n(term: Term, K: int, Q: int, J: float, : float, : int, : int, Jʹʹ: float, Jʹʹʹ: float, atmosphere_parameters: AtmosphereParameters)[source]

Reference: (7.41)

t_a(term: Term, K: int, Q: int, J: float, : float, term_lower: Term, Kl: int, Ql: int, Jl: float, Jʹl: float, radiation_tensor: RadiationTensor)[source]

Reference: (7.45a)

t_e(term: Term, K: int, Q: int, J: float, : float, term_upper: Term, Ku: int, Qu: int, Ju: float, Jʹu: float)[source]

Reference: (7.45b)

t_s(term: Term, K: int, Q: int, J: float, : float, term_upper: Term, Ku: int, Qu: int, Ju: float, Jʹu: float, radiation_tensor: RadiationTensor)[source]

Reference: (7.45c)

get_solution() Rho[source]

Get the solution of the Statistical Equilibrium Equations.

Returns:

Rho instance

The solution is constructed by manual linalg solving, which proved to be a bit more reliable than available homogeneous solvers. The idea is simple:

The matrix equation is \(A x = 0\).

Let \(x[0] = 1\) (it is always \(\rho_0^0\) of some kind, so it is least likely to be exactly zero). Then we have a non-homogeneous system of equations:

\[ \begin{align}\begin{aligned}A[1:] x &= 0\\A[1:, 1:] x[1:] &= -A[1:, 0]\end{aligned}\end{align} \]

This system generally behaves well enough for linalg.solve to succeed, but pinv is more robust.