codexnuclear-magic-shell-capacities.py
nuclear-magic-shell-capacities.py
"""Draw state capacities for a chosen spherical nuclear level scheme.
Python 3.14, matplotlib 3.10.7. Run from _media with MPLBACKEND=Agg.
Orbital grouping is illustrative, not a computed energy spectrum or a universal
ordering. Integers preceding orbital letters count radial levels from one.
"""
from pathlib import Path
import matplotlib.pyplot as plt
# (radial index, orbital letter, twice j); all states count ONE species.
GROUPS = [
[(1, 's', 1)],
[(1, 'p', 3), (1, 'p', 1)],
[(1, 'd', 5), (2, 's', 1), (1, 'd', 3)],
[(1, 'f', 7)],
[(2, 'p', 3), (1, 'f', 5), (2, 'p', 1), (1, 'g', 9)],
[(1, 'g', 7), (2, 'd', 5), (2, 'd', 3), (3, 's', 1), (1, 'h', 11)],
[(1, 'h', 9), (2, 'f', 7), (2, 'f', 5), (3, 'p', 3), (3, 'p', 1), (1, 'i', 13)],
]
def main():
plt.rcParams.update({'font.size': 12, 'font.family': 'DejaVu Sans'})
fig, ax = plt.subplots(figsize=(11.6, 6.9), dpi=100, facecolor='white')
fig.subplots_adjust(left=0.025, right=0.985, top=0.84, bottom=0.14)
ax.set(xlim=(0, 12), ylim=(-0.65, 6.7))
ax.axis('off')
ax.text(0.1, 6.55, 'Levels in the group (capacity below each level)', weight='bold')
ax.text(8.95, 6.55, 'Added', ha='center', weight='bold')
ax.text(10.7, 6.55, 'Filled total', ha='center', weight='bold')
total = 0
for row, group in enumerate(GROUPS):
y = 5.9 - row
color = '#156c9a' if row % 2 == 0 else '#276e51'
ax.axhspan(y - 0.43, y + 0.43, color='#f2f5f8', zorder=0)
for k, (n, letter, twice_j) in enumerate(group):
x = 0.73 + 1.34 * k
ax.text(x, y + 0.10, rf'${n}{letter}_{{{twice_j}/2}}$', ha='center', fontsize=15, color=color)
ax.text(x, y - 0.24, str(twice_j + 1), ha='center', fontsize=12)
if k + 1 < len(group):
ax.text(x + 0.67, y - 0.24, '+', ha='center', color='#737d88')
added = sum(twice_j + 1 for _, _, twice_j in group)
total += added
ax.text(8.95, y - 0.02, f'+{added}', ha='center', fontsize=15)
ax.annotate('', xy=(10.05, y - 0.02), xytext=(9.45, y - 0.02),
arrowprops={'arrowstyle': '->', 'color': '#737d88'})
ax.text(10.7, y - 0.02, str(total), ha='center', va='center', color=color,
fontsize=20, weight='bold', bbox={'boxstyle': 'round,pad=0.2', 'fc': 'white', 'ec': color})
fig.suptitle('From orbital capacities to traditional magic numbers', y=0.97, fontsize=18)
fig.text(0.5, 0.895, r'One species: each $nlj$ level holds $2j+1$ neutrons OR $2j+1$ protons', ha='center', fontsize=14)
fig.text(0.5, 0.065, 'Chosen grouping; rows are not an energy axis. Level ordering and physical gaps depend on the nucleus.', ha='center', fontsize=11)
fig.text(0.5, 0.025, 'Capacities follow from state counting; strong spin–orbit coupling helps explain why the groups change.', ha='center', fontsize=11, color='#505967')
fig.savefig(Path(__file__).stem + '.png', facecolor='white')
plt.close(fig)
if __name__ == '__main__':
main()