-
-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decay energy chain #2448
Decay energy chain #2448
Changes from 20 commits
fc42f85
52faa24
d0e9e23
f77e720
f0b7572
4a5bc6f
ae66f13
8f46268
b2a951a
adc1ea9
d19b559
7c76a7f
809cf33
c65626c
ec64ddf
c057a02
28b4103
0d28444
76f30db
48eb360
bdc68e0
6b3d9a4
0c7521c
b06c0e6
170d0d1
17a6233
56a6d30
f62643b
442bcc4
f2c3122
3714d87
8d97457
17954c5
fb0d32f
32bd989
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import os | ||
import pytest | ||
import numpy as np | ||
import numpy.testing as npt | ||
from pathlib import Path | ||
import radioactivedecay as rd | ||
|
||
import tardis | ||
from tardis.model import SimulationState | ||
from tardis.io.configuration import config_reader | ||
from tardis.io.util import yaml_load_file, YAMLLoader | ||
from tardis.energy_input.gamma_ray_transport import ( | ||
calculate_shell_masses, | ||
create_isotope_dicts, | ||
get_all_isotopes, | ||
create_inventories_dict, | ||
calculate_total_decays, | ||
) | ||
import astropy.units as u | ||
import astropy.constants as c | ||
|
||
# DATA_PATH = os.path.join( | ||
# tardis.__path__[0], "io", "configuration", "tests", "data" | ||
# ) | ||
NI56_NUCLIDE = rd.Nuclide("Ni56") | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def gamma_ray_config(example_configuration_dir: Path): | ||
""" | ||
Parameters | ||
---------- | ||
example_configuration_dir: Path to the configuration directory. | ||
|
||
Returns | ||
------- | ||
Tardis configuration | ||
""" | ||
yml_path = ( | ||
example_configuration_dir | ||
/ "tardis_configv1_density_exponential_nebular.yml" | ||
) | ||
|
||
return config_reader.Configuration.from_yaml(yml_path) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def simulation_setup(gamma_ray_config): | ||
Knights-Templars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Parameters | ||
---------- | ||
gamma_ray_config: | ||
|
||
Returns | ||
------- | ||
|
||
""" | ||
gamma_ray_config.model.structure.velocity.start = 1.0 * u.km / u.s | ||
gamma_ray_config.model.structure.density.rho_0 = 5.0e2 * u.g / (u.cm**3) | ||
gamma_ray_config.supernova.time_explosion = 1.0 * (u.d) | ||
model = SimulationState.from_config(gamma_ray_config) | ||
return model | ||
|
||
|
||
def test_calculate_shell_masses(simulation_setup): | ||
Knights-Templars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Function to test calculation of shell masses. | ||
Parameters | ||
---------- | ||
simulation_setup: A simulation setup which returns a model. | ||
""" | ||
model = simulation_setup | ||
volume = model.volume.to("cm^3") | ||
density = model.density.to("g/cm^3") | ||
desired = (volume * density).to(u.g).value | ||
|
||
shell_masses = calculate_shell_masses(model).value | ||
npt.assert_almost_equal(shell_masses, desired) | ||
|
||
|
||
@pytest.mark.parametrize("nuclide_name", ["Ni-56"]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add one or two more nuclides. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but it is not resolved - there is still just one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. Three. Ni56, Cr48, and Fe52 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there something wrong with the files changed here? I would expect the other nuclides to show up in this pytest parameterize here, but it still just looks like Ni56. Also I don't see any mentions of Cr48 or Fe52 in the code. Is something not updating correctly? |
||
def test_activity(simulation_setup, nuclide_name): | ||
""" | ||
Function to test the decay of 56Ni in radioactivedecay with an analytical solution. | ||
Parameters | ||
---------- | ||
simulation_setup: A simulation setup which returns a model. | ||
nuclide_name: Name of the nuclide. | ||
""" | ||
nuclide = rd.Nuclide(nuclide_name) | ||
model = simulation_setup | ||
t_half = nuclide.half_life() * u.s | ||
decay_constant = np.log(2) / t_half | ||
time_delta = 1.0 * u.s | ||
shell_masses = calculate_shell_masses(model) | ||
raw_isotope_abundance = model.raw_isotope_abundance | ||
raw_isotope_abundance_mass = raw_isotope_abundance.apply( | ||
lambda x: x * shell_masses, axis=1 | ||
) | ||
mass = raw_isotope_abundance_mass.loc[nuclide.Z, nuclide.A][0] | ||
iso_dict = create_isotope_dicts(raw_isotope_abundance, shell_masses) | ||
inv_dict = create_inventories_dict(iso_dict) | ||
|
||
total_decays = calculate_total_decays(inv_dict, time_delta) | ||
actual = total_decays[0][nuclide.Z, nuclide.A][nuclide_name] | ||
|
||
isotopic_mass = nuclide.atomic_mass * (u.g) | ||
number_of_moles = mass * (u.g) / isotopic_mass | ||
number_of_atoms = (number_of_moles * c.N_A).value | ||
N1 = number_of_atoms * np.exp(-decay_constant * time_delta) | ||
expected = number_of_atoms - N1.value | ||
|
||
npt.assert_allclose(actual, expected, rtol=1e-7) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accurate upto 8 decimal places. |
||
|
||
|
||
@pytest.mark.xfail(reason="To be implemented") | ||
def test_activity_chain(simulation_setup): | ||
model = simulation_setup | ||
t_half_Ni = NI_INV.half_lives("s")["Ni-56"] | ||
t_half_Co = 77.236 * u.d.to(u.s) | ||
decay_constant_Ni = np.log(2) / t_half_Ni | ||
decay_constant_Co = np.log(2) / t_half_Co | ||
time_delta = 80.0 * u.d.to(u.s) | ||
shell_masses = calculate_shell_masses(model) | ||
raw_isotope_abundance = model.raw_isotope_abundance | ||
raw_isotope_abundance_mass = raw_isotope_abundance.apply( | ||
lambda x: x * shell_masses, axis=1 | ||
) | ||
ni_mass = raw_isotope_abundance_mass.loc[28, 56][0] | ||
iso_dict = create_isotope_dicts(raw_isotope_abundance, shell_masses) | ||
inv_dict = create_inventories_dict(iso_dict) | ||
total_decays = calculate_total_decays(inv_dict, time_delta) | ||
actual_Ni = total_decays[0][28, 56]["Ni-56"] | ||
actual_Co = total_decays[0][28, 56]["Co-56"] | ||
|
||
isotopic_mass_Ni = NI_INV._get_atomic_mass("Ni-56") * (u.g) | ||
number_of_moles = ni_mass * (u.g) / isotopic_mass_Ni | ||
number_of_atoms = number_of_moles * c.N_A | ||
N1 = number_of_atoms.value * np.exp(-decay_constant_Ni * time_delta) | ||
N2 = ( | ||
number_of_atoms.value | ||
* decay_constant_Ni | ||
/ (decay_constant_Co - decay_constant_Ni) | ||
* ( | ||
np.exp(-decay_constant_Ni * time_delta) | ||
- np.exp(-decay_constant_Co * time_delta) | ||
) | ||
) | ||
expected_Ni = number_of_atoms.value * ( | ||
1 - np.exp(-decay_constant_Ni * time_delta) | ||
) | ||
expected_Co = number_of_atoms.value - N1 - N2 | ||
|
||
npt.assert_almost_equal(actual_Ni, expected_Ni) | ||
npt.assert_almost_equal(actual_Co, expected_Co) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The for loop here might be easier to do using the dataframe methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sonachitchyan. Do you mean pandas dataframe? Since radioactivedecay gives output as dictionaries. I created dictionaries, as they are easy to manipulate with key, value pairs. Later I convert them to dataframe.