Multigroup neutron diffusion solver for 1-D and 2-D geometries. The solvers are written in C++17 and exposed to Python through pybind11; the Python package adds cross-section builders, meshes and core layouts, kinetics data, post-processing and a discretization-error estimator.
Documentation: https://bwhewe-13.github.io/NeutronDiffusion/
- k-eigenvalue, fixed-source and time-dependent solvers on 1-D slab, cylinder and sphere meshes, 2-D structured XY and RZ meshes, and 2-D unstructured polygonal meshes - nine solvers, all built and run the same way
- Matrix-free throughout: tridiagonal (Thomas) solves inside a Gauss-Seidel group sweep on structured meshes, and a cell-centered finite volume scheme with a deferred non-orthogonal correction on unstructured ones, so triangles and skewed cells stay second order
- Robin boundary conditions on every edge (vacuum, reflective, albedo), boundary tags and periodic boundaries on unstructured meshes
- Delayed neutron precursors, theta-weighted time differencing up to Crank-Nicolson, and mid-transient perturbations
- Gmsh import, material assignment separate from the geometry, and preset Cartesian and hexagonal cores with symmetry sectors
- Published two-group benchmarks (Ringhals, TWIGL, IAEA, BIBLIS) and a transport-to-diffusion cross-section conversion
- Post-processing (power normalization, reaction rates, peaking factors), adjoint cross sections, and single-mesh error estimates by the method of nearby problems
- numpy in and out, Python convergence warnings, and Ctrl-C during a solve
pip install ndiffusionWheels are published for Linux (x86_64, aarch64), macOS (Intel, Apple silicon) and Windows, for Python 3.9 to 3.14. Elsewhere pip builds from source, which needs a C++17 compiler.
For development, pip install -e ".[dev]" installs everything CI runs; re-run it
after editing C++ sources to rebuild the extension. See the
installation guide
for the optional extras.
A bare uranium sphere, one energy group, zero flux at the surface:
import numpy as np
import ndiffusion as nd
m = nd.Materials()
m.n_mat = 1
m.n_groups = 1
m.D = [3.850204978408833]
m.removal = [0.1532]
m.scatter = [0.0]
m.chi = [1.0]
m.nusigf = [0.1570]
cells = 50
solver = nd.KEigenSolver(
mats = m,
medium_map = [0] * cells,
edges_x = np.linspace(0.0, 100.0, cells + 1),
geom = nd.Geometry.Sphere,
bc = [nd.BoundaryCondition(A=1.0, B=0.0)],
max_outer = 500,
)
result = solver.solve()
print(f"keff = {result.keff:.8f}") # -> 1.00000475result.flux is a numpy array of shape (n_cells, n_groups). The
quickstart goes on
to 2-D structured and unstructured problems, and examples/ has runnable scripts
for each solver family.
- User guide - meshes, cross sections, boundary conditions, solvers, kinetics, post-processing and verification
- Examples and benchmarks
- Theory - the equations, the discretizations and the iterative methods
- Python API and C++ API
- Roadmap and changelog
pip install -e ".[dev]"
pytestWithout the dev extra, parts of the suite are skipped rather than failing; run
pytest -rs to see what was skipped.
If ndiffusion contributes to published work, please cite it:
@software{whewell_ndiffusion,
author = {Whewell, Ben},
title = {ndiffusion: multigroup neutron diffusion in {C++} and {Python}},
publisher = {Zenodo},
doi = {10.5281/zenodo.23212416},
url = {https://github.com/bwhewe-13/NeutronDiffusion},
}That DOI always resolves to the latest release; each version also has its own (see Citing).
MIT - see LICENSE.
