Mass-model effects on transmission-coefficient uncertainty

This notebook explores how mass-model choices propagate into transmission coefficients and related uncertainty estimates. It is a good next step once you are comfortable with the built-in uncertainty-quantified optical potentials.

1import numpy as np
2from IPython.display import Math, display
3from periodictable import elements
4
5from jitr.utils import mass
1def neutron_fermi_energy_KD(A, Z):
2    return -11.2814 + 0.02646 * A
3
4
5def proton_fermi_energy_KD(A, Z):
6    return -8.4075 + 0.01378 * A

Compare mass-model inputs to Koning-Delaroche

1A, Z = (154, 56)
1name_core = str(elements[Z].symbol)
2display(Math(f"^{{{A}}} \\rm{{{name_core}}}"))
\[\displaystyle ^{154} \rm{Ba}\]
1for m in mass.__MASS_MODELS__:
2    Ef = mass.neutron_fermi_energy(A, Z, model=m)
3    print(f"{m:7}: {Ef[0]:1.4f} +/- {Ef[1]}")
BMA    : -3.6700 +/- 2.928163874630591
UNEDF2 : -3.5264 +/- None
BCPM   : -3.6764 +/- None
dz31   : -3.4939 +/- None
hfb31  : -3.6514 +/- None
ws4rbf : -3.4174 +/- None
FRDM2012: -3.5514 +/- None
SLY4   : -3.4264 +/- None
SKP    : -3.6264 +/- None
ame2020: nan +/- None
SKM    : -4.1414 +/- None
UNEDF0 : -3.6114 +/- None
D1M    : -3.6014 +/- None
SVMIN  : -3.6514 +/- None
UNEDF1 : -3.4964 +/- None
HFB24  : -3.7864 +/- None
1neutron_fermi_energy_KD(A, Z)
-7.20656
1for m in mass.__MASS_MODELS__:
2    Ef = mass.proton_fermi_energy(A, Z, model=m)
3    print(f"{m:7}: {Ef[0]:1.4f} +/- {Ef[1]}")
BMA    : -13.1027 +/- 2.8786616888136276
UNEDF2 : -13.6486 +/- None
BCPM   : -13.2686 +/- None
dz31   : -13.5521 +/- None
hfb31  : -12.6936 +/- None
ws4rbf : -13.8941 +/- None
FRDM2012: -13.5936 +/- None
SLY4   : -13.8936 +/- None
SKP    : -13.1386 +/- None
ame2020: nan +/- None
SKM    : -12.5986 +/- None
UNEDF0 : -13.3486 +/- None
D1M    : -13.6836 +/- None
SVMIN  : -13.4186 +/- None
UNEDF1 : -13.7586 +/- None
HFB24  : -13.2636 +/- None
1proton_fermi_energy_KD(A, Z)
-6.28538

Compute transmission coefficients

Let’s use jitr to calculate UQ’ed transmission coefficients using KDUQ Fermi energies and those from a variety of mass models

1from tqdm import tqdm
2
3import jitr
1neutron = (1, 0)
2target = (A, Z)
1# com_energy_grid = np.logspace(-1, 1.3, 100)
2com_energy_grid = np.linspace(0.01, 5, 100)
3range_fm = jitr.utils.interaction_range(A)
4lmax = 2
5print(range_fm)
6.432130093158435
1reaction = jitr.reactions.Reaction(target=target, projectile=neutron, process="EL")
 1def set_up_grid(core, com_energy_grid, mass_model="BMA"):
 2    solvers = []
 3    mn = jitr.utils.constants.MASS_N
 4    mcore = jitr.utils.mass.mass(*core, model=mass_model)[0]
 5    for _i, Ecm in enumerate(tqdm(com_energy_grid)):
 6        kinematics = jitr.utils.kinematics.classical_kinematics_cm(mcore, mn, Ecm)
 7        a = range_fm * kinematics.k + np.pi
 8        N = 50
 9        assert N > jitr.utils.suggested_basis_size(a)
10
11        solvers.append(
12            jitr.xs.elastic.IntegralWorkspace(
13                reaction=reaction,
14                kinematics=kinematics,
15                channel_radius_fm=a / kinematics.k,
16                solver=jitr.rmatrix.Solver(N),
17                lmax=lmax,
18                smatrix_abs_tol=0,
19            )
20        )
21    return solvers
1solvers = set_up_grid(target, com_energy_grid, mass_model="BMA")
100%|███████████████████████████████████████████████████████████████████████████████| 100/100 [00:16<00:00,  5.89it/s]

