Including Radioactive Isotopes in NuPyCEE

Prepared by: Benoit Côté

This notebook describe the radioactive isotope implementation in NuPyCEE and shows how to run a SYGMA and OMEGA with radioactive yields.


In [1]:
# Import python modules
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Import the NuPyCEE codes
import sygma
import omega

1. Input Parameters

The inputs that need to be provided to activate the radioactive option are:

  • the list of selected radioactive isotopes,
  • the radioactive yield tables.

The list of isotopes is declared in the yield_tables/decay_info.txt file and can be modified prior any simulation. The radioactive yields are found (or need to be added) in the yield_tables/ folder. Each stable yield table can have their associated radioactive yield table:

  • Massive and AGB stars
    • Stable isotopes: table
    • Radioactive isotopes: table_radio
  • Type Ia supernovae
    • Stable isotopes: sn1a_table
    • Radioactive isotopes: sn1a_table_radio
  • Neutron star mergers
    • Stable isotopes: nsmerger_table
    • Radioactive isotopes: nsmerger_table_radio
  • Etc..

Each enrichment source can be activated independently by providing its input radioactive yield table. The radioactive yield table file format needs to be identical to its stable counterpart.

Warning: Radioactive isotopes will decay into stable isotopes. When using radioactive yields, please make sure that the stable yields do not include the decayed isotopes already.

2. Single Decay Channel (Default Option)

If the radioactive isotopes you selected have only one decay channel, you can use the default decay option, which uses the following exponential law,

$N_r(t)=N_r(t_0)\,\mathrm{exp}\left[\frac{-(t-t_0)}{\tau}\right],$

$\tau=\frac{T_{1/2}}{\mathrm{ln}(2)},$

where $t_0$ is the reference time where the number of radioactive isotopes was equal to $N_0$. $T_{1/2}$ is the half-life of the isotope, which needs to be specified in yield_tables/decay_info.txt. The decayed product will be added to the corresponding stable isotope, as defined in yield_tables/decay_info.txt.

Example with Al-26

Below, a SYGMA simulation is ran with no star formation to better isolate the decay process. Here we choose Al-26 as an example, which decays into Mg-26.


In [2]:
# Number of timesteps in the simulaton.
# See https://github.com/NuGrid/NuPyCEE/blob/master/DOC/Capabilities/Timesteps_size_management.ipynb
special_timesteps = -1
nb_dt = 100
tend = 2.0e6
dt = tend / float(nb_dt)

# No star formation.
sfr = '' 
starbursts = np.zeros(nb_dt)

# Dummy neutron star merger yields to activate the radioactive option.
nsmerger_table_radio = 'yield_tables/extra_table_radio_dummy.txt'

In [3]:
# Add 1 Msun of radioactive Al-26 in the gas.
# The indexes of this array reflect the order seen in the yield_tables/decay_file.txt file
# Index 0, 1, 2 --> Al-26, K-40, U-238
ism_ini_radio = [1.0, 0.0, 0.0]

Run SYGMA


In [4]:
# Run SYGMA (or in this case, the decay process)
s = sygma.sygma(iniZ=0.0, sfr=sfr, starbursts=starbursts, ism_ini_radio=ism_ini_radio,\
                special_timesteps=special_timesteps, tend=tend, dt=dt,\
                decay_file='yield_tables/decay_file.txt', nsmerger_table_radio=nsmerger_table_radio)


SYGMA run in progress..
   SYGMA run completed - Run time: 0.74s

In [5]:
# Get the Al-26 (radioactive) and Mg-26 (stable) indexes in the gas arrays
i_Al_26 = s.radio_iso.index('Al-26')
i_Mg_26 = s.history.isotopes.index('Mg-26')

# Extract the evolution of these isotopes as a function of time
Al_26 = np.zeros(s.nb_timesteps+1)
Mg_26 = np.zeros(s.nb_timesteps+1)
for i_t in range(s.nb_timesteps+1):
    Al_26[i_t] = s.ymgal_radio[i_t][i_Al_26]
    Mg_26[i_t] = s.ymgal[i_t][i_Mg_26]

