This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org
Viv Python

← Posts

demoAINuclear physics

Skyrme Hartree-Fock of oxygen-16

The ground state of O from the SLy5 Skyrme functional, solved on a radial mesh at two spacings and extrapolated. The binding energy comes out 8.0250 MeV per nucleon and the charge radius 2.7993 fm; skyrme_rpa, the published code of Colò et al. (2013), gives 8.0261 MeV and 2.7991 fm in its own test run with the same force, and the six single-particle energies agree with it to 3 keV.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • Explore

    Run it and step through what each part did, with the code, values and plots beside it.

A nucleus is up to a few hundred protons and neutrons (sixteen here) held together by the strong force, which has no simple closed form. Nuclear density functional theory replaces it with an energy that depends only on a few local densities: the number density of neutrons () and protons (), their kinetic-energy densities , and their spin-orbit densities . Skyrme's functional is the oldest of these, with about ten parameters fitted to nuclear data. Minimizing the energy gives each nucleon a Schrödinger equation (the second equation above) with a position-dependent effective mass , a central potential and a spin-orbit field , all computed from the densities. That makes the problem self-consistent, and the program solves it by iteration: densities, then fields, then orbitals, then new densities.

O has 8 protons and 8 neutrons, which fill the , and shells of each, so it is spherical and every orbital is the lowest of its block. The force is SLy5 (Chabanat et al., Nucl. Phys. A 643, 441 (1998)), with the parameters and conventions of skyrme_rpa (G. Colò, L. Cao, N. Van Giai and L. Capelli, Comput. Phys. Commun. 184, 142 (2013)), whose distribution includes a Hartree-Fock run of O with SLy5 as its test case. That output file is the published reference here. posts/refs/skyrme-hartree-fock-of-oxygen-16.py copies its numbers, describes rerunning the program, and holds a numpy twin of this solver that diagonalizes each block densely.

The discretization

Each orbital is , and on a mesh , , the radial equation for is a symmetric tridiagonal matrix:

The first term uses at the half points, which keeps the matrix symmetric; the term comes from writing the equation for rather than . Each block's lowest eigenvector comes from inverse iteration: three solves of by the tridiagonal (Thomas) algorithm per pass, starting from the previous pass's vector, with the shift 0.1 MeV below the previous orbital energy. On the first pass the eigenvalue itself is found first, by bisection on the Sturm count (the number of negative pivots of is the number of eigenvalues below ), so the iteration starts on the right state. Derivatives of the densities are centered differences with second-order one-sided ones at the ends, and integrals are trapezoidal. The protons also feel the Coulomb field of their own density, with exchange in the Slater approximation.

Every piece is second order in , so the program solves the problem at and fm in a 15 fm box and extrapolates, .

Two meshes and the extrapolation

The iteration starts from a Woods-Saxon density and mixes half of each new density into the old one until the energy changes by less than MeV, which takes 38 passes on each mesh. On both meshes the energy per nucleon, the three radii and the six orbital energies match the numpy twin to ; the tests allow . Going from to fm moves the energy per nucleon by 0.016 MeV and the charge radius by 0.002 fm.

Printed

res_c: [-8.04654, 2.68099, 2.65585, 2.79668, -36.1866, -20.6314, -14.4236, -32.3899, -17.153, -11.0744, 38]
res_f: [-8.03037, 2.683, 2.65789, 2.79861, -36.1494, -20.616, -14.4267, -32.3568, -17.1412, -11.0806, 38]
BE_per_A: 8.02498
r_charge: 2.79926
twin_diff: 6.14952e-09
mesh_shift_e: 0.0161722
mesh_shift_rc: 0.00193025

Tests 3 of 3 pass

  • on both meshes E/A, the radii and the six orbital energies are the numpy twin's to 1e-7 (passes)
  • the largest difference from the numpy twin is under 7e-9 (passes)
  • going from h = 0.1 to 0.05 fm moves E/A by 0.016 MeV and the charge radius by 0.002 fm (passes)

Against the published run

The extrapolated binding energy is MeV per nucleon, against skyrme_rpa's : the two differ by MeV per nucleon, 18 keV out of 128 MeV. skyrme_rpa's own answer moves by MeV per nucleon between its 0.1 fm and 0.05 fm meshes (the reference script records the rerun), so most of the remaining difference is between the two programs' formulas, not their meshes. The radii agree to fm and the six orbital energies to 3 keV. On the 0.1 fm mesh alone, this program's second-order scheme is off by 0.02 MeV per nucleon, which is why it extrapolates.

The figure shows the converged densities on the fine mesh.

Printed

total_diff_kev: 18.1596
pub_mesh_shift: 0.0001191
coarse_off: -0.0204279
Oxygen-16 with SLy5: neutron and proton densities
neutronsprotons
00.020.040.060.080123456r (fm)density (fm−3)

Tests 6 of 6 pass

  • extrapolated E/A is skyrme_rpa's -8.0261107 MeV to 2e-3 MeV (passes)
  • extrapolated proton, neutron and charge radii are skyrme_rpa's 2.6836, 2.6585 and 2.7991 fm to 3e-4 fm (passes)
  • the six extrapolated orbital energies are skyrme_rpa's to 3 keV (passes)
  • the extrapolated energy is 18 keV from skyrme_rpa's, out of 128 MeV (passes)
  • skyrme_rpa's E/A moves by 1.2e-4 MeV between its 0.1 fm and 0.05 fm meshes (passes)
  • on the 0.1 fm mesh alone the energy per nucleon is off by 0.02 MeV (passes)

Checked when the site was built: 9 of 9 tests passed, in 3.17 s. Download 2026-09-25-skyrme-hartree-fock-of-oxygen-16.viv