Working with the Reaction helper¶
This notebook demonstrates the convenience methods exposed by Reaction for building reaction systems and combining model ingredients. It is especially useful if you want a simpler interface than wiring every component together by hand.
1import jitr.reactions as rx
2import jitr.utils.constants as constants
3import jitr.utils.mass as mass
1mass.mass_models() # default is ame2020
['BMA',
'UNEDF2',
'BCPM',
'dz31',
'hfb31',
'ws4rbf',
'FRDM2012',
'SLY4',
'SKP',
'ame2020',
'SKM',
'UNEDF0',
'D1M',
'SVMIN',
'UNEDF1',
'HFB24']
1mass_model = "ame2024"
2rxn = rx.Reaction(
3 target=(48, 20),
4 projectile=(1, 1),
5 product=(1, 0),
6 residual=(48, 21),
7 mass_kwargs={"model": "ame2020"},
8)
9print(rxn)
48-Ca(p,n)48-Sc
1from IPython.display import Math, display
2
3display(Math(rxn.reaction_latex))
\[\displaystyle ^{48} \rm{Ca}(p,n)^{48} \rm{Sc}\]
1print(f"Q-value: {rxn.Q:1.4f} MeV")
Q-value: -0.5036 MeV
1# 35 MeV proton beam incident on 48Ca
2Elab = 35
3entrance_kinematics = rxn.kinematics(Elab)
4entrance_kinematics
ChannelKinematics(Elab=35, Ecm=34.27976496842483, mu=np.float64(951.4664814091528), k=np.float64(1.28287146975579), eta=np.float64(0.5485537668413036))
1# the excitation energy of the state in 48Sc that is the isobaric analog to the 48Ca G.S.s
2# (above the 48Sc G.S.)
3# from https://www.sciencedirect.com/science/article/pii/S0092640X97907403
4Ex_IAS = 6.675
5exit_kinematics = rxn.kinematics_exit(
6 entrance_kinematics, residual_excitation_energy=Ex_IAS
7)
8exit_kinematics
ChannelKinematics(Elab=27.671337282951978, Ecm=27.10121706917766, mu=np.float64(945.9090824120628), k=np.float64(1.1394155566936675), eta=np.float64(0.0))
1import numpy as np
2
3assert np.isclose(exit_kinematics.Ecm, 27.101217)
1print(
2 f"proton mass: {rxn.projectile.m0:1.4f} MeV/c^2 ~ {constants.MASS_P:1.4f} MeV/c^2"
3)
proton mass: 938.2717 MeV/c^2 ~ 938.2717 MeV/c^2
This small difference will be the result of some of the differences below when manually calculating vs using the mass model passed into Reaction
1print(
2 f"target mass: {rxn.target.m0:1.4f} MeV/c^2 = {mass.mass(*rxn.target)[0]:1.4f} MeV/c^2"
3)
target mass: 44657.2720 MeV/c^2 = 44657.2720 MeV/c^2
1print(
2 f"reaction threshold: {rxn.threshold:1.4f} MeV = proton separation energy "
3 f"in {rxn.target}: {mass.proton_separation_energy(*rxn.target)[0]:1.4f} MeV"
4)
reaction threshold: 15.8014 MeV = proton separation energy in 48-Ca: 15.8014 MeV
1rxn.compound_system
49-Sc
1print(
2 f"threshold for {rxn.projectile}-removal from {rxn.compound_system}: {rxn.compound_system_threshold:1.4f} MeV = "
3 f"proton separation energy in {rxn.compound_system}:"
4 f" {mass.proton_separation_energy(*rxn.compound_system)[0]:1.4f} MeV"
5)
threshold for p-removal from 49-Sc: 9.6261 MeV = proton separation energy in 49-Sc: 9.6261 MeV
1print(
2 f"{rxn.target} proton Fermi energy: {rxn.Ef:1.4f} MeV = "
3 f"{rxn.target.Efp:1.4f} MeV = "
4 f"{mass.proton_fermi_energy(*rxn.target)[0]:1.4f} MeV"
5)
48-Ca proton Fermi energy: -12.7138 MeV = -12.7138 MeV = -12.7138 MeV
1rxn = rx.Reaction(
2 target=(50, 20),
3 projectile=(4, 2),
4 product=(2, 1),
5 mass_kwargs={"model": "ame2020"},
6)
1rxn
50-Ca(alpha,d)52-Sc
1display(Math(rxn.reaction_latex))
\[\displaystyle ^{50} \rm{Ca}(\alpha,d)^{52} \rm{Sc}\]
1print(f"Q value: {rxn.Q:1.4f} MeV")
Q value: -9.7765 MeV
1rxn.compound_system
54-Ti
1print(
2 f"threshold for {rxn.projectile} from compound system: {rxn.compound_system_threshold:1.4f} MeV = "
3 f"{rxn.projectile} separation energy in {rxn.compound_system}:"
4 f" {rx.cluster_separation_energy(rxn.compound_system, rxn.projectile):1.4f} MeV"
5)
threshold for alpha from compound system: 8.5795 MeV = alpha separation energy in 54-Ti: 8.5795 MeV
Mix mass models when needed¶
For example some of the models don’t have some light particle masses, but ame2020 doesn’t have a 60-Ca mass. We can use the Nucleus class to do this.
1nuc = rx.Nucleus(3, 1)
2display(Math(f"^{nuc.A}_{nuc.Z}" + nuc.latex()))
3print("=====================")
4
5for m in mass.__MASS_MODELS__:
6 print(f"{m:8}: {mass.mass(*nuc, model=m)[0]:1.6f}")
\[\displaystyle ^3_1t\]
=====================
BMA : nan
UNEDF2 : nan
BCPM : nan
dz31 : nan
hfb31 : nan
ws4rbf : nan
FRDM2012: nan
SLY4 : nan
SKP : nan
ame2020 : 2808.921118
SKM : nan
UNEDF0 : nan
D1M : nan
SVMIN : nan
UNEDF1 : nan
HFB24 : nan
1nuc = rx.Nucleus(60, 20)
2display(Math(nuc.latex()))
3print("=====================")
4for m in mass.__MASS_MODELS__:
5 print(f"{m:8}: {mass.mass(*nuc, model=m)[0]:1.6f}")
\[\displaystyle ^{60} \rm{Ca}\]
=====================
BMA : 55887.086308
UNEDF2 : 55891.426141
BCPM : 55883.586141
dz31 : 55891.798141
hfb31 : 55889.466141
ws4rbf : 55891.702141
FRDM2012: 55890.176141
SLY4 : 55885.506141
SKP : 55882.246141
ame2020 : nan
SKM : 55878.546141
UNEDF0 : 55885.826141
D1M : 55891.736141
SVMIN : 55885.796141
UNEDF1 : 55891.066141
HFB24 : 55890.236141
1rxn = rx.Reaction(
2 target=rx.Nucleus(60, 20, mass_kwargs={"model": "UNEDF2"}),
3 projectile=(2, 1),
4 product=(3, 1),
5 mass_kwargs={"model": "ame2020"}, # AME2020 for everything else
6)
7rxn
60-Ca(d,t)59-Ca
1rxn.Q
3.2259119999994255
1entrance_kinematics = rxn.kinematics(240)
2entrance_kinematics
ChannelKinematics(Elab=240, Ecm=232.2075441296029, mu=np.float64(2027.0754691804402), k=np.float64(4.779677811174583), eta=np.float64(0.31367517605122724))