Skip to content

Commit

Permalink
Fix low temperature problem of Van Regemorter approximation (#1992)
Browse files Browse the repository at this point in the history
* Fix low temperature problem of Van Regemorter approximation

* Add test for function in Van Regemorter approximation

* Fix test

* Fix test 2
  • Loading branch information
chvogl authored May 10, 2022
1 parent 120b303 commit c188b8a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
32 changes: 28 additions & 4 deletions tardis/plasma/properties/atomic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
import pandas as pd
from numba import njit
from scipy.special import expn
from scipy.special import exp1
from scipy.interpolate import PchipInterpolator
from collections import Counter as counter
import radioactivedecay as rd
Expand Down Expand Up @@ -758,9 +758,9 @@ def calculate(self, atomic_data, continuum_interaction_species):
)
return yg_data, t_yg, index, delta_E, yg_idx

@staticmethod
@classmethod
def calculate_yg_van_regemorter(
atomic_data, t_electrons, continuum_interaction_species
cls, atomic_data, t_electrons, continuum_interaction_species
):
"""
Calculate collision strengths in the van Regemorter approximation.
Expand Down Expand Up @@ -806,13 +806,37 @@ def calculate_yg_van_regemorter(
yg = 14.5 * coll_const * t_electrons * yg[:, np.newaxis]

u0 = nu_lines[np.newaxis].T / t_electrons * (H / K_B)
gamma = 0.276 * np.exp(u0) * expn(1, u0)
gamma = 0.276 * cls.exp1_times_exp(u0)
gamma[gamma < 0.2] = 0.2
yg *= u0 * gamma / BETA_COLL
yg = pd.DataFrame(yg, index=lines_filtered.index, columns=t_electrons)

return yg

@staticmethod
def exp1_times_exp(x):
"""
Product of the Exponential integral E1 and an exponential.
This function calculates the product of the Exponential integral E1
and an exponential in a way that also works for large values.
Parameters
----------
x : array_like
Input values.
Returns
-------
array_like
Output array.
"""
f = exp1(x) * np.exp(x)
# Use Laurent series for large values to avoid infinite exponential
mask = x > 500
f[mask] = (x**-1 - x**-2 + 2 * x**-3 - 6 * x**-4)[mask]
return f


class YgInterpolator(ProcessingPlasmaProperty):
"""
Expand Down
11 changes: 11 additions & 0 deletions tardis/plasma/tests/test_plasma_contiuum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pytest
import numpy as np
from numpy.testing import assert_allclose
from tardis.plasma.properties import YgData


def test_exp1_times_exp():
x = np.array([499.0, 501.0, 710.0])
desired = np.array([0.00200000797, 0.0019920397, 0.0014064725])
actual = YgData.exp1_times_exp(x)
assert_allclose(actual, desired)

0 comments on commit c188b8a

Please sign in to comment.