Plot results


In [7]:
# Plot the evolution of Al-26 and Mg-26
%matplotlib nbagg
plt.figure(figsize=(8,4.5))
plt.plot( np.array(s.history.age)/1e6, Al_26, '--b', label='Al-26' )
plt.plot( np.array(s.history.age)/1e6, Mg_26, '-r',  label='Mg-26' )
plt.plot([0,2.0], [0.5,0.5], ':k')
plt.plot([0.717,0.717], [0,1], ':k')

# Labels and fontsizes
plt.xlabel('Time [Myr]', fontsize=16)
plt.ylabel('Mass of isotope [M$_\odot$]', fontsize=16)
plt.legend(fontsize=14, loc='center left', bbox_to_anchor=(1, 0.5))
plt.subplots_adjust(top=0.96)
plt.subplots_adjust(bottom=0.15)
plt.subplots_adjust(right=0.75)
matplotlib.rcParams.update({'font.size': 14.0})


3. Multiple Decay Channels

If the radioactive isotopes you selected have more than one decay channel, you need to use the provided decay module. This option can be activated by adding use_decay_module=True in the list of parameters when creating an instance of SYGMA and OMEGA. When using the decay module, the yield_tables/decay_file.txt file still needs to be provided as an input to define which radioactive isotopes are selected for the calculation.

Example with K-40

Below we still run a SYGMA simulation with no star formation to better isolate the decay process. A fraction of K-40 decays into Ca-40, and another fraction decays into Ar-40.

Run SYGMA


In [8]:
# Add 1 Msun of radioactive K-40 in the gas.
# The indexes of this array reflect the order seen in the yield_tables/decay_file.txt file
# Index 0, 1, 2 --> Al-26, K-40, U-238
ism_ini_radio = [0.0, 1.0, 0.0]

In [9]:
# Number of timesteps in the simulaton.
# See https://github.com/NuGrid/NuPyCEE/blob/master/DOC/Capabilities/Timesteps_size_management.ipynb
special_timesteps = -1
nb_dt = 100
tend = 5.0e9
dt = tend / float(nb_dt)

In [10]:
# Run SYGMA (or in this case, the decay process)
# with the decay module
s = sygma.sygma(iniZ=0.0, sfr=sfr, starbursts=starbursts, ism_ini_radio=ism_ini_radio,\
                special_timesteps=special_timesteps, tend=tend, dt=dt,\
                decay_file='yield_tables/decay_file.txt', nsmerger_table_radio=nsmerger_table_radio,\
                use_decay_module=True, radio_refinement=1)


SYGMA run in progress..
   SYGMA run completed - Run time: 1.15s

In [11]:
# Get the K-40 (radioactive) and Ca-40 and Ar-40 (stable) indexes in the gas arrays
i_K_40 = s.radio_iso.index('K-40')
i_Ca_40 = s.history.isotopes.index('Ca-40')
i_Ar_40 = s.history.isotopes.index('Ar-40')

# Extract the evolution of these isotopes as a function of time
K_40  = np.zeros(s.nb_timesteps+1)
Ca_40 = np.zeros(s.nb_timesteps+1)
Ar_40 = np.zeros(s.nb_timesteps+1)
for i_t in range(s.nb_timesteps+1):
    K_40[i_t]  = s.ymgal_radio[i_t][i_K_40]
    Ca_40[i_t] = s.ymgal[i_t][i_Ca_40]
    Ar_40[i_t] = s.ymgal[i_t][i_Ar_40]

In [12]:
# Plot the evolution of Al-26 and Mg-26
%matplotlib nbagg
plt.figure(figsize=(8,4.5))
plt.plot( np.array(s.history.age)/1e6, K_40, '--b', label='K-40' )
plt.plot( np.array(s.history.age)/1e6, Ca_40, '-r', label='Ca-40' )
plt.plot( np.array(s.history.age)/1e6, Ar_40, '-g', label='Ar-40' )

# Labels and fontsizes
plt.xlabel('Time [Myr]', fontsize=16)
plt.ylabel('Mass of isotope [M$_\odot$]', fontsize=16)
plt.legend(fontsize=14, loc='center left', bbox_to_anchor=(1, 0.5))
plt.subplots_adjust(top=0.96)
plt.subplots_adjust(bottom=0.15)
plt.subplots_adjust(right=0.75)
matplotlib.rcParams.update({'font.size': 14.0})


Example with U-238


In [13]:
# Add 1 Msun of radioactive U-238 in the gas.
# The indexes of this array reflect the order seen in the yield_tables/decay_file.txt file
# Index 0, 1, 2 --> Al-26, K-40, U-238
ism_ini_radio = [0.0, 0.0, 1.0]

In [14]:
# Number of timesteps in the simulaton.
# See https://github.com/NuGrid/NuPyCEE/blob/master/DOC/Capabilities/Timesteps_size_management.ipynb
special_timesteps = -1
nb_dt = 100
tend = 5.0e9
dt = tend / float(nb_dt)

In [15]:
# Run SYGMA (or in this case, the decay process)
# with the decay module
s = sygma.sygma(iniZ=0.0, sfr=sfr, starbursts=starbursts, ism_ini_radio=ism_ini_radio,\
                special_timesteps=special_timesteps, tend=tend, dt=dt,\
                decay_file='yield_tables/decay_file.txt', nsmerger_table_radio=nsmerger_table_radio,\
                use_decay_module=True, radio_refinement=1)


SYGMA run in progress..
   SYGMA run completed - Run time: 3.28s

In the case of U-238, there are many isotopes that are resulting from the multiple decay channels. Those new radioactive isotopes are added automatically in the list of isotopes in NuPyCEE.


In [16]:
print(s.radio_iso)


['Al-26', 'K-40', 'U-238', 'NN-1', 'Ga-78', 'Ga-79', 'Ga-80', 'Ga-81', 'Ga-82', 'Ga-83', 'Ga-84', 'Ga-85', 'Ge-78', 'Ge-79', 'Ge-80', 'Ge-81', 'Ge-82', 'Ge-83', 'Ge-84', 'Ge-85', 'Ge-86', 'Ge-87', 'Ge-88', 'Ge-89', 'As-80', 'As-81', 'As-82', 'As-83', 'As-84', 'As-85', 'As-86', 'As-87', 'As-88', 'As-89', 'As-90', 'As-91', 'Se-81', 'Se-83', 'Se-84', 'Se-85', 'Se-86', 'Se-87', 'Se-88', 'Se-89', 'Se-90', 'Se-91', 'Se-92', 'Se-93', 'Se-94', 'Br-83', 'Br-84', 'Br-85', 'Br-86', 'Br-87', 'Br-88', 'Br-89', 'Br-90', 'Br-91', 'Br-92', 'Br-93', 'Br-94', 'Br-95', 'Br-96', 'Br-97', 'Kr-85', 'Kr-87', 'Kr-88', 'Kr-89', 'Kr-90', 'Kr-91', 'Kr-92', 'Kr-93', 'Kr-94', 'Kr-95', 'Kr-96', 'Kr-97', 'Kr-98', 'Kr-99', 'Kr-100', 'Rb-86', 'Rb-88', 'Rb-89', 'Rb-90', 'Rb-91', 'Rb-92', 'Rb-93', 'Rb-94', 'Rb-95', 'Rb-96', 'Rb-97', 'Rb-98', 'Rb-99', 'Rb-100', 'Rb-101', 'Sr-89', 'Sr-90', 'Sr-91', 'Sr-92', 'Sr-93', 'Sr-94', 'Sr-95', 'Sr-96', 'Sr-97', 'Sr-98', 'Sr-99', 'Sr-100', 'Sr-101', 'Sr-102', 'Sr-103', 'Sr-104', 'Sr-105', 'Y-90', 'Y-91', 'Y-92', 'Y-93', 'Y-94', 'Y-95', 'Y-96', 'Y-97', 'Y-98', 'Y-99', 'Y-100', 'Y-101', 'Y-102', 'Y-103', 'Y-104', 'Y-105', 'Y-106', 'Y-107', 'Zr-93', 'Zr-95', 'Zr-97', 'Zr-98', 'Zr-99', 'Zr-100', 'Zr-101', 'Zr-102', 'Zr-103', 'Zr-104', 'Zr-105', 'Zr-106', 'Zr-107', 'Zr-108', 'Zr-109', 'Zr-110', 'Nb-96', 'Nb-97', 'Nb-98', 'Nb-99', 'Nb-100', 'Nb-101', 'Nb-102', 'Nb-103', 'Nb-104', 'Nb-105', 'Nb-106', 'Nb-107', 'Nb-108', 'Nb-109', 'Nb-110', 'Nb-111', 'Nb-112', 'Nb-113', 'Mo-99', 'Mo-101', 'Mo-102', 'Mo-103', 'Mo-104', 'Mo-105', 'Mo-106', 'Mo-107', 'Mo-108', 'Mo-109', 'Mo-110', 'Mo-111', 'Mo-112', 'Mo-113', 'Mo-114', 'Tc-101', 'Tc-102', 'Tc-103', 'Tc-104', 'Tc-105', 'Tc-106', 'Tc-107', 'Tc-108', 'Tc-109', 'Tc-110', 'Tc-111', 'Tc-112', 'Tc-113', 'Tc-114', 'Tc-115', 'Ru-105', 'Ru-106', 'Ru-107', 'Ru-108', 'Ru-109', 'Ru-110', 'Ru-111', 'Ru-112', 'Ru-113', 'Ru-114', 'Ru-115', 'Ru-116', 'Ru-117', 'Ru-118', 'Ru-119', 'Rh-111', 'Rh-112', 'Rh-113', 'Rh-114', 'Rh-115', 'Rh-116', 'Rh-117', 'Rh-118', 'Rh-119', 'Rh-120', 'Rh-121', 'Pd-113', 'Pd-114', 'Pd-115', 'Pd-116', 'Pd-117', 'Pd-118', 'Pd-119', 'Pd-120', 'Pd-121', 'Pd-122', 'Pd-123', 'Pd-124', 'Ag-116', 'Ag-117', 'Ag-118', 'Ag-119', 'Ag-120', 'Ag-121', 'Ag-122', 'Ag-123', 'Ag-124', 'Ag-125', 'Ag-126', 'Cd-118', 'Cd-119', 'Cd-120', 'Cd-121', 'Cd-122', 'Cd-123', 'Cd-124', 'Cd-125', 'Cd-126', 'Cd-127', 'Cd-128', 'Cd-129', 'Cd-130', 'Cd-131', 'Cd-132', 'In-122', 'In-123', 'In-124', 'In-125', 'In-126', 'In-127', 'In-128', 'In-129', 'In-130', 'In-131', 'In-132', 'In-133', 'In-134', 'In-135', 'Sn-123', 'Sn-125', 'Sn-126', 'Sn-127', 'Sn-128', 'Sn-129', 'Sn-130', 'Sn-131', 'Sn-132', 'Sn-133', 'Sn-134', 'Sn-135', 'Sn-136', 'Sn-137', 'Sb-124', 'Sb-125', 'Sb-126', 'Sb-127', 'Sb-128', 'Sb-129', 'Sb-130', 'Sb-131', 'Sb-132', 'Sb-133', 'Sb-134', 'Sb-135', 'Sb-136', 'Sb-137', 'Sb-138', 'Sb-139', 'Te-127', 'Te-129', 'Te-131', 'Te-132', 'Te-133', 'Te-134', 'Te-135', 'Te-136', 'Te-137', 'Te-138', 'Te-139', 'Te-140', 'Te-141', 'Te-142', 'I-130', 'I-131', 'I-132', 'I-133', 'I-134', 'I-135', 'I-136', 'I-137', 'I-138', 'I-139', 'I-140', 'I-141', 'I-142', 'I-143', 'I-144', 'Xe-133', 'Xe-135', 'Xe-137', 'Xe-138', 'Xe-139', 'Xe-140', 'Xe-141', 'Xe-142', 'Xe-143', 'Xe-144', 'Xe-145', 'Xe-146', 'Cs-135', 'Cs-136', 'Cs-137', 'Cs-138', 'Cs-139', 'Cs-140', 'Cs-141', 'Cs-142', 'Cs-143', 'Cs-144', 'Cs-145', 'Cs-146', 'Cs-147', 'Cs-148', 'Cs-149', 'Cs-150', 'Cs-151', 'Ba-139', 'Ba-140', 'Ba-141', 'Ba-142', 'Ba-143', 'Ba-144', 'Ba-145', 'Ba-146', 'Ba-147', 'Ba-148', 'Ba-149', 'Ba-150', 'Ba-151', 'Ba-152', 'Ba-153', 'La-140', 'La-141', 'La-142', 'La-143', 'La-144', 'La-145', 'La-146', 'La-147', 'La-148', 'La-149', 'La-150', 'La-151', 'La-152', 'La-153', 'La-154', 'Ce-143', 'Ce-144', 'Ce-145', 'Ce-146', 'Ce-147', 'Ce-148', 'Ce-149', 'Ce-150', 'Ce-151', 'Ce-152', 'Ce-153', 'Ce-154', 'Ce-155', 'Ce-156', 'Pr-146', 'Pr-147', 'Pr-148', 'Pr-149', 'Pr-150', 'Pr-151', 'Pr-152', 'Pr-153', 'Pr-154', 'Pr-155', 'Pr-156', 'Pr-157', 'Nd-149', 'Nd-151', 'Nd-152', 'Nd-153', 'Nd-154', 'Nd-155', 'Nd-156', 'Nd-157', 'Nd-158', 'Nd-159', 'Pm-152', 'Pm-153', 'Pm-154', 'Pm-155', 'Pm-156', 'Pm-157', 'Pm-158', 'Pm-159', 'Th-234', 'As-78', 'As-79', 'Nb-95', 'Tc-99', 'Ru-103', 'Rh-105', 'Rh-106', 'Rh-107', 'Rh-108', 'Rh-109', 'Rh-110', 'Pd-111', 'Pd-112', 'Ag-113', 'Ag-114', 'Ag-115', 'Cd-117', 'In-118', 'In-119', 'In-120', 'In-121', 'I-129', 'Ce-141', 'Pr-143', 'Pr-144', 'Pr-145', 'Nd-147', 'Pm-149', 'Pm-151', 'Sm-153', 'Sm-155', 'Sm-156', 'Sm-157', 'Sm-158', 'Sm-159', 'Pa-234', 'Se-79', 'Pd-107', 'Pd-109', 'Ag-111', 'Ag-112', 'Cd-115', 'In-117', 'Sn-121', 'Pm-147', 'Sm-151', 'Eu-155', 'Eu-156', 'Eu-157', 'Eu-158', 'Eu-159', 'U-234', 'Zn-77', 'Zn-78', 'Zn-79', 'Zn-80', 'Ga-76', 'Ga-77', 'Ge-77', 'Br-80', 'Br-82', 'Rb-84', 'Nb-94', 'Tc-100', 'Cs-134', 'Pm-150', 'Gd-159', 'Th-230', 'As-77', 'Ra-226', 'Rn-222', 'Po-218', 'Pb-214', 'At-218', 'Bi-214', 'Rn-218', 'Tl-210', 'Po-214', 'Pb-209', 'Pb-210', 'Hg-206', 'Bi-210', 'Tl-206', 'Po-210']

In [ ]: