Approximating double n-capture

Approximating double n-capture#

We want to approximate the seqeunce \(A(n,\gamma)X(n,\gamma)B\) as \(A(nn,\gamma)B\) by combining the two successive neutron captures into a single rate, assuming equilibrium of nucleus \(X\).

This type of approximation is commonly done in the “aprox” family of networks, for example, approximating the sequence: \({}^{52}\mathrm{Fe}(n,\gamma){}^{53}\mathrm{Fe}(n,\gamma){}^{54}\mathrm{Fe}\).

import pynucastro as pyna
rl = pyna.ReacLibLibrary()

Unapproximated version#

We’ll create a simple network of iron isotopes linked by neutron capture.

lib = rl.linking_nuclei(["fe52", "fe53", "fe54", "n"])
rc = pyna.PythonNetwork(libraries=[lib])
rc.write_network("ncapture.py")
import ncapture
fig = rc.plot(rotated=True, curved_edges=True)
_images/d1db3d9b30f4402df2f702b87fa5342c1975f356777bd9a00a10d091429e961b.png

Now we’ll integrate it, starting with a mix of \({}^{52}\mathrm{Fe}\) and \(n\).

import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
rho = 1.e9
T = 3.e9

X0 = np.zeros(ncapture.nnuc)
X0[ncapture.jn] = 0.5
X0[ncapture.jfe52] = 0.5
Y0 = X0 / ncapture.A
tmax = 1.e-5
sol = solve_ivp(ncapture.rhs, [0, tmax], Y0, method="BDF", jac=ncapture.jacobian,
                dense_output=True, args=(rho, T), rtol=1.e-6, atol=1.e-8)
fig = plt.figure()
ax = fig.add_subplot(111)

for i in range(ncapture.nnuc):
    ax.loglog(sol.t, sol.y[i,:] * ncapture.A[i], label=f"X({ncapture.names[i].capitalize()})")

ax.set_xlim(right=1.e-11)
ax.set_ylim(1.e-6, 1)

ax.legend(fontsize="small")
ax.set_xlabel("t (s)")
ax.set_ylabel("X")
Text(0, 0.5, 'X')
_images/a8f9d05e9a98b7422774939eec1be6300484ed4e53f35a2f12ac23c243ee1a11.png

We see that the long term evolution is that all the iron winds up as \({}^{54}\mathrm{Fe}\).

Approximating the double n capture#

We can use the helper function create_double_neutron_capture() to create a pair (forward and reverse) of ApproximateRates that approximate out the intermedia nucleus:

rf, rr = pyna.rates.create_double_neutron_capture(rl, pyna.Nucleus("fe52"), pyna.Nucleus("fe54"))
rf
Fe52 + n + n ⟶ Fe54 + 𝛾

We can see what rates this carries internally:

rf.hidden_rates
[Fe52 + n ⟶ Fe53 + 𝛾, Fe53 + n ⟶ Fe54 + 𝛾, Fe54 ⟶ n + Fe53, Fe53 ⟶ n + Fe52]

Tip

Alternately, we could use the make_nn_g_approx() method on the PythonNetwork once we create it.

Now we’ll build a new network with just these approximate rates:

rc2 = pyna.PythonNetwork(rates=[rf, rr])
rc2.write_network("ncapture_approx.py")
import ncapture_approx
fig = rc2.plot(rotated=True, curved_edges=True)
_images/17ede72388e86e48a24b04728498bad670326219fa4ba5a5b494cd515242e59e.png
rho = 1.e9
T = 3.e9

X0 = np.zeros(ncapture_approx.nnuc)
X0[ncapture_approx.jn] = 0.5
X0[ncapture_approx.jfe52] = 0.5
Y0 = X0 / ncapture_approx.A
tmax = 1.e-5
approx_sol = solve_ivp(ncapture_approx.rhs, [0, tmax], Y0, method="BDF", jac=ncapture_approx.jacobian,
                       dense_output=True, args=(rho, T), rtol=1.e-6, atol=1.e-8)
fig = plt.figure()
ax = fig.add_subplot(111)

for i in range(ncapture_approx.nnuc):
    ax.loglog(approx_sol.t, approx_sol.y[i,:] * ncapture_approx.A[i],
              label=f"X({ncapture_approx.names[i].capitalize()})")

ax.set_xlim(right=1.e-11)
ax.set_ylim(1.e-6, 1)

ax.legend(fontsize="small")
ax.set_xlabel("t (s)")
ax.set_ylabel("X")
Text(0, 0.5, 'X')
_images/94d58472e1575cd71108ac44092152470f11517a42a8b33a345344495792d7ea.png

Comparison#

Finally, let’s plot the nuclei in common from both nets together

fig = plt.figure()
ax = fig.add_subplot(111)

for i in range(ncapture_approx.nnuc):
    ax.loglog(approx_sol.t, approx_sol.y[i,:] * ncapture_approx.A[i],
              linestyle=":", color=f"C{i}")

    idx = ncapture.names.index(ncapture_approx.names[i])
    ax.loglog(sol.t, sol.y[idx,:] * ncapture.A[idx],
              label=f"X({ncapture.names[idx].capitalize()})",
              linestyle="-", color=f"C{i}")

ax.legend()
ax.set_xlim(right=1.e-11)
ax.set_ylim(1.e-6, 1)
(1e-06, 1)
_images/d47f494a1ae80eed1b341c1d6507c3d0d107ffe7e73439c0b513ceff8f9069de.png

Here the dotted line is the approximate version. We see that the \({}^{52}\mathrm{Fe}\) is consumed at the same rate. The approximate net produces \({}^{54}\mathrm{Fe}\) faster simply because there is no intermediate \({}^{53}\mathrm{Fe}\) in the network.