Run the uncertainty propagation

1samples = jitr.optical_potentials.kduq.get_samples(neutron)

KDUQ

 1tcoeff_kduq = np.zeros((com_energy_grid.size, samples.shape[0], 2, lmax + 1))
 2for j, sample in enumerate(tqdm(samples)):
 3    for i, _Ecm in enumerate(com_energy_grid):
 4        rgrid = solvers[i].radial_grid()
 5        central_params, spin_orbit_params, coulomb_params = (
 6            jitr.optical_potentials.kduq.calculate_params(
 7                neutron,
 8                target,
 9                solvers[i].kinematics.Elab,
10                *sample,
11            )
12        )
13
14        tplus, tminus = solvers[i].transmission_coefficients(
15            jitr.optical_potentials.kduq.central(rgrid, *central_params),
16            jitr.optical_potentials.kduq.spin_orbit(rgrid, *spin_orbit_params),
17            jitr.optical_potentials.kduq.coulomb_charged_sphere(rgrid, *coulomb_params),
18        )
19        tcoeff_kduq[i, j, 0, :] = tplus
20        tcoeff_kduq[i, j, 1, :] = tminus
 97%|████████████████████████████████████████████████████████████████████████████▌  | 403/416 [00:44<00:01, 11.49it/s]/home/kyle/umich/jitr/src/jitr/optical_potentials/kduq.py:467: RuntimeWarning: overflow encountered in exp
  d2 = d2_0 + d2_A / (1 + np.exp((A - d2_A3) / d2_A2))
100%|███████████████████████████████████████████████████████████████████████████████| 416/416 [00:45<00:00,  9.14it/s]

KDUQ with BMA Fermi energies

1param_order = jitr.optical_potentials.kduq.get_param_names(neutron)
2idx_Ef0 = [i for i in range(len(param_order)) if param_order[i] == "Ef_0"][0]
3idx_EfA = [i for i in range(len(param_order)) if param_order[i] == "Ef_A"][0]
4
5idx_Ef0, idx_EfA
(0, 1)
1# set Fermi energy to BMA
2Ef = mass.neutron_fermi_energy(A, Z, model="BMA")
 1tcoeff_kduq_bma = np.zeros((com_energy_grid.size, samples.shape[0], 2, lmax + 1))
 2for j, sample in enumerate(tqdm(samples)):
 3    # reset Ef
 4    sample[idx_EfA] = 0
 5    sample[idx_Ef0] = np.random.normal(loc=Ef[0], scale=Ef[1])  # sample from BMA
 6
 7    for i, _Ecm in enumerate(com_energy_grid):
 8        rgrid = solvers[i].radial_grid()
 9        central_params, spin_orbit_params, coulomb_params = (
10            jitr.optical_potentials.kduq.calculate_params(
11                neutron,
12                target,
13                solvers[i].kinematics.Elab,
14                *sample,
15            )
16        )
17
18        tplus, tminus = solvers[i].transmission_coefficients(
19            jitr.optical_potentials.kduq.central(rgrid, *central_params),
20            jitr.optical_potentials.kduq.spin_orbit(rgrid, *spin_orbit_params),
21            jitr.optical_potentials.kduq.coulomb_charged_sphere(rgrid, *coulomb_params),
22        )
23        tcoeff_kduq_bma[i, j, 0, :] = tplus
24        tcoeff_kduq_bma[i, j, 1, :] = tminus
100%|███████████████████████████████████████████████████████████████████████████████| 416/416 [00:34<00:00, 11.97it/s]

Extract confidence intervals

 1def get_confidence_intervals(tcoeffs):
 2    ci = []
 3    for l in range(3):
 4        ci.append([])
 5        ci[l].append(
 6            (
 7                np.percentile(tcoeffs[:, :, 0, l], 16, axis=1),
 8                np.percentile(tcoeffs[:, :, 0, l], 84, axis=1),
 9            )
10        )
11        if l > 0:
12            ci[l].append(
13                (
14                    np.percentile(tcoeffs[:, :, 1, l], 16, axis=1),
15                    np.percentile(tcoeffs[:, :, 1, l], 84, axis=1),
16                )
17            )
18    return ci
1kduq_ci = get_confidence_intervals(tcoeff_kduq)
2kduq_bma_ci = get_confidence_intervals(tcoeff_kduq_bma)

Plot the results

1kduq_color = "tab:blue"
2bma_color = "tab:orange"
1from matplotlib import pyplot as plt
  1fig, (ax1, ax2, ax3) = plt.subplots(
  2    figsize=(4, 6), nrows=3, ncols=1, dpi=300, sharex=True
  3)
  4
  5ax1.fill_between(
  6    com_energy_grid,
  7    kduq_bma_ci[0][0][0],
  8    kduq_bma_ci[0][0][1],
  9    color=bma_color,
 10    alpha=0.3,
 11    label="KDUQ + BMA",
 12)
 13ax1.fill_between(
 14    com_energy_grid,
 15    kduq_ci[0][0][0],
 16    kduq_ci[0][0][1],
 17    color=kduq_color,
 18    alpha=0.3,
 19    label="KDUQ",
 20)
 21
 22ax2.fill_between(
 23    com_energy_grid,
 24    kduq_bma_ci[1][0][0],
 25    kduq_bma_ci[1][0][1],
 26    color=bma_color,
 27    alpha=0.2,
 28    hatch="|||",
 29)
 30ax2.fill_between(
 31    com_energy_grid,
 32    kduq_ci[1][0][0],
 33    kduq_ci[1][0][1],
 34    color=kduq_color,
 35    alpha=0.2,
 36    hatch="|||",
 37)
 38ax2.fill_between(
 39    com_energy_grid,
 40    kduq_bma_ci[1][1][0],
 41    kduq_bma_ci[1][1][1],
 42    color=bma_color,
 43    alpha=0.2,
 44    hatch="---",
 45)
 46ax2.fill_between(
 47    com_energy_grid,
 48    kduq_ci[1][1][0],
 49    kduq_ci[1][1][1],
 50    color=kduq_color,
 51    alpha=0.2,
 52    hatch="---",
 53)
 54
 55ax3.fill_between(
 56    com_energy_grid,
 57    kduq_bma_ci[2][0][0],
 58    kduq_bma_ci[2][0][1],
 59    color=bma_color,
 60    alpha=0.2,
 61    hatch="|||",
 62)
 63ax3.fill_between(
 64    com_energy_grid,
 65    kduq_ci[2][0][0],
 66    kduq_ci[2][0][1],
 67    color=kduq_color,
 68    alpha=0.2,
 69    hatch="|||",
 70)
 71ax3.fill_between(
 72    com_energy_grid,
 73    kduq_bma_ci[2][1][0],
 74    kduq_bma_ci[2][1][1],
 75    color=bma_color,
 76    alpha=0.2,
 77    hatch="---",
 78)
 79ax3.fill_between(
 80    com_energy_grid,
 81    kduq_ci[2][1][0],
 82    kduq_ci[2][1][1],
 83    color=kduq_color,
 84    alpha=0.2,
 85    hatch="---",
 86)
 87
 88# style legend
 89swave_style = [
 90    ax3.fill_between(
 91        [-1, 0],
 92        [-1, 0],
 93        [-1, 0],
 94        color="k",
 95        alpha=0.2,
 96    ),
 97]
 98lwave_style = [
 99    ax3.fill_between(
100        [-1, 0],
101        [-1, 0],
102        [-1, 0],
103        color="k",
104        alpha=0.2,
105        hatch="---",
106    ),
107    ax3.fill_between(
108        [-1, 0],
109        [-1, 0],
110        [-1, 0],
111        color="k",
112        alpha=0.2,
113        hatch="|||",
114    ),
115]
116
117
118style_legend2 = ax2.legend(
119    lwave_style,
120    [r"$p_{1/2}$", r"$p_{3/2}$"],
121    ncols=2,
122    # loc="upper  right",
123    fontsize=12,
124    framealpha=1,
125)
126style_legend3 = ax3.legend(
127    lwave_style,
128    [r"$d_{1/2}$", r"$d_{3/2}$"],
129    ncols=2,
130    loc="lower right",
131    fontsize=12,
132    framealpha=1,
133)
134fig.legend(loc="upper center", ncols=2, framealpha=0.5)
135
136ax1.set_ylim([0, 1])
137ax2.set_ylim([0, 1])
138ax3.set_ylim([0, 1])
139
140ax1.set_ylabel(r"$T_{jl}(E)$ for $s_{1/2}$")
141ax2.set_ylabel(r"$T_{jl}(E)$ for $p$-wave")
142ax3.set_ylabel(r"$T_{jl}(E)$ for $d$-wave")
143
144plt.xlabel(r"$E_{cm}$ [MeV]")
145plt.xlim([0, 5])
(0.0, 5.0)
../../_images/0a6671a5097d9e102913af868d9e0cf559a9f8d72880800fe71ba942a9473bb8.png