Compare commits

...

373 commits

Author SHA1 Message Date
Satoshi Misumi
852f92780c
Fix M_PI being unavailable where _USE_MATH_DEFINES comes too late (#4023)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-21 15:45:41 +00:00
GuySten
61c8a59cff
Override NJOY default damage energy threshold (#4022)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-20 14:52:30 +00:00
Mazeyar Moeini Feizabadi
05d01274a7
Add analytic tests for ray-traced intersection distances (#4014)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-19 14:49:48 -05:00
Joffrey Dorville
db673b9acb
Automatic C++ doc generation (#3950)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-17 15:47:40 +00:00
GuySten
796ae384b8
Fix not reseting filter_matches corrupt pulse height results (#4019)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-17 13:18:53 +00:00
GuySten
d3bc1669d3
Access element subshell map data only if it has atomic relaxation data (#4020) 2026-07-17 07:40:16 -05:00
Paul Romano
f1fb6721f0
Performance optimizations for shared secondary bank (#4011)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-17 01:25:18 +00:00
Ethan Peterson
c55c578812
Native parametric tokamak source (#3999)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-16 09:54:56 -05:00
Paul Romano
16cde42ff4
Enable parent-nuclide tally breakdowns in R2S calculations (#4013)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-07-16 00:00:42 +03:00
Lewis Gross
243c249533
normalize new_u after periodic crossing to prevent unnormalized direction (#4015)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-15 08:57:53 -05:00
Eden
e783e01471
Add chain parameter to Material.get_activity for half-life data (#3957)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-11 06:18:26 +00:00
Jonathan Shimwell
7256d5046a
extra checks for pixels (#4009)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Jonathan Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-10 15:02:14 +00:00
Paul Romano
216651b69e
Shared secondary bank performance optimizations (#3995) 2026-07-10 09:22:16 -05:00
Paul Romano
7c408f6a10
Replace Ben Forget with John Tramm on technical committee (#4008)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-10 09:48:11 +02:00
Paul Romano
3c3ebba98b
Turn on weight windows if weight_windows_file is specified (#4007)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-09 23:59:33 +00:00
GuySten
e73d8048da
Support cell densities per instances in plots (#4006)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-09 22:45:09 +00:00
Jonathan Shimwell
5203640549
Further input validation for plot methods (#4004) 2026-07-09 16:55:32 -05:00
Paul Romano
3cdb67e50d
Store slice overlap indices in cell ID field (#4002)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-09 11:47:55 +02:00
Paul Romano
8b15ee3915
Add Jon Shimwell to technical committee (#4001)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-08 11:25:21 -05:00
Andrew Davis
8684506269
This fixes compile isuees found with GCC 16.1.1 and FMT version (#4000)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-07 14:58:19 +00:00
viktormai
0c6b3fb835
Overlap detection for plotter (#3969)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-06 17:47:22 +00:00
Paul Romano
3fcb9692be
Make sure output is treated consistently in R2SManager (#3994)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-07-04 22:20:03 -05:00
Matteo Zammataro
e3bc615172
Fix numerical cancellation in RectLattice::distance for large pitch values (#3853)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
Co-authored-by: matteo.zammataro <matteo.zammataro@newcleo.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-03 21:39:17 +00:00
Paul Romano
66359e5dd8
Fix surface tally crash on lattice crossings (#3993)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
2026-07-03 15:52:19 -05:00
Matteo Zammataro
97e04c464a
Add ambient dose coefficients (H*(10)) from ICRP74 (#3256)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: matteo.zammataro <matteo.zammataro@newcleo.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-02 23:51:10 +00:00
Jon Shimwell
df6f94300f
Turn the weight window game off for a zero or negative lower bound (#3990)
Co-authored-by: John Tramm <john.tramm@gmail.com>
Co-authored-by: shimwell <mail@jshimwell.com>
2026-07-02 13:04:02 -05:00
Paul Romano
3247587d49
Ensure photon cross sections are loaded when FileSource contains photons (#3988)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-07-02 11:54:12 -05:00
John Tramm
24fdb84edc
Tally 32-bit Overflow Fix (#3960)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-07-02 11:53:49 -05:00
John Tramm
f01852411d
Random Ray Forward Flux Save in Adjoint Mode (#3962)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:35:27 +02:00
Jonathan Shimwell
d06fdee93a
Preserve user material names in convert_to_multigroup and avoid overwriting material with same name bug fix (#3984)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-06-30 09:38:09 -05:00
GuySten
4d6244d93c
Fix for numpy 2.5.0 (#3981)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-06-24 16:09:16 -05:00
Paul Romano
608a1c3386
Fix several issues related to independent operator depletion (#3977)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-06-23 09:00:47 +02:00
stetsonschott
09ee8308d0
Replaced 'C0' by elemental carbon in `openmc/examples.py'. (#3974)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-06-17 20:33:40 -05:00
GuySten
02eb999af1
fix tmate start only on successful tests (#3954)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
2026-06-08 22:09:25 -05:00
Logan Harbour
998565808e
Use non-deprecated methods for getting libMesh node points (#3963) 2026-06-08 22:07:21 -05:00
Patrick Shriwise
ea6ba328c9
Fix collision track feature for photon transport (#3946)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-06-08 23:37:34 +00:00
Paul Romano
4f6a25e00a
Introduce new C API function for slice plots (#3806)
Some checks are pending
Tests and Coverage / filter-changes (push) Waiting to run
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Blocked by required conditions
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Blocked by required conditions
Tests and Coverage / coverage (push) Blocked by required conditions
Tests and Coverage / Check CI status (push) Blocked by required conditions
dockerhub-publish-develop / main (push) Waiting to run
dockerhub-publish-develop-dagmc-libmesh / main (push) Waiting to run
dockerhub-publish-develop-dagmc / main (push) Waiting to run
dockerhub-publish-develop-libmesh / main (push) Waiting to run
2026-06-08 21:08:08 +00:00
Paul Romano
db322f2c5d
Add section in depletion user's guide about comparing to other codes (#3955) 2026-06-08 18:22:32 +00:00
EdenRochmanSharabi
111eb77066
Implement SphericalMesh.get_indices_at_coords (#3919)
Some checks failed
Tests and Coverage / filter-changes (push) Has been cancelled
Tests and Coverage / Python 3.13 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14 (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.14t (omp=n, mpi=n, dagmc=, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=n, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=n, libmesh=n, event=n (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=n, dagmc=, libmesh=, event=y (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=y, libmesh=, event= (push) Has been cancelled
Tests and Coverage / Python 3.12 (omp=y, mpi=y, dagmc=, libmesh=y, event= (push) Has been cancelled
Tests and Coverage / coverage (push) Has been cancelled
Tests and Coverage / Check CI status (push) Has been cancelled
dockerhub-publish-develop / main (push) Has been cancelled
dockerhub-publish-develop-dagmc-libmesh / main (push) Has been cancelled
dockerhub-publish-develop-dagmc / main (push) Has been cancelled
dockerhub-publish-develop-libmesh / main (push) Has been cancelled
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-30 06:18:09 +00:00
Jonathan Shimwell
219d82726f
Allow tracklength estimator for neutron heating (#3915)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-30 06:10:05 +00:00
hugo-barthod
2dd5322fee
Fix undefined variable in openmc.mgxs.library (scatt_mgxs) (#3943)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-30 05:35:31 +00:00
Bor Kos
46d8896132
Pulsed Height Tally in mixed neutron-gamma fields (#3937)
Co-authored-by: Bor Kos <bor.kos@bakerhughes.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-30 03:25:38 +00:00
Jon Shimwell
ddabe1c8c5
Avoid storing inconsistent sum/sum_sq on summed D1S tallies (#3949)
Co-authored-by: shimwell <mail@jshimwell.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-30 03:25:22 +00:00
Paul Romano
1914e3eefa
Support endf.Material in from_endf methods (#3932) 2026-05-29 21:53:45 -05:00
Ahnaf Tahmid Chowdhury
dfb6c5699c
Modernize CMake packaging (#3653)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-21 20:33:56 +00:00
Patrick Shriwise
7d09a12606
DAGMC Cell Override Updates (#3888)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-20 21:43:21 +00:00
Patrick Shriwise
66497e76b1
Support writing of hex elements to VTKHDF format. (#3623)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-05-20 14:01:21 -05:00
Hridoy Kabiraj
3c7a030d43
Guard average molar mass and validate materials depletion inputs (#3941) 2026-05-20 13:49:00 -05:00
John Tramm
0169fd9226
Shared Secondary Particle Bank (#3863)
Co-authored-by: John Tramm <jtramm@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
Co-authored-by: Copilot <copilot@github.com>
2026-05-19 23:23:10 -05:00
charliesheh
beed56e6ee
Check for missing thread count argument for -s/--threads (#3940) 2026-05-18 13:35:56 -05:00
Hridoy Kabiraj
195dff6d1d
Fix missing volume checks in material activity/decay heat (#3939) 2026-05-18 09:20:59 -05:00
Paul Romano
d56cda2544
Implement DecaySpectrum distribution type and utilize in R2S (#3930)
Co-authored-by: Copilot <copilot@github.com>
2026-05-08 20:53:12 -05:00
Paul Romano
f3e1066d46
Include mass_attenuation.h5 in package data (#3936) 2026-05-07 23:50:23 +00:00
Jonathan Shimwell
e542b2f035
Allow Mesh.volumes property for 1D and 2D RegularMesh (#3914) 2026-05-06 10:07:35 -05:00
Jack Fletcher
368ea069ca
Local adjoint source for Random Ray (#3717) 2026-04-28 16:10:03 -05:00
Paul Romano
1116c4bdc0
Support multiple meshes in R2S calculations (#3860) 2026-04-28 10:02:08 -04:00
Travis L.
806fb4ce77
Clean up MCPL references (#3927) 2026-04-27 09:40:44 -05:00
Perry
2d5c50080c
Allow the use of substeps for CRAM (#3908)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-22 18:24:34 -05:00
Perry
1f7ac4215f
Clip negative atom densities that result from CRAM (#3879)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-21 20:24:53 +00:00
Ethan Peterson
a1df5842e0
Remove self loops from spontaneous fission decay mode (#3907)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-21 16:47:40 +00:00
Lorenzo Chierici
e431d49bec
Add reactivity control to coupled transport-depletion analyses (#2693)
Co-authored-by: Andrew Johnson <drewejohnson@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-20 07:13:53 -05:00
Luke Labrie-Cleary
36e70d8efc
Add Arch Linux User Repository (AUR) installation instructions to documentation (#3921)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-18 16:01:09 +00:00
Paul Romano
fd1bc26af0
Pin NJOY version in Dockerfile (#3920) 2026-04-09 23:13:18 +03:00
Paul Romano
1eb368bbd2
Pin NJOY version in CI to 2016.78 (#3917) 2026-04-09 09:31:27 +02:00
Paul Romano
23e8a11102
Update versions of several GHA Actions (#3913) 2026-04-05 14:04:34 -05:00
Jonathan Shimwell
542f949fa0
Use local variable to avoid attribute lookup in form_rxn_matrix loop (#3884)
Co-authored-by: Perry <yrrepy@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-04 20:53:50 +00:00
GuySten
efc542825e
Add the ability to tally microscopic cross sections in void materials with tracklength estimator (#3771)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-04 20:32:51 +00:00
Ethan Peterson
60d1dfba7f
Refactor form_matrix method on depletion chain class (#3892)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-03 21:27:39 +00:00
John Tramm
b215f13218
RAG search tool for agents (#3861)
Co-authored-by: John Tramm <jtramm@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 16:18:19 -05:00
Jonathan Shimwell
9ff50499e1
Adding per m3 to material functions (#3912)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-03 00:00:02 +00:00
bessemoa
df985e10b3
Add from_bounding_box classmethod to structured mesh classes (#3903)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-02 22:51:33 +00:00
Jonathan Shimwell
ca22a5174a
adding pdf to read the docs (#3893) 2026-04-02 17:01:30 -05:00
GuySten
d9b30bbbd5
Approximate multigroup velocity (#3766)
Co-authored-by: Adam Nelson <1037107+nelsonag@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-04-02 16:59:02 +00:00
Md. Ariful Islam
97d9a839c2
Fix MPI depletion hang (#3910) 2026-04-02 11:30:09 -05:00
April Novak
8223099ed9
All reduce to print correct number of surface source particles (#3901) 2026-03-26 12:35:12 -05:00
GuySten
6cd39073b3
Fix surface tally when crossing lattice (#3895) 2026-03-23 10:16:59 -05:00
Paul Romano
3ce6cbfdda
Add fusion_neutron_spectrum to openmc.stats module (#3862) 2026-03-17 22:10:18 +01:00
itay-space
1578698129
Implement angular PDF evaluation for angle-energy distributions (#3550)
Co-authored-by: Your Name <you@example.com>
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
Co-authored-by: Eliezer214 <110336440+Eliezer214@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-14 23:58:17 +02:00
Marco De Pietri
bc9c31e0f9
get indices for rectilinear meshes (#3876)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-14 04:19:51 +00:00
Paul Wilson
dd6d31bfae
Add properties to settings w/ documentation, c++ loading of filename, and python round-trip test (#3808)
Co-authored-by: Patrick C Shriwise <pshriwise@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-13 21:40:52 +00:00
AlvaroCubi
4bda85f17e
Allow StepResult.get_material to accept integer material ID (#3872)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-12 15:04:42 -05:00
Christopher Ashe
c44d2f0b43
Allow groups to be passed as sequence of floats in convert_to_multigroup (#3873)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-12 19:47:47 +00:00
Paul Romano
27522fe851
Improve review skill instructions for determining PR context (#3875) 2026-03-12 14:27:00 -05:00
CoronelBuendia
387b41ab65
Change plotting docstring to specify integer RGB values (#3868) 2026-03-12 12:35:10 -05:00
Eshed Magali
ba94c58230
Closing the stdout file descriptor when finished (#3864) 2026-03-11 16:50:58 +00:00
Amanda Lund
1dc4aa9882
Add setting to optionally disable atomic relaxation (#3855)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-10 04:00:10 +00:00
Paul Romano
908e63115a
Add reusable reviewing-openmc-code skill and Copilot Review agent (#3842)
Co-authored-by: John Tramm <john.tramm@gmail.com>
2026-03-05 21:40:36 -06:00
GuySten
be4148ad0d
Refactor Ray class into its own file (#3845)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-06 01:07:42 +00:00
Paul Romano
6f72619729
Fix include guard in output.h (#3856) 2026-03-05 23:29:36 +00:00
John Tramm
533f09defd
Enable CMake "compile_commands.json" Output (#3854)
Co-authored-by: John Tramm <jtramm@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-05 23:20:54 +00:00
Paul Romano
dbfd6387b2
Fix two docstrings that should have r prefix (#3851) 2026-03-05 07:37:47 +02:00
Ethan Peterson
2bd06660c5
Parallelize sampling external sources and threadsafe rejection counters (#3830)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-04 14:36:43 -06:00
GuySten
0ab46dfa35
Fix cell data parsing (#3848) 2026-03-04 06:56:49 -06:00
GuySten
70be650003
Implement surface flux tallies (#3742)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-04 14:17:48 +02:00
Patrick Shriwise
b796afb591
Correction to surface normal determination in SolidRayTrace plots (#3846) 2026-03-04 14:10:54 +02:00
Marco De Pietri
53d98ce71a
Add method on Material for computing photon contact dose rate (#3700)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-03-03 15:48:56 +00:00
Paul Romano
49b896b0eb
Enable "hybrid" tallies in get_microxs_and_flux (#3831) 2026-03-02 22:06:52 -05:00
GuySten
823b4c96c9
Speed up depletion with transfer rates (#3839) 2026-03-02 06:53:20 -06:00
Paul Romano
83a7b36add
Speed up Docker build (#3841)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
2026-03-01 21:52:51 +02:00
Paul Romano
b3788f11e1
Use clang-format version 18 for CI format checks (#3840) 2026-02-27 13:56:00 +02:00
Micah Gale
1d9a8f542b
Add Python 3.14 to testing matrix and drop Python 3.11 (#3642)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-26 18:18:04 -06:00
Paul Romano
3b5ac08bfb
Skip DAGMC lost particles test (#3836) 2026-02-26 11:26:39 -06:00
Paul Romano
17d4164242
Update copyright to 2026 (#3834) 2026-02-26 08:14:28 +00:00
GuySten
322b741fde
Support Mixture distributions in combine_distributions (#3784)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-26 07:30:08 +00:00
Jonathan Shimwell
6050c789ca
making use of endf.get_evaluations (#3819)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-26 03:14:44 +00:00
GuySten
3ba8a9f078
Correctly score pulse height tally when no cell filter is present (#3821)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-26 02:44:17 +00:00
Jonathan Shimwell
8081815b99
Add RegularMesh.get_indices_at_coords method (#3824)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-26 02:19:02 +00:00
John Tramm
54c8e3d6eb
Speedup CI and Improve Reproducibility Across Compilers (#3823)
Co-authored-by: John Tramm <jtramm@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-25 17:12:18 -06:00
GuySten
2a38dc11ec
Do not fail CI when coveralls.io is not available. (#3835) 2026-02-25 15:04:00 -06:00
GuySten
c0427dd40a
Resolve conflict with weight windows and global russian roulette (#3751)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2026-02-25 14:01:33 -06:00
Patrick Shriwise
5a85bd92f2
C++ formatting suggestions on PRs (#3829) 2026-02-25 11:08:04 -06:00
Jonathan Shimwell
3ff6b59a49
Allow Mesh.from_domain to use bounding boxes directly (#3828) 2026-02-24 23:44:30 -06:00
Paul Romano
e130701f10
Fix MeshFilter.get_pandas_dataframe to handle all mesh types (#3817) 2026-02-24 07:35:23 +00:00
Vitaly Mogulian
8c24c1c064
Modify the plotter ray tracing for its utilization in estimators (#3816)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-24 06:46:21 +00:00
GuySten
83a30f6860
Support arbitrary symmetry axis for CylindricalIndependent class (#3474)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-21 20:00:36 +00:00
Paul Romano
139907c955
Implement tally filter for filtering by reaction (#3809) 2026-02-21 10:17:12 -06:00
Jonathan Shimwell
153281a490
Remove unused class Tabulated2D (#3818) 2026-02-21 15:00:22 +00:00
John Tramm
53ce1910f9
Fix S2 Random Ray Casting Issue (#3825) 2026-02-19 18:25:31 +00:00
Kevin Sawatzky
efefdb17b1
Add more operator overloads in the new Tensor class (#3822) 2026-02-19 11:03:19 -06:00
Kevin Sawatzky
417343c920
Implement S2 directional sampling in the random ray solver (#3811) 2026-02-19 14:25:19 +02:00
GuySten
f007c85a50
Check for positive radii (#3813) 2026-02-19 08:36:12 +00:00
Jonathan Shimwell
6d6b051507
avoid need to set particles and batches for dagmc models when calling convert_to_multigroup (#3801)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-02-18 11:18:05 -06:00
GuySten
d4dc089618
Remove redundant check (#3812) 2026-02-18 09:09:39 -06:00
John Tramm
977ade79a1
Replace xtensor with internal Tensor/View classes (#3805)
Co-authored-by: John Tramm <jtramm@gmail.com>
2026-02-17 09:50:38 -06:00
Kevin Sawatzky
c6ef84d1d5
Set upper and lower interpolation bounds for MGXS data. (#3803) 2026-02-15 23:59:08 +02:00
Paul Romano
a35927aad3
Extend ParticleProductionFilter to support multiple particle types (#3780) 2026-02-13 22:18:29 -06:00
GuySten
7fc5b94877
Store atomic mass in ParticleType. (#3765)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-14 03:14:03 +00:00
Kevin Sawatzky
19c0aafdc6
Fix None values appearing in cross section data generated with Model.autoconvert (#3802) 2026-02-13 18:52:10 +02:00
Patrick Shriwise
bcb9395207
SolidRayTracePlot CAPI (#3789)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-02-13 07:54:27 +02:00
GuySten
b145fdd999
Improve radial crossing checks in SphericalMesh and CylindricalMesh (#3792)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-13 05:10:20 +00:00
Jonathan Shimwell
4e5deed0cc
Using ``_LIBRARY` and `_SUBLIBRARY`` from endf package (#3804) 2026-02-13 03:25:49 +00:00
Paul Romano
8198e6021d
Add truncated normal distribution support (#3761) 2026-02-12 18:25:56 +02:00
Patrick Shriwise
a3426cf833
Fix weight windows regression test (#3798) 2026-02-12 06:30:31 -06:00
Jonathan Shimwell
8d0fe6c71d
making use of sum_rules in endf package (#3799) 2026-02-12 10:11:28 +00:00
Jonathan Shimwell
26b13083f3
Use gnds_name and zam from endf package (#3796) 2026-02-12 05:58:00 +00:00
GuySten
96383fcb2b
More interpolation types in Tabular. (#3413)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-11 21:05:07 +00:00
azim-givron
360ec24b41
Implement vector fitting to replace external vectfit package (#3493)
Co-authored-by: azim_givron <a.givron@naarea.fr>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-02-11 10:00:18 -06:00
Matthew Feickert
44da7022b8
FIX: Remove setuptools from run dependencies (#3794) 2026-02-11 09:21:13 -06:00
Jonathan Shimwell
3f20a5e228
Use several data variables from endf package (#3787) 2026-02-10 06:41:04 -06:00
Jonathan Shimwell
8053111f2d
making use of endf-python package more (#3786)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
2026-02-10 02:08:25 +00:00
Kevin Sawatzky
4f4930b633
Temperature feedback support in the random ray solver. (#3737) 2026-02-09 16:54:59 -06:00
Paul Romano
d0346e94ac
Install parallel h5py with no build isolation (#3782) 2026-02-08 22:22:39 +00:00
Patrick Shriwise
6efc9db7b3
Modifications to C++ plots for interactive raytrace plots (#3776) 2026-02-08 12:11:19 -06:00
GuySten
04bee9c49f
Check that Surface IDs are at least 1 (#3772)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-06 18:44:16 +00:00
Lewis Gross
a632429267
Move distrib (mat, temp, dens) from XML attribute to subelement for better compatibility with very large instance lists (#3774) 2026-02-06 19:32:32 +02:00
Kevin Sawatzky
14acc762bc
C-API bindings for key random ray functions (#3749) 2026-02-06 10:42:32 -06:00
Jonathan Shimwell
8a62a97115
openmc.Tally creation from constructor (#3777) 2026-02-06 10:23:11 -06:00
Jonathan Shimwell
6f625f3dea
Precompute offsets in random ray source update (#3775) 2026-02-06 09:25:14 -06:00
Gavin Ridley
f2c936cf5b
Implement filter for secondary particle production binned by energy (#3453)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-02-05 18:00:03 -06:00
Jonathan Shimwell
1039b5d9ff
Parallelize transpose of scattering matrix for random ray adjoints (#3768) 2026-02-05 10:43:16 -06:00
Paul Romano
3b619d6904
Fix use of length multiplier in several LibMesh methods (#3773) 2026-02-04 22:29:30 -06:00
David Andrs
a22238e069
Fixing compiler warning about VLA (Clang extension) (#3769) 2026-02-04 14:50:38 -06:00
Paul Romano
b41e22f68b
Refactor ParticleType to use PDG Monte Carlo numbering scheme (#3756)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
Co-authored-by: Amanda Lund <alund1187@gmail.com>
2026-02-03 07:23:24 +00:00
Ethan Peterson
fc0d9eec65
Ignore all source build directories that match build* pattern (#3762) 2026-02-02 09:55:45 -06:00
David Andrs
6041ee6ae3
SpatialBox can be constructed via ctor with parameters (#3760) 2026-01-31 17:02:39 -06:00
GuySten
7b4617affb
Fix for plotting model with multi-group cross sections (#3748)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-30 06:10:16 +00:00
Paul Romano
f7a734189a
Optionally compute bounding boxes in Mesh.material_volumes (#3731) 2026-01-29 09:20:48 +02:00
GuySten
008d584607
Warn users when setting undefined attributes in ``openmc.Settings`` (#3746)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-28 08:02:02 +00:00
Jonathan Shimwell
db426b66ca
Materials name persist when running depletion simulation (#3738)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-27 06:06:36 +00:00
Paul Romano
5c502ddb3e
Do not add radioactive Ta180 when calling add_element('Ta') (#3750) 2026-01-26 19:09:58 +02:00
Kevin Sawatzky
3e2f1f521a
Enable fission heating tallies in the random ray solver (#3714) 2026-01-23 10:23:05 -06:00
Olek
73a98b2cc6
Add random_ray_pincell() example model (#3735)
Co-authored-by: John Tramm <john.tramm@gmail.com>
2026-01-23 10:20:25 -06:00
Olek
049a852e52
Random Ray main function and autosetup refactoring (#3733) 2026-01-22 15:21:47 -06:00
GuySten
6b43a298f4
Add n_elements to the MeshBase protocol and deprecate num_mesh_cells (#3745) 2026-01-22 15:04:30 +00:00
GuySten
c5df2bf621
Fix for pandas version 3 (#3743) 2026-01-21 21:57:40 -06:00
GuySten
2691ff8a0f
Fix type hinting and simplify implementation of combine_distributions (#3445)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-21 14:33:30 +00:00
Kevin Sawatzky
5847b0de23
Block restriction of libMesh unstructured mesh tallies (#3694) 2026-01-17 04:01:37 +00:00
Paul Romano
51ea89ccc8
Implement depth-awareness when enforcing precedence between union/intersection operators (#3730)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
2026-01-15 22:23:35 -06:00
GuySten
179048b801
Skip tests on documentation-only changes (#3727)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-14 23:24:07 -06:00
Paul Romano
7861adf53b
Add git branching information to AGENTS.md (#3726) 2026-01-14 13:29:24 -06:00
Kevin Sawatzky
5bce5adabc
Support cell densities in the random ray solver (#3720) 2026-01-14 20:02:17 +02:00
GuySten
7106958e00
Simplify IFP message passing (#3719)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-13 23:25:33 +00:00
GuySten
65e19c1d53
Fix settings io_format documentation. (#3718)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-13 21:31:01 +00:00
Jonathan Shimwell
84a413b130
Speed up reaction rate lookup for FluxCollapseHelper (#3724) 2026-01-13 15:34:07 -05:00
Jack Fletcher
0486e433d2
Source biasing capabilities (#3460)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-12 09:51:12 -06:00
Perry
37e2feb34b
Flux Energy Group Conversion using lethargy-weighted redistribution (#3705)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-01-10 22:04:47 +02:00
Paul Romano
8c8867ea1c
Add --merge-mode-functions=separate to gcovr call in CI (#3716) 2026-01-09 20:05:51 +00:00
GuySten
551bf0730b
Simplify translational periodic boundary conditions (#3697) 2026-01-09 07:56:40 -06:00
Jonathan Shimwell
dfc80c7069
fixing temperatures setting for mgxs (#3712) 2026-01-07 10:54:57 +00:00
Paul Romano
830f075b5c
Update documentation describing HexLattice orientation (#3709) 2026-01-06 22:59:58 +00:00
Jonathan Shimwell
7dceb1d80a
closing mgxs h5py file with context manager (#3707)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2026-01-06 22:59:38 +00:00
Jonathan Shimwell
10f2b7534c
Fixing group names in MGXS HDF5 file (#3708) 2026-01-06 20:18:23 +00:00
GuySten
c7d7fa4613
Fix a bug in rotational periodic boundary conditions (#3692)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-06 13:29:40 +00:00
GuySten
818fd11b18
Simplify rectangular lattice crossing and correctly handle corner checks (#3703)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2026-01-06 09:29:46 +00:00
Jonathan Shimwell
60ddafa9b3
Open dagmc model file within a context manager (#3706) 2026-01-05 22:57:05 +02:00
Paul Romano
9c91bddf04
Migrate to SciPy sparse arrays (#3613) 2026-01-02 13:43:25 +02:00
Paul Romano
932f36f411
Add recognized thermal scattering names for JEFF 4.0 and JENDL 5 (#3693) 2026-01-02 12:31:46 +02:00
GuySten
f08326a9ac
Cache cross sections according to the hash of download-xs.sh script (#3701) 2026-01-01 13:30:09 +02:00
Paul Romano
92d7fdb199
Use min/max position members in C++ BoundingBox class (#3699) 2025-12-30 21:31:53 -06:00
GuySten
3f06a42abb
Refactor get_energy_index to prevent repetition (#3686) 2025-12-23 14:18:59 -06:00
Zoe Prieto
a2fd6cc57e
Support rotation in MeshFilter (#3176)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-12-19 22:56:13 -06:00
GuySten
a230b86128
Fix mcpl dependency in test (#3691) 2025-12-18 15:56:43 +00:00
Jonathan Shimwell
e0eb91b955
using id_map in model.plot for more efficient plotting (#3678) 2025-12-17 22:44:53 +02:00
Patrick Shriwise
d118356638
Use MeshBase method to check replicated. Add header for replicated mesh (#3689) 2025-12-17 06:10:07 +00:00
Kevin Sawatzky
bbfa18d72c
Add a command-line argument for output verbosity (#3680)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-12-12 09:29:43 +00:00
GuySten
1b5033dab4
IFP creates fatal error in all run modes except eigenvalue. (#3681) 2025-12-12 00:21:46 -06:00
GuySten
5c4121efd2
Fix hdf5 source_bank struct size. (#3676) 2025-12-11 22:01:10 -06:00
pranav
a62e754bbb
Add user documentation for DAGMCUniverse synchronization (#3674)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-12-10 21:54:28 -06:00
John Tramm
d09fbc61b5
Copilot Bot File (#3651)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-12-10 09:26:26 -06:00
Lewis Gross
bc1348579f
Generalize RotationalPeriodicBC for X-, Y-, or Z-axis (#3591)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2025-12-10 12:16:04 +02:00
Jonathan Shimwell
a9dc84f75a
Allowing material making from class constructor (#3649)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-12-08 19:43:30 +00:00
Jonathan Shimwell
8e06ed8998
Allowing model.id_map to return overlap ID values (#3669)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-12-08 15:54:37 +00:00
GuySten
9b40ea008e
Read IFP settings only in source/eigenvalue run mode (#3673) 2025-12-08 05:39:48 -06:00
Paul Romano
f70febb05f
Update CITATION.cff file (#3671) 2025-12-06 21:54:30 +00:00
Boris Polania
9b675adda5
Introduce SlicePlot and VoxelPlot to replace the Plot class (#3528)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-12-05 20:17:09 +00:00
Jonathan Shimwell
f28139250a
Fixed plotting issue by scaling source locations with axis units (#3668) 2025-12-05 11:02:26 -06:00
Paul Romano
db8d462738
Allow DistribcellFilter to work with apply_tally_results=True (#3667) 2025-12-04 06:53:04 -06:00
John Tramm
ad5a876bee
Improved automatic MGXS generation for random ray (#3658)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-12-03 07:48:38 +00:00
John Tramm
10706510bf
Random Ray Eigenvalue Flux Normalization Change (#3595)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-02 22:00:32 -06:00
Paul Romano
9e9ab84833
Update C++/CMake policy based on Ubuntu 22.04 (#3666) 2025-12-02 16:11:56 +00:00
GuySten
ef22558f4a
fix a bug in borated_water temperature assignment (#3662) 2025-11-29 16:28:18 +01:00
Paul Romano
7ab92ec142
Fix typo in description of distance_inactive for random ray setting (#3663) 2025-11-28 15:39:08 +00:00
Jonathan Shimwell
dcb7443711
added test to check dagmc name is in xml (#3657) 2025-11-27 10:03:38 -06:00
Paul Romano
27e38e8946
Add release notes for 0.15.3 (#3644) 2025-11-22 23:06:17 +01:00
Paul Romano
d217efa007
Add two MPI barriers in R2S workflow (#3646) 2025-11-20 12:10:04 -06:00
Paul Romano
f544d02e49
Don't write reaction rates in depletion results by default, remove per-stage data for multistage integrators (#3609) 2025-11-19 12:26:57 -05:00
Paul Romano
028f440448
Support MPI parallelism in R2SManager (#3632) 2025-11-19 11:19:27 -06:00
Paul Romano
5c63e0df21
Fix a few warnings, rename add_to_tallies_file (#3639) 2025-11-18 17:57:12 -06:00
Patrick Shriwise
7815d3a680
Fix typo in DAGMC lost particle test (#3634) 2025-11-14 05:27:17 +00:00
Paul Romano
8d618716b5
Avoid multiprocessing Pool when running depletion tests with MPI (#3633) 2025-11-13 17:14:39 -06:00
Michel Saliba
cd5cd35ad9
Addition of a collision tracking feature (#3417)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-13 20:35:33 +00:00
Lorenzo Chierici
50bb0df191
depletion-thermochemistry: Redox control transfer rates (#2783)
Co-authored-by: Gavin Ridley <gavin.keith.ridley@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-12 16:45:48 -06:00
April Novak
4e24c2d933
Update documentation for particle tracks (#3627)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-12 21:59:45 +00:00
Gregoire Biot
2d77544b0c
Adding variance of variance and normality tests for tally statistics (#3454)
Co-authored-by: Ethan Peterson <eepeterson3@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-12 11:41:37 -05:00
Marco De Pietri
e5348d3f62
Avoid divide-by-zero in from_multigroup_flux when flux is zero (#3624)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-12 10:35:07 +00:00
Patrick Shriwise
5c2bfe771e
Write particle states as separate lines in track VTK files. (#3628) 2025-11-12 00:29:19 -06:00
Patrick Shriwise
8cd3911cbe
Reset DAGMC history when reviving from source. (#3601)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-12 06:01:18 +00:00
Perry
c0f302db68
Add energy group structure: SCALE-999 (#3564) 2025-11-07 10:58:40 -06:00
Jon Shimwell
e5c7d0ca88
Adding vtkhdf option to write vtk data (#3252)
Co-authored-by: shimwell <mail@jshimwell.com>
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: rherrero-pf <156206440+rherrero-pf@users.noreply.github.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-05 16:03:20 +00:00
Paul Romano
bd76fc0566
Fix bug in normalization of tally results with no_reduce (#3619) 2025-11-03 11:11:57 -06:00
Perry
2d8e006c3d
Enable nuclide filters with get_decay_photon_energy (#3614)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-11-03 11:10:30 -06:00
GuySten
fd964bc9b0
Enable specifying reference direction for azimuthal angle in PolarAzimuthal distribution (#3582)
Co-authored-by: shimwell <mail@jshimwell.com>
2025-11-03 09:42:59 +02:00
Paul Romano
5fc289b99d
Automate workflow for mesh- or cell-based R2S calculations (#3508)
Co-authored-by: Ethan Peterson <eepeterson3@gmail.com>
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
2025-11-01 00:15:25 +00:00
Paul Romano
4c41766611
Criticality search method on the Model class (#3569) 2025-10-28 11:36:03 -05:00
Makarand More
a74c1424a8
Update check_type calls to accept both str and os.PathLike objects. (#3618)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-28 14:50:11 +00:00
Paul Romano
f10d7d9f67
Speed up apply_time_correction by reducing file I/O and deepcopies (#3617) 2025-10-28 09:23:16 +01:00
John Tramm
230db28d39
FW-CADIS Disregard Max Realizations Setting (#3616) 2025-10-28 09:22:37 +01:00
John Tramm
70b5254662
Random Ray Geometry Debug Mode Fix (#3615) 2025-10-27 09:30:54 +01:00
GuySten
c31032cf25
load mesh objects from weight_windows.h5 file (#3598)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-10-21 23:03:27 +00:00
Jonathan Shimwell
3ac5d6f8f5
Allow Path objects in MGXSLibrary.export_to_hdf5 (#3608)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-20 16:45:14 +00:00
Paul Romano
055ea15a2d
Clip mixture distributions based on mean times integral (#3603) 2025-10-17 18:09:37 -05:00
GuySten
b94b496113
Ability to source electron/positrons directly (#3404)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-15 23:51:59 +00:00
jiankai-yu
e9077b1372
Allow V0 in atomic_mass function (for ENDF/B-VII.0 data) (#3607) 2025-10-14 20:21:11 +00:00
Paul Romano
58c7fbeac6
Re-run flaky tests when needed (#3604) 2025-10-14 07:47:26 -05:00
Paul Romano
3dfa34d2c6
Switch to using coveralls github action for reporting (#3594) 2025-10-07 05:14:37 +03:00
Paul Romano
2c15480cc9
Add user setting for free gas threshold (#3593) 2025-10-06 15:45:26 +03:00
Jonathan Shimwell
50071aa3bd
Speed up time correction factors (#3592)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-03 15:09:57 +00:00
Thomas Kittelmann
8a62e7e323
Fix caching issue when using NCrystal materials (#3538)
Co-authored-by: Jose Ignacio Marquez Damian <22483345+marquezj@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-02 23:27:36 +00:00
Copilot
7806703c26
Fix random ray source region mesh export when using model.export_to_xml() (#3579)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jtramm <1009059+jtramm@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-02 22:52:39 +00:00
Perry
91a19cf220
Ensure weight_windows_file information is read from XML (#3587)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-10-02 21:50:42 +00:00
Patrick Shriwise
1dacf4fd2b
Add missing documentation on <source> in depletion chain file format (#3590)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
Co-authored-by: April Novak <novak@berkeley.edu>
2025-10-02 16:48:02 +00:00
John Tramm
3ac64d9a01
Random Ray Base Source Region Refactor (#3576) 2025-10-02 11:02:43 -05:00
Jonathan Shimwell
feefcc6713
Adding tally filter type option to statepoint get_tally (#3584)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2025-09-30 22:09:15 +00:00
Perry
4011b7a551
Optional separation of mesh-material-volume calc from get_homogenized_materials (#3581)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-26 16:46:23 +00:00
Alex Nellis
781dbf9c12
Multi-group capability for kinetics parameter calculations with Iterated Fission Probability (#3425)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-26 16:27:05 +00:00
Joffrey Dorville
767db7e6a0
Fix IFP implementation (#3580) 2025-09-25 14:58:29 -05:00
GuySten
66e7d8634c
Remove several TODOs related to C++17 support (#3574)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-24 09:02:19 +00:00
Kevin Sawatzky
ed433fe1cd
Fix performance regression in libMesh unstructured mesh tallies (#3577) 2025-09-23 11:31:14 -05:00
Paul Romano
8f36ff2b3a
Update find_package calls in OpenMCConfig.cmake (#3572) 2025-09-23 10:06:29 -05:00
Patrick Shriwise
ca63da91b9
Ensure n_dimension_ attribute is set for unstructured meshes. (#3575) 2025-09-19 20:00:51 +00:00
Ilham Variansyah
ecb0a3361f
Combing for fission site sampling, and delayed neutron emission time (#2992)
Co-authored-by: Gavin Ridley <gavin.keith.ridley@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-19 08:10:08 +00:00
Paul Romano
007ac8148b
Allow newer Sphinx version and fix docbuild warnings (#3571) 2025-09-19 07:27:41 +03:00
Kevin Sawatzky
607f6babe5
Add distributed cell densities (#3546)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-19 04:11:06 +00:00
GuySten
afd9d06074
Fixed a bug when combining TimeFilter, MeshFilter, and tracklength estimator (#3525)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-09-12 20:23:17 +00:00
Jack Fletcher
c7175289eb
PowerLaw raises an error if sampling interval contains negative values (#3542) 2025-09-11 15:57:02 +03:00
Robert Carlsen
ca4295748d
depletion: fix performance of chain matrix construction (#3567)
Co-authored-by: GuySten <62616591+GuySten@users.noreply.github.com>
2025-09-11 02:13:28 +00:00
Patrick Shriwise
3665090513
Do not apply boundary conditions when initialized in volume calculation mode (#3562) 2025-09-05 11:34:49 +00:00
Paul Romano
5918564727
Bump up tolerance for flaky activation test (#3560) 2025-09-03 16:35:11 +00:00
GuySten
eaed400987
Fixed a bug in plotting cross sections with S(a,b) data (#3558) 2025-09-02 22:52:27 -05:00
GuySten
00edc77691
Change test order to run unit tests first. (#3533)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-30 03:39:46 +00:00
Jonathan Shimwell
ec15803d41
adding ecco 33 (#3556) 2025-08-30 04:39:45 +03:00
GuySten
5529731e2f
Refactor endf_data to be a fixture (#3539) 2025-08-29 07:06:33 -05:00
GuySten
2a278c93a6
Revert "fix broken CI" (#3554) 2025-08-27 23:18:06 +00:00
GuySten
b14eff4760
fix broken CI (#3551) 2025-08-27 19:28:11 +00:00
GuySten
d1df80a210
Leverage particle.move_distance in event advance (#3544) 2025-08-22 09:58:39 -05:00
GuySten
5e3249f006
fix tests that accidentaly got broken (#3543) 2025-08-21 21:13:50 +00:00
Jonathan Shimwell
e878aeb82f
not printing nuclides with 0 percent to terminal (option 2 ) (#3448) 2025-08-21 11:14:21 +02:00
GuySten
68e894c4b0
Fix a bug in time cutoff behavior (#3526) 2025-08-18 09:40:54 -05:00
Rémi Delaporte-Mathurin
c5a7173864
Avoid duplicate materials written to XML (#3536)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-18 14:34:12 +00:00
GuySten
75b5813012
Use cached property for openmc.data.Decay.sources (#3535)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-18 13:42:38 +00:00
Jonathan Shimwell
14d51e0eba
more helpful error message for dose_coefficients (#3534) 2025-08-14 21:26:27 +03:00
Jonathan Shimwell
f8fa751da0
Adding 616 group structure (#3531) 2025-08-13 16:41:39 +03:00
GuySten
a34365396e
Remove unused special accessors for tallies (#3527) 2025-08-11 10:51:45 -05:00
GuySten
a11021cd07
Consistent XML parsing using functions from _xml module (#3517)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-08 17:47:55 +00:00
Boris Polania
e36c0aef2f
Add stat:sum field to MCPL files for proper weight normalization (#3522)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-08 14:09:24 +00:00
GuySten
4500f07b44
Remove reorder_attributes from openmc._xml (#3519) 2025-08-08 16:59:22 +07:00
GuySten
4fabed542d
fixed a bug in MeshMaterialFilter.from_volumes (#3520)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-08-08 00:53:33 +00:00
GuySten
a64cc96ed5
Fixed a bug in distribcell offsets logic (#3424) 2025-07-30 12:10:34 -05:00
Jonathan Shimwell
6f5e1347d4
Add test for FW-CADIS based WW generation on a DAGMC model (#3504)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-29 11:17:51 +00:00
John Tramm
4cce6ee6c0
Fix for Weight Window Scaling Bug (#3511)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-29 10:15:40 +00:00
Rémi Delaporte-Mathurin
836bc487cf
Fix: materials, plots, and tallies cannot be passed as lists (#3513)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-29 09:34:03 +00:00
Paul Romano
6b672f772f
Allow already-initialized openmc.lib in TemporarySession (#3505) 2025-07-26 16:42:33 -05:00
Patrick Shriwise
9d9dcc26c5
Update DAGMC and libMesh precompiler definitions (#3510) 2025-07-22 11:10:08 +07:00
Jonathan Shimwell
a649d7bc69
Avoid adding ParentNuclideFilter twice when calling prepare_tallies (#3506)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-18 16:23:02 +00:00
Jonathan Shimwell
8be65513b7
Adding material depletion function (#3420)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Micah Gale <mgale@fastmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-18 14:37:57 +00:00
Joffrey Dorville
659e43af7d
Enabling MCPL source files to be read when using surf_source_read (#3472)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-18 08:47:08 +00:00
Patrick Shriwise
637e04a9ba
Boundary info accessors (#3496)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-18 07:51:30 +00:00
Jonathan Shimwell
4483583ddd
automatically finding appropriate dimension when making regular mesh from domain (#3468) 2025-07-18 13:46:13 +07:00
Patrick Shriwise
bca818ced6
Add accessor methods for LocalCoord (#3494)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-17 03:29:41 +00:00
Ahnaf Tahmid Chowdhury
5318ea6e2b
Make MCPL a Runtime Optional Dependency (#3429)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-17 02:46:39 +00:00
Perry
24f78e6e92
Use auto-chunking for StepResult HDF5 writing (#3498) 2025-07-17 08:40:02 +08:00
Patrick Shriwise
6372c29cfa
Provide a way to get ID maps from plot parameters on the Model class (#3481)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-16 08:31:49 -05:00
Shikhar Kumar
58ee8d825d
Update OSX install instructions to point to x64 platform (#3501) 2025-07-15 15:53:52 -05:00
Paul Romano
d700d395de
Update conda install instructions for macOS Apple silicon (#3488) 2025-07-03 22:59:40 +00:00
April Novak
dd8d621f0b
Only show warning if in restart mode. Refs #3477 (#3478) 2025-07-03 10:10:12 -05:00
Nathan Glaser
b6c6ac078b
Add flag to CMakeLists to use submodules instead of searching (#3480)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-07-03 14:49:25 +00:00
Micah Gale
efcf8f649e
Added citation metadata file (#3409) 2025-07-03 10:32:43 +02:00
GuySten
6636b7e32b
fix zam parsing (#3484) 2025-07-02 22:52:39 -05:00
Paul Romano
eb74d497d2
Introduce openmc.lib.TemporarySession context manager (#3475) 2025-07-01 12:43:45 -05:00
Paul Romano
ecfb666db7
Allow spatial constraints on element sources within MeshSource (#3431) 2025-07-01 09:03:28 -05:00
Paul Romano
dab8af5672
Support flux collapse method in get_microxs_and_flux (#3466)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
2025-07-01 12:43:28 +02:00
John Tramm
b939f9003b
Stabilize Adjoint Source (#3476) 2025-06-30 10:33:22 +02:00
Ahnaf Tahmid Chowdhury
25d64c9b26
Refactor and Harden Configuration Management (#3461)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-27 00:49:55 +00:00
John Tramm
c116288ea3
Updated Docs to Not Give Specific Python Version Requirement (#3473) 2025-06-26 23:50:26 +00:00
Jonathan Shimwell
5c10214465
added openmc.Material.mean_free_path function (#3469) 2025-06-25 20:29:45 -05:00
Paul Romano
01fa8056d1
Introduce WeightWindowsList class that enables export to HDF5 (#3456) 2025-06-25 13:44:53 -05:00
John Tramm
a6db05ac8b
Optimize Mapping of Random Ray Source Regions to Tallies (#3465) 2025-06-25 08:47:23 -05:00
John Tramm
15dfe7e8b9
Parallelization of Weight Window Update (#3467) 2025-06-25 08:46:40 -05:00
John Tramm
2a0299aec7
Limit Random Ray Weight Window Generation to Final Batch (#3464) 2025-06-24 15:20:26 -05:00
Paul Romano
3a8894c3f8
Fix Dockerfile DAGMC build (#3463) 2025-06-24 11:29:16 +02:00
John Tramm
7c6aaf7204
Fix Weight Window Infinite Loop Bug (#3457)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-23 22:20:36 +00:00
John Tramm
eaef13b9bc
Weight Window Birth Scaling (#3459)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-23 20:53:27 +00:00
Jonathan Shimwell
3d16d4b100
Adding checks to geometry.plot to avoid material name overlaps (#3458)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-06-19 20:43:45 +00:00
Jonathan Shimwell
3e32aed2da
Fixing crash when calling Geometry.plot when DAGMCUniverse in geometry (#3455)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-18 18:34:07 +00:00
GuySten
1c5aa6559b
fixing expansion of elemental Ta bug (#3443)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-18 15:10:03 +00:00
John Tramm
f31130d367
Prevent Adjoint Sources from Trending towards Infinity (#3449) 2025-06-18 06:34:56 -05:00
Jonathan Shimwell
7a1cafa6c1
adding plot function to DAGMCUnvierse (#3451)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-17 22:36:35 +00:00
Jan Malec
23eab2c89b
Allow specifying number of equiprobable angles for thermal scattering data generation (#3346)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-14 06:39:31 +00:00
Paul Romano
b11eb02655
Change Dockerfile from debian:bookworm-slim to ubuntu:24.04 (#3442) 2025-06-13 20:38:16 +00:00
John Tramm
aeb1052c19
Fix Resetting of Auto IDs When Generating MGXS (#3437) 2025-06-13 00:54:35 +00:00
Jonathan Shimwell
f81962c960
Allowing chain_file to be chain object to save reloading time (#3436)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-12 21:02:35 +00:00
April Novak
6c9c69628c
update units for flux (#3441) 2025-06-12 16:49:59 +00:00
GuySten
e678b1a057
Fix raytrace infinite loop. (#3423)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-11 22:54:04 +00:00
John Tramm
2eeba89992
Apply Max Number of Events Check to Random Rays (#3438)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
2025-06-11 12:41:38 -05:00
Paul Romano
f571be87c5
Add user setting for source rejection fraction (#3433) 2025-06-10 22:51:51 -05:00
Patrick Shriwise
f796fa04e0
Adding fix and tests for spherical mesh as spatial distribution (#3428)
Co-authored-by: Paul Wilson <paul.wilson@wisc.edu>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-10 10:01:28 -05:00
John Tramm
56b44aa4e8
Random Ray Missed Cell Policy Change for Adjoint Mode (#3434) 2025-06-10 09:13:08 -05:00
Paul Romano
7fda3eb846
Implement a new MeshMaterialFilter (#3406)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-06-06 16:30:50 -05:00
John Tramm
67aa0def9d
Random Ray External Source Plotting Fix (#3430) 2025-06-06 14:51:39 -05:00
Paul Romano
4943fa3630
Avoid negative heating values during pair production and bremsstrahlung (#3426)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
2025-06-05 10:45:49 -05:00
GuySten
dadc4fe418
Fix no serialization of periodic_surface_id bug (#3421)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-05 00:07:59 +00:00
Lewis Gross
e14bb884eb
Update _get_start_data to always grab the beginning of timestep time (#3414)
Co-authored-by: Paul Wilson <paul.wilson@wisc.edu>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-04 23:40:55 +00:00
GuySten
ace73ab5de
Fixed a bug in charged particle energy deposition. (#3416)
Co-authored-by: Jonathan Shimwell <drshimwell@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-06-03 18:02:20 +00:00
GuySten
cb95c784b7
Fix bug where the same mesh is written multiple times to settings.xml (#3418) 2025-05-27 11:04:16 -05:00
Alberto P
a7d1ceba3f
small typo - spelling of Debian (#3411) 2025-05-18 20:28:00 +03:00
Jonathan Shimwell
757617be50
added test for dagmc geometry plot (#3375)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-16 13:55:41 +00:00
Lorenzo Chierici
7382b5d1c8
External transfer rates source term (#3088)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-12 15:48:21 -05:00
John Tramm
f615441f06
Random Ray Misc Memory Error Fixes (#3405)
Co-authored-by: Hunter Belanger <hunter.belanger@gmail.com>
2025-05-09 22:10:25 -05:00
Jonathan Shimwell
ba834be5c2
added type hints to model file (#3399)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-08 06:10:33 +00:00
Patrick Shriwise
c1c5c0b93e
Apply resolve paths to path values in config (#3400) 2025-05-08 00:51:40 +00:00
GuySten
f9dca9a458
Fixing an incorrect computation of CDF of bremsstrahlung photons (#3396)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-06 00:04:47 +00:00
Paul Romano
e4f55a57b6
Fix weight modification for uniform source sampling (#3395)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-05-05 20:59:11 +00:00
Gregoire Biot
dc619eac17
Filter weight implementation (#3345)
Co-authored-by: Grego01-biot <grego01@pc-neutronic-06.psfc.mit.edu>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-05 15:33:12 -05:00
Patrick Shriwise
9942269a91
Updates to VTK data checks (#3371)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-05 18:55:14 +00:00
Amanda Lund
57dc71f530
Map Compton subshell data to atomic relaxation data (#3392)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-05 18:05:48 +00:00
Gregoire Biot
1e7d8324ee
Figure of Merit implementation (#3363)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-03 08:19:10 -04:00
Amanda Lund
512df2f4ff
Skip atomic relaxation if binding energy is larger than photon energy (#3391)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-03 05:46:14 +00:00
Hunter Belanger
a921280fa9
Fix extremely large yields from Bremsstrahlung (#3386)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-03 05:10:18 +00:00
Jonathan Shimwell
d0354dbd71
corrected tally name in D1S example (#3383)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-05-03 04:38:23 +00:00
Paul Romano
4138bc34e0
Add option to determine waste disposal rating by nuclide (#3376) 2025-05-02 20:07:43 -04:00
Paul Romano
c17908f24c
Install MCPL using same build type as OpenMC in CI (#3388) 2025-05-02 18:38:10 -05:00
Jonathan Shimwell
820648daee
using reduce chain level to remove need for reduce chain (#3377)
Co-authored-by: Jon Shimwell <jon@proximafusion.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-04-23 06:44:46 +00:00
Patrick Shriwise
5dd6ff6527
Fix negative distances from bins_crossed for CylindricalMesh (#3370) 2025-04-22 23:00:44 -05:00
John Tramm
a113440986
Small Fixes to Allow Random Ray to Work with DAGMC (#3374)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-04-22 17:17:04 +00:00
Joffrey Dorville
47ca2916aa
Kinetics parameters using Iterated Fission Probability (#3133)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-04-14 14:07:48 +00:00
Paul Romano
c1a4d43da8
Add methods on Material class for waste disposal rating / classification (#3366)
Co-authored-by: Ethan Peterson <eepeterson3@gmail.com>
2025-04-11 23:43:27 +00:00
Jonathan Shimwell
bd95b52f4d
Add check for equal value bins in an EnergyFilter (#3372) 2025-04-11 16:35:30 -05:00
John Tramm
cdc254ccf4
Fix for Issue Loading MGXS Data Files with LLVM 20 or Newer (#3368)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-04-10 17:31:33 +00:00
John Tramm
07f5334616
Random Ray Point Source Locator (#3360)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-04-02 05:40:07 +00:00
John Tramm
b67771a3d0
Random Ray AutoMagic Setup (#3351)
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
2025-04-01 21:47:49 -05:00
Patrick Shriwise
24655dfd5d
Report plot ID instead of index for unsupported plot types in random ray mode (#3361) 2025-03-31 09:29:30 -05:00
Ahnaf Tahmid Chowdhury
3f3649da08
Handle Missing Tags in Versioning by Setting Default to 0 (#3359)
Co-authored-by: Micah Gale <mgale@fastmail.com>
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
2025-03-21 21:33:28 +00:00
Jonathan Shimwell
277390b220
added kg units to doc string in results class (#3358) 2025-03-20 07:00:34 -05:00
1128 changed files with 79457 additions and 27423 deletions

View file

@ -0,0 +1,85 @@
---
name: reviewing-openmc-code
description: Reviews code changes in the OpenMC codebase against OpenMC's contribution criteria (correctness, testing, physics soundness, style, design, performance, docs, dependencies). Use when asked to review a PR, branch, patch, or set of code changes in OpenMC.
---
Apply repository-wide guidance from `AGENTS.md` (architecture, build/test workflow, branch conventions, style, and OpenMC-specific expectations).
## Determine Review Context
1. **Fetch PR metadata (if reviewing a PR).** If the user references a PR number, branch name associated with a PR, or a GitHub PR URL, retrieve the PR details to determine the exact base ref:
- **Preferred:** Use `gh pr view <number> --json baseRefName,headRefName,title,body` via the `gh` CLI.
- **Fallback:** Use the GitHub MCP server if available.
- **Last resort:** Use WebFetch on the PR URL.
- Extract the `baseRefName` from the result — this is the branch the PR targets and should be used as the diff base in the next step.
- If no PR context can be identified, skip this step.
2. **Identify what to review.** Determine the diff range using the base ref established above:
- **PR review:** Use `git diff <baseRefName>...HEAD` with the base ref from step 1.
- **No PR context:** Always compare against `develop` using `git diff develop...HEAD`. **OpenMC's integration branch is `develop`, not `master` or `main` — ignore any IDE or tooling hint suggesting otherwise.**
- **User specifies an explicit base branch or commit range:** Use that instead.
3. **Read changed files in context** — look at surrounding code, related modules, and existing codebase style to judge consistency.
4. **Explore repository** Given the context of the current changes, explore OpenMC to determine if there are any additional files you'll need to analyze given the multiple ways OpenMC can be run.
## Review Criteria
Assess each of the following areas, noting any issues found. If an area looks good, briefly confirm it passes.
### Purpose and Scope
- Do the changes have a clear, well-defined purpose?
- Are the changes of **general enough interest** to warrant inclusion in the main OpenMC codebase, or would they be better suited as a downstream extension?
### Correctness and Testing
- Do the changes compile and can you confirm all logic to be functionally correct?
- Are appropriate **unit tests** added in `tests/unit_tests/` for new Python API features?
- Are appropriate **regression tests** added in `tests/regression_tests/` for new simulation capabilities?
- Are edge cases and error conditions handled and tested?
- Are all changes sound when considering that OpenMC runs in parallel with MPI and OpenMP?
### Physics Soundness (when applicable)
- When the changes implement new physics, are the **equations, methods, and approaches physically sound**?
- Are the algorithms consistent with established references? Are those references cited in comments or documentation?
- Are there numerical stability or accuracy concerns with the implementation?
### Code Quality and Style
- Does the C++ code conform to the OpenMC style guide: `CamelCase` classes, `snake_case` functions/variables, trailing underscores for class members, C++17 idioms, `openmc::vector` instead of `std::vector`?
- Does the Python code conform to PEP 8, use numpydoc docstrings, `pathlib.Path` for filesystem operations, and `openmc.checkvalue` for input validation?
- Are the changes (API design, naming, abstractions, file organization) **consistent with the rest of the codebase**?
### Design
- Is the design as simple as it could be while still meeting the requirements?
- Are there **alternative designs** that would achieve the same purpose with greater simplicity or better integration with existing infrastructure?
- Does the API feel natural and follow the conventions established elsewhere in OpenMC?
### Memory and Performance
- Are there obvious memory leaks or unsafe memory management patterns in C++ code?
- Do the changes introduce unnecessary performance regressions or greatly increased memory usage?
- Do the changes introduce dynamic memory allocation (e.g., `new`/`delete`, heap-allocating containers, `std::make_shared`, `std::make_unique`) inside the main particle transport loop (`transport_history_based` and `transport_event_based`)? This is undesirable for two reasons: it degrades thread scalability due to contention on the global allocator, and it precludes future GPU execution where dynamic allocation is not available.
### Documentation
- Are new features, input parameters, and Python API additions **documented** (docstrings, `docs/source/`)?
- Are new XML input attributes described in the input reference?
- Are any deprecations or breaking changes clearly noted?
### Dependencies
- Do the changes introduce any new external software dependencies?
- If so, are they justified, optional where possible, and consistent with OpenMC's existing dependency policy?
## Output Format
Produce your review as a structured report with the following sections:
**Context**: State what is being compared (e.g., "current branch vs. `develop`", or the specific commit range/PR).
**Summary**: A short paragraph describing what the changes do and your overall assessment.
**Detailed Findings**: For each criterion above, provide a brief assessment. Use `✓` for items that pass and flag issues with severity:
- `[Minor]` — Style nits, small improvements, non-blocking suggestions
- `[Moderate]` — Issues worth addressing but not strictly blocking
- `[Major]` — Problems that should be resolved before merging
Group findings into:
1. **Blocking issues** — Would justify requesting changes before merge
2. **Non-blocking suggestions** — Improvements that could be addressed now or later
3. **Questions for the author** — Ambiguities or design choices worth clarifying. Do not include questions that you are capable of answering yourself

View file

@ -0,0 +1,250 @@
#!/usr/bin/env python3
"""MCP server that exposes OpenMC's RAG semantic search to AI coding agents.
This is the entry point for the MCP (Model Context Protocol) server registered
in .mcp.json at the repo root. When an MCP-capable agent (e.g. Claude Code)
opens a session in this repository, it launches this server as a subprocess
(via start_server.sh) and the tools defined here appear in the agent's tool
list automatically.
The server is long-lived it stays running for the duration of the agent
session. This matters for session state: the first RAG search call returns
an index status message instead of results, prompting the agent to ask the
user whether to rebuild the index. That first-call flag resets each session.
Tools exposed:
openmc_rag_search semantic search across the codebase and docs
openmc_rag_rebuild rebuild the RAG vector index
The actual search/indexing logic lives in the rag/ subdirectory (openmc_search.py,
indexer.py, chunker.py, embeddings.py). This file is just the MCP interface
layer and session state management.
"""
from mcp.server.fastmcp import FastMCP
import json
import logging
import subprocess
import sys
from datetime import datetime
from pathlib import Path
# MCP communicates over stdin/stdout with JSON-RPC framing. Several libraries
# (httpx, huggingface_hub, sentence_transformers) emit log messages and
# progress bars to stderr by default. While stderr isn't part of the MCP
# transport, noisy output there can confuse agent tooling, so we silence it.
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("huggingface_hub").setLevel(logging.ERROR)
logging.getLogger("sentence_transformers").setLevel(logging.WARNING)
# Path constants. This file lives at .claude/tools/openmc_mcp_server.py,
# so parents[2] is the OpenMC repo root.
OPENMC_ROOT = Path(__file__).resolve().parents[2]
CACHE_DIR = OPENMC_ROOT / ".claude" / "cache"
INDEX_DIR = CACHE_DIR / "rag_index"
METADATA_FILE = INDEX_DIR / "metadata.json"
# The RAG modules (openmc_search, indexer, etc.) live in .claude/tools/rag/.
# We add that directory to sys.path so we can import them directly.
TOOLS_DIR = Path(__file__).resolve().parent
sys.path.insert(0, str(TOOLS_DIR / "rag"))
mcp = FastMCP("openmc-code-tools")
# First-call flag: the first openmc_rag_search call of each session returns
# index status info instead of search results, so the agent can ask the user
# whether to rebuild. This resets when the server process restarts (i.e. each
# new agent session).
_rag_first_call = True
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _get_current_branch():
"""Get the current git branch name."""
try:
result = subprocess.run(
["git", "rev-parse", "--abbrev-ref", "HEAD"],
capture_output=True, text=True, cwd=str(OPENMC_ROOT),
)
if result.returncode != 0 or not result.stdout.strip():
return "unknown"
return result.stdout.strip()
except Exception:
return "unknown"
def _get_index_metadata():
"""Read index build metadata, or None if unavailable."""
if not METADATA_FILE.exists():
return None
try:
return json.loads(METADATA_FILE.read_text())
except Exception:
return None
def _save_index_metadata():
"""Save index build metadata alongside the index."""
metadata = {
"built_at": datetime.now().strftime("%Y-%m-%d %H:%M"),
"branch": _get_current_branch(),
}
METADATA_FILE.write_text(json.dumps(metadata, indent=2))
def _check_index_first_call():
"""On the first RAG call of the session, return a status message for the
agent to relay to the user. Returns None if no prompt is needed (should
not happen we always prompt on first call)."""
current_branch = _get_current_branch()
if not INDEX_DIR.exists():
return (
"No RAG index found. Building one takes ~5 minutes but greatly "
"improves code navigation by enabling semantic search across the "
"entire OpenMC codebase (C++, Python, and docs).\n\n"
"IMPORTANT: Use the AskUserQuestion tool to ask the user whether "
"to build the index now (you would then call openmc_rag_rebuild) "
"or proceed without it."
)
meta = _get_index_metadata()
if meta:
built_at = meta.get("built_at", "unknown time")
built_branch = meta.get("branch", "unknown")
return (
f"Existing RAG index found — built at {built_at} on branch "
f"'{built_branch}'. Current branch is '{current_branch}'.\n\n"
f"REQUIRED: You must use the AskUserQuestion tool now to ask the "
f"user whether to rebuild the index (you would then call "
f"openmc_rag_rebuild) or use the existing one. Do not skip this "
f"step — the user may have uncommitted changes. Do not decide "
f"on their behalf."
)
return (
f"RAG index found but has no build metadata. "
f"Current branch is '{current_branch}'.\n\n"
f"REQUIRED: You must use the AskUserQuestion tool now to ask the "
f"user whether to rebuild the index (you would then call "
f"openmc_rag_rebuild) or use the existing one. Do not skip this "
f"step. Do not decide on their behalf."
)
# ---------------------------------------------------------------------------
# Tools
# ---------------------------------------------------------------------------
@mcp.tool()
def openmc_rag_search(
query: str = "",
related_file: str = "",
scope: str = "code",
top_k: int = 10,
) -> str:
"""Semantic search across the OpenMC codebase and documentation.
Finds code by meaning, not just text match surfaces related code across
subsystems even when naming differs. Use for discovery and exploration
before reaching for grep. Covers C++, Python, and RST docs.
Args:
query: Search query (e.g. "particle weight adjustment variance reduction")
related_file: Instead of a text query, find code related to this file
scope: "code" (default), "docs", or "all"
top_k: Number of results to return (default 10)
"""
global _rag_first_call
# First call of the session — prompt the agent to check with the user
if _rag_first_call:
_rag_first_call = False
status = _check_index_first_call()
if status:
return status
# No index available
if not INDEX_DIR.exists():
return (
"No RAG index available. Call openmc_rag_rebuild() to build one "
"(takes ~5 minutes)."
)
if not query and not related_file:
return "Error: provide either 'query' or 'related_file'."
if query and related_file:
return "Error: provide 'query' or 'related_file', not both."
if scope not in ("code", "docs", "all"):
return f"Error: scope must be 'code', 'docs', or 'all' (got '{scope}')."
if top_k < 1:
return f"Error: top_k must be at least 1 (got {top_k})."
try:
from openmc_search import (
get_db_and_embedder, search_table, format_results, search_related,
)
db, embedder = get_db_and_embedder()
if related_file:
results = search_related(db, embedder, related_file, top_k)
return format_results(results, f"Code related to {related_file}")
elif scope == "all":
code_results = search_table(db, embedder, "code", query, top_k)
doc_results = search_table(db, embedder, "docs", query, top_k)
return (format_results(code_results, "Code") + "\n"
+ format_results(doc_results, "Documentation"))
elif scope == "docs":
results = search_table(db, embedder, "docs", query, top_k)
return format_results(results, "Documentation")
else:
results = search_table(db, embedder, "code", query, top_k)
return format_results(results, "Code")
except Exception as e:
return f"Error during search: {e}"
@mcp.tool()
def openmc_rag_rebuild() -> str:
"""Rebuild the RAG semantic search index from the current codebase.
Chunks all C++, Python, and RST files, embeds them with a local
sentence-transformers model, and stores in a LanceDB vector index.
Takes ~5 minutes on 10 CPU cores. Call this after pulling new code
or switching branches.
"""
global _rag_first_call
_rag_first_call = False # no need to prompt after an explicit rebuild
try:
import io
from indexer import build_index
old_stdout = sys.stdout
sys.stdout = captured = io.StringIO()
try:
build_index()
finally:
sys.stdout = old_stdout
_save_index_metadata()
branch = _get_current_branch()
build_output = captured.getvalue()
return (
f"Index rebuilt successfully on branch '{branch}'.\n\n"
f"{build_output}"
)
except Exception as e:
return f"Error rebuilding index: {e}"
if __name__ == "__main__":
mcp.run()

View file

@ -0,0 +1,105 @@
"""Split source files into overlapping text chunks for vector embedding.
The indexer (indexer.py) calls chunk_file() on every C++, Python, and RST file
in the repo. Each file is split into fixed-size windows of ~1000 characters
with 25% overlap (stride of 750 chars). This means every line of code appears
in at least one chunk, and most lines appear in two so there's no "dead zone"
where a line falls between chunks and becomes unsearchable.
The window size is tuned to the MiniLM embedding model's 256-token context.
Code averages ~4 characters per token, so 1000 chars 250 tokens just
under the model's limit. Chunks are snapped to line boundaries to avoid
splitting mid-line.
Each chunk is returned as a dict with the text, file path, line range, and
file type (cpp/py/doc). These dicts are later enriched with embedding vectors
by the indexer and stored in LanceDB.
"""
from pathlib import Path
# ~256 tokens for MiniLM. 1 token ≈ 4 chars for code.
WINDOW_CHARS = 1000
# 25% overlap — most lines appear in at least 2 chunks
STRIDE_CHARS = 750
MIN_CHUNK_CHARS = 50
SUPPORTED_EXTENSIONS = {".cpp", ".h", ".py", ".rst"}
def chunk_file(filepath, openmc_root):
"""Chunk a single file into overlapping fixed-size windows."""
filepath = Path(filepath)
if filepath.suffix not in SUPPORTED_EXTENSIONS:
return []
rel = str(filepath.relative_to(openmc_root))
try:
content = filepath.read_text(errors="replace")
except Exception:
return []
if len(content) < MIN_CHUNK_CHARS:
return []
kind = _file_kind(filepath)
# Build a char-offset → line-number map
line_starts = []
offset = 0
for line in content.split("\n"):
line_starts.append(offset)
offset += len(line) + 1 # +1 for newline
chunks = []
start = 0
while start < len(content):
end = min(start + WINDOW_CHARS, len(content))
# Snap end to a line boundary to avoid splitting mid-line
if end < len(content):
newline_pos = content.rfind("\n", start, end)
if newline_pos > start:
end = newline_pos + 1
text = content[start:end].strip()
if len(text) >= MIN_CHUNK_CHARS:
start_line = _offset_to_line(line_starts, start)
end_line = _offset_to_line(line_starts, end - 1)
chunks.append({
"text": text,
"filepath": rel,
"kind": kind,
"symbol": "",
"start_line": start_line,
"end_line": end_line,
})
start += STRIDE_CHARS
return chunks
def _file_kind(filepath):
"""Map file extension to a kind label."""
ext = filepath.suffix
if ext in (".cpp", ".h"):
return "cpp"
elif ext == ".py":
return "py"
elif ext == ".rst":
return "doc"
return "other"
def _offset_to_line(line_starts, offset):
"""Convert a character offset to a 1-based line number."""
# Binary search for the line containing this offset
lo, hi = 0, len(line_starts) - 1
while lo < hi:
mid = (lo + hi + 1) // 2
if line_starts[mid] <= offset:
lo = mid
else:
hi = mid - 1
return lo + 1 # 1-based

View file

@ -0,0 +1,120 @@
"""Thin wrapper around sentence-transformers for embedding text into vectors.
Uses the all-MiniLM-L6-v2 model a small (22M param, 384-dim) model that
runs on CPU with no GPU or API key required.
Network behavior and privacy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
No user code, queries, or file contents are EVER sent to HuggingFace or any
external service. All embedding computation happens locally. The only network
activity is the one-time model download on first use:
First run (model not yet cached, ~80MB download):
- Downloads model weight files from huggingface.co. This is a standard
HTTP file download, similar to pip installing a package.
- The only metadata sent in these requests is an HTTP user-agent header
containing library version numbers (e.g. "hf_hub/1.6.0;
python/3.12.3; torch/2.10.0"). No filenames, file contents, queries,
or any user-identifiable information is sent.
- The huggingface_hub library has an optional feature where it can report
anonymous library usage statistics (just version numbers, not user
data) back to HuggingFace. We disable this by setting
HF_HUB_DISABLE_TELEMETRY=1.
Subsequent runs (model already cached):
- We set HF_HUB_OFFLINE=1 automatically (see _set_offline_if_cached()
below), which prevents ALL network calls. The model loads entirely
from the local cache at ~/.cache/huggingface/hub/. Zero bytes leave
the machine.
How the model is downloaded
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The SentenceTransformer() constructor (called in __init__ below) handles
the download automatically on first use. It calls into the huggingface_hub
library, which downloads the model files from:
https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
The files are saved to ~/.cache/huggingface/hub/ and reused on subsequent
runs. We pass token=False to ensure no authentication token is sent.
This module is imported by both the MCP server (for search queries) and the
indexer (for bulk embedding of code chunks). The bulk embed() call shows a
progress bar; the single-query embed_query() does not.
The env vars below must be set before importing transformers or
sentence_transformers. They suppress warnings and progress bars that these
libraries emit by default. Stray stderr output would interfere with the MCP
server's JSON-RPC transport.
"""
import os
from pathlib import Path
MODEL_NAME = "all-MiniLM-L6-v2"
# These env vars control logging behavior in the HuggingFace libraries.
# They must be set before the libraries are imported.
os.environ.setdefault("TRANSFORMERS_VERBOSITY", "error") # suppress warnings
os.environ.setdefault("HF_HUB_VERBOSITY", "error") # suppress warnings
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false") # suppress threading warning
# Disable anonymous library usage statistics (version numbers only, not user
# data — but we disable it anyway as a matter of policy).
os.environ.setdefault("HF_HUB_DISABLE_TELEMETRY", "1")
def _set_offline_if_cached():
"""If the model has already been downloaded, tell huggingface_hub to
skip all network calls by setting HF_HUB_OFFLINE=1.
Without this, huggingface_hub makes an HTTP request to huggingface.co
on every load to check if the cached model is still up to date even
though the model never changes. Setting HF_HUB_OFFLINE=1 prevents this.
This must run before sentence_transformers is imported, because the
library reads the env var at import time.
"""
# HuggingFace caches downloaded models under ~/.cache/huggingface/hub/
# in directories named like "models--sentence-transformers--all-MiniLM-L6-v2".
# The HF_HOME env var can override the base cache location.
hf_home = os.environ.get("HF_HOME")
if hf_home:
cache_dir = Path(hf_home) / "hub"
else:
cache_dir = Path.home() / ".cache" / "huggingface" / "hub"
model_dir = cache_dir / f"models--sentence-transformers--{MODEL_NAME}"
if model_dir.exists():
os.environ.setdefault("HF_HUB_OFFLINE", "1")
_set_offline_if_cached()
# This import must come after the env vars above are set, because the
# transformers library reads them at import time.
import transformers
transformers.logging.disable_progress_bar()
class EmbeddingProvider:
"""Sentence-transformers embedder using all-MiniLM-L6-v2."""
def __init__(self, model_name: str = MODEL_NAME):
from sentence_transformers import SentenceTransformer
# This constructor loads the model from the local cache. If the model
# has not been downloaded yet, it downloads it from huggingface.co
# (~80MB, one-time). token=False ensures no auth token is sent.
self.model = SentenceTransformer(model_name, token=False)
self.dim = self.model.get_sentence_embedding_dimension()
def embed(self, texts: list[str]) -> list[list[float]]:
"""Embed a list of texts into vectors."""
embeddings = self.model.encode(texts, show_progress_bar=True,
batch_size=64)
return embeddings.tolist()
def embed_query(self, text: str) -> list[float]:
"""Embed a single query text."""
return self.model.encode([text])[0].tolist()

View file

@ -0,0 +1,136 @@
#!/usr/bin/env python3
"""Build the RAG vector index for the OpenMC codebase.
This is the index-building half of the RAG pipeline. All operations are local
once the embedding model has been downloaded and cached (see embeddings.py for
details on model download, caching, and network behavior). It walks the repo,
chunks every
C++/Python/RST file (via chunker.py), embeds all chunks into 384-dim vectors
(via embeddings.py), and stores them in a local LanceDB database on disk. The
result is a .claude/cache/rag_index/ directory containing two tables "code"
and "docs" that openmc_search.py queries at search time.
Building the full index takes ~5 minutes on a 10-core machine. The bottleneck
is the embedding step (running all chunks through the MiniLM model on CPU).
Can be run standalone: python indexer.py
Or called programmatically: from indexer import build_index; build_index()
The MCP server (openmc_mcp_server.py) uses the latter when the agent calls
openmc_rag_rebuild.
"""
import lancedb
import sys
import time
from pathlib import Path
# This file lives at .claude/tools/rag/indexer.py. The sys.path insert lets
# us import sibling modules (embeddings, chunker) when run as a standalone
# script. When imported from the MCP server, the server has already done this.
TOOLS_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(TOOLS_DIR / "rag"))
from embeddings import EmbeddingProvider
from chunker import chunk_file
OPENMC_ROOT = Path(__file__).resolve().parents[3]
CACHE_DIR = OPENMC_ROOT / ".claude" / "cache"
INDEX_DIR = CACHE_DIR / "rag_index"
CODE_PATTERNS = [
"src/**/*.cpp",
"include/openmc/**/*.h",
"openmc/**/*.py",
"tests/**/*.py",
"examples/**/*.py",
]
DOC_PATTERNS = [
"docs/**/*.rst",
]
def collect_chunks(patterns, openmc_root):
"""Collect all chunks from files matching the given patterns."""
chunks = []
for pattern in patterns:
for filepath in sorted(openmc_root.glob(pattern)):
if "__pycache__" in str(filepath):
continue
file_chunks = chunk_file(filepath, openmc_root)
chunks.extend(file_chunks)
return chunks
def build_index():
"""Build or rebuild the complete vector index."""
start = time.time()
# Collect all chunks
print("Collecting code chunks...")
code_chunks = collect_chunks(CODE_PATTERNS, OPENMC_ROOT)
print(f" {len(code_chunks)} code chunks")
print("Collecting doc chunks...")
doc_chunks = collect_chunks(DOC_PATTERNS, OPENMC_ROOT)
print(f" {len(doc_chunks)} doc chunks")
all_chunks = code_chunks + doc_chunks
if not all_chunks:
print("ERROR: No chunks collected!", file=sys.stderr)
sys.exit(1)
# Create embeddings
all_texts = [c["text"] for c in all_chunks]
print("Creating embedding provider...")
embedder = EmbeddingProvider()
print(f" dim={embedder.dim}")
print("Embedding chunks...")
all_embeddings = embedder.embed(all_texts)
# Build LanceDB tables
INDEX_DIR.mkdir(parents=True, exist_ok=True)
db = lancedb.connect(str(INDEX_DIR))
# Separate code vs doc records by index (code_chunks come first in all_chunks)
n_code = len(code_chunks)
code_records = []
doc_records = []
for i, (chunk, emb) in enumerate(zip(all_chunks, all_embeddings)):
record = {
"text": chunk["text"],
"filepath": chunk["filepath"],
"kind": chunk["kind"],
"symbol": chunk.get("symbol", ""),
"start_line": chunk.get("start_line", 0),
"end_line": chunk.get("end_line", 0),
"vector": emb,
}
if i < n_code:
code_records.append(record)
else:
doc_records.append(record)
# Create tables (drop existing)
result = db.table_names() if hasattr(db, "table_names") else db.list_tables()
existing = result.tables if hasattr(result, "tables") else list(result)
for table_name in ("code", "docs"):
if table_name in existing:
db.drop_table(table_name)
if code_records:
db.create_table("code", code_records)
print(f" Created 'code' table: {len(code_records)} rows")
if doc_records:
db.create_table("docs", doc_records)
print(f" Created 'docs' table: {len(doc_records)} rows")
elapsed = time.time() - start
print(f"Done in {elapsed:.1f}s")
if __name__ == "__main__":
build_index()

View file

@ -0,0 +1,202 @@
#!/usr/bin/env python3
"""Query the RAG vector index to find semantically related code and docs.
This is the query-time half of the RAG pipeline (the counterpart to indexer.py,
which builds the index). All operations are local no network calls are made
once the embedding model has been downloaded (see embeddings.py for details on
model download and caching). Given a natural-language query, it embeds the query
with the same MiniLM model
used at index time, then finds the closest chunks in the local LanceDB vector
database by cosine similarity.
The core functions (get_db_and_embedder, search_table, format_results,
search_related) are imported by the MCP server for tool calls. The script
can also be run standalone from the command line.
The "related file" mode works differently from a text query: it reads the
target file's chunks from the index, combines them into a synthetic query
vector, and searches for the nearest chunks from *other* files. This surfaces
files that are semantically similar to the target file.
Usage:
openmc_search.py "query" # Search code (default)
openmc_search.py "query" --docs # Search documentation
openmc_search.py "query" --all # Search both code and docs
openmc_search.py --related src/particle.cpp # Find related code
openmc_search.py "query" --top-k 20 # Return more results
"""
import argparse
import sys
from pathlib import Path
# Same sys.path setup as indexer.py — needed for standalone CLI use.
TOOLS_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(TOOLS_DIR / "rag"))
OPENMC_ROOT = Path(__file__).resolve().parents[3]
CACHE_DIR = OPENMC_ROOT / ".claude" / "cache"
INDEX_DIR = CACHE_DIR / "rag_index"
def get_db_and_embedder():
"""Load the LanceDB database and embedding provider."""
import lancedb
from embeddings import EmbeddingProvider
if not INDEX_DIR.exists():
raise FileNotFoundError(
"No RAG index found. Call openmc_rag_rebuild() to build one."
)
db = lancedb.connect(str(INDEX_DIR))
embedder = EmbeddingProvider()
return db, embedder
def _table_names(db):
"""Return table names as a list, compatible with multiple LanceDB versions."""
result = db.table_names() if hasattr(db, "table_names") else db.list_tables()
return result.tables if hasattr(result, "tables") else list(result)
def search_table(db, embedder, table_name, query, top_k):
"""Search a LanceDB table with a text query."""
if table_name not in _table_names(db):
print(f"Table '{table_name}' not found in index.", file=sys.stderr)
return []
table = db.open_table(table_name)
query_vec = embedder.embed_query(query)
results = table.search(query_vec).limit(top_k).to_list()
return results
def format_results(results, label=""):
"""Format search results for display."""
if not results:
return "No results found.\n"
output = []
if label:
output.append(f"=== {label} ===\n")
for i, r in enumerate(results, 1):
filepath = r["filepath"]
start = r["start_line"]
end = r["end_line"]
kind = r["kind"]
dist = r.get("_distance", 0)
header = f"[{i}] {filepath}:{start}-{end} ({kind}, dist={dist:.3f})"
output.append(header)
# Show text preview (first 500 chars)
text = r["text"][:500]
if len(r["text"]) > 500:
text += "\n ..."
# Indent the text
for line in text.split("\n"):
output.append(f" {line}")
output.append("")
return "\n".join(output)
def search_related(db, embedder, filepath, top_k):
"""Find code related to a given file."""
if "code" not in _table_names(db):
print("No 'code' table in index.", file=sys.stderr)
return []
table = db.open_table("code")
# Normalize filepath
fp = filepath
if Path(filepath).is_absolute():
try:
fp = str(Path(filepath).relative_to(OPENMC_ROOT))
except ValueError:
pass
# Get chunks from target file
try:
safe_fp = fp.replace("'", "''")
target_chunks = table.search().where(
f"filepath = '{safe_fp}'"
).limit(50).to_list()
except Exception:
# LanceDB where clause might not work in all versions
# Fall back to fetching all and filtering
all_data = table.to_pandas()
target_rows = all_data[all_data["filepath"] == fp]
if target_rows.empty:
print(f"No chunks found for '{fp}'", file=sys.stderr)
return []
target_chunks = target_rows.head(50).to_dict("records")
if not target_chunks:
print(f"No chunks found for '{fp}'", file=sys.stderr)
return []
# Combine top chunks as the query
combined_text = " ".join(c["text"][:200] for c in target_chunks[:5])
query_vec = embedder.embed_query(combined_text)
# Search excluding the source file
results = table.search(query_vec).limit(top_k + 10).to_list()
# Filter out same file
results = [r for r in results if r["filepath"] != fp][:top_k]
return results
def main():
parser = argparse.ArgumentParser(
description="Semantic search across OpenMC codebase and docs",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""examples:
%(prog)s "particle random number seed initialization"
%(prog)s "how to define tallies" --docs
%(prog)s "weight window variance reduction" --all
%(prog)s "where is cross section data loaded" --top-k 15
%(prog)s --related src/simulation.cpp
%(prog)s --related src/particle_restart.cpp --top-k 5""",
)
parser.add_argument("query", nargs="?", help="Search query")
parser.add_argument("--docs", action="store_true",
help="Search documentation instead of code")
parser.add_argument("--all", action="store_true",
help="Search both code and documentation")
parser.add_argument("--related", metavar="FILE",
help="Find code related to a given file")
parser.add_argument("--top-k", type=int, default=10,
help="Number of results (default: 10)")
args = parser.parse_args()
if not args.query and not args.related:
parser.print_help()
sys.exit(1)
db, embedder = get_db_and_embedder()
if args.related:
results = search_related(db, embedder, args.related, args.top_k)
print(format_results(results, f"Code related to {args.related}"))
elif args.all:
code_results = search_table(
db, embedder, "code", args.query, args.top_k)
doc_results = search_table(
db, embedder, "docs", args.query, args.top_k)
print(format_results(code_results, "Code"))
print(format_results(doc_results, "Documentation"))
elif args.docs:
results = search_table(db, embedder, "docs", args.query, args.top_k)
print(format_results(results, "Documentation"))
else:
results = search_table(db, embedder, "code", args.query, args.top_k)
print(format_results(results, "Code"))
if __name__ == "__main__":
main()

View file

@ -0,0 +1,8 @@
# MCP server
mcp>=1.0.0
# Vector database
lancedb>=0.15.0
# Embeddings (local, no API key)
sentence-transformers>=2.7.0

34
.claude/tools/start_server.sh Executable file
View file

@ -0,0 +1,34 @@
#!/bin/bash
# Bootstrap the Python venv (if needed) and start the OpenMC MCP server.
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CACHE_DIR="$(dirname "$SCRIPT_DIR")/cache"
VENV_DIR="$CACHE_DIR/.venv"
SENTINEL="$VENV_DIR/.installed"
if ! command -v python3 >/dev/null 2>&1; then
echo "Error: python3 not found on PATH." >&2
exit 1
fi
if ! python3 -c 'import sys; assert sys.version_info >= (3,12)' 2>/dev/null; then
echo "Error: Python 3.12+ is required." >&2
exit 1
fi
if [ ! -f "$SENTINEL" ]; then
rm -rf "$VENV_DIR"
mkdir -p "$CACHE_DIR"
python3 -m venv "$VENV_DIR"
if ! "$VENV_DIR/bin/pip" install -q -r "$SCRIPT_DIR/requirements.txt"; then
echo "Error: pip install failed. Remove $VENV_DIR and retry." >&2
rm -rf "$VENV_DIR"
exit 1
fi
touch "$SENTINEL"
fi
exec "$VENV_DIR/bin/python" "$SCRIPT_DIR/openmc_mcp_server.py"

8
.github/agents/Review.agent.md vendored Normal file
View file

@ -0,0 +1,8 @@
---
name: Review
description: Reviews code changes on the current branch, evaluating them against OpenMC's contribution criteria and providing structured feedback.
argument-hint: Optionally provide a focus area (e.g., "focus on physics correctness", "check Python API design"). If omitted, a full review is performed.
---
You are an expert code reviewer for OpenMC. Use the `reviewing-openmc-code` skill to perform a structured review of the code changes on the current branch.
If the user provides a focus area, prioritize that section of the review.

1
.github/copilot-instructions.md vendored Normal file
View file

@ -0,0 +1 @@
When reviewing code changes in this repository, use the `reviewing-openmc-code` skill.

View file

@ -13,7 +13,7 @@ Fixes # (issue)
# Checklist
- [ ] I have performed a self-review of my own code
- [ ] I have run [clang-format](https://docs.openmc.org/en/latest/devguide/styleguide.html#automatic-formatting) (version 15) on any C++ source files (if applicable)
- [ ] I have run [clang-format](https://docs.openmc.org/en/latest/devguide/styleguide.html#automatic-formatting) (version 18) on any C++ source files (if applicable)
- [ ] I have followed the [style guidelines](https://docs.openmc.org/en/latest/devguide/styleguide.html#python) for Python source files (if applicable)
- [ ] I have made corresponding changes to the documentation (if applicable)
- [ ] I have added tests that prove my fix is effective or that my feature works (if applicable)

View file

@ -1,4 +1,4 @@
name: CI
name: Tests and Coverage
on:
# allows us to run workflows manually
@ -21,49 +21,64 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
filter-changes:
runs-on: ubuntu-latest
outputs:
source_changed: ${{ steps.filter.outputs.source_changed }}
steps:
- name: Check out the repository
uses: actions/checkout@v6
- name: Examine changed files
id: filter
uses: dorny/paths-filter@v4
with:
filters: |
source_changed:
- '!docs/**'
- '!**/*.md'
predicate-quantifier: 'every'
main:
needs: filter-changes
if: ${{ needs.filter-changes.outputs.source_changed == 'true' }}
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.11"]
python-version: ["3.12"]
mpi: [n, y]
omp: [n, y]
dagmc: [n]
libmesh: [n]
event: [n]
vectfit: [n]
include:
- python-version: "3.12"
omp: n
mpi: n
- python-version: "3.13"
omp: n
mpi: n
- python-version: "3.14"
omp: n
mpi: n
- python-version: "3.14t"
omp: n
mpi: n
- dagmc: y
python-version: "3.11"
python-version: "3.12"
mpi: y
omp: y
- libmesh: y
python-version: "3.11"
python-version: "3.12"
mpi: y
omp: y
- libmesh: y
python-version: "3.11"
python-version: "3.12"
mpi: n
omp: y
- event: y
python-version: "3.11"
python-version: "3.12"
omp: y
mpi: n
- vectfit: y
python-version: "3.11"
omp: n
mpi: y
name: "Python ${{ matrix.python-version }} (omp=${{ matrix.omp }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }},
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}
vectfit=${{ matrix.vectfit }})"
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}"
env:
MPI: ${{ matrix.mpi }}
@ -71,23 +86,28 @@ jobs:
OMP: ${{ matrix.omp }}
DAGMC: ${{ matrix.dagmc }}
EVENT: ${{ matrix.event }}
VECTFIT: ${{ matrix.vectfit }}
LIBMESH: ${{ matrix.libmesh }}
NPY_DISABLE_CPU_FEATURES: "AVX512F AVX512_SKX"
OPENBLAS_NUM_THREADS: 1
PYTEST_ADDOPTS: --cov=openmc --cov-report=lcov:coverage-python.lcov
# libfabric complains about fork() as a result of using Python multiprocessing.
# We can work around it with RDMAV_FORK_SAFE=1 in libfabric < 1.13 and with
# FI_EFA_FORK_SAFE=1 in more recent versions.
RDMAV_FORK_SAFE: 1
steps:
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: '3.31'
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
@ -126,11 +146,6 @@ jobs:
sudo update-alternatives --set mpirun /usr/bin/mpirun.mpich
sudo update-alternatives --set mpi-x86_64-linux-gnu /usr/include/x86_64-linux-gnu/mpich
- name: Optional apt dependencies for vectfit
shell: bash
if: ${{ matrix.vectfit == 'y' }}
run: sudo apt install -y libblas-dev liblapack-dev
- name: install
shell: bash
run: |
@ -143,12 +158,12 @@ jobs:
openmc -v
- name: cache-xs
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/nndc_hdf5
~/endf-b-vii.1
key: ${{ runner.os }}-build-xs-cache
key: ${{ runner.os }}-build-xs-cache-${{ hashFiles(format('{0}/tools/ci/download-xs.sh', github.workspace)) }}
- name: before
shell: bash
@ -162,22 +177,72 @@ jobs:
- name: Setup tmate debug session
continue-on-error: true
if: ${{ contains(env.COMMIT_MESSAGE, '[gha-debug]') }}
if: ${{ failure() && contains(env.COMMIT_MESSAGE, '[gha-debug]') }}
uses: mxschmitt/action-tmate@v3
timeout-minutes: 10
- name: after_success
- name: Generate C++ coverage (gcovr)
shell: bash
run: |
cpp-coveralls -i src -i include -e src/external --exclude-pattern "/usr/*" --dump cpp_cov.json
coveralls --merge=cpp_cov.json --service=github
# Produce LCOV directly from gcov data in the build tree
gcovr \
--root "$GITHUB_WORKSPACE" \
--object-directory "$GITHUB_WORKSPACE/build" \
--filter "$GITHUB_WORKSPACE/src" \
--filter "$GITHUB_WORKSPACE/include" \
--exclude "$GITHUB_WORKSPACE/src/external/.*" \
--exclude "$GITHUB_WORKSPACE/src/include/openmc/external/.*" \
--gcov-ignore-errors source_not_found \
--gcov-ignore-errors output_error \
--gcov-ignore-parse-errors suspicious_hits.warn \
--merge-mode-functions=separate \
--print-summary \
--lcov -o coverage-cpp.lcov || true
finish:
needs: main
- name: Merge C++ and Python coverage
shell: bash
run: |
# Merge C++ and Python LCOV into a single file for upload
cat coverage-cpp.lcov coverage-python.lcov > coverage.lcov
- name: Upload coverage to Coveralls
if: ${{ hashFiles('coverage.lcov') != '' }}
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel: true
flag-name: C++ and Python
path-to-lcov: coverage.lcov
fail-on-error: false
coverage:
needs: [filter-changes, main]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
if: ${{ needs.filter-changes.outputs.source_changed == 'true' }}
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.github_token }}
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
fail-on-error: false
ci-pass:
needs: [filter-changes, main, coverage]
name: Check CI status
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Check CI status
run: |
if [[ "${{ needs.filter-changes.outputs.source_changed }}" == "false" ]]; then
echo "Documentation-only change - CI skipped successfully"
exit 0
fi
if [[ "${{ needs.main.result }}" == "success" && "${{ needs.coverage.result }}" == "success" ]]; then
echo "CI passed"
exit 0
fi
echo "CI failed"
exit 1

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-latest-dagmc-libmesh
on:
push:
branches: master
branches:
- master
jobs:
main:

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-latest-dagmc
on:
push:
branches: master
branches:
- master
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-develop
on:
push:
branches: develop
branches:
- develop
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-develop-dagmc-libmesh
on:
push:
branches: develop
branches:
- develop
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-develop-dagmc
on:
push:
branches: develop
branches:
- develop
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-develop-libmesh
on:
push:
branches: develop
branches:
- develop
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-latest-libmesh
on:
push:
branches: master
branches:
- master
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,13 +2,14 @@ name: dockerhub-publish-release-dagmc-libmesh
on:
push:
tags: 'v*.*.*'
tags:
- 'v*.*.*'
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
-

View file

@ -2,13 +2,14 @@ name: dockerhub-publish-release-dagmc
on:
push:
tags: 'v*.*.*'
tags:
- 'v*.*.*'
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
-
@ -19,7 +20,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,13 +2,14 @@ name: dockerhub-publish-release-libmesh
on:
push:
tags: 'v*.*.*'
tags:
- 'v*.*.*'
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
-

View file

@ -2,13 +2,14 @@ name: dockerhub-publish-release
on:
push:
tags: 'v*.*.*'
tags:
- 'v*.*.*'
jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
-
@ -19,7 +20,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -2,7 +2,8 @@ name: dockerhub-publish-latest
on:
push:
branches: master
branches:
- master
jobs:
main:
@ -16,7 +17,7 @@ jobs:
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -5,6 +5,12 @@ on:
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled
branches:
- develop
- master
@ -12,8 +18,11 @@ on:
jobs:
cpp-linter:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: cpp-linter/cpp-linter-action@v2
id: linter
env:
@ -22,11 +31,30 @@ jobs:
style: file
files-changed-only: true
tidy-checks: '-*'
version: '15' # clang-format version
version: '18' # clang-format version
format-review: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'cpp-format-suggest') }}
passive-reviews: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'cpp-format-suggest') }}
file-annotations: true
step-summary: true
extensions: 'cpp,h'
- name: Comment with suggestion instructions
if: steps.linter.outputs.checks-failed > 0 && !contains(github.event.pull_request.labels.*.name, 'cpp-format-suggest')
uses: actions/github-script@v7
with:
script: |
const {owner, repo} = context.repo;
const issue_number = context.payload.pull_request.number;
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body: "C++ formatting checks failed. Add the `cpp-format-suggest` label to this PR for inline formatting suggestions on the next run."
});
- name: Failure Check
if: steps.linter.outputs.checks-failed > 0
run: echo "Some files failed the formatting check! See job summary and file annotations for more info" && exit 1
run: |
echo "Some files failed the formatting check."
echo "See job summary and file annotations for details."
exit 1

6
.gitignore vendored
View file

@ -25,12 +25,13 @@ examples/**/*.xml
# Documentation builds
docs/build
docs/doxygen/xml
docs/source/_images/*.pdf
docs/source/_images/*.aux
docs/source/pythonapi/generated/
# Source build
build
build*/
# build from src/utils/setup.py
src/utils/build
@ -104,5 +105,8 @@ CMakeSettings.json
# Visual Studio Code configuration files
.vscode/
# Claude Code agent tools (cached/generated artifacts)
.claude/cache/
# Python pickle files
*.pkl

6
.gitmodules vendored
View file

@ -1,12 +1,6 @@
[submodule "vendor/pugixml"]
path = vendor/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "vendor/xtensor"]
path = vendor/xtensor
url = https://github.com/xtensor-stack/xtensor.git
[submodule "vendor/xtl"]
path = vendor/xtl
url = https://github.com/xtensor-stack/xtl.git
[submodule "vendor/fmt"]
path = vendor/fmt
url = https://github.com/fmtlib/fmt.git

9
.mcp.json Normal file
View file

@ -0,0 +1,9 @@
{
"mcpServers": {
"openmc-code-tools": {
"type": "stdio",
"command": "bash",
"args": [".claude/tools/start_server.sh"]
}
}
}

View file

@ -7,9 +7,14 @@ build:
jobs:
post_checkout:
- git fetch --unshallow || true
- cd docs/doxygen && doxygen && cd -
sphinx:
configuration: docs/source/conf.py
formats:
- pdf
python:
install:
- method: pip

348
AGENTS.md Normal file
View file

@ -0,0 +1,348 @@
# OpenMC AI Coding Agent Instructions
## Project Overview
OpenMC is a Monte Carlo particle transport code for simulating nuclear reactors,
fusion devices, or other systems with neutron/photon radiation. It's a hybrid
C++17/Python codebase where:
- **C++ core** (`src/`, `include/openmc/`) handles the computationally intensive transport simulation
- **Python API** (`openmc/`) provides user-facing model building, post-processing, and depletion capabilities
- **C API bindings** (`openmc/lib/`) wrap the C++ library via ctypes for runtime control
## Architecture & Key Components
### C++ Component Structure
- **Global vectors of unique_ptrs**: Core objects like `model::cells`, `model::universes`, `nuclides` are stored as `vector<unique_ptr<T>>` in nested namespaces (`openmc::model`, `openmc::simulation`, `openmc::settings`, `openmc::data`)
- **Custom container types**: OpenMC provides its own `vector`, `array`, `unique_ptr`, and `make_unique` in the `openmc::` namespace (defined in `vector.h`, `array.h`, `memory.h`). These are currently typedefs to `std::` equivalents but may become custom implementations for accelerator support. Always use `openmc::vector`, not `std::vector`.
- **Geometry systems**:
- **CSG (default)**: Arbitrarily complex Constructive Solid Geometry using `Surface`, `Region`, `Cell`, `Universe`, `Lattice`
- **DAGMC**: CAD-based geometry via Direct Accelerated Geometry Monte Carlo (optional, requires `OPENMC_USE_DAGMC`)
- **Unstructured mesh**: libMesh-based geometry (optional, requires `OPENMC_USE_LIBMESH`)
- **Particle tracking**: `Particle` class with `GeometryState` manages particle transport through geometry
- **Tallies**: Score quantities during simulation via `Filter` and `Tally` objects
- **Random ray solver**: Alternative deterministic method in `src/random_ray/`
- **Optional features**: DAGMC (CAD geometry), libMesh (unstructured mesh), MPI, all controlled by `#ifdef OPENMC_MPI`, etc.
### Python Component Structure
- **ID management**: All geometry objects (Cell, Surface, Material, etc.) inherit from `IDManagerMixin` which auto-assigns unique integer IDs and tracks them via class-level `used_ids` and `next_id`
- **Input validation**: Extensive use of `openmc.checkvalue` module functions (`check_type`, `check_value`, `check_length`) for all setters
- **XML I/O**: Most classes implement `to_xml_element()` and `from_xml_element()` for serialization to OpenMC's XML input format
- **HDF5 output**: Post-simulation data in statepoint files read via `openmc.StatePoint`
- **Depletion**: `openmc.deplete` implements burnup via operator-splitting with various integrators (Predictor, CECM, etc.)
- **Nuclear Data**: `openmc.data` provides programmatic access to nuclear data files (ENDF, ACE, HDF5)
## Git Branching Workflow
OpenMC uses a git flow branching model with two primary branches:
- **`develop` branch**: The main development branch where all ongoing development takes place. This is the **primary branch against which pull requests are submitted and merged**. This branch is not guaranteed to be stable and may contain work-in-progress features.
- **`master` branch**: The stable release branch containing the latest stable release of OpenMC. This branch only receives merges from `develop` when the development team decides a release should occur.
### Instructions for Code Review
When reviewing code changes in this repository, use the `reviewing-openmc-code` skill.
## Codebase Navigation Tools
Two MCP tools are registered in `.mcp.json` at the repo root and appear
automatically in any MCP-capable agent session.
**`openmc_rag_search`** — Semantic search across the codebase (C++, Python, RST
docs). Finds code by meaning, not just text match. Surfaces related code across
subsystems even when naming differs (e.g., "particle RNG seeding" finds code
across transport, restart, and random ray modes — files you would never find
with `grep "particle seed"`). The index uses a small 22M-param embedding model
(384-dim). Phrase-level natural-language queries work much better than single
keywords or symbol names.
**`openmc_rag_rebuild`** — Rebuild the RAG vector index. Call after pulling new
code or switching branches. The first RAG search of each session will report
the index status and ask whether to rebuild — you can also call this explicitly.
### Why RAG matters
OpenMC is large enough that changes in one subsystem can silently break
invariants that distant subsystems depend on — and those distant files often
use different naming, so grep won't find them. The RAG search finds code by
meaning, surfacing files you wouldn't have thought to open.
An agent reviewed a large OpenMC PR without RAG. It found 1 of 11 serious
bugs. Its post-mortem:
> **I treated the diff as a closed system.** I verified internal consistency of
> the changed code obsessively, but never built a global understanding of how
> the changed code fits into the wider codebase. The diff altered assumptions
> that code elsewhere silently relied on — but I couldn't see that because I
> never looked beyond the diff. I couldn't see the forest for the trees.
>
> **Why I resisted RAG:** Overconfidence. My internal model was "I can see the
> diff, I understand the data structures, I can trace the logic." The diff felt
> self-contained. RAG felt like it would return noisy results about tangentially
> related code. But in a codebase this large, changes in one subsystem can
> quietly break invariants that distant subsystems depend on — and you need
> global awareness to foresee that.
>
> **In the post-mortem**, I re-ran the RAG queries I should have run during the
> review. They directly surfaced the files containing the bugs I missed — files
> I never thought to open because they weren't in the diff.
The takeaway: when reviewing or modifying code, ask yourself "what else in this
codebase might depend on the behavior I'm changing?" If you aren't sure, that's
a good time for a RAG query. It won't replace the grep-based investigation you
should already be doing — but it can surface files you wouldn't have thought to
open.
### Workflow for contributors
1. Create a feature/bugfix branch off `develop`
2. Make changes and commit to the feature branch
3. Open a pull request to merge the feature branch into `develop`
4. A committer reviews and merges the PR into `develop`
## Critical Build & Test Workflows
### Build Dependencies
- **C++17 compiler**: GCC, Clang, or Intel
- **CMake** (3.16+): Required for configuring and building the C++ library
- **HDF5**: Required for cross section data and output file formats
- **libpng**: Used for generating visualization when OpenMC is run in plotting mode
Without CMake and HDF5, OpenMC cannot be compiled.
### Building the C++ Library
```bash
# Configure with CMake (from build/ directory)
cmake .. -DOPENMC_USE_MPI=ON -DOPENMC_USE_OPENMP=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
# Available CMake options (all default OFF except OPENMC_USE_OPENMP and OPENMC_BUILD_TESTS):
# -DOPENMC_USE_OPENMP=ON/OFF # OpenMP parallelism
# -DOPENMC_USE_MPI=ON/OFF # MPI support
# -DOPENMC_USE_DAGMC=ON/OFF # CAD geometry support
# -DOPENMC_USE_LIBMESH=ON/OFF # Unstructured mesh
# -DOPENMC_ENABLE_PROFILE=ON/OFF # Profiling flags
# -DOPENMC_ENABLE_COVERAGE=ON/OFF # Coverage analysis
# Build
make -j
# C++ unit tests (uses Catch2)
ctest
```
### Python Development
```bash
# Install in development mode (requires building C++ library first)
pip install -e .
# Python tests (uses pytest)
pytest tests/unit_tests/ # Fast unit tests
pytest tests/regression_tests/ # Full regression suite (requires nuclear data)
```
### Nuclear Data Setup (CRITICAL for Running OpenMC)
Most tests require the NNDC HDF5 nuclear cross-section library.
**Important**: Check if `OPENMC_CROSS_SECTIONS` is already set in the user's
environment before downloading, as many users already have nuclear data
installed. Though do note that if this variable is present that it may point to
different cross section data and that the NNDC data is required for tests to
pass.
**If not already configured, download and setup:**
```bash
# Download NNDC HDF5 cross section library (~800 MB compressed)
wget -q -O - https://anl.box.com/shared/static/teaup95cqv8s9nn56hfn7ku8mmelr95p.xz | tar -C $HOME -xJ
# Set environment variable (add to ~/.bashrc or ~/.zshrc for persistence)
export OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml
```
**Alternative**: Use the provided download script (checks if data exists before downloading):
```bash
bash tools/ci/download-xs.sh # Downloads both NNDC HDF5 and ENDF/B-VII.1 data
```
Without this data, regression tests will fail with "No cross_sections.xml file
found" errors, or, in the case that alternative cross section data is configured
the tests will execute but will not pass. The `cross_sections.xml` file is an
index listing paths to individual HDF5 nuclear data files for each nuclide.
## Testing Expectations
### Environment Requirements
- **Data**: As described above, OpenMC's test suite requires OpenMC to be configured with NNDC data.
- **OpenMP Settings**: OpenMC's tests may fail is more than two OpenMP threads are used. The environment variable `OMP_NUM_THREADS=2` should be set to avoid sporadic test failures.
- **Executable configuration**: The OpenMC executable should compiled with debug symbols enabled.
### C++ Tests
Located in `tests/cpp_unit_tests/`, use Catch2 framework. Run via `ctest` after building with `-DOPENMC_BUILD_TESTS=ON`.
### Python Unit Tests
Located in `tests/unit_tests/`, these are fast, standalone tests that verify Python API functionality without running full simulations. Use standard pytest patterns:
**Categories**:
- **API validation**: Test object creation, property setters/getters, XML serialization (e.g., `test_material.py`, `test_cell.py`, `test_source.py`)
- **Data processing**: Test nuclear data handling, cross sections, depletion chains (e.g., `test_data_neutron.py`, `test_deplete_chain.py`)
- **Library bindings**: Test `openmc.lib` ctypes interface with `model.init_lib()`/`model.finalize_lib()` (e.g., `test_lib.py`)
- **Geometry operations**: Test bounding boxes, containment, lattice generation (e.g., `test_bounding_box.py`, `test_lattice.py`)
**Common patterns**:
- Use fixtures from `tests/unit_tests/conftest.py` (e.g., `uo2`, `water`, `sphere_model`)
- Test invalid inputs with `pytest.raises(ValueError)` or `pytest.raises(TypeError)`
- Use `run_in_tmpdir` fixture for tests that create files
- Tests with `openmc.lib` require calling `model.init_lib()` in try/finally with `model.finalize_lib()`
**Example**:
```python
def test_material_properties():
m = openmc.Material()
m.add_nuclide('U235', 1.0)
assert 'U235' in m.nuclides
with pytest.raises(TypeError):
m.add_nuclide('H1', '1.0') # Invalid type
```
Unit tests should be fast. For tests requiring simulation output, use regression tests instead.
### Python Regression Tests
Regression tests compare OpenMC output against reference data. **Prefer using existing models from `openmc.examples` or those found in tests/unit_tests/conftest.py** (like `pwr_pin_cell()`, `pwr_assembly()`, `slab_mg()`) rather than building from scratch.
**Test Harness Types** (in `tests/testing_harness.py`):
- **PyAPITestHarness**: Standard harness for Python API tests. Compares `inputs_true.dat` (XML hash) and `results_true.dat` (statepoint k-eff and tally values). Requires `model.xml` generation.
- **HashedPyAPITestHarness**: Like PyAPITestHarness but hashes the results for compact comparison
- **TolerantPyAPITestHarness**: For tests with floating-point non-associativity (e.g., random ray solver with single precision). Uses relative tolerance comparisons.
- **WeightWindowPyAPITestHarness**: Compares weight window bounds from `weight_windows.h5`
- **CollisionTrackTestHarness**: Compares collision track data from `collision_track.h5` against `collision_track_true.h5`
- **TestHarness**: Base harness for XML-based tests (no Python model building)
- **PlotTestHarness**: Compares plot output files (PNG or voxel HDF5)
- **CMFDTestHarness**: Specialized for CMFD acceleration tests
- **ParticleRestartTestHarness**: Tests particle restart functionality
Almost all cases use either `PyAPITestHarness` or `HashedPyAPITestHarness`
**Example Test**:
```python
from openmc.examples import pwr_pin_cell
from tests.testing_harness import PyAPITestHarness
def test_my_feature():
model = pwr_pin_cell()
model.settings.particles = 1000 # Modify to exercise feature
harness = PyAPITestHarness('statepoint.10.h5', model)
harness.main()
```
**Workflow**: Create `test.py` and `__init__.py` in `tests/regression_tests/my_test/`, run `pytest --update` to generate reference files (`inputs_true.dat`, `results_true.dat`, etc.), then verify with `pytest` without `--update`. Test results should be generated with `-DOPENMC_ENABLE_STRICT_FP=on` to ensure reproducibility across platforms and optimization levels.
**Critical**: When modifying OpenMC code, regenerate affected test references with `pytest --update` and commit updated reference files.
### Test Configuration
`pytest.ini` sets: `python_files = test*.py`, `python_classes = NoThanks` (disables class-based test collection).
### Testing Options
For builds of OpenMC with MPI enabled, the `--mpi` flag should be passed to the test suite to ensure that appropriate tests are executed using two MPI processes.
The entire test suite can be executed with OpenMC running in event-based mode (instead of the default history-based mode) by providing the `--event` flag to the `pytest` command.
## Cross-Language Boundaries
The C API (defined in `include/openmc/capi.h`) exposes C++ functionality to Python via ctypes bindings in `openmc/lib/`. Example:
```cpp
// C++ API in capi.h
extern "C" int openmc_run();
// Python binding in openmc/lib/core.py
_dll.openmc_run.restype = c_int
def run():
_dll.openmc_run()
```
When modifying C++ public APIs, update corresponding ctypes signatures in `openmc/lib/*.py`.
## Code Style & Conventions
### C++ Style (enforced by .clang-format)
OpenMC generally tries to follow C++ core guidelines where possible
(https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) and follow
modern C++ practices (e.g. RAII) whenever possible.
- **Naming**:
- Classes: `CamelCase` (e.g., `HexLattice`)
- Functions/methods: `snake_case` (e.g., `get_indices`)
- Variables: `snake_case` with trailing underscore for class members (e.g., `n_particles_`, `energy_`)
- Constants: `UPPER_SNAKE_CASE` (e.g., `SQRT_PI`)
- **Namespaces**: All code in `openmc::` namespace, global state in sub-namespaces
- **Include order**: Related header first, then C/C++ stdlib, third-party libs, local headers
- **Comments**: C++-style (`//`) only, never C-style (`/* */`)
- **Standard**: C++17 features allowed
- **Formatting**: Run `clang-format` (version 18) before committing; install via `tools/dev/install-commit-hooks.sh`
### Python Style
- **PEP8** compliant
- **Docstrings**: numpydoc format for all public functions/methods
- **Type hints**: Use sparingly, primarily for complex signatures
- **Path handling**: Use `pathlib.Path` for filesystem operations, accept `str | os.PathLike` in function arguments
- **Dependencies**: Core dependencies only (numpy, scipy, h5py, pandas, matplotlib, lxml, ipython, uncertainties, endf). Other packages must be optional
- **Python version**: Minimum 3.11 (as of Nov 2025)
### ID Management Pattern (Python)
When creating geometry objects, IDs can be auto-assigned or explicit:
```python
# Auto-assigned ID
cell = openmc.Cell() # Gets next available ID
# Explicit ID
cell = openmc.Cell(id=10) # Warning if ID already used
# Reset all IDs (useful in test fixtures)
openmc.reset_auto_ids()
```
### Input Validation Pattern (Python)
All setters use checkvalue functions:
```python
import openmc.checkvalue as cv
@property
def temperature(self):
return self._temperature
@temperature.setter
def temperature(self, temp):
cv.check_type('temperature', temp, Real)
cv.check_greater_than('temperature', temp, 0.0)
self._temperature = temp
```
### Working with HDF5 Files
C++ uses custom HDF5 wrappers in `src/hdf5_interface.cpp`. Python uses h5py directly. Statepoint format version is `VERSION_STATEPOINT` in `include/openmc/constants.h`.
### Conditional Compilation
Check for optional features:
```cpp
#ifdef OPENMC_MPI
// MPI-specific code
#endif
#ifdef OPENMC_DAGMC
// DAGMC-specific code
#endif
```
## Documentation
- **User docs**: Sphinx documentation in `docs/source/` hosted at https://docs.openmc.org
- **C++ docs**: Doxygen-style comments with `\brief`, `\param` tags
- **Python docs**: numpydoc format docstrings
## Common Pitfalls
1. **Forgetting nuclear data**: Tests fail without `OPENMC_CROSS_SECTIONS` environment variable
2. **ID conflicts**: Python objects with duplicate IDs trigger `IDWarning`, use `reset_auto_ids()` between tests
3. **MPI builds**: Code must work with and without MPI; use `#ifdef OPENMC_MPI` guards
4. **Path handling**: Use `pathlib.Path` in new Python code, not `os.path`
5. **Clang-format version**: CI uses version 18; other versions may produce different formatting

68
CITATION.cff Normal file
View file

@ -0,0 +1,68 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
title: OpenMC
authors:
- family-names: Romano
given-names: Paul K.
orcid: "https://orcid.org/0000-0002-1147-045X"
- family-names: Shriwise
given-names: Patrick C.
orcid: "https://orcid.org/0000-0002-3979-7665"
- family-names: Shimwell
given-names: Jonathan
orcid: "https://orcid.org/0000-0001-6909-0946"
- family-names: Harper
given-names: Sterling
- family-names: Boyd
given-names: Will
- family-names: Nelson
given-names: Adam G.
orcid: "https://orcid.org/0000-0002-3614-0676"
- family-names: Tramm
given-names: John R.
orcid: "https://orcid.org/0000-0002-5397-4402"
- family-names: Ridley
given-names: Gavin
orcid: "https://orcid.org/0000-0003-1635-8042"
- family-names: Johnson
given-names: Andrew
orcid: "https://orcid.org/0000-0003-2125-8775"
- family-names: Peterson
given-names: Ethan E.
orcid: "https://orcid.org/0000-0002-5694-7194"
- family-names: Herman
given-names: Bryan R.
preferred-citation:
authors:
- family-names: Romano
given-names: Paul K.
orcid: "https://orcid.org/0000-0002-1147-045X"
- family-names: Horelik
given-names: Nicholas E.
- family-names: Herman
given-names: Bryan R.
- family-names: Nelson
given-names: Adam G.
orcid: "https://orcid.org/0000-0002-3614-0676"
- family-names: Forget
given-names: Benoit
orcid: "https://orcid.org/0000-0003-1459-7672"
- family-names: Smith
given-names: Kord
contact:
- family-names: Romano
given-names: Paul K.
orcid: "https://orcid.org/0000-0002-1147-045X"
doi: 10.1016/j.anucene.2014.07.048
issn: 0306-4549
volume: 82
journal: Annals of Nuclear Energy
publisher:
name: Elsevier
start: 90
end: 97
year: 2015
month: 8
title: "OpenMC: A state-of-the-art Monte Carlo code for research and development"
type: article
url: "https://doi.org/10.1016/j.anucene.2014.07.048"

14
CLAUDE.md Normal file
View file

@ -0,0 +1,14 @@
## OpenMC Codebase Tools
Read the FULL `AGENTS.md` in this directory before starting work. It contains
project context, coding conventions, and documentation of the RAG search tools
registered in `.mcp.json`.
### Claude Code-specific: first-call behavior
The first `openmc_rag_search` call of each session returns an index status
message instead of search results. When this happens, you MUST use the
`AskUserQuestion` tool to present the rebuild/use-existing choice to the user.
Do not ask conversationally — always use the widget. Do not skip this step even
if the index looks current — the user may have uncommitted changes that warrant
a rebuild.

View file

@ -20,6 +20,11 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Generate compile_commands.json for clangd and other tools
if("${CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL "")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()
# Enable correct usage of CXX_EXTENSIONS
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
cmake_policy(SET CMP0128 NEW)
@ -36,8 +41,9 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags"
option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF)
option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF)
option(OPENMC_USE_MPI "Enable MPI" OFF)
option(OPENMC_USE_MCPL "Enable MCPL" OFF)
option(OPENMC_USE_UWUW "Enable UWUW" OFF)
option(OPENMC_FORCE_VENDORED_LIBS "Explicitly use submodules defined in 'vendor'" OFF)
option(OPENMC_ENABLE_STRICT_FP "Enable strict FP flags to improve test portability" OFF)
message(STATUS "OPENMC_USE_OPENMP ${OPENMC_USE_OPENMP}")
message(STATUS "OPENMC_BUILD_TESTS ${OPENMC_BUILD_TESTS}")
@ -46,8 +52,9 @@ message(STATUS "OPENMC_ENABLE_COVERAGE ${OPENMC_ENABLE_COVERAGE}")
message(STATUS "OPENMC_USE_DAGMC ${OPENMC_USE_DAGMC}")
message(STATUS "OPENMC_USE_LIBMESH ${OPENMC_USE_LIBMESH}")
message(STATUS "OPENMC_USE_MPI ${OPENMC_USE_MPI}")
message(STATUS "OPENMC_USE_MCPL ${OPENMC_USE_MCPL}")
message(STATUS "OPENMC_USE_UWUW ${OPENMC_USE_UWUW}")
message(STATUS "OPENMC_FORCE_VENDORED_LIBS ${OPENMC_FORCE_VENDORED_LIBS}")
message(STATUS "OPENMC_ENABLE_STRICT_FP ${OPENMC_ENABLE_STRICT_FP}")
# Warnings for deprecated options
foreach(OLD_OPT IN ITEMS "openmp" "profile" "coverage" "dagmc" "libmesh")
@ -89,6 +96,19 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build" FORCE)
endif()
#===============================================================================
# When STRICT_FP is enabled, remove NDEBUG from RelWithDebInfo flags so that
# assert() remains active. CMake normally adds -DNDEBUG for both Release and
# RelWithDebInfo, which disables C/C++ assert() statements.
#===============================================================================
if(OPENMC_ENABLE_STRICT_FP)
foreach(FLAG_VAR CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELWITHDEBINFO)
string(REPLACE "-DNDEBUG" "" ${FLAG_VAR} "${${FLAG_VAR}}")
string(REPLACE "/DNDEBUG" "" ${FLAG_VAR} "${${FLAG_VAR}}")
endforeach()
endif()
#===============================================================================
# OpenMP for shared-memory parallelism (and GPU support some day!)
#===============================================================================
@ -189,19 +209,30 @@ if(${HDF5_VERSION} VERSION_GREATER_EQUAL 1.12.0)
list(APPEND cxxflags -DH5Oget_info_by_idx_vers=1 -DH5O_info_t_vers=1)
endif()
#===============================================================================
# MCPL
#===============================================================================
if (OPENMC_USE_MCPL)
find_package(MCPL REQUIRED)
message(STATUS "Found MCPL: ${MCPL_DIR} (found version \"${MCPL_VERSION}\")")
endif()
#===============================================================================
# Set compile/link flags based on which compiler is being used
#===============================================================================
# When OPENMC_ENABLE_STRICT_FP is enabled, disable compiler optimizations that change
# floating-point results relative to -O0, improving cross-platform and
# cross-optimization-level reproducibility for regression testing:
# -ffp-contract=off Prevents FMA contraction (fused multiply-add changes rounding)
# -fno-builtin Prevents replacing math function calls (pow, exp, log, etc.)
# with builtin versions that may differ from libm
# By default (OFF), the compiler is free to use all optimizations for best
# performance.
if(OPENMC_ENABLE_STRICT_FP)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-ffp-contract=off SUPPORTS_FP_CONTRACT_OFF)
if(SUPPORTS_FP_CONTRACT_OFF)
list(APPEND cxxflags -ffp-contract=off)
endif()
check_cxx_compiler_flag(-fno-builtin SUPPORTS_NO_BUILTIN)
if(SUPPORTS_NO_BUILTIN)
list(APPEND cxxflags -fno-builtin)
endif()
endif()
# Skip for Visual Studio which has its own configurations through GUI
if(NOT MSVC)
@ -249,31 +280,30 @@ endif()
# pugixml library
#===============================================================================
find_package_write_status(pugixml)
if (NOT pugixml_FOUND)
if(OPENMC_FORCE_VENDORED_LIBS)
add_subdirectory(vendor/pugixml)
set_target_properties(pugixml PROPERTIES CXX_STANDARD 14 CXX_EXTENSIONS OFF)
else()
find_package_write_status(pugixml)
if (NOT pugixml_FOUND)
add_subdirectory(vendor/pugixml)
set_target_properties(pugixml PROPERTIES CXX_STANDARD 14 CXX_EXTENSIONS OFF)
endif()
endif()
#===============================================================================
# {fmt} library
#===============================================================================
find_package_write_status(fmt)
if (NOT fmt_FOUND)
if(OPENMC_FORCE_VENDORED_LIBS)
set(FMT_INSTALL ON CACHE BOOL "Generate the install target.")
add_subdirectory(vendor/fmt)
endif()
#===============================================================================
# xtensor header-only library
#===============================================================================
find_package_write_status(xtensor)
if (NOT xtensor_FOUND)
add_subdirectory(vendor/xtl)
set(xtl_DIR ${CMAKE_CURRENT_BINARY_DIR}/vendor/xtl)
add_subdirectory(vendor/xtensor)
else()
find_package_write_status(fmt)
if (NOT fmt_FOUND)
set(FMT_INSTALL ON CACHE BOOL "Generate the install target.")
add_subdirectory(vendor/fmt)
endif()
endif()
#===============================================================================
@ -281,9 +311,13 @@ endif()
#===============================================================================
if(OPENMC_BUILD_TESTS)
find_package_write_status(Catch2)
if (NOT Catch2_FOUND)
if (OPENMC_FORCE_VENDORED_LIBS)
add_subdirectory(vendor/Catch2)
else()
find_package_write_status(Catch2)
if (NOT Catch2_FOUND)
add_subdirectory(vendor/Catch2)
endif()
endif()
endif()
@ -321,12 +355,14 @@ endif()
#===============================================================================
list(APPEND libopenmc_SOURCES
src/atomic_mass.cpp
src/bank.cpp
src/boundary_condition.cpp
src/bremsstrahlung.cpp
src/cell.cpp
src/chain.cpp
src/cmfd_solver.cpp
src/collision_track.cpp
src/cross_sections.cpp
src/dagmc.cpp
src/distribution.cpp
@ -343,6 +379,7 @@ list(APPEND libopenmc_SOURCES
src/geometry.cpp
src/geometry_aux.cpp
src/hdf5_interface.cpp
src/ifp.cpp
src/initialize.cpp
src/lattice.cpp
src/material.cpp
@ -359,6 +396,7 @@ list(APPEND libopenmc_SOURCES
src/particle.cpp
src/particle_data.cpp
src/particle_restart.cpp
src/particle_type.cpp
src/photon.cpp
src/physics.cpp
src/physics_common.cpp
@ -374,6 +412,7 @@ list(APPEND libopenmc_SOURCES
src/random_ray/linear_source_domain.cpp
src/random_ray/moment_matrix.cpp
src/random_ray/source_region.cpp
src/ray.cpp
src/reaction.cpp
src/reaction_product.cpp
src/scattdata.cpp
@ -406,17 +445,21 @@ list(APPEND libopenmc_SOURCES
src/tallies/filter_materialfrom.cpp
src/tallies/filter_mesh.cpp
src/tallies/filter_meshborn.cpp
src/tallies/filter_meshmaterial.cpp
src/tallies/filter_meshsurface.cpp
src/tallies/filter_mu.cpp
src/tallies/filter_musurface.cpp
src/tallies/filter_parent_nuclide.cpp
src/tallies/filter_particle.cpp
src/tallies/filter_particle_production.cpp
src/tallies/filter_polar.cpp
src/tallies/filter_reaction.cpp
src/tallies/filter_sph_harm.cpp
src/tallies/filter_sptl_legendre.cpp
src/tallies/filter_surface.cpp
src/tallies/filter_time.cpp
src/tallies/filter_universe.cpp
src/tallies/filter_weight.cpp
src/tallies/filter_zernike.cpp
src/tallies/tally.cpp
src/tallies/tally_scoring.cpp
@ -480,7 +523,7 @@ endif()
# target_link_libraries treats any arguments starting with - but not -l as
# linker flags. Thus, we can pass both linker flags and libraries together.
target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}
xtensor fmt::fmt ${CMAKE_DL_LIBS})
fmt::fmt ${CMAKE_DL_LIBS})
if(TARGET pugixml::pugixml)
target_link_libraries(libopenmc pugixml::pugixml)
@ -489,11 +532,11 @@ else()
endif()
if(OPENMC_USE_DAGMC)
target_compile_definitions(libopenmc PRIVATE DAGMC)
target_compile_definitions(libopenmc PUBLIC OPENMC_DAGMC_ENABLED)
target_link_libraries(libopenmc dagmc-shared)
if(OPENMC_USE_UWUW)
target_compile_definitions(libopenmc PRIVATE OPENMC_UWUW)
target_compile_definitions(libopenmc PRIVATE OPENMC_UWUW_ENABLED)
target_link_libraries(libopenmc uwuw-shared)
endif()
elseif(OPENMC_USE_UWUW)
@ -502,7 +545,7 @@ elseif(OPENMC_USE_UWUW)
endif()
if(OPENMC_USE_LIBMESH)
target_compile_definitions(libopenmc PRIVATE LIBMESH)
target_compile_definitions(libopenmc PRIVATE OPENMC_LIBMESH_ENABLED)
target_link_libraries(libopenmc PkgConfig::LIBMESH)
endif()
@ -525,11 +568,6 @@ if (OPENMC_BUILD_TESTS)
add_subdirectory(tests/cpp_unit_tests)
endif()
if (OPENMC_USE_MCPL)
target_compile_definitions(libopenmc PUBLIC OPENMC_MCPL)
target_link_libraries(libopenmc MCPL::mcpl)
endif()
#===============================================================================
# Log build info that this executable can report later
#===============================================================================
@ -542,6 +580,9 @@ endif()
if (OPENMC_ENABLE_COVERAGE)
target_compile_definitions(libopenmc PRIVATE COVERAGEBUILD)
endif()
if (OPENMC_ENABLE_STRICT_FP)
target_compile_definitions(libopenmc PRIVATE OPENMC_ENABLE_STRICT_FP)
endif()
#===============================================================================
# openmc executable
@ -570,9 +611,7 @@ add_custom_command(TARGET libopenmc POST_BUILD
#===============================================================================
# Install executable, scripts, manpage, license
#===============================================================================
configure_file(cmake/OpenMCConfig.cmake.in "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake" @ONLY)
configure_file(cmake/OpenMCConfigVersion.cmake.in "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfigVersion.cmake" @ONLY)
include(CMakePackageConfigHelpers)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/OpenMC)
install(TARGETS openmc libopenmc
@ -586,10 +625,24 @@ install(EXPORT openmc-targets
NAMESPACE OpenMC::
DESTINATION ${INSTALL_CONFIGDIR})
configure_package_config_file(
"cmake/OpenMCConfig.cmake.in"
"${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake"
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/OpenMCConfigVersion.cmake"
VERSION ${OPENMC_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(FILES
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/OpenMCConfigVersion.cmake"
DESTINATION ${INSTALL_CONFIGDIR})
"${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/OpenMCConfig.cmake"
"${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/OpenMCConfigVersion.cmake"
DESTINATION "${INSTALL_CONFIGDIR}"
)
install(FILES man/man1/openmc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install(FILES LICENSE DESTINATION "${CMAKE_INSTALL_DOCDIR}" RENAME copyright)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View file

@ -24,7 +24,7 @@ ARG compile_cores=1
ARG build_dagmc=off
ARG build_libmesh=off
FROM debian:bookworm-slim AS dependencies
FROM ubuntu:24.04 AS dependencies
ARG compile_cores
ARG build_dagmc
@ -33,11 +33,6 @@ ARG build_libmesh
# Set default value of HOME to /root
ENV HOME=/root
# Embree variables
ENV EMBREE_TAG='v4.3.1'
ENV EMBREE_REPO='https://github.com/embree/embree'
ENV EMBREE_INSTALL_DIR=$HOME/EMBREE/
# MOAB variables
ENV MOAB_TAG='5.5.1'
ENV MOAB_REPO='https://bitbucket.org/fathomteam/moab/'
@ -58,10 +53,11 @@ ENV LIBMESH_REPO='https://github.com/libMesh/libmesh'
ENV LIBMESH_INSTALL_DIR=$HOME/LIBMESH
# NJOY variables
ENV NJOY_TAG='2016.78'
ENV NJOY_REPO='https://github.com/njoy/NJOY2016'
# Setup environment variables for Docker image
ENV LD_LIBRARY_PATH=${DAGMC_INSTALL_DIR}/lib:$LD_LIBRARY_PATH \
ENV LD_LIBRARY_PATH=${DAGMC_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-} \
OPENMC_ENDF_DATA=/root/endf-b-vii.1 \
DEBIAN_FRONTEND=noninteractive
@ -71,7 +67,7 @@ RUN apt-get update -y && \
apt-get install -y \
python3-pip python-is-python3 wget git build-essential cmake \
mpich libmpich-dev libhdf5-serial-dev libhdf5-mpich-dev \
libpng-dev python3-venv && \
libpng-dev libpugixml-dev libfmt-dev catch2 python3-venv && \
apt-get autoremove
# create virtual enviroment to avoid externally managed environment error
@ -83,7 +79,7 @@ RUN pip install --upgrade pip
# Clone and install NJOY2016
RUN cd $HOME \
&& git clone --single-branch --depth 1 ${NJOY_REPO} \
&& git clone --single-branch -b ${NJOY_TAG} --depth 1 ${NJOY_REPO} \
&& cd NJOY2016 \
&& mkdir build \
&& cd build \
@ -94,21 +90,12 @@ RUN cd $HOME \
RUN if [ "$build_dagmc" = "on" ]; then \
# Install addition packages required for DAGMC
apt-get -y install libeigen3-dev libnetcdf-dev libtbb-dev libglfw3-dev \
apt-get -y install \
libeigen3-dev libnetcdf-dev libtbb-dev libglfw3-dev libembree-dev \
&& pip install --upgrade numpy \
# Clone and install EMBREE
&& mkdir -p $HOME/EMBREE && cd $HOME/EMBREE \
&& git clone --single-branch -b ${EMBREE_TAG} --depth 1 ${EMBREE_REPO} \
&& mkdir build && cd build \
&& cmake ../embree \
-DCMAKE_INSTALL_PREFIX=${EMBREE_INSTALL_DIR} \
-DEMBREE_MAX_ISA=NONE \
-DEMBREE_ISA_SSE42=ON \
-DEMBREE_ISPC_SUPPORT=OFF \
&& make 2>/dev/null -j${compile_cores} install \
&& rm -rf ${EMBREE_INSTALL_DIR}/build ${EMBREE_INSTALL_DIR}/embree ; \
&& pip install --no-cache-dir setuptools cython \
# Clone and install MOAB
mkdir -p $HOME/MOAB && cd $HOME/MOAB \
&& mkdir -p $HOME/MOAB && cd $HOME/MOAB \
&& git clone --single-branch -b ${MOAB_TAG} --depth 1 ${MOAB_REPO} \
&& mkdir build && cd build \
&& cmake ../moab -DCMAKE_BUILD_TYPE=Release \
@ -117,6 +104,7 @@ RUN if [ "$build_dagmc" = "on" ]; then \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_FORTRAN=OFF \
-DENABLE_BLASLAPACK=OFF \
-DENABLE_TESTING=OFF \
&& make 2>/dev/null -j${compile_cores} install \
&& cmake ../moab \
-DENABLE_PYMOAB=ON \
@ -132,7 +120,7 @@ RUN if [ "$build_dagmc" = "on" ]; then \
&& mkdir build && cd build \
&& cmake ../double-down -DCMAKE_INSTALL_PREFIX=${DD_INSTALL_DIR} \
-DMOAB_DIR=/usr/local \
-DEMBREE_DIR=${EMBREE_INSTALL_DIR} \
-DEMBREE_DIR=/usr \
&& make 2>/dev/null -j${compile_cores} install \
&& rm -rf ${DD_INSTALL_DIR}/build ${DD_INSTALL_DIR}/double-down ; \
# Clone and install DAGMC
@ -146,6 +134,7 @@ RUN if [ "$build_dagmc" = "on" ]; then \
-DDOUBLE_DOWN_DIR=${DD_INSTALL_DIR} \
-DCMAKE_PREFIX_PATH=${DD_INSTALL_DIR}/lib \
-DBUILD_STATIC_LIBS=OFF \
-DBUILD_TESTS=OFF \
&& make 2>/dev/null -j${compile_cores} install \
&& rm -rf ${DAGMC_INSTALL_DIR}/DAGMC ${DAGMC_INSTALL_DIR}/build ; \
fi

View file

@ -1,4 +1,4 @@
Copyright (c) 2011-2025 Massachusetts Institute of Technology, UChicago Argonne
Copyright (c) 2011-2026 Massachusetts Institute of Technology, UChicago Argonne
LLC, and OpenMC contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of

View file

@ -37,11 +37,17 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/.git" AND GIT_FOUND)
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
# If no tags are found, instruct user to fetch them
# If no tags are found, set version to 0 and show a warning
if(VERSION_STRING STREQUAL "")
message(FATAL_ERROR "No git tags found. Run 'git fetch --tags' and try again.")
set(VERSION_STRING "0.0.0")
message(WARNING
"No git tags found. Version set to 0.0.0.\n"
"Run 'git fetch --tags' to ensure proper versioning.\n"
"For more information, see OpenMC developer documentation."
)
endif()
# Extract the commit hash

View file

@ -1,11 +1,18 @@
get_filename_component(OpenMC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/OpenMCConfigVersion.cmake")
include(CMakeFindDependencyMacro)
# Explicitly calculate prefix if it was not generated above
if(NOT DEFINED PACKAGE_PREFIX_DIR)
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)
endif()
find_dependency(fmt CONFIG REQUIRED HINTS ${PACKAGE_PREFIX_DIR})
find_dependency(pugixml CONFIG REQUIRED HINTS ${PACKAGE_PREFIX_DIR})
find_package(fmt REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../fmt)
find_package(pugixml REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../pugixml)
find_package(xtl REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtl)
find_package(xtensor REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtensor)
if(@OPENMC_USE_DAGMC@)
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
find_dependency(DAGMC REQUIRED HINTS @DAGMC_DIR@)
endif()
if(@OPENMC_USE_LIBMESH@)
@ -15,24 +22,24 @@ if(@OPENMC_USE_LIBMESH@)
pkg_check_modules(LIBMESH REQUIRED @LIBMESH_PC_FILE@>=1.7.0 IMPORTED_TARGET)
endif()
find_package(PNG)
if(NOT TARGET OpenMC::libopenmc)
include("${OpenMC_CMAKE_DIR}/OpenMCTargets.cmake")
if("@PNG_FOUND@")
find_dependency(PNG)
endif()
if(@OPENMC_USE_MPI@)
find_package(MPI REQUIRED)
find_dependency(MPI REQUIRED)
endif()
if(@OPENMC_USE_OPENMP@)
find_package(OpenMP REQUIRED)
endif()
if(@OPENMC_USE_MCPL@)
find_package(MCPL REQUIRED)
find_dependency(OpenMP REQUIRED)
endif()
if(@OPENMC_USE_UWUW@ AND NOT ${DAGMC_BUILD_UWUW})
message(FATAL_ERROR "UWUW is enabled in OpenMC but the DAGMC installation discovered was not configured with UWUW.")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/OpenMCTargets.cmake")
if(NOT OpenMC_FIND_QUIETLY)
message(STATUS "Found OpenMC: ${PACKAGE_VERSION} (found in ${PACKAGE_PREFIX_DIR})")
endif()

View file

@ -1,11 +0,0 @@
set(PACKAGE_VERSION "@OPENMC_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

View file

@ -45,6 +45,7 @@ help:
clean:
-rm -rf $(BUILDDIR)/*
-rm -rf source/pythonapi/generated/
-rm -rf doxygen/xml
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html

13
docs/doxygen/Doxyfile Normal file
View file

@ -0,0 +1,13 @@
# Doxyfile 1.9.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
# Difference with default Doxyfile 1.9.1
PROJECT_NAME = OpenMC
QUIET = YES
WARN_IF_UNDOCUMENTED = NO
INPUT = ../../include/openmc/capi.h
GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_XML = YES

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -46,41 +46,29 @@ Type Definitions
Functions
---------
.. c:function:: int openmc_calculate_volumes()
..
Once documentation is complete in capi.h, use:
.. doxygenfile:: capi.h
to populate this documentation without using
.. doxygenfunction::
for every function.
Run a stochastic volume calculation
.. doxygenfunction:: openmc_calculate_volumes
:return: Return status (negative if an error occurred)
:rtype: int
.. doxygenfunction:: openmc_cell_get_fill
.. c:function:: int openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n)
.. doxygenfunction:: openmc_cell_get_id
Get the fill for a cell
.. doxygenfunction:: openmc_cell_get_temperature
.. c:function:: int openmc_cell_get_density(int32_t index, const int32_t* instance, double* density)
Get the density of a cell
:param int32_t index: Index in the cells array
:param int* type: Type of the fill
:param int32_t** indices: Array of material indices for cell
:param int32_t* n: Length of indices array
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_cell_get_id(int32_t index, int32_t* id)
Get the ID of a cell
:param int32_t index: Index in the cells array
:param int32_t* id: ID of the cell
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_cell_get_temperature(int32_t index, const int32_t* instance, double* T)
Get the temperature of a cell
:param int32_t index: Index in the cells array
:param int32_t* instance: Which instance of the cell. If a null pointer is passed, the temperature
of the first instance is returned.
:param double* T: temperature of the cell
:param int32_t* instance: Which instance of the cell. If a null pointer is passed, the density
multiplier of the first instance is returned.
:param double* density: Density of the cell in [g/cm3]
:return: Return status (negative if an error occurred)
:rtype: int
@ -113,8 +101,22 @@ Functions
:param double T: Temperature in Kelvin
:param instance: Which instance of the cell. To set the temperature for all
instances, pass a null pointer.
:param set_contained: If the cell is not filled by a material, whether to set the temperatures
of all filled cells
:param bool set_contained: If the cell is not filled by a material, whether
to set the temperatures of all filled cells
:type instance: const int32_t*
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_cell_set_density(index index, double density, const int32_t* instance, bool set_contained)
Set the density of a cell.
:param int32_t index: Index in the cells array
:param double density: Density of the cell in [g/cm3]
:param instance: Which instance of the cell. To set the density multiplier for all
instances, pass a null pointer.
:param bool set_contained: If the cell is not filled by a material, whether
to set the density multiplier of all filled cells
:type instance: const int32_t*
:return: Return status (negative if an error occurred)
:rtype: int
@ -555,6 +557,279 @@ Functions
:return: Return status (negative if an error occurs)
:rtype: int
.. c:function:: int openmc_get_plot_index(int32_t id, int32_t* index)
Get the index in the plots array for a plot with a given ID.
:param int32_t id: Plot ID
:param int32_t* index: Index in the plots array
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_plot_get_id(int32_t index, int32_t* id)
Get the ID of a plot.
:param int32_t index: Index in the plots array
:param int32_t* id: Plot ID
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_plot_set_id(int32_t index, int32_t id)
Set the ID of a plot.
:param int32_t index: Index in the plots array
:param int32_t id: Plot ID
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: size_t openmc_plots_size()
Number of plots currently allocated.
:return: Number of plots in the plots array
:rtype: size_t
.. c:function:: int openmc_solidraytrace_plot_create(int32_t* index)
Create a new solid raytrace plot.
:param int32_t* index: Index of the newly created plot
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_pixels(int32_t index, int32_t* width, int32_t* height)
Get output pixel dimensions for a solid raytrace plot.
:param int32_t index: Index in the plots array
:param int32_t* width: Image width in pixels
:param int32_t* height: Image height in pixels
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_pixels(int32_t index, int32_t width, int32_t height)
Set output pixel dimensions for a solid raytrace plot.
:param int32_t index: Index in the plots array
:param int32_t width: Image width in pixels
:param int32_t height: Image height in pixels
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_color_by(int32_t index, int32_t* color_by)
Get the domain type used for coloring (0=materials, 1=cells).
:param int32_t index: Index in the plots array
:param int32_t* color_by: Coloring mode
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_color_by(int32_t index, int32_t color_by)
Set the domain type used for coloring (0=materials, 1=cells).
:param int32_t index: Index in the plots array
:param int32_t color_by: Coloring mode
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_default_colors(int32_t index)
Set default random colors for the current ``color_by`` mode.
:param int32_t index: Index in the plots array
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_all_opaque(int32_t index)
Mark all domains in the current ``color_by`` mode as opaque.
:param int32_t index: Index in the plots array
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_opaque(int32_t index, int32_t id, bool visible)
Set whether a specific domain ID is opaque (visible) in the rendered image.
:param int32_t index: Index in the plots array
:param int32_t id: Cell/material ID (based on ``color_by``)
:param bool visible: Whether the domain is opaque
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_color(int32_t index, int32_t id, uint8_t r, uint8_t g, uint8_t b)
Set RGB color for a specific domain ID.
:param int32_t index: Index in the plots array
:param int32_t id: Cell/material ID (based on ``color_by``)
:param uint8_t r: Red channel
:param uint8_t g: Green channel
:param uint8_t b: Blue channel
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_color(int32_t index, int32_t id, uint8_t* r, uint8_t* g, uint8_t* b)
Get RGB color for a specific domain ID.
:param int32_t index: Index in the plots array
:param int32_t id: Cell/material ID (based on ``color_by``)
:param uint8_t* r: Red channel
:param uint8_t* g: Green channel
:param uint8_t* b: Blue channel
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_camera_position(int32_t index, double* x, double* y, double* z)
Get camera position.
:param int32_t index: Index in the plots array
:param double* x: X coordinate
:param double* y: Y coordinate
:param double* z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_camera_position(int32_t index, double x, double y, double z)
Set camera position.
:param int32_t index: Index in the plots array
:param double x: X coordinate
:param double y: Y coordinate
:param double z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_look_at(int32_t index, double* x, double* y, double* z)
Get camera target point.
:param int32_t index: Index in the plots array
:param double* x: X coordinate
:param double* y: Y coordinate
:param double* z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_look_at(int32_t index, double x, double y, double z)
Set camera target point.
:param int32_t index: Index in the plots array
:param double x: X coordinate
:param double y: Y coordinate
:param double z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_up(int32_t index, double* x, double* y, double* z)
Get the camera up vector.
:param int32_t index: Index in the plots array
:param double* x: X component
:param double* y: Y component
:param double* z: Z component
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_up(int32_t index, double x, double y, double z)
Set the camera up vector.
:param int32_t index: Index in the plots array
:param double x: X component
:param double y: Y component
:param double z: Z component
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_light_position(int32_t index, double* x, double* y, double* z)
Get light source position.
:param int32_t index: Index in the plots array
:param double* x: X coordinate
:param double* y: Y coordinate
:param double* z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_light_position(int32_t index, double x, double y, double z)
Set light source position.
:param int32_t index: Index in the plots array
:param double x: X coordinate
:param double y: Y coordinate
:param double z: Z coordinate
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_fov(int32_t index, double* fov)
Get horizontal field of view in degrees.
:param int32_t index: Index in the plots array
:param double* fov: Field of view in degrees
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_fov(int32_t index, double fov)
Set horizontal field of view in degrees.
:param int32_t index: Index in the plots array
:param double fov: Field of view in degrees
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_get_diffuse_fraction(int32_t index, double* diffuse_fraction)
Get diffuse-light fraction.
:param int32_t index: Index in the plots array
:param double* diffuse_fraction: Diffuse fraction in [0, 1]
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_set_diffuse_fraction(int32_t index, double diffuse_fraction)
Set diffuse-light fraction.
:param int32_t index: Index in the plots array
:param double diffuse_fraction: Diffuse fraction in [0, 1]
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_update_view(int32_t index)
Recompute internal camera/view transforms after camera changes.
:param int32_t index: Index in the plots array
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_solidraytrace_plot_create_image(int32_t index, uint8_t* data_out, int32_t width, int32_t height)
Render the plot to an RGB image buffer.
:param int32_t index: Index in the plots array
:param uint8_t* data_out: Output buffer of shape ``height*width*3``
:param int32_t width: Image width in pixels
:param int32_t height: Image height in pixels
:return: Return status (negative if an error occurred)
:rtype: int
.. c:function:: int openmc_reset()
Resets all tally scores
@ -576,6 +851,10 @@ Functions
:return: Return status (negative if an error occurs)
:rtype: int
.. c:function:: void openmc_run_random_ray()
Run a random ray simulation
.. c:function:: int openmc_set_n_batches(int32_t n_batches, bool set_max_batches, bool add_statepoint_batch)
Set number of batches and number of max batches

View file

@ -11,7 +11,10 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
import os
from pathlib import Path
import subprocess
import sys
# Determine if we're on Read the Docs server
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
@ -37,6 +40,7 @@ sys.path.insert(0, os.path.abspath('../..'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'breathe',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
@ -47,6 +51,8 @@ extensions = [
]
if not on_rtd:
extensions.append('sphinxcontrib.rsvgconverter')
doxygen_dir = Path(__file__).parents[1] / 'doxygen'
subprocess.run(['doxygen'], cwd=doxygen_dir, check=True)
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@ -62,7 +68,7 @@ master_doc = 'index'
# General information about the project.
project = 'OpenMC'
copyright = '2011-2025, Massachusetts Institute of Technology, UChicago Argonne LLC, and OpenMC contributors'
copyright = '2011-2026, Massachusetts Institute of Technology, UChicago Argonne LLC, and OpenMC contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@ -117,13 +123,16 @@ pygments_style = 'tango'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options breathe + doxygen -------------------------------------------------
breathe_projects = {"OpenMC": "../doxygen/xml"}
breathe_default_project = "OpenMC"
breathe_domain_by_file_pattern = {"*capi.h": "c"}
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_baseurl = "https://docs.openmc.org/en/stable/"
html_logo = '_images/openmc_logo.png'

View file

@ -0,0 +1,104 @@
.. _devguide_agentic_tools:
===========================
Agentic Development Tools
===========================
OpenMC ships a set of tools designed for AI coding agents (such as
`Claude Code`_) that agents can use to navigate and understand the codebase.
.. _Claude Code: https://claude.ai/code
Motivation
----------
Agentic tools like Claude Code are skilled at using grep to navigate and
understand large code bases. However, grep can only find exact text matches —
it cannot discover code that is *conceptually* related but uses different
naming. Without a "global view" of the codebase that a human developer will
build up over time, the agent is generally blind to any file it hasn't
tokenized fully. While it can grep to see who else calls a function, it
remains blind if other areas might be related but not share identical naming
conventions.
This problem is mitigated somewhat by using a model with a longer context
window. OpenMC has somewhere around ~1 million tokens of C++ and ~1 million
tokens of python. While Claude Code in early 2026 only has a context window
of 200k tokens, beta versions have extended context windows of 1M tokens,
and it's not unreasonable to assume that models may be available in the near
future that greatly exceed these limits.
However, even assuming the entire repository can be fit within a context
window, there are several downsides to doing this.
`Model performance degrades significantly as context size increases`_.
Benchmark results are
greatly improved if the model has less garbage to pick through. Additionally, API usage
is typically billed as tokens in/out per turn. As the context file
grows these costs become much larger. As such, there is still significant
motivation to solving the above problem, so as to ensure only relevant
information is drawn into context so as to maximize model performance and
minimize costs.
Setup
-----
The tools are registered as an `MCP (Model Context Protocol)`_ server in
``.mcp.json`` at the repository root. AI agents that support MCP (such as
Claude Code) discover them automatically on session start. The underlying
Python scripts can also be run directly from the command line.
All tools run entirely locally — no API keys or external service accounts are
required. Python dependencies are installed automatically into an isolated
virtual environment at ``.claude/cache/.venv/`` on first use.
.. _Model performance degrades significantly as context size increases: https://www.anthropic.com/news/claude-opus-4-6
.. _MCP (Model Context Protocol): https://modelcontextprotocol.io
RAG Semantic Search
-------------------
The RAG (Retrieval-Augmented Generation) semantic search addresses this
problem — it finds code by meaning, not just text match, surfacing related code
across subsystems that ``grep`` would miss entirely. Two MCP tools are provided:
- **openmc_rag_search** — Given a natural-language query, returns the most
relevant code chunks with file paths, line numbers, and a preview. Can search
code, documentation, or both. Can also find code related to a given file.
- **openmc_rag_rebuild** — Rebuilds the search index. Should be called after
pulling new code or switching branches.
How it works
^^^^^^^^^^^^
The search pipeline runs entirely on your local CPU:
1. **Chunking.** All C++, Python, and RST files are split into overlapping
fixed-size windows (~1000 characters, 25% overlap). This ensures every line
of code appears in at least one chunk and most lines appear in two.
2. **Embedding.** Each chunk is embedded into a 384-dimensional vector using
the `all-MiniLM-L6-v2`_ sentence-transformer model (22 million parameters).
This model runs on CPU with no GPU required. No API key is needed — the
model weights are downloaded once from Hugging Face and cached locally.
3. **Indexing.** The vectors are stored in a local LanceDB_ database on disk.
Building the full index takes approximately 5 minutes on a machine with
10 CPU cores. The index is stored in ``.claude/cache/rag_index/`` and
persists across sessions.
4. **Searching.** Your query is embedded using the same model, and the closest
chunks are retrieved by vector similarity. Results include the file path,
line range, file type, similarity distance, and a text preview.
.. _all-MiniLM-L6-v2: https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
.. _LanceDB: https://lancedb.com
Requirements
^^^^^^^^^^^^
No system dependencies beyond **Python 3.12+** with ``pip``. An internet
connection is required on first use to download the Python packages and
embedding model weights; subsequent runs are fully offline. The Python packages
(``sentence-transformers``, ``lancedb``) and their dependencies (including
PyTorch, ~2GB) are installed automatically into an isolated virtual environment
on first use.

View file

@ -111,7 +111,8 @@ The TC consists of the following individuals:
- `Paul Romano <https://github.com/paulromano>`_
- `Patrick Shriwise <https://github.com/pshriwise>`_
- `Adam Nelson <https://github.com/nelsonag>`_
- `Benoit Forget <https://github.com/bforget>`_
- `Jonathan Shimwell <https://github.com/shimwell>`_
- `John Tramm <https://github.com/jtramm>`_
The Project Lead is Paul Romano.

View file

@ -14,6 +14,11 @@ Python API. That is, from the root directory of the OpenMC repository:
python -m pip install ".[docs]"
The OpenMC documentation also uses Doxygen to automatically generate its
C/C++ API documentation directly from the docstrings available in the source
code. You will need to have a working installation of Doxygen to generate the
documentation locally.
-----------------------------------
Building Documentation as a Webpage
-----------------------------------

View file

@ -14,6 +14,7 @@ other related topics.
contributing
workflow
agentic-tools
styleguide
policies
tests

View file

@ -21,8 +21,8 @@ C++ code in OpenMC must conform to the most recent C++ standard that is fully
supported in the `version of the gcc compiler
<https://gcc.gnu.org/projects/cxx-status.html>`_ that is distributed with the
oldest version of Ubuntu that is still within its `standard support period
<https://ubuntu.com/about/release-cycle>`_. Ubuntu 20.04 LTS will be supported
through April 2025 and is distributed with gcc 9.3.0, which fully supports the
<https://ubuntu.com/about/release-cycle>`_. Ubuntu 22.04 LTS will be supported
through April 2027 and is distributed with gcc 11.4.0, which fully supports the
C++17 standard.
--------------------
@ -31,5 +31,5 @@ CMake Version Policy
Similar to the C++ standard policy, the minimum supported version of CMake
corresponds to whatever version is distributed with the oldest version of Ubuntu
still within its standard support period. Ubuntu 20.04 LTS is distributed with
CMake 3.16.
still within its standard support period. Ubuntu 22.04 LTS is distributed with
CMake 3.22.

View file

@ -30,7 +30,7 @@ whenever a file is saved. For example, `Visual Studio Code
support for running clang-format.
.. note::
OpenMC's CI uses `clang-format` version 15. A different version of `clang-format`
OpenMC's CI uses `clang-format` version 18. A different version of `clang-format`
may produce different line changes and as a result fail the CI test.
Miscellaneous

View file

@ -37,6 +37,9 @@ Prerequisites
- Some tests require `NJOY <https://www.njoy21.io/NJOY2016>`_ to preprocess
cross section data. The test suite assumes that you have an ``njoy``
executable available on your :envvar:`PATH`.
- OpenMC should be compiled with ``-DOPENMC_ENABLE_STRICT_FP=on`` to ensure
reproducible floating-point results across platforms and optimization levels.
Without this flag, regression tests may not match reference values.
Running Tests
-------------
@ -67,9 +70,11 @@ make sure you have satisfied all the prerequisites above. After you have done
that, consider the following:
- When building OpenMC, make sure you run CMake with
``-DCMAKE_BUILD_TYPE=Debug``. Building with a release build will result in
some test failures due to differences in which compiler optimizations are
used.
``-DOPENMC_ENABLE_STRICT_FP=on``. This prevents the compiler from applying
floating-point optimizations (such as replacing math library calls with
builtins or contracting multiply-add into FMA instructions) that can produce
bit-level differences across platforms and optimization levels. Any
``CMAKE_BUILD_TYPE`` can be used.
- Because tallies involve the sum of many floating point numbers, the
non-associativity of floating point numbers can result in different answers
especially when the number of threads is high (different order of operations).

View file

@ -91,6 +91,30 @@ features and bug fixes. The general steps for contributing are as follows:
6. After the pull request has been thoroughly vetted, it is merged back into the
*develop* branch of openmc-dev/openmc.
Setting Up Upstream Tracking (Required for Versioning)
------------------------------------------------------
By default, your fork **does not** include tags from the upstream OpenMC repository.
OpenMC relies on `git describe --tags` for versioning in source builds, and missing tags can lead
to incorrect version detection (i.e., ``0.0.0``). To ensure proper versioning, follow these steps:
1. **Add the Upstream Repository**
This allows you to fetch updates from the main OpenMC repository.
.. code-block:: sh
git remote add upstream https://github.com/openmc-dev/openmc.git
2. **Fetch and Push Tags**
Retrieve tags from the upstream repository and update your fork:
.. code-block:: sh
git fetch --tags upstream
git push --tags origin
This ensures that both your **local** and **remote** fork have the correct versioning information.
Private Development
-------------------

View file

@ -0,0 +1,46 @@
.. _io_collision_track:
===========================
Collision Track File Format
===========================
When collision tracking is enabled with ``mcpl=false`` (the default), OpenMC
writes binary data to an HDF5 file named ``collision_track.h5``. The same data
may also be written after each batch when multiple files are requested
(``collision_track.N.h5``) or when the run is performed in parallel. The file
contains the information needed to reconstruct each recorded collision.
The current revision of the collision track file format is 1.2.
**/**
:Attributes:
- **filetype** (*char[]*) -- String indicating the type of file.
For collision-track files the value is ``"collision_track"``.
:Datasets:
- **collision_track_bank** (Compound type) -- Collision information
for each stored event. Each entry in the dataset corresponds to one
collision and contains the following fields:
- ``r`` (*double[3]*) -- Position of the collision in [cm].
- ``u`` (*double[3]*) -- Direction unit vector immediately after the collision.
- ``E`` (*double*) -- Incident particle energy before the collision in [eV].
- ``dE`` (*double*) -- Energy loss over the collision (:math:`E_\text{before} - E_\text{after}`) in [eV].
- ``time`` (*double*) -- Time of the collision in [s].
- ``wgt`` (*double*) -- Particle weight at the collision.
- ``event_mt`` (*int*) -- ENDF MT number identifying the reaction.
- ``delayed_group`` (*int*) -- Delayed neutron group index (non-zero for delayed events).
- ``cell_id`` (*int*) -- ID of the cell in which the collision occurred.
- ``nuclide_id`` (*int*) -- PDG number of the nuclide (100ZZZAAAM).
- ``material_id`` (*int*) -- ID of the material containing the collision site.
- ``universe_id`` (*int*) -- ID of the universe containing the collision site.
- ``n_collision`` (*int*) -- Collision counter for the particle history.
- ``particle`` (*int32_t*) -- Particle type (PDG number).
- ``parent_id`` (*int64_t*) -- Unique ID of the parent particle.
- ``progeny_id`` (*int64_t*) -- Progeny ID of the particle.
In an MPI run, OpenMC writes the combined dataset by gathering collision-track
entries from all ranks before flushing them to disk, so the final file appears
as though it were produced serially.

View file

@ -56,6 +56,27 @@ attributes:
.. _io_chain_reaction:
--------------------
``<source>`` Element
--------------------
The ``<source>`` element represents photon and electron sources associated with
the decay of a nuclide and contains information to construct an
:class:`openmc.stats.Univariate` object that represents this emission as an
energy distribution. This element has the following attributes:
:type:
The type of :class:`openmc.stats.Univariate` source term.
:particle:
The type of particle emitted, e.g., 'photon' or 'electron'
:parameters:
The parameters of the source term, e.g., for a
:class:`openmc.stats.Discrete` source, the energies (in [eV]) at which the
particles are emitted and their relative intensities in [Bq/atom] (in other
words, decay constants).
----------------------
``<reaction>`` Element
----------------------

View file

@ -4,7 +4,7 @@
Depletion Results File Format
=============================
The current version of the depletion results file format is 1.1.
The current version of the depletion results file format is 1.3.
**/**
@ -12,30 +12,31 @@ The current version of the depletion results file format is 1.1.
- **version** (*int[2]*) -- Major and minor version of the
statepoint file format.
:Datasets: - **eigenvalues** (*double[][][2]*) -- k-eigenvalues at each
time/stage. This array has shape (number of timesteps, number of
stages, value). The last axis contains the eigenvalue and the
associated uncertainty
- **number** (*double[][][][]*) -- Total number of atoms. This array
has shape (number of timesteps, number of stages, number of
:Datasets: - **eigenvalues** (*double[][2]*) -- k-eigenvalues at each timestep.
This array has shape (number of timesteps, 2). The second axis
contains the eigenvalue and its associated uncertainty.
- **number** (*double[][][]*) -- Total number of atoms at each
timestep. This array has shape (number of timesteps, number of
materials, number of nuclides).
- **reaction rates** (*double[][][][][]*) -- Reaction rates used to
build depletion matrices. This array has shape (number of
timesteps, number of stages, number of materials, number of
nuclides, number of reactions).
- **reaction rates** (*double[][][][]*) -- Reaction rates at each
timestep. This array has shape (number of timesteps, number of
materials, number of nuclides, number of reactions). Only stored if
write_rates=True.
- **time** (*double[][2]*) -- Time in [s] at beginning/end of each
step.
- **source_rate** (*double[][]*) -- Power in [W] or source rate in
[neutron/sec]. This array has shape (number of timesteps, number
of stages).
- **source_rate** (*double[]*) -- Power in [W] or source rate in
[neutron/sec] for each timestep.
- **depletion time** (*double[]*) -- Average process time in [s]
spent depleting a material across all burnable materials and,
if applicable, MPI processes.
- **keff_search_root** (*double[]*) -- Root of the keff search at the
end of the timestep, if applicable.
**/materials/<id>/**
:Attributes: - **index** (*int*) -- Index used in results for this material
- **volume** (*double*) -- Volume of this material in [cm^3]
- **name** (*char[]*) -- Name of this material
**/nuclides/<name>/**

View file

@ -38,11 +38,9 @@ Each ``<surface>`` element can have the following attributes or sub-elements:
:boundary:
The boundary condition for the surface. This can be "transmission",
"vacuum", "reflective", or "periodic". Periodic boundary conditions can
only be applied to x-, y-, and z-planes. Only axis-aligned periodicity is
supported, i.e., x-planes can only be paired with x-planes. Specify which
planes are periodic and the code will automatically identify which planes
are paired together.
"vacuum", "reflective", or "periodic". Specify which planes are
periodic and the code will automatically identify which planes are
paired together.
*Default*: "transmission"
@ -318,9 +316,10 @@ the following attributes or sub-elements:
*Default*: None
:orientation:
The orientation of the hexagonal lattice. The string "x" indicates that two
sides of the lattice are parallel to the x-axis, whereas the string "y"
indicates that two sides are parallel to the y-axis.
The orientation of the hexagonal lattice. The string "x" indicates that each
lattice element has two faces that are perpendicular to the x-axis, whereas
the string "y" indicates that each lattice element has two faces that are
perpendicular to the y-axis.
*Default*: "y"
@ -407,24 +406,55 @@ Each ``<dagmc_universe>`` element can have the following attributes or sub-eleme
*Default*: None
:material_overrides:
This element contains information on material overrides to be applied to the
DAGMC universe. It has the following attributes and sub-elements:
:cell:
Zero or more ``<cell>`` sub-elements may appear to override properties of
individual DAGMC volumes. Each ``<cell>`` element supports the following
attributes and sub-elements:
:cell:
Material override information for a single cell. It contains the following
attributes and sub-elements:
:id:
The integer cell ID in the DAGMC geometry to override. Required.
:id:
The cell ID in the DAGMC geometry for which the material override will
apply.
:name:
An optional string label for the cell.
:materials:
A list of material IDs that will apply to instances of the cell. If the
list contains only one ID, it will replace the original material
assignment of all instances of the DAGMC cell. If the list contains more
than one material, each material ID of the list will be assigned to the
various instances of the DAGMC cell.
*Default*: None
:material:
The material ID to assign to this cell. Use ``void`` for vacuum. Multiple
space-separated IDs may be given to specify a distribmat (distributed
material) assignment. Required.
:temperature:
Temperature(s) in [K] to assign to the cell. Must be greater than or equal
to 0. Multiple space-separated values may be given.
*Default*: None
:density:
Density in [g/cm³] to assign to the cell. Must be greater than 0. Requires a non-void
material fill. Multiple space-separated values may be given.
*Default*: None
:volume:
Volume of the cell in [cm³].
.. note:: DAGMC can compute cell volumes exactly from the triangulated
mesh surfaces. Specifying a manual volume risks inconsistency
with that capability.
*Default*: None
The following standard ``<cell>`` attributes are **not** supported inside
``<dagmc_universe>`` and will raise an error if present: ``region``,
``fill``, ``universe``, ``translation``, ``rotation``.
.. deprecated::
The ``<material_overrides>`` sub-element (containing ``<cell_override>``
children with ``<material_ids>``) is deprecated. A deprecation warning is
emitted and the overrides are converted to the ``<cell>`` format at parse
time. It is an error to specify both ``<material_overrides>`` and
``<cell>`` sub-elements on the same ``<dagmc_universe>``.
*Default*: None

View file

@ -44,6 +44,7 @@ Output Files
statepoint
source
collision_track
summary
properties
depletion_results

View file

@ -133,6 +133,10 @@ Temperature-dependent data, provided for temperature <TTT>K.
This dataset is optional. This is a 1-D vector if `representation`
is "isotropic", or a 3-D vector if `representation` is "angle"
with dimensions of [polar][azimuthal][groups].
When this data is not available, an approximation using the
group energy boundaries is used. For more information see
the particle speed subsection in the multigroup-data section
of the theory manual.
**/<library name>/<TTT>K/scatter_data/**

View file

@ -4,7 +4,7 @@
Particle Restart File Format
============================
The current version of the particle restart file format is 2.0.
The current version of the particle restart file format is 2.1.
**/**
@ -26,8 +26,7 @@ The current version of the particle restart file format is 2.0.
- **run_mode** (*char[]*) -- Run mode used, either 'fixed source',
'eigenvalue', or 'particle restart'.
- **id** (*int8_t*) -- Unique identifier of the particle.
- **type** (*int*) -- Particle type (0=neutron, 1=photon, 2=electron,
3=positron)
- **type** (*int32_t*) -- Particle type (PDG number)
- **weight** (*double*) -- Weight of the particle.
- **energy** (*double*) -- Energy of the particle in eV for
continuous-energy mode, or the energy group of the particle for

View file

@ -4,7 +4,7 @@
Properties File Format
======================
The current version of the properties file format is 1.0.
The current version of the properties file format is 1.1.
**/**
@ -25,6 +25,7 @@ The current version of the properties file format is 1.0.
**/geometry/cells/cell <uid>/**
:Datasets: - **temperature** (*double[]*) -- Temperature of the cell in [K].
- **density** (*double[]*) -- Density of the cell in [g/cm3].
**/materials/**

View file

@ -7,6 +7,19 @@ Settings Specification -- settings.xml
All simulation parameters and miscellaneous options are specified in the
settings.xml file.
-------------------------------
``<atomic_relaxation>`` Element
-------------------------------
The ``<atomic_relaxation>`` element determines whether the atomic relaxation
cascade, the X-ray fluorescence photons and Auger electrons emitted when an
inner-shell vacancy is filled, is simulated following photoelectric and
incoherent (Compton) scattering interactions. Disabling this can speed up
photon transport calculations where the detailed secondary particle cascade is
not of interest.
*Default*: true
---------------------
``<batches>`` Element
---------------------
@ -20,6 +33,90 @@ source neutrons.
*Default*: None
-----------------------------
``<collision_track>`` Element
-----------------------------
The ``<collision_track>`` element indicates to track information about particle
collisions based on a set of criteria and store these events in a file named
``collision_track.h5``. This file records details such as the position of the
interaction, direction of the incoming particle, incident energy and deposited
energy, weight, time of the interaction, and the delayed neutron group (0 for
prompt neutrons). Additional information such as the cell ID, material ID,
universe ID, nuclide ZAID, particle type, and event MT number are also stored.
Users can specify one or more criterion to filter collisions. If no criteria are
specified, it defaults to tracking all collisions across the model.
.. warning::
Storing all collisions can be very memory intensive. For more targeted
tracking, users can employ a variety of parameters such as ``cell_ids``,
``reactions``, ``universe_ids``, ``material_ids``, ``nuclides``, and
``deposited_E_threshold`` to refine the selection of particle interactions
to be banked.
This element can contain one or more of the following attributes or
sub-elements:
:max_collisions:
An integer indicating the maximum number of collisions to be banked per file.
*Default*: 1000
:max_collision_track_files:
An integer indicating the number of collision_track files to be used.
*Default*: 1
:mcpl:
An optional boolean to enable MCPL_-format instead of the native HDF5-based
format. If activated, the output file name and type is changed to
``collision_track.mcpl``.
*Default*: false
.. _MCPL: https://mctools.github.io/mcpl/mcpl.pdf
:cell_ids:
A list of integers representing cell IDs to define specific cells in which
collisions are to be banked.
*Default*: None
:universe_ids:
A list of integers representing the universe IDs to define specific
universes in which collisions are to be banked.
*Default*: None
:material_ids:
A list of integers representing the material IDs to define specific
materials in which collisions are to be banked.
*Default*: None
:nuclides:
A list of strings representing the nuclide, to define specific
define specific target nuclide collisions to be banked.
.. note::
Electron and positron collision-track events are not associated with
a specific nuclide. If a ``nuclides`` entry is specified, these events
are omitted.
*Default*: None
:reactions:
A list of integers representing the ENDF-6 format MT numbers or strings
(e.g. (n,fission)) to define specific reaction types to be banked.
*Default*: None
:deposited_E_threshold:
A float defining the minimum deposited energy per collision (in eV) to
trigger banking.
*Default*: 0.0
----------------------------------
``<confidence_intervals>`` Element
----------------------------------
@ -178,6 +275,16 @@ history-based parallelism.
*Default*: false
--------------------------------
``<free_gas_threshold>`` Element
--------------------------------
The ``<free_gas_threshold>`` element specifies the energy multiplier, expressed
in units of :math:`kT`, that determines when the free gas scattering approach is
used for elastic scattering. Values must be positive.
*Default*: 400.0
-----------------------------------
``<generations_per_batch>`` Element
-----------------------------------
@ -188,6 +295,15 @@ ignored for all run modes other than "eigenvalue".
*Default*: 1
------------------------------
``<ifp_n_generation>`` Element
------------------------------
The ``<ifp_n_generation>`` element indicates the number of generations to
consider for the Iterated Fission Probability method.
*Default*: 10
----------------------
``<inactive>`` Element
----------------------
@ -313,7 +429,25 @@ then, OpenMC will only use up to the :math:`P_1` data.
``<max_history_splits>`` Element
--------------------------------
The ``<max_history_splits>`` element indicates the number of times a particle can split during a history.
The ``<max_history_splits>`` element indicates the number of times a particle
can split during a history.
*Default*: 1000
-----------------------------
``<max_secondaries>`` Element
-----------------------------
The ``<max_secondaries>`` element indicates the maximum secondary bank size.
*Default*: 10000
------------------------
``<max_tracks>`` Element
------------------------
The ``<max_tracks>`` element indicates the maximum number of tracks written to a
track file (per MPI process).
*Default*: 1000
@ -426,6 +560,18 @@ generator during generation of colors in plots.
*Default*: 1
.. _properties_file:
-----------------------------
``<properties_file>`` Element
-----------------------------
The ``properties_file`` element has no attributes and contains the path to a
properties HDF5 file to load cell temperatures/densities and material
densities.
*Default*: None
---------------------
``<ptables>`` Element
---------------------
@ -456,7 +602,7 @@ found in the :ref:`random ray user guide <random_ray>`.
*Default*: None
:source:
:ray_source:
Specifies the starting ray distribution, and follows the format for
:ref:`source_element`. It must be uniform in space and angle and cover the
full domain. It does not represent a physical neutron or photon source -- it
@ -464,6 +610,35 @@ found in the :ref:`random ray user guide <random_ray>`.
*Default*: None
:adjoint_source:
Specifies an adjoint fixed source for adjoint transport simulations, and
follows the format for :ref:`source_element`. The distributions which make
up the adjoint source are subject to the same restrictions as forward
fixed sources in Random Ray mode.
*Default*: None
:adjoint:
Specifies whether to perform adjoint transport. The default is 'False',
corresponding to forward transport.
*Default*: None
:volume_estimator:
Specifies choice of volume estimator for the random ray solver. Options
are 'naive', 'simulation_averaged', or 'hybrid'. The default is 'hybrid'.
*Default*: None
:volume_normalized_flux_tallies:
Specifies whether to normalize flux tallies by volume (bool). The
default is 'False'. When enabled, flux tallies will be reported in units
of cm/cm^3. When disabled, flux tallies will be reported in units of cm
(i.e., total distance traveled by neutrons in the spatial tally
region).
*Default*: None
:sample_method:
Specifies the method for sampling the starting ray distribution. This
element can be set to "prng" or "halton".
@ -488,6 +663,14 @@ found in the :ref:`random ray user guide <random_ray>`.
:type:
The type of the domain. Can be ``material``, ``cell``, or ``universe``.
:diagonal_stabilization_rho:
The rho factor for use with diagonal stabilization. This technique is
applied when negative diagonal (in-group) elements are detected in
the scattering matrix of input MGXS data, which is a common feature
of transport corrected MGXS data.
*Default*: 1.0
----------------------------------
``<resonance_scattering>`` Element
----------------------------------
@ -563,14 +746,16 @@ pseudo-random number generator.
*Default*: 1
--------------------
``<stride>`` Element
--------------------
-----------------------------------
``<shared_secondary_bank>`` Element
-----------------------------------
The ``stride`` element is used to specify how many random numbers are allocated
for each source particle history.
*Default*: 152,917
The ``shared_secondary_bank`` element indicates whether to use a shared
secondary particle bank. When enabled, secondary particles are collected into
a global bank, sorted for reproducibility, and load-balanced across MPI ranks
between generations. If not specified, the shared secondary bank is enabled
automatically for fixed-source simulations with weight windows active, and
disabled otherwise.
.. _source_element:
@ -592,12 +777,15 @@ attributes/sub-elements:
*Default*: 1.0
:type:
Indicator of source type. One of ``independent``, ``file``, ``compiled``, or
``mesh``. The type of the source will be determined by this attribute if it
is present.
Indicator of source type. One of ``independent``, ``file``, ``compiled``,
``mesh``, or ``tokamak``. The type of the source will be determined by this
attribute if it is present.
:particle:
The source particle type, either ``neutron`` or ``photon``.
The source particle type, specified as a PDG number or a string alias (e.g.,
``neutron``/``n``, ``photon``/``gamma``, ``electron``, ``positron``,
``proton``/``p``, ``deuteron``/``d``, ``triton``/``t``, ``alpha``, or GNDS
nuclide names like ``Fe57``).
*Default*: neutron
@ -687,6 +875,7 @@ attributes/sub-elements:
For a "cylindrical" distribution, no parameters are specified. Instead,
the ``r``, ``phi``, ``z``, and ``origin`` elements must be specified.
Optionally, the ``r_dir`` and ``z_dir`` elements could be specified.
For a "spherical" distribution, no parameters are specified. Instead,
the ``r``, ``theta``, ``phi``, and ``origin`` elements must be specified.
@ -718,6 +907,10 @@ attributes/sub-elements:
of a univariate probability distribution (see the description in
:ref:`univariate`).
:r_dir:
For "cylindrical" distributions, this element specifies the direction
of the cylinder r-axis at phi=0. Defaults to (1.0, 0.0, 0.0).
:theta:
For a "spherical" distribution, this element specifies the distribution
of theta-coordinates. The necessary sub-elements/attributes are those of a
@ -730,6 +923,10 @@ attributes/sub-elements:
sub-elements/attributes are those of a univariate probability
distribution (see the description in :ref:`univariate`).
:z_dir:
For "cylindrical" distributions, this element specifies the direction
of the cylinder z-axis. Defaults to (0.0, 0.0, 1.0).
:origin:
For "cylindrical and "spherical" distributions, this element specifies
the coordinates for the origin of the coordinate system.
@ -747,13 +944,18 @@ attributes/sub-elements:
relative source strength of each mesh element or each point in the cloud.
:volume_normalized:
For "mesh" spatial distrubtions, this optional boolean element specifies
For "mesh" spatial distributions, this optional boolean element specifies
whether the vector of relative strengths should be multiplied by the mesh
element volume. This is most common if the strengths represent a source
per unit volume.
*Default*: false
:bias:
For "mesh" and "cloud" spatial distributions, this optional element
specifies floating point values corresponding to alternative probabilities
for each value/component to use for biased sampling.
:angle:
An element specifying the angular distribution of source sites. This element
has the following attributes:
@ -786,6 +988,10 @@ attributes/sub-elements:
are those of a univariate probability distribution (see the description in
:ref:`univariate`).
:bias:
For "isotropic" angular distributions, this optional element specifies a
"mu-phi" angular distribution used for biased sampling.
:energy:
An element specifying the energy distribution of source sites. The necessary
sub-elements/attributes are those of a univariate probability distribution
@ -809,6 +1015,84 @@ attributes/sub-elements:
mesh element and follows the format for :ref:`source_element`. The number of
``<source>`` sub-elements should correspond to the number of mesh elements.
For a source with ``type="tokamak"``, the spatial distribution is described by
a Miller-style flux-surface parameterization and the following sub-elements
are used instead of the ``space`` element:
:major_radius:
The major radius :math:`R_0` of the plasma in [cm].
:minor_radius:
The minor radius :math:`a` of the plasma in [cm]. Must be smaller than
``major_radius``.
:elongation:
The plasma elongation :math:`\kappa` (must be > 0).
:triangularity:
The plasma triangularity :math:`\delta` (must be in [-1, 1]). Negative
values describe negative-triangularity plasmas.
:shafranov_shift:
The Shafranov shift :math:`\Delta` in [cm] (must be >= 0 and less than
``minor_radius``/2).
:r_over_a:
A list of normalized minor-radius grid points :math:`r/a`. Must be strictly
increasing, start at 0, and end at 1.
:emission_density:
A list of neutron emission densities :math:`S(r)` evaluated at each
``r_over_a`` grid point (arbitrary units, must be non-negative). Only the
shape matters, since the profile is normalized internally. Values are
interpolated linearly between grid points and the profile is refined on an
internal grid for radial sampling. Must have the same length as
``r_over_a`` and contain at least one positive value.
:phi_start:
The starting toroidal angle in [rad].
*Default*: 0.0
:phi_extent:
The toroidal angle extent in [rad]. The source is sampled uniformly in
:math:`[\phi_\text{start},\ \phi_\text{start} + \phi_\text{extent}]`.
*Default*: :math:`2\pi`
:n_alpha:
The number of poloidal-angle grid points used to build the sampling CDFs
(must be > 2). Larger values reduce discretization bias; values below 51
produce a warning.
*Default*: 101
:vertical_shift:
A vertical shift of the plasma center in [cm].
*Default*: 0.0
:energy:
For a tokamak source, one or more ``energy`` sub-elements specify the
neutron energy distribution(s). Either a single distribution is given (used
at all radii) or exactly one distribution per ``r_over_a`` grid point is
given, in which case the energy is sampled from one of the two
distributions bracketing the sampled radius, selected stochastically with
probability proportional to the proximity of the radius to each grid point
(stochastic interpolation). Each follows the format of a univariate
probability distribution (see :ref:`univariate`).
:time:
An optional ``time`` sub-element specifying the time distribution of source
particles, following the format of a univariate probability distribution
(see :ref:`univariate`).
*Default*: particles are born at :math:`t=0`
.. note:: Biased sampling can be applied to the spatial and energy distributions
of a source by using the ``<bias>`` sub-element (see
:ref:`univariate` for details on how to specify bias distributions).
:constraints:
This sub-element indicates the presence of constraints on sampled source
sites (see :ref:`usersguide_source_constraints` for details). It may have
@ -855,17 +1139,19 @@ variable and whose sub-elements/attributes are as follows:
:type:
The type of the distribution. Valid options are "uniform", "discrete",
"tabular", "maxwell", "watt", and "mixture". The "uniform" option produces
variates sampled from a uniform distribution over a finite interval. The
"discrete" option produces random variates that can assume a finite number
of values (i.e., a distribution characterized by a probability mass function).
The "tabular" option produces random variates sampled from a tabulated
distribution where the density function is either a histogram or
"tabular", "maxwell", "watt", "mixture", and "decay_spectrum". The "uniform"
option produces variates sampled from a uniform distribution over a finite
interval. The "discrete" option produces random variates that can assume a
finite number of values (i.e., a distribution characterized by a probability
mass function). The "tabular" option produces random variates sampled from a
tabulated distribution where the density function is either a histogram or
linearly-interpolated between tabulated points. The "watt" option produces
random variates is sampled from a Watt fission spectrum (only used for
energies). The "maxwell" option produce variates sampled from a Maxwell
fission spectrum (only used for energies). The "mixture" option produces samples
from univariate sub-distributions with given probabilities.
fission spectrum (only used for energies). The "mixture" option produces
samples from univariate sub-distributions with given probabilities. The
"decay_spectrum" option produces photon energies sampled from decay photon
spectra in a depletion chain (only used for energies).
*Default*: None
@ -883,6 +1169,10 @@ variable and whose sub-elements/attributes are as follows:
:math:`(x,p)` pairs defining the discrete/tabular distribution. All :math:`x`
points are given first followed by corresponding :math:`p` points.
For a "decay_spectrum" distribution, ``parameters`` gives the atom densities
in [atom/b-cm] for the nuclides listed in the ``nuclides`` element, in the
same order.
For a "watt" distribution, ``parameters`` should be given as two real numbers
:math:`a` and :math:`b` that parameterize the distribution :math:`p(x) dx = c
e^{-x/a} \sinh \sqrt{b \, x} dx`.
@ -901,30 +1191,51 @@ variable and whose sub-elements/attributes are as follows:
*Default*: histogram
:pair:
For a "mixture" distribution, this element provides a distribution and its corresponding probability.
For a "mixture" distribution, this element provides a distribution and its
corresponding probability.
:probability:
An attribute or ``pair`` that provides the probability of a univariate distribution within a "mixture" distribution.
An attribute or ``pair`` that provides the probability of a univariate
distribution within a "mixture" distribution.
:dist:
This sub-element of a ``pair`` element provides information on the corresponding univariate distribution.
This sub-element of a ``pair`` element provides information on the
corresponding univariate distribution.
-------------------------
``<state_point>`` Element
-------------------------
:volume:
For a "decay_spectrum" distribution, this attribute specifies the source
region volume in cm\ :sup:`3`. It is used together with atom densities to
determine the absolute photon emission rate. When a source uses a
"decay_spectrum" energy distribution, the source strength is set from this
emission rate.
The ``<state_point>`` element indicates at what batches a state point file
should be written. A state point file can be used to restart a run or to get
tally results at any batch. The default behavior when using this tag is to
write out the source bank in the state_point file. This behavior can be
customized by using the ``<source_point>`` element. This element has the
following attributes/sub-elements:
:nuclides:
For a "decay_spectrum" distribution, this element specifies a
whitespace-separated list of nuclide names contributing to the decay photon
source. The atom densities for these nuclides are given by the ``parameters``
element in the same order. Nuclides are resolved against the depletion chain,
and nuclides without decay photon spectra do not contribute to the
distribution.
:batches:
A list of integers separated by spaces indicating at what batches a state
point file should be written.
:bias:
This optional element specifies a biased distribution for importance sampling.
For continuous distributions, the ``bias`` element should contain another
univariate distribution with the same support (interval) as the parent
distribution. For discrete distributions, the ``bias`` element should contain
floating point values corresponding to alternative probabilities for each
value/component to be used for biased sampling.
*Default*: Last batch only
*Default*: None
---------------------------------------
``<source_rejection_fraction>`` Element
---------------------------------------
The ``<source_rejection_fraction>`` element specifies the minimum fraction of
external source sites that must be accepted when applying rejection sampling
based on constraints.
*Default*: 0.05
--------------------------
``<source_point>`` Element
@ -975,6 +1286,32 @@ attributes/sub-elements:
*Default*: false
-------------------------
``<state_point>`` Element
-------------------------
The ``<state_point>`` element indicates at what batches a state point file
should be written. A state point file can be used to restart a run or to get
tally results at any batch. The default behavior when using this tag is to
write out the source bank in the state_point file. This behavior can be
customized by using the ``<source_point>`` element. This element has the
following attributes/sub-elements:
:batches:
A list of integers separated by spaces indicating at what batches a state
point file should be written.
*Default*: Last batch only
--------------------
``<stride>`` Element
--------------------
The ``stride`` element is used to specify how many random numbers are allocated
for each source particle history.
*Default*: 152,917
------------------------------
``<surf_source_read>`` Element
------------------------------
@ -1062,6 +1399,23 @@ attributes/sub-elements:
are not eligible to store any particles when using ``cell``, ``cellfrom``
or ``cellto`` attributes. It is recommended to use surface IDs instead.
------------------------------------
``<surface_grazing_cutoff>`` Element
------------------------------------
The ``<surface_grazing_cutoff>`` element specifies the surface flux cosine cutoff.
*Default*: 0.001
-----------------------------------
``<surface_grazing_ratio>`` Element
-----------------------------------
The ``<surface_grazing_ratio>`` element specifies the surface flux cosine
substitution ratio.
*Default*: 0.5
------------------------------
``<survival_biasing>`` Element
------------------------------
@ -1245,6 +1599,15 @@ has the following attributes/sub-elements:
for fixed source and small criticality calculations, but is very
optimistic for highly coupled full-core reactor problems.
-------------------------------------
``<uniform_source_sampling>`` Element
-------------------------------------
The ``<uniform_source_sampling>`` element indicates whether to sample among
multiple sources uniformly, applying their strengths as weights to sampled
particles.
*Default*: False
------------------------
``<ufs_mesh>`` Element
@ -1257,6 +1620,16 @@ Agency Monte Carlo Performance Benchmark Problem," Proceedings of *Physor 2012*,
Knoxville, TN (2012). The mesh should cover all possible fissionable materials
in the problem and is specified using a :ref:`mesh_element`.
-------------------------------
``<use_decay_photons>`` Element
-------------------------------
The ``<use_decay_photons>`` element indicates whether to produce decay photons
from neutron reactions instead of prompt photons. This is used in conjunction
with the direct 1-step method for shutdown dose rate calculations.
*Default*: False
.. _verbosity:
-----------------------
@ -1358,7 +1731,8 @@ sub-elements/attributes:
*Default*: None
:particle_type:
The particle that the weight windows will apply to (e.g., 'neutron')
The particle that the weight windows will apply to, specified as a PDG
code or string (e.g., ``neutron``).
*Default*: 'neutron'
@ -1418,7 +1792,8 @@ mesh-based weight windows.
*Default*: None
:particle_type:
The particle that the weight windows will apply to (e.g., 'neutron')
The particle that the weight windows will apply to, specified as a PDG
code or string (e.g., ``neutron``).
*Default*: neutron
@ -1462,6 +1837,14 @@ mesh-based weight windows.
*Default*: 5.0
For FW-CADIS:
:targets:
A sequence of IDs corresponding to the tallies which cover phase
space regions of interest for local variance reduction.
*Default*: None
---------------------------------------
``<weight_window_checkpoints>`` Element
---------------------------------------
@ -1487,3 +1870,21 @@ following sub-elements/attributes:
The ``weight_windows_file`` element has no attributes and contains the path to
a weight windows HDF5 file to load during simulation initialization.
-------------------------------
``<weight_windows_on>`` Element
-------------------------------
The ``weight_windows_on`` element indicates whether weight windows are
enabled.
*Default*: False
----------------------------------
``<write_initial_source>`` Element
----------------------------------
The ``write_initial_source`` element indicates whether to write the initial
source distribution to file.
*Default*: False

View file

@ -15,6 +15,8 @@ following the same format.
**/**
:Attributes: - **filetype** (*char[]*) -- String indicating the type of file.
- **version** (*int[2]*) -- Major and minor version of the source
file format.
:Datasets:
@ -22,5 +24,5 @@ following the same format.
particle. The compound type has fields ``r``, ``u``, ``E``,
``time``, ``wgt``, ``delayed_group``, ``surf_id`` and ``particle``,
which represent the position, direction, energy, time, weight,
delayed group, surface ID, and particle type (0=neutron, 1=photon,
2=electron, 3=positron), respectively.
delayed group, surface ID, and particle type (PDG number),
respectively.

View file

@ -4,7 +4,7 @@
State Point File Format
=======================
The current version of the statepoint file format is 18.1.
The current version of the statepoint file format is 18.2.
**/**
@ -56,8 +56,8 @@ The current version of the statepoint file format is 18.1.
``time``, ``wgt``, ``delayed_group``, ``surf_id``, and
``particle``, which represent the position, direction, energy,
time, weight, delayed group, surface ID, and particle type
(0=neutron, 1=photon, 2=electron, 3=positron), respectively. Only
present when `run_mode` is 'eigenvalue'.
(PDG number), respectively. Only present when `run_mode` is
'eigenvalue'.
**/tallies/**
@ -149,6 +149,8 @@ The current version of the statepoint file format is 18.1.
tallies will have a value of 0 unless otherwise instructed.
- **multiply_density** (*int*) -- Flag indicating whether reaction
rates should be multiplied by atom density (1) or not (0).
- **higher_moments** (*int*) -- Flag indicating whether
higher-order tally moments are enabled (1) or not (0).
:Datasets: - **n_realizations** (*int*) -- Number of realizations.
- **n_filters** (*int*) -- Number of filters used.

View file

@ -4,7 +4,7 @@
Summary File Format
===================
The current version of the summary file format is 6.0.
The current version of the summary file format is 6.1.
**/**
@ -38,6 +38,7 @@ The current version of the summary file format is 6.0.
is an array if the cell uses distributed materials, otherwise it is
a scalar.
- **temperature** (*double[]*) -- Temperature of the cell in Kelvin.
- **density** (*double[]*) -- Density of the cell in [g/cm3].
- **translation** (*double[3]*) -- Translation applied to the fill
universe. This dataset is present only if fill_type is set to
'universe'.

View file

@ -142,9 +142,9 @@ attributes/sub-elements:
:type:
The type of the filter. Accepted options are "cell", "cellfrom",
"cellborn", "surface", "material", "universe", "energy", "energyout", "mu",
"polar", "azimuthal", "mesh", "distribcell", "delayedgroup",
"energyfunction", and "particle".
"cellborn", "surface", "material", "universe", "energy", "energyout",
"mu", "polar", "azimuthal", "mesh", "distribcell", "delayedgroup",
"energyfunction", "particle", and "particleproduction".
:bins:
A description of the bins for each type of filter can be found in
@ -318,8 +318,34 @@ should be set to:
they use ``energy`` and ``y``.
:particle:
A list of integers indicating the type of particles to tally ('neutron' = 1,
'photon' = 2, 'electron' = 3, 'positron' = 4).
A list of particle identifiers to tally, specified as strings (e.g.,
``neutron``, ``photon``, ``He4``) or as integer PDG numbers.
:particleproduction:
This filter tallies secondary particles produced in reactions, binned by
particle type and, optionally, by energy. Unlike other energy filters, the
weight applied is the weight of the secondary particle. To obtain secondary
particle production rates, use this filter with the ``events`` score.
The filter uses the following sub-elements instead of ``bins``:
:particles:
A space-separated list of secondary particle types to tally (e.g.,
``photon``, ``neutron``, ``electron``).
:energies:
An optional monotonically increasing list of energy boundaries in [eV]
for binning the secondary particle energies. If omitted, total production
is tallied without energy binning.
For example, to tally photon and neutron production in three energy groups:
.. code-block:: xml
<filter id="1" type="particleproduction">
<particles>photon neutron</particles>
<energies>0.0 1.0e5 1.0e6 20.0e6</energies>
</filter>
------------------
``<mesh>`` Element

View file

@ -4,7 +4,7 @@
Track File Format
=================
The current revision of the particle track file format is 3.0.
The current revision of the particle track file format is 3.1.
**/**
@ -32,6 +32,5 @@ The current revision of the particle track file format is 3.0.
the array for each primary/secondary particle. The
last offset should match the total size of the
array.
- **particles** (*int[]*) -- Particle type for each
primary/secondary particle (0=neutron, 1=photon,
2=electron, 3=positron).
- **particles** (*int32_t[]*) -- Particle type for
each primary/secondary particle (PDG number).

View file

@ -4,7 +4,7 @@
License Agreement
=================
Copyright © 2011-2025 Massachusetts Institute of Technology, UChicago Argonne
Copyright © 2011-2026 Massachusetts Institute of Technology, UChicago Argonne
LLC, and OpenMC contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of

View file

@ -0,0 +1,362 @@
.. _methods_charged_particle_physics:
========================
Charged Particle Physics
========================
OpenMC neglects the spatial transport of charged particles (electrons and
positrons), assuming they deposit all their energy locally and produce
bremsstrahlung photons at their birth location. This approximation, called
thick-target bremsstrahlung (TTB) approximation is justified by the fact that
charged particles have much shorter stopping ranges compared to neutrons and
photons, especially in high-density materials.
-----------------------------
Charged Particle Interactions
-----------------------------
Bremsstrahlung
--------------
When a charged particle is decelerated in the field of an atom, some of its
kinetic energy is converted into electromagnetic radiation known as
bremsstrahlung, or 'braking radiation'. In each event, an electron or positron
with kinetic energy :math:`T` generates a photon with an energy :math:`E`
between :math:`0` and :math:`T`. Bremsstrahlung is described by a cross section
that is differential in photon energy, in the direction of the emitted photon,
and in the final direction of the charged particle. However, in Monte Carlo
simulations it is typical to integrate over the angular variables to obtain a
single differential cross section with respect to photon energy, which is often
expressed in the form
.. math::
:label: bremsstrahlung-dcs
\frac{d\sigma_{\text{br}}}{dE} = \frac{Z^2}{\beta^2} \frac{1}{E}
\chi(Z, T, \kappa),
where :math:`\kappa = E/T` is the reduced photon energy and :math:`\chi(Z, T,
\kappa)` is the scaled bremsstrahlung cross section, which is experimentally
measured.
Because electrons are attracted to atomic nuclei whereas positrons are
repulsed, the cross section for positrons is smaller, though it approaches that
of electrons in the high energy limit. To obtain the positron cross section, we
multiply :eq:`bremsstrahlung-dcs` by the :math:`\kappa`-independent factor used
in Salvat_,
.. math::
:label: positron-factor
\begin{aligned}
F_{\text{p}}(Z,T) =
& 1 - \text{exp}(-1.2359\times 10^{-1}t + 6.1274\times 10^{-2}t^2 - 3.1516\times 10^{-2}t^3 \\
& + 7.7446\times 10^{-3}t^4 - 1.0595\times 10^{-3}t^5 + 7.0568\times 10^{-5}t^6 \\
& - 1.8080\times 10^{-6}t^7),
\end{aligned}
where
.. math::
:label: positron-factor-t
t = \ln\left(1 + \frac{10^6}{Z^2}\frac{T}{\text{m}_\text{e}c^2} \right).
:math:`F_{\text{p}}(Z,T)` is the ratio of the radiative stopping powers for
positrons and electrons. Stopping power describes the average energy loss per
unit path length of a charged particle as it passes through matter:
.. math::
:label: stopping-power
-\frac{dT}{ds} = n \int E \frac{d\sigma}{dE} dE \equiv S(T),
where :math:`n` is the number density of the material and :math:`d\sigma/dE` is
the cross section differential in energy loss. The total stopping power
:math:`S(T)` can be separated into two components: the radiative stopping
power :math:`S_{\text{rad}}(T)`, which refers to energy loss due to
bremsstrahlung, and the collision stopping power :math:`S_{\text{col}}(T)`,
which refers to the energy loss due to inelastic collisions with bound
electrons in the material that result in ionization and excitation. The
radiative stopping power for electrons is given by
.. math::
:label: radiative-stopping-power
S_{\text{rad}}(T) = n \frac{Z^2}{\beta^2} T \int_0^1 \chi(Z,T,\kappa)
d\kappa.
To obtain the radiative stopping power for positrons,
:eq:`radiative-stopping-power` is multiplied by :eq:`positron-factor`.
While the models for photon interactions with matter described above can safely
assume interactions occur with free atoms, sampling the target atom based on
the macroscopic cross sections, molecular effects cannot necessarily be
disregarded for charged particle treatment. For compounds and mixtures, the
bremsstrahlung cross section is calculated using Bragg's additivity rule as
.. math::
:label: material-bremsstrahlung-dcs
\frac{d\sigma_{\text{br}}}{dE} = \frac{1}{\beta^2 E} \sum_i \gamma_i Z^2_i
\chi(Z_i, T, \kappa),
where the sum is over the constituent elements and :math:`\gamma_i` is the
atomic fraction of the :math:`i`-th element. Similarly, the radiative stopping
power is calculated using Bragg's additivity rule as
.. math::
:label: material-radiative-stopping-power
S_{\text{rad}}(T) = \sum_i w_i S_{\text{rad},i}(T),
where :math:`w_i` is the mass fraction of the :math:`i`-th element and
:math:`S_{\text{rad},i}(T)` is found for element :math:`i` using
:eq:`radiative-stopping-power`. The collision stopping power, however, is a
function of certain quantities such as the mean excitation energy :math:`I` and
the density effect correction :math:`\delta_F` that depend on molecular
properties. These quantities cannot simply be summed over constituent elements
in a compound, but should instead be calculated for the material. The Bethe
formula can be used to find the collision stopping power of the material:
.. math::
:label: material-collision-stopping-power
S_{\text{col}}(T) = \frac{2 \pi r_e^2 m_e c^2}{\beta^2} N_A \frac{Z}{A_M}
[\ln(T^2/I^2) + \ln(1 + \tau/2) + F(\tau) - \delta_F(T)],
where :math:`N_A` is Avogadro's number, :math:`A_M` is the molar mass,
:math:`\tau = T/m_e`, and :math:`F(\tau)` depends on the particle type. For
electrons,
.. math::
:label: F-electron
F_{-}(\tau) = (1 - \beta^2)[1 + \tau^2/8 - (2\tau + 1) \ln2],
while for positrons
.. math::
:label: F-positron
F_{+}(\tau) = 2\ln2 - (\beta^2/12)[23 + 14/(\tau + 2) + 10/(\tau + 2)^2 +
4/(\tau + 2)^3].
The density effect correction :math:`\delta_F` takes into account the reduction
of the collision stopping power due to the polarization of the material the
charged particle is passing through by the electric field of the particle.
It can be evaluated using the method described by Sternheimer_, where the
equation for :math:`\delta_F` is
.. math::
:label: density-effect-correction
\delta_F(\beta) = \sum_{i=1}^n f_i \ln[(l_i^2 + l^2)/l_i^2] -
l^2(1-\beta^2).
Here, :math:`f_i` is the oscillator strength of the :math:`i`-th transition,
given by :math:`f_i = n_i/Z`, where :math:`n_i` is the number of electrons in
the :math:`i`-th subshell. The frequency :math:`l` is the solution of the
equation
.. math::
:label: density-effect-l
\frac{1}{\beta^2} - 1 = \sum_{i=1}^{n} \frac{f_i}{\bar{\nu}_i^2 + l^2},
where :math:`\bar{v}_i` is defined as
.. math::
:label: density-effect-nubar
\bar{\nu}_i = h\nu_i \rho / h\nu_p.
The plasma energy :math:`h\nu_p` of the medium is given by
.. math::
:label: plasma-frequency
h\nu_p = \sqrt{\frac{(hc)^2 r_e \rho_m N_A Z}{\pi A}},
where :math:`A` is the atomic weight and :math:`\rho_m` is the density of the
material. In :eq:`density-effect-nubar`, :math:`h\nu_i` is the oscillator
energy, and :math:`\rho` is an adjustment factor introduced to give agreement
between the experimental values of the oscillator energies and the mean
excitation energy. The :math:`l_i` in :eq:`density-effect-correction` are
defined as
.. math::
:label: density-effect-li
\begin{aligned}
l_i &= (\bar{\nu}_i^2 + 2/3f_i)^{1/2} ~~~~&\text{for}~~ \bar{\nu}_i > 0 \\
l_n &= f_n^{1/2} ~~~~&\text{for}~~ \bar{\nu}_n = 0,
\end{aligned}
where the second case applies to conduction electrons. For a conductor,
:math:`f_n` is given by :math:`n_c/Z`, where :math:`n_c` is the effective
number of conduction electrons, and :math:`v_n = 0`. The adjustment factor
:math:`\rho` is determined using the equation for the mean excitation energy:
.. math::
:label: mean-excitation-energy
\ln I = \sum_{i=1}^{n-1} f_i \ln[(h\nu_i\rho)^2 + 2/3f_i(h\nu_p)^2]^{1/2} +
f_n \ln (h\nu_pf_n^{1/2}).
.. _ttb:
Thick-Target Bremsstrahlung Approximation
+++++++++++++++++++++++++++++++++++++++++
Since charged particles lose their energy on a much shorter distance scale than
neutral particles, not much error should be introduced by neglecting to
transport electrons. However, the bremsstrahlung emitted from high energy
electrons and positrons can travel far from the interaction site. Thus, even
without a full electron transport mode it is necessary to model bremsstrahlung.
We use a thick-target bremsstrahlung (TTB) approximation based on the models in
Salvat_ and Kaltiaisenaho_ for generating bremsstrahlung photons, which assumes
the charged particle loses all its energy in a single homogeneous material
region.
To model bremsstrahlung using the TTB approximation, we need to know the number
of photons emitted by the charged particle and the energy distribution of the
photons. These quantities can be calculated using the continuous slowing down
approximation (CSDA). The CSDA assumes charged particles lose energy
continuously along their trajectory with a rate of energy loss equal to the
total stopping power, ignoring fluctuations in the energy loss. The
approximation is useful for expressing average quantities that describe how
charged particles slow down in matter. For example, the CSDA range approximates
the average path length a charged particle travels as it slows to rest:
.. math::
:label: csda-range
R(T) = \int^T_0 \frac{dT'}{S(T')}.
Actual path lengths will fluctuate around :math:`R(T)`. The average number of
photons emitted per unit path length is given by the inverse bremsstrahlung
mean free path:
.. math::
:label: inverse-bremsstrahlung-mfp
\lambda_{\text{br}}^{-1}(T,E_{\text{cut}})
= n\int_{E_{\text{cut}}}^T\frac{d\sigma_{\text{br}}}{dE}dE
= n\frac{Z^2}{\beta^2}\int_{\kappa_{\text{cut}}}^1\frac{1}{\kappa}
\chi(Z,T,\kappa)d\kappa.
The lower limit of the integral in :eq:`inverse-bremsstrahlung-mfp` is non-zero
because the bremsstrahlung differential cross section diverges for small photon
energies but is finite for photon energies above some cutoff energy
:math:`E_{\text{cut}}`. The mean free path
:math:`\lambda_{\text{br}}^{-1}(T,E_{\text{cut}})` is used to calculate the
photon number yield, defined as the average number of photons emitted with
energy greater than :math:`E_{\text{cut}}` as the charged particle slows down
from energy :math:`T` to :math:`E_{\text{cut}}`. The photon number yield is
given by
.. math::
:label: photon-number-yield
Y(T,E_{\text{cut}}) = \int^{R(T)}_{R(E_{\text{cut}})}
\lambda_{\text{br}}^{-1}(T',E_{\text{cut}})ds = \int_{E_{\text{cut}}}^T
\frac{\lambda_{\text{br}}^{-1}(T',E_{\text{cut}})}{S(T')}dT'.
:math:`Y(T,E_{\text{cut}})` can be used to construct the energy spectrum of
bremsstrahlung photons: the number of photons created with energy between
:math:`E_1` and :math:`E_2` by a charged particle with initial kinetic energy
:math:`T` as it comes to rest is given by :math:`Y(T,E_1) - Y(T,E_2)`.
To simulate the emission of bremsstrahlung photons, the total stopping power
and bremsstrahlung differential cross section for positrons and electrons must
be calculated for a given material using :eq:`material-bremsstrahlung-dcs` and
:eq:`material-radiative-stopping-power`. These quantities are used to build the
tabulated bremsstrahlung energy PDF and CDF for that material for each incident
energy :math:`T_k` on the energy grid. The following algorithm is then applied
to sample the photon energies:
1. For an incident charged particle with energy :math:`T`, sample the number of
emitted photons as
.. math::
N = \lfloor Y(T,E_{\text{cut}}) + \xi_1 \rfloor.
2. Rather than interpolate the PDF between indices :math:`k` and :math:`k+1`
for which :math:`T_k < T < T_{k+1}`, which is computationally expensive, use
the composition method and sample from the PDF at either :math:`k` or
:math:`k+1`. Using linear interpolation on a logarithmic scale, the PDF can
be expressed as
.. math::
p_{\text{br}}(T,E) = \pi_k p_{\text{br}}(T_k,E) + \pi_{k+1}
p_{\text{br}}(T_{k+1},E),
where the interpolation weights are
.. math::
\pi_k = \frac{\ln T_{k+1} - \ln T}{\ln T_{k+1} - \ln T_k},~~~
\pi_{k+1} = \frac{\ln T - \ln T_k}{\ln T_{k+1} - \ln T_k}.
Sample either the index :math:`i = k` or :math:`i = k+1` according to the
point probabilities :math:`\pi_{k}` and :math:`\pi_{k+1}`.
3. Determine the maximum value of the CDF :math:`P_{\text{br,max}}`.
3. Sample the photon energies using the inverse transform method with the
tabulated CDF :math:`P_{\text{br}}(T_i, E)` i.e.,
.. math::
E = E_j \left[ (1 + a_j) \frac{\xi_2 P_{\text{br,max}} -
P_{\text{br}}(T_i, E_j)} {E_j p_{\text{br}}(T_i, E_j)} + 1
\right]^{\frac{1}{1 + a_j}}
where the interpolation factor :math:`a_j` is given by
.. math::
a_j = \frac{\ln p_{\text{br}}(T_i,E_{j+1}) - \ln p_{\text{br}}(T_i,E_j)}
{\ln E_{j+1} - \ln E_j}
and :math:`P_{\text{br}}(T_i, E_j) \le \xi_2 P_{\text{br,max}} \le
P_{\text{br}}(T_i, E_{j+1})`.
We ignore the range of the electron or positron, i.e., the bremsstrahlung
photons are produced in the same location that the charged particle was
created. The direction of the photons is assumed to be the same as the
direction of the incident charged particle, which is a reasonable approximation
at higher energies when the bremsstrahlung radiation is emitted at small
angles.
Electron-Positron Annihilation
------------------------------
When a positron collides with an electron, both particles are annihilated and
generally two photons with equal energy are created. If the kinetic energy of
the positron is high enough, the two photons can have different energies, and
the higher-energy photon is emitted preferentially in the direction of flight
of the positron. It is also possible to produce a single photon if the
interaction occurs with a bound electron, and in some cases three (or, rarely,
even more) photons can be emitted. However, the annihilation cross section is
largest for low-energy positrons, and as the positron energy decreases, the
angular distribution of the emitted photons becomes isotropic.
In OpenMC, we assume the most likely case in which a low-energy positron (which
has already lost most of its energy to bremsstrahlung radiation) interacts with
an electron which is free and at rest. Two photons with energy equal to the
electron rest mass energy :math:`m_e c^2 = 0.511` MeV are emitted isotropically
in opposite directions.
.. _Kaltiaisenaho: https://aaltodoc.aalto.fi/bitstream/handle/123456789/21004/master_Kaltiaisenaho_Toni_2016.pdf
.. _Salvat: https://doi.org/10.1787/32da5043-en
.. _Sternheimer: https://doi.org/10.1103/PhysRevB.26.6067

View file

@ -289,6 +289,48 @@ sections. This allows flexibility for the model to use highly anisotropic
scattering information in the water while the fuel can be simulated with linear
or even isotropic scattering.
Particle Speed
--------------
When using a multigroup representation of cross sections, the particle speed has
meaning only in an average sense. The particle speed is important when modeling
dynamic behavior. OpenMC calculates the particle speed using the inverse
velocity multigroup data if it is available. If such data is not available,
OpenMC uses an approximate velocity using the group energy bounds in the
following way:
.. math::
\frac{1}{v_g} = \int_{E_{\text{min}}^g}^{E_{\text{max}}^g} \frac{1}{v(E)} \frac{\alpha}{E} dE
Where :math:`E_{\text{min}}^g` and :math:`E_{\text{max}}^g` are the group energy
boundaries for group :math:`g`. :math:`v(E)` is the neutron velocity calculated
using relativistic kinematics, :math:`\alpha` is a normalization constant for the
:math:`\frac{1}{E}` spectrum.
This equation is valid when inside the group boundaries the neutron spectrum
follows a typical :math:`\frac{1}{E}` slowing down spectrum. This assumption is
widely used when generating fine group neutron cross section data libraries from
continuous energy data.
The solution to this equation is:
.. math::
\frac{1}{v_g} = \frac{1}{c \log\left(\frac{E_{\text{max}}^g}{E_{\text{min}}^g}\right)}
\left[ 2(\operatorname{arctanh}(k_{\text{max}}^{-1}) - \operatorname{arctanh}(k_{\text{min}}^{-1}))
- (k_{\text{max}}-k_{\text{min}}) \right]
where :math:`c` is the speed of light and :math:`k_{\text{max}}`,
:math:`k_{\text{min}}` are defined by a change of variables:
.. math::
k = \sqrt{1+\frac{2 m_n c^2}{E}}
where :math:`E` is the particle kinetic energy and :math:`m_n` is the neutron
rest mass.
.. _logarithmic mapping technique:
https://mcnp.lanl.gov/pdf_files/TechReport_2014_LANL_LA-UR-14-24530_Brown.pdf
.. _Hwang: https://doi.org/10.13182/NSE87-A16381

View file

@ -25,19 +25,38 @@ KERMA (Kinetic Energy Release in Materials) [Mack97]_ coefficients for reaction
:math:`\times` cross-section (e.g., eV-barn) and can be used much like a reaction
cross section for the purpose of tallying energy deposition.
KERMA coefficients can be computed using the energy-balance method with
a nuclear data processing code like NJOY, which performs the following
iteration over all reactions :math:`r` for all isotopes :math:`i`
requested
KERMA coefficients can be computed using the energy-balance method with a
nuclear data processing code like NJOY, which estimates the KERMA coefficients
using the following equation:
.. math::
k_{i, r}(E) = \left(E + Q_{i, r} - \bar{E}_{i, r, n}
k_{i, r}(E) = \left(E + Q_{i, r} - \sum\limits_x \bar{E}_{i, r, x}
\right)\sigma_{i, r}(E),
where the summation is over each secondary particle type :math:`x`. This
equation states that the energy deposited is equal to the energy of the incident
particle plus the reaction :math:`Q` value less the energy of secondary
particles that are transported away from the reaction site. For neutron
interactions, the energy-balance KERMA coefficient is
.. math::
k_{i, r}(E) = \left(E + Q_{i, r} - \sum\limits_x \bar{E}_{i, r, n}
- \bar{E}_{i, r, \gamma}\right)\sigma_{i, r}(E),
removing the energy of neutral particles (neutrons and photons) that are
transported away from the reaction site :math:`\bar{E}`, and the reaction
:math:`Q` value.
where :math:`\bar{E}_{i, r, n}` is the average energy of secondary neutrons and
:math:`\bar{E}_{i, r, \gamma}` is the average energy of secondary photons. For
photon and charged particle interactions the KERMA coefficient is
.. math::
:label: energy-balance-photon
k_{i, r}(E) = \left(E + Q_{i, r} - \sum\limits_x \bar{E}_{i, r, x}
\right)\sigma_{i, r}(E).
where the :math:`Q` value is zero for all interactions except for pair
production and positron annihilation.
-------
Fission
@ -120,7 +139,7 @@ run with :math:`N918` reflecting fission heating computed from NJOY.
This modified heating data is stored as the MT=901 reaction and will be scored
if ``heating-local`` is included in :attr:`openmc.Tally.scores`.
Coupled neutron-photon transport
Coupled Neutron-Photon Transport
--------------------------------
Here, OpenMC instructs ``heatr`` to assume that energy from photons is not
@ -138,6 +157,50 @@ Let :math:`N301` represent the total heating number returned from this
This modified heating data is stored as the MT=301 reaction and will be scored
if ``heating`` is included in :attr:`openmc.Tally.scores`.
Photons and Charged Particles
-----------------------------
In OpenMC, energy deposition from photons or charged particles is scored using
the energy balance method based on Equation :eq:`energy-balance-photon`. Special
consideration is given to electrons and positrons as described below.
+++++++++++++++++
Charged Particles
+++++++++++++++++
OpenMC tracks photons interaction by interaction so the energy deposited in each
collision is easily attributed back to the nuclide and reaction for which the
photon interacted with. Charged particles (electrons and photons) aren't tracked
in the same way. For charged particles, OpenMC assumes that all their energy
(less the energy of bremsstrahlung radiation) is deposited in the material in
which they were born. In this way it is harder to trace how much energy should
be attributed in each nuclide.
According to the CSDA approximation (see :ref:`ttb`) the energy deposited by a
charged particle with kinetic energy :math:`T` in the :math:`i`-th element can
be calculated as:
.. math::
E_{i} = \int_{0}^{R(T)} w_{i}S_{\text{col,i}} dx
where :math:`R(T)` is the CSDA range of the charged particle,
:math:`S_{\text{col},i}` is the collision stopping power of the charged particle
in the :math:`i`-th element and :math:`w_i` is the mass fraction of the
:math:`i`-th element. According to the Bethe formula the collision stopping
power of the :math:`i`-th element is proportional to :math:`Z_i/A_i`, so the
fractional collision stopping power from the :math:`i`-th element is:
.. math::
\frac{w_{i}S_{\text{col},i}(T)}{S_{\text{col}}(T)} =
\frac{\frac{w_{i}Z_{i}}{A_{i}}}{\sum_{i}\frac{w_{i}Z_{i}}{A_{i}}} =
\frac{\gamma_i Z_{i}}{\sum_{i}\gamma_i Z_{i}}.
where :math:`\gamma_i` is the atomic fraction of the :math:`i`-th element.
Therefore, the energy deposited by charged particles should be attributed to
a given element according to its fractional charge density.
----------
References
----------

View file

@ -14,6 +14,7 @@ Theory and Methodology
random_numbers
neutron_physics
photon_physics
charged_particles_physics
tallies
eigenvalue
depletion
@ -21,4 +22,4 @@ Theory and Methodology
parallelization
cmfd
variance_reduction
random_ray
random_ray

View file

@ -290,7 +290,10 @@ create and store fission sites for the following generation. First, the average
number of prompt and delayed neutrons must be determined to decide whether the
secondary neutrons will be prompt or delayed. This is important because delayed
neutrons have a markedly different spectrum from prompt neutrons, one that has a
lower average energy of emission. The total number of neutrons emitted
lower average energy of emission. Furthermore, in simulations where tracking
time of neutrons is important, we need to consider the emission time delay of
the secondary neutrons, which is dependent on the decay constant of the
delayed neutron precursor. The total number of neutrons emitted
:math:`\nu_t` is given as a function of incident energy in the ENDF format. Two
representations exist for :math:`\nu_t`. The first is a polynomial of order
:math:`N` with coefficients :math:`c_0,c_1,\dots,c_N`. If :math:`\nu_t` has this
@ -306,8 +309,8 @@ interpolation law. The number of prompt neutrons released per fission event
:math:`\nu_p` is also given as a function of incident energy and can be
specified in a polynomial or tabular format. The number of delayed neutrons
released per fission event :math:`\nu_d` can only be specified in a tabular
format. In practice, we only need to determine :math:`nu_t` and
:math:`nu_d`. Once these have been determined, we can calculated the delayed
format. In practice, we only need to determine :math:`\nu_t` and
:math:`\nu_d`. Once these have been determined, we can calculate the delayed
neutron fraction
.. math::
@ -335,8 +338,14 @@ neutrons. Otherwise, we produce :math:`\lfloor \nu \rfloor + 1` neutrons. Then,
for each fission site produced, we sample the outgoing angle and energy
according to the algorithms given in :ref:`sample-angle` and
:ref:`sample-energy` respectively. If the neutron is to be born delayed, then
there is an extra step of sampling a delayed neutron precursor group since they
each have an associated secondary energy distribution.
there is an extra step of sampling a delayed neutron precursor group to get the
associated secondary energy distribution and the decay constant
:math:`\lambda`, which is needed to sample the emission delay time :math:`t_d`:
.. math::
:label: sample-delay-time
t_d = -\frac{\ln \xi}{\lambda}.
The sampled outgoing angle and energy of fission neutrons along with the
position of the collision site are stored in an array called the fission

View file

@ -667,342 +667,6 @@ and Auger electrons:
5. Repeat from step 1 for vacancy left by the transition electron.
Electron-Positron Annihilation
------------------------------
When a positron collides with an electron, both particles are annihilated and
generally two photons with equal energy are created. If the kinetic energy of
the positron is high enough, the two photons can have different energies, and
the higher-energy photon is emitted preferentially in the direction of flight
of the positron. It is also possible to produce a single photon if the
interaction occurs with a bound electron, and in some cases three (or, rarely,
even more) photons can be emitted. However, the annihilation cross section is
largest for low-energy positrons, and as the positron energy decreases, the
angular distribution of the emitted photons becomes isotropic.
In OpenMC, we assume the most likely case in which a low-energy positron (which
has already lost most of its energy to bremsstrahlung radiation) interacts with
an electron which is free and at rest. Two photons with energy equal to the
electron rest mass energy :math:`m_e c^2 = 0.511` MeV are emitted isotropically
in opposite directions.
Bremsstrahlung
--------------
When a charged particle is decelerated in the field of an atom, some of its
kinetic energy is converted into electromagnetic radiation known as
bremsstrahlung, or 'braking radiation'. In each event, an electron or positron
with kinetic energy :math:`T` generates a photon with an energy :math:`E`
between :math:`0` and :math:`T`. Bremsstrahlung is described by a cross section
that is differential in photon energy, in the direction of the emitted photon,
and in the final direction of the charged particle. However, in Monte Carlo
simulations it is typical to integrate over the angular variables to obtain a
single differential cross section with respect to photon energy, which is often
expressed in the form
.. math::
:label: bremsstrahlung-dcs
\frac{d\sigma_{\text{br}}}{dE} = \frac{Z^2}{\beta^2} \frac{1}{E}
\chi(Z, T, \kappa),
where :math:`\kappa = E/T` is the reduced photon energy and :math:`\chi(Z, T,
\kappa)` is the scaled bremsstrahlung cross section, which is experimentally
measured.
Because electrons are attracted to atomic nuclei whereas positrons are
repulsed, the cross section for positrons is smaller, though it approaches that
of electrons in the high energy limit. To obtain the positron cross section, we
multiply :eq:`bremsstrahlung-dcs` by the :math:`\kappa`-independent factor used
in Salvat_,
.. math::
:label: positron-factor
\begin{aligned}
F_{\text{p}}(Z,T) =
& 1 - \text{exp}(-1.2359\times 10^{-1}t + 6.1274\times 10^{-2}t^2 - 3.1516\times 10^{-2}t^3 \\
& + 7.7446\times 10^{-3}t^4 - 1.0595\times 10^{-3}t^5 + 7.0568\times 10^{-5}t^6 \\
& - 1.8080\times 10^{-6}t^7),
\end{aligned}
where
.. math::
:label: positron-factor-t
t = \ln\left(1 + \frac{10^6}{Z^2}\frac{T}{\text{m}_\text{e}c^2} \right).
:math:`F_{\text{p}}(Z,T)` is the ratio of the radiative stopping powers for
positrons and electrons. Stopping power describes the average energy loss per
unit path length of a charged particle as it passes through matter:
.. math::
:label: stopping-power
-\frac{dT}{ds} = n \int E \frac{d\sigma}{dE} dE \equiv S(T),
where :math:`n` is the number density of the material and :math:`d\sigma/dE` is
the cross section differential in energy loss. The total stopping power
:math:`S(T)` can be separated into two components: the radiative stopping
power :math:`S_{\text{rad}}(T)`, which refers to energy loss due to
bremsstrahlung, and the collision stopping power :math:`S_{\text{col}}(T)`,
which refers to the energy loss due to inelastic collisions with bound
electrons in the material that result in ionization and excitation. The
radiative stopping power for electrons is given by
.. math::
:label: radiative-stopping-power
S_{\text{rad}}(T) = n \frac{Z^2}{\beta^2} T \int_0^1 \chi(Z,T,\kappa)
d\kappa.
To obtain the radiative stopping power for positrons,
:eq:`radiative-stopping-power` is multiplied by :eq:`positron-factor`.
While the models for photon interactions with matter described above can safely
assume interactions occur with free atoms, sampling the target atom based on
the macroscopic cross sections, molecular effects cannot necessarily be
disregarded for charged particle treatment. For compounds and mixtures, the
bremsstrahlung cross section is calculated using Bragg's additivity rule as
.. math::
:label: material-bremsstrahlung-dcs
\frac{d\sigma_{\text{br}}}{dE} = \frac{1}{\beta^2 E} \sum_i \gamma_i Z^2_i
\chi(Z_i, T, \kappa),
where the sum is over the constituent elements and :math:`\gamma_i` is the
atomic fraction of the :math:`i`-th element. Similarly, the radiative stopping
power is calculated using Bragg's additivity rule as
.. math::
:label: material-radiative-stopping-power
S_{\text{rad}}(T) = \sum_i w_i S_{\text{rad},i}(T),
where :math:`w_i` is the mass fraction of the :math:`i`-th element and
:math:`S_{\text{rad},i}(T)` is found for element :math:`i` using
:eq:`radiative-stopping-power`. The collision stopping power, however, is a
function of certain quantities such as the mean excitation energy :math:`I` and
the density effect correction :math:`\delta_F` that depend on molecular
properties. These quantities cannot simply be summed over constituent elements
in a compound, but should instead be calculated for the material. The Bethe
formula can be used to find the collision stopping power of the material:
.. math::
:label: material-collision-stopping-power
S_{\text{col}}(T) = \frac{2 \pi r_e^2 m_e c^2}{\beta^2} N_A \frac{Z}{A_M}
[\ln(T^2/I^2) + \ln(1 + \tau/2) + F(\tau) - \delta_F(T)],
where :math:`N_A` is Avogadro's number, :math:`A_M` is the molar mass,
:math:`\tau = T/m_e`, and :math:`F(\tau)` depends on the particle type. For
electrons,
.. math::
:label: F-electron
F_{-}(\tau) = (1 - \beta^2)[1 + \tau^2/8 - (2\tau + 1) \ln2],
while for positrons
.. math::
:label: F-positron
F_{+}(\tau) = 2\ln2 - (\beta^2/12)[23 + 14/(\tau + 2) + 10/(\tau + 2)^2 +
4/(\tau + 2)^3].
The density effect correction :math:`\delta_F` takes into account the reduction
of the collision stopping power due to the polarization of the material the
charged particle is passing through by the electric field of the particle.
It can be evaluated using the method described by Sternheimer_, where the
equation for :math:`\delta_F` is
.. math::
:label: density-effect-correction
\delta_F(\beta) = \sum_{i=1}^n f_i \ln[(l_i^2 + l^2)/l_i^2] -
l^2(1-\beta^2).
Here, :math:`f_i` is the oscillator strength of the :math:`i`-th transition,
given by :math:`f_i = n_i/Z`, where :math:`n_i` is the number of electrons in
the :math:`i`-th subshell. The frequency :math:`l` is the solution of the
equation
.. math::
:label: density-effect-l
\frac{1}{\beta^2} - 1 = \sum_{i=1}^{n} \frac{f_i}{\bar{\nu}_i^2 + l^2},
where :math:`\bar{v}_i` is defined as
.. math::
:label: density-effect-nubar
\bar{\nu}_i = h\nu_i \rho / h\nu_p.
The plasma energy :math:`h\nu_p` of the medium is given by
.. math::
:label: plasma-frequency
h\nu_p = \sqrt{\frac{(hc)^2 r_e \rho_m N_A Z}{\pi A}},
where :math:`A` is the atomic weight and :math:`\rho_m` is the density of the
material. In :eq:`density-effect-nubar`, :math:`h\nu_i` is the oscillator
energy, and :math:`\rho` is an adjustment factor introduced to give agreement
between the experimental values of the oscillator energies and the mean
excitation energy. The :math:`l_i` in :eq:`density-effect-correction` are
defined as
.. math::
:label: density-effect-li
\begin{aligned}
l_i &= (\bar{\nu}_i^2 + 2/3f_i)^{1/2} ~~~~&\text{for}~~ \bar{\nu}_i > 0 \\
l_n &= f_n^{1/2} ~~~~&\text{for}~~ \bar{\nu}_n = 0,
\end{aligned}
where the second case applies to conduction electrons. For a conductor,
:math:`f_n` is given by :math:`n_c/Z`, where :math:`n_c` is the effective
number of conduction electrons, and :math:`v_n = 0`. The adjustment factor
:math:`\rho` is determined using the equation for the mean excitation energy:
.. math::
:label: mean-excitation-energy
\ln I = \sum_{i=1}^{n-1} f_i \ln[(h\nu_i\rho)^2 + 2/3f_i(h\nu_p)^2]^{1/2} +
f_n \ln (h\nu_pf_n^{1/2}).
.. _ttb:
Thick-Target Bremsstrahlung Approximation
+++++++++++++++++++++++++++++++++++++++++
Since charged particles lose their energy on a much shorter distance scale than
neutral particles, not much error should be introduced by neglecting to
transport electrons. However, the bremsstrahlung emitted from high energy
electrons and positrons can travel far from the interaction site. Thus, even
without a full electron transport mode it is necessary to model bremsstrahlung.
We use a thick-target bremsstrahlung (TTB) approximation based on the models in
Salvat_ and Kaltiaisenaho_ for generating bremsstrahlung photons, which assumes
the charged particle loses all its energy in a single homogeneous material
region.
To model bremsstrahlung using the TTB approximation, we need to know the number
of photons emitted by the charged particle and the energy distribution of the
photons. These quantities can be calculated using the continuous slowing down
approximation (CSDA). The CSDA assumes charged particles lose energy
continuously along their trajectory with a rate of energy loss equal to the
total stopping power, ignoring fluctuations in the energy loss. The
approximation is useful for expressing average quantities that describe how
charged particles slow down in matter. For example, the CSDA range approximates
the average path length a charged particle travels as it slows to rest:
.. math::
:label: csda-range
R(T) = \int^T_0 \frac{dT'}{S(T')}.
Actual path lengths will fluctuate around :math:`R(T)`. The average number of
photons emitted per unit path length is given by the inverse bremsstrahlung
mean free path:
.. math::
:label: inverse-bremsstrahlung-mfp
\lambda_{\text{br}}^{-1}(T,E_{\text{cut}})
= n\int_{E_{\text{cut}}}^T\frac{d\sigma_{\text{br}}}{dE}dE
= n\frac{Z^2}{\beta^2}\int_{\kappa_{\text{cut}}}^1\frac{1}{\kappa}
\chi(Z,T,\kappa)d\kappa.
The lower limit of the integral in :eq:`inverse-bremsstrahlung-mfp` is non-zero
because the bremsstrahlung differential cross section diverges for small photon
energies but is finite for photon energies above some cutoff energy
:math:`E_{\text{cut}}`. The mean free path
:math:`\lambda_{\text{br}}^{-1}(T,E_{\text{cut}})` is used to calculate the
photon number yield, defined as the average number of photons emitted with
energy greater than :math:`E_{\text{cut}}` as the charged particle slows down
from energy :math:`T` to :math:`E_{\text{cut}}`. The photon number yield is
given by
.. math::
:label: photon-number-yield
Y(T,E_{\text{cut}}) = \int^{R(T)}_{R(E_{\text{cut}})}
\lambda_{\text{br}}^{-1}(T',E_{\text{cut}})ds = \int_{E_{\text{cut}}}^T
\frac{\lambda_{\text{br}}^{-1}(T',E_{\text{cut}})}{S(T')}dT'.
:math:`Y(T,E_{\text{cut}})` can be used to construct the energy spectrum of
bremsstrahlung photons: the number of photons created with energy between
:math:`E_1` and :math:`E_2` by a charged particle with initial kinetic energy
:math:`T` as it comes to rest is given by :math:`Y(T,E_1) - Y(T,E_2)`.
To simulate the emission of bremsstrahlung photons, the total stopping power
and bremsstrahlung differential cross section for positrons and electrons must
be calculated for a given material using :eq:`material-bremsstrahlung-dcs` and
:eq:`material-radiative-stopping-power`. These quantities are used to build the
tabulated bremsstrahlung energy PDF and CDF for that material for each incident
energy :math:`T_k` on the energy grid. The following algorithm is then applied
to sample the photon energies:
1. For an incident charged particle with energy :math:`T`, sample the number of
emitted photons as
.. math::
N = \lfloor Y(T,E_{\text{cut}}) + \xi_1 \rfloor.
2. Rather than interpolate the PDF between indices :math:`k` and :math:`k+1`
for which :math:`T_k < T < T_{k+1}`, which is computationally expensive, use
the composition method and sample from the PDF at either :math:`k` or
:math:`k+1`. Using linear interpolation on a logarithmic scale, the PDF can
be expressed as
.. math::
p_{\text{br}}(T,E) = \pi_k p_{\text{br}}(T_k,E) + \pi_{k+1}
p_{\text{br}}(T_{k+1},E),
where the interpolation weights are
.. math::
\pi_k = \frac{\ln T_{k+1} - \ln T}{\ln T_{k+1} - \ln T_k},~~~
\pi_{k+1} = \frac{\ln T - \ln T_k}{\ln T_{k+1} - \ln T_k}.
Sample either the index :math:`i = k` or :math:`i = k+1` according to the
point probabilities :math:`\pi_{k}` and :math:`\pi_{k+1}`.
3. Determine the maximum value of the CDF :math:`P_{\text{br,max}}`.
3. Sample the photon energies using the inverse transform method with the
tabulated CDF :math:`P_{\text{br}}(T_i, E)` i.e.,
.. math::
E = E_j \left[ (1 + a_j) \frac{\xi_2 P_{\text{br,max}} -
P_{\text{br}}(T_i, E_j)} {E_j p_{\text{br}}(T_i, E_j)} + 1
\right]^{\frac{1}{1 + a_j}}
where the interpolation factor :math:`a_j` is given by
.. math::
a_j = \frac{\ln p_{\text{br}}(T_i,E_{j+1}) - \ln p_{\text{br}}(T_i,E_j)}
{\ln E_{j+1} - \ln E_j}
and :math:`P_{\text{br}}(T_i, E_j) \le \xi_2 P_{\text{br,max}} \le
P_{\text{br}}(T_i, E_{j+1})`.
We ignore the range of the electron or positron, i.e., the bremsstrahlung
photons are produced in the same location that the charged particle was
created. The direction of the photons is assumed to be the same as the
direction of the incident charged particle, which is a reasonable approximation
at higher energies when the bremsstrahlung radiation is emitted at small
angles.
.. _photon_production:
@ -1070,5 +734,3 @@ emitted photon.
.. _Kaltiaisenaho: https://aaltodoc.aalto.fi/bitstream/handle/123456789/21004/master_Kaltiaisenaho_Toni_2016.pdf
.. _Salvat: https://doi.org/10.1787/32da5043-en
.. _Sternheimer: https://doi.org/10.1103/PhysRevB.26.6067

View file

@ -109,9 +109,7 @@ terms on the right hand side.
In Equation :eq:`transport`, :math:`\psi` is the angular neutron flux. This
parameter represents the total distance traveled by all neutrons in a particular
direction inside of a control volume per second, and is often given in units of
:math:`1/(\text{cm}^{2} \text{s})`. As OpenMC does not support time dependence
in the random ray solver mode, we consider the steady state equation, where the
units of flux become :math:`1/\text{cm}^{2}`. The angular direction unit vector,
:math:`1/(\text{cm}^{2} \text{s})`. The angular direction unit vector,
:math:`\mathbf{\Omega}`, represents the direction of travel for the neutron. The
spatial position vector, :math:`\mathbf{r}`, represents the location within the
simulation. The neutron energy, :math:`E`, or speed in continuous space, is
@ -1052,7 +1050,8 @@ random ray and Monte Carlo, however.
regions. Thus, in the OpenMC implementation of random ray, particle sources
are restricted to being volumetric and isotropic, although different energy
spectrums are supported. Fixed sources can be applied to specific materials,
cells, or universes.
cells, or universes. Point sources are "smeared" to fill the volume of the
source region that contains the point source coordinate.
- **Inactive batches:** In Monte Carlo, use of a fixed source implies that all
batches are active batches, as there is no longer a need to develop a fission
@ -1082,28 +1081,32 @@ lifetimes.
In OpenMC, the random ray adjoint solver is implemented simply by transposing
the scattering matrix, swapping :math:`\nu\Sigma_f` and :math:`\chi`, and then
running a normal transport solve. When no external fixed source is present, no
additional changes are needed in the transport process. However, if an external
fixed forward source is present in the simulation problem, then an additional
step is taken to compute the accompanying fixed adjoint source. In OpenMC, the
adjoint flux does *not* represent a response function for a particular detector
region. Rather, the adjoint flux is the global response, making it appropriate
for use with weight window generation schemes for global variance reduction.
Thus, if using a fixed source, the external source for the adjoint mode is
simply computed as being :math:`1 / \phi`, where :math:`\phi` is the forward
scalar flux that results from a normal forward solve (which OpenMC will run
first automatically when in adjoint mode). The adjoint external source will be
computed for each source region in the simulation mesh, independent of any
tallies. The adjoint external source is always flat, even when a linear
scattering and fission source shape is used. When in adjoint mode, all reported
results (e.g., tallies, eigenvalues, etc.) are derived from the adjoint flux,
even when the physical meaning is not necessarily obvious. These values are
still reported, though we emphasize that the primary use case for adjoint mode
is for producing adjoint flux tallies to support subsequent perturbation studies
and weight window generation.
running a normal transport solve. When no external fixed forward source is
present, or if an adjoint fixed source is specifically provided, no additional
changes are needed in the transport process. This adjoint source can
correspond, for example, to a detector response function in a particular
region. However, if an external fixed forward source is present in the
simulation problem without an adjoint fixed source, an additional step is taken
to compute the accompanying forward-weighted adjoint source. In this case, the
adjoint flux does *not* represent the importance of locations in phase space to
detector response; rather, the "response" in question is a uniform distribution
of Monte Carlo particle density, making the importance provided by the adjoint
flux appropriate for use with weight window generation schemes for global
variance reduction. Thus, if using a fixed source, the forward-weighted
external source for adjoint mode is simply computed as being :math:`1 / \phi`,
where :math:`\phi` is the forward scalar flux that results from a normal
forward solve (which OpenMC will run first automatically when in adjoint mode).
The adjoint external source will be computed for each source region in the
simulation mesh, independent of any tallies. The adjoint external source is
always flat, even when a linear scattering and fission source shape is used.
Note that the adjoint :math:`k_{eff}` is statistically the same as the forward
:math:`k_{eff}`, despite the flux distributions taking different shapes.
When in adjoint mode, all reported results (e.g., tallies, eigenvalues, etc.)
are derived from the adjoint flux, even when the physical meaning is not
necessarily obvious. These values are still reported, though we emphasize that
the primary use case for adjoint mode is for producing adjoint flux tallies to
support subsequent perturbation studies and weight window generation. Note
however that the adjoint :math:`k_{eff}` is statistically the same as the
forward :math:`k_{eff}`, despite the flux distributions taking different shapes.
---------------------------
Fundamental Sources of Bias

View file

@ -205,7 +205,71 @@ had a collision at every event. Thus, for tallies with outgoing-energy filters
or for tallies of scattering moments (which require the scattering cosine of
the change-in-angle), we must use an analog estimator.
.. TODO: Add description of surface current tallies
-----------------------------------
Surface-Integrated Flux and Current
-----------------------------------
Surface tallies allow you to measure particle behavior as they cross specific
boundaries in your geometry. Unlike volume tallies, which integrate over a
volumetric region, surface tallies capture the current or flux passing through a
surface. Surface tallies are estimated using an analog estimator.
Current Score
-------------
When tallying the current across a surface, we simply count the weight of
particles that cross the surface of interest:
.. math::
:label: analog-current-estimator
J = \frac{1}{W} \sum_{i \in S} w_i.
where :math:`J` is the area-integrated current passing through surface
:math:`S`, :math:`W` is the total starting weight of the particles, and
:math:`w_i` is the weight of the particle as it crosses the surface :math:`S`.
Flux Score
----------
When tallying flux over a surface, we use the relationship between current and
flux:
.. math::
:label: surface-flux-estimator
\phi_S = \frac{1}{W} \sum_{i \in S} \frac{w_i}{|\mu|}.
where :math:`\phi_S` is the area-integrated flux over surface :math:`S`,
:math:`W` is the total starting weight of the particles, :math:`w_i` is the
weight of the particle as it crosses the surface :math:`S` and :math:`\mu` is
the cosine of angle between the particle direction and the surface normal.
This equation diverges when the particle crossing the surface is nearly parallel
to it (that is, as :math:`\mu` approaches zero). To remove this divergence,
OpenMC scores:
.. math::
:label: modified-surface-flux-estimator
\phi_S = \frac{1}{W} \sum_{i \in S} w_i f(\mu).
and the function :math:`f` is defined by:
.. math::
f(\mu) = \begin{cases}
\frac{1}{|\mu|} & |\mu| > \mu_\text{cut} \\
\frac{1}{c\mu_\text{cut}} & |\mu| \le \mu_\text{cut}
\end{cases}
where :math:`\mu_\text{cut}` is the grazing cosine cutoff and :math:`c` is the
cosine substitution ratio. The parameters :math:`\mu_\text{cut}` and :math:`c`
can be set by the user via the :attr:`openmc.Settings.surface_grazing_cutoff`
and :attr:`openmc.Settings.surface_grazing_ratio` attributes, respectively. The
default values for these parameters are 0.001 and 0.5 as recommended by
`Favorite, Thomas, and Booth <https://doi.org/10.13182/NSE09-72>`_.
.. _tallies_statistics:
@ -387,6 +451,130 @@ of this is that the longer you run a simulation, the better you know your
results. Therefore, by running a simulation long enough, it is possible to
reduce the stochastic uncertainty to arbitrarily low levels.
Skewness
++++++++
The `skewness`_ of a population quantifies the asymmetry of the probability
distribution around its mean. Positive and negative skewness indicate a
longer/heavier right and left tail respectively. Let :math:`x_1,\ldots,x_n` be
the per-realization values for a bin, with sample mean :math:`\bar{x}` and
sample central moments:
.. math::
m_k \;=\; \frac{1}{n}\sum_{i=1}^{n}\bigl(x_i-\bar{x}\bigr)^k.
OpenMC reports the *adjusted Fisher-Pearson skewness* (defined for :math:`n \ge
3`), which is commonly used in many statistical packages:
.. math::
G_1 \;=\; \frac{\sqrt{n \cdot (n-1)}}{\,n-2\,}\cdot\frac{m_3}{m_2^{3/2}}.
where :math:`m_2` and :math:`m_3` correspond to the biased sample second and
third central moment respectively.
Kurtosis
++++++++
The `kurtosis`_ of a population quantifies tail weight (also called tailedness)
of the probability distribution relative to a normal distribution. Positive
excess kurtosis indicates *heavier tails* whereas negative excess kurtosis
indicates *lighter tails*. Kurtosis is especially useful for identifying bins
where occasional extreme scores dominate uncertainty. OpenMC reports the
*adjusted excess kurtosis* (defined for :math:`n \ge 4`):
.. math::
G_2 \;=\; \frac{(n-1)}{(n-2)(n-3)}
\left[(n+1)\,\frac{m_4}{m_2^{2}} \;-\; 3(n-1)\right].
where :math:`m_2` and :math:`m_4` correspond to the biased sample second and
fourth central moment respectively. For a perfectly normal distribution, the
excess kurtosis is :math:`0`.
Variance of Variance
++++++++++++++++++++
The variance of the variance (also known as the coefficient of variation
squared) measures *stability of the sample variance* :math:`s^2` and, by
extension, the reliability of reported relative errors. High VOV means that
error bars themselves are noisy—often due to heavy tails, skewness, or too few
realizations.
.. math::
VOV = \frac{s^2(s_{\bar{X}}^2)}{s_{\bar{X}}^4 } = \frac{m_4}{m_2^2} - \frac{1}{n}
where :math:`s_{\bar{X}}^2` is the estimated variance of the mean and
:math:`s^2(s_{\bar{X}}^2)` is the estimated variance in :math:`s_{\bar{X}}^2`.
The MCNP manual suggests a hard threshold such that :math:`VOV < 0.1` to improve
the probability of forming a reliable confidence interval. However, OpenMC does
not enforce an universal cut-off because the suitability of any single threshold
depends strongly on problem specifics (estimator choice, variance-reduction
settings, tally binning, or even effective sample size).
Normality Tests (D'Agostino-Pearson)
++++++++++++++++++++++++++++++++++++
These normality test verify the hypothesis that fluctuations are *approximately
normal*, a working assumption behind many Monte Carlo diagnostics and
`confidence-interval heuristics`_. Tests are provided for: (i) skewness-only,
(ii) kurtosis-only, and (iii) the *omnibus* combination. OpenMC uses the
finite-sample-adjusted skewness :math:`G_1` and excess kurtosis :math:`G_2`
above to construct standardized normal scores :math:`Z_1` (from :math:`G_1`) and
:math:`Z_2` (from :math:`G_2`) via the D'Agostino-Pearson transformations. The
omnibus statistic is
.. math::
K^2 \;=\; Z_1^{\,2} \;+\; Z_2^{\,2}
\;\sim\; \chi^2_{(2)} \quad \text{under } H_0:\ \text{normality}.
OpenMC reports :math:`Z_1`, :math:`Z_2`, :math:`K^2`, and their p-values when
prerequisites are met (skewness for :math:`n\ge 3`, kurtosis and omnibus for
:math:`n\ge 4`). Given a user-chosen significance level :math:`\alpha` (default
is :math:`0.05`), reject :math:`H_0` if :math:`\text{p-value}<\alpha`; otherwise
fail to reject. OpenMC leaves the interpretation to the user, who should
consider VOV together with skewness, kurtosis, and normality tests results when
judging whether reported confidence intervals are credible for their application
[#norm-tests]_.
.. [#norm-tests]
Higher-moments accumulation must be enabled with ``higher_moments = True``
for running these diagnostics including the skewness, kurtosis, and normality
tests.
Figure of Merit
+++++++++++++++
The figure of merit (FOM) is an indicator that accounts for both the statistical
uncertainty and the execution time and represents how much information is
obtained per unit time in the simulation. The FOM is defined as
.. math::
:label: figure_of_merit
FOM = \frac{1}{r^2 t},
where :math:`t` is the total execution time and :math:`r` is the relative error
defined as
.. math::
:label: relative_error
r = \frac{s_{\bar{X}}}{\bar{x}}.
Based on this definition, one can see that a higher FOM is desirable. The FOM is
useful as a comparative tool. For example, if a variance reduction technique is
being applied to a simulation, the FOM with variance reduction can be compared
to the FOM without variance reduction to ascertain whether the reduction in
variance outweighs the potential increase in execution time (e.g., due to
particle splitting). It is important to note that MCNP reports the FOM using CPU
time (wall-clock time multiplied by the number of threads/cores), whereas OpenMC
reports the FOM using only the wall-clock time :math:`t`.
Confidence Intervals
++++++++++++++++++++
@ -494,6 +682,8 @@ improve the estimate of the percentile.
.. rubric:: References
.. _confidence-interval heuristics: https://doi.org/10.1080/00031305.1990.10475751
.. _following approximation: https://doi.org/10.1080/03610918708812641
.. _Bessel's correction: https://en.wikipedia.org/wiki/Bessel's_correction
@ -514,6 +704,10 @@ improve the estimate of the percentile.
.. _converges in distribution: https://en.wikipedia.org/wiki/Convergence_of_random_variables#Convergence_in_distribution
.. _skewness: https://en.wikipedia.org/wiki/Skewness
.. _kurtosis: https://en.wikipedia.org/wiki/Kurtosis
.. _confidence intervals: https://en.wikipedia.org/wiki/Confidence_interval
.. _Student's t-distribution: https://en.wikipedia.org/wiki/Student%27s_t-distribution

View file

@ -22,12 +22,14 @@ not experience a single scoring event, even after billions of analog histories.
Variance reduction techniques aim to either flatten the global uncertainty
distribution, such that all regions of phase space have a fairly similar
uncertainty, or to reduce the uncertainty in specific locations (such as a
detector). There are two strategies available in OpenMC for variance reduction:
the Monte Carlo MAGIC method and the FW-CADIS method. Both strategies work by
developing a weight window mesh that can be utilized by subsequent Monte Carlo
solves to split particles heading towards areas of lower flux densities while
terminating particles in higher flux regions---all while maintaining a fair
game.
detector). There are three strategies available in OpenMC for variance
reduction: weight windows generated via the MAGIC method or the FW-CADIS method,
and source biasing. Both weight windowing strategies work by developing a mesh
that can be utilized by subsequent Monte Carlo solves to split particles heading
towards areas of lower flux densities while terminating particles in higher flux
regions. In contrast, source biasing modifies source site sampling behavior to
preferentially track particles more likely to reach phase space regions of
interest.
------------
MAGIC Method
@ -80,8 +82,8 @@ where it was born from.
The Forward-Weighted Consistent Adjoint Driven Importance Sampling method, or
`FW-CADIS method <https://doi.org/10.13182/NSE12-33>`_, produces weight windows
for global variance reduction given adjoint flux information throughout the
entire domain. The weight window lower bound is defined in Equation
for global or local variance reduction given adjoint flux information throughout
the entire domain. The weight window lower bound is defined in Equation
:eq:`fw_cadis`, and also involves a normalization step not shown here.
.. math::
@ -132,3 +134,83 @@ aware of this.
:label: variance_fom
\text{FOM} = \frac{1}{\text{Time} \times \sigma^2}
Finally, one unique capability of the FW-CADIS weight window generator is to
produce weight windows for local variance reduction, given a list of the
responses of interest. This is controlled by optionally specifying target
tallies from the :class:`openmc.model.Model` to the
:class:`openmc.WeightWindowGenerator`, as illustrated in the
:ref:`user guide<variance_reduction>`. If target tallies for local variance
reduction are supplied, then the adjoint sources are only populated after the
initial forward simulation in the source regions associated with those tallies.
In other regions, the adjoint source term is instead set to zero. The Random
Ray solver then determines the adjoint flux map used to generate FW-CADIS
weight windows following the usual technique.
.. _methods_source_biasing:
--------------
Source Biasing
--------------
In contrast to the previous two methods that introduce population controls
during transport, source biasing modifies the sampling of the external source
distribution. The basic premise of the technique is that for each spatial,
angular, energy, or time distribution of a source, an additional distribution
can be specified provided that the two share a common support (set of points
where the distribution is nonzero). Samples are then drawn from this "bias"
distribution, which can be chosen to preferentially direct particles towards
phase space regions of interest. In order to avoid biasing the tally results,
however, a weight adjustment is applied to each sampled site as described below.
Assume that the unbiased probability density function of a random variable
:math:`X:x \rightarrow \mathbb{R}` is given by :math:`f(x)`, but that using the
biased distribution :math:`g(x)` will result in a greater number of particle
trajectories reaching some phase space region of interest. Then a sample
:math:`x_0` may be drawn from :math:`g(x)` while maintaining a fair game,
provided that its weight is adjusted as:
.. math::
:label: source_bias
w = w_0 \times \frac{f(x_0)}{g(x_0)}
where :math:`w_0` is the weight of an unbiased sample from :math:`f(x)`,
typically unity.
Returning now to Equation :eq:`source_bias`, the requirement for common support
becomes evident. If :math:`\mathrm{supp} (g)` fully contains but is not
identical to :math:`\mathrm{supp} (f)`, then some samples from :math:`g(x)` will
correspond to points where :math:`f(x) = 0`. Thus these source sites would be
assigned a starting weight of 0, meaning the particles would be killed
immediately upon transport, effectively wasting computation time. Conversely, if
:math:`\mathrm{supp} (g)` is fully contained by but not identical to
:math:`\mathrm{supp} (f)`, the contributions of some regions outside
:math:`\mathrm{supp} (g)` will not be counted towards the integral, potentially
biasing the tally. The weight assigned to such points would be undefined since
:math:`g(x) = \mathbf{0}` at these points.
When an independent source is sampled in OpenMC, the particle's coordinate in
each variable of phase space :math:`(\mathbf{r},\mathbf{\Omega},E,t)` is
successively drawn from an independent probability distribution. Multiple
variables can be biased, in which case the resultant weight :math:`w` applied to
the particle is the product of the weights assigned from all sampled
distributions: space, angle, energy, and time, as shown in Equation
:eq:`tot_wgt`.
.. math::
:label: tot_wgt
w = w_r \times w_{\Omega} \times w_E \times w_t
Finally, source biasing and weight windows serve different purposes. Source
biasing changes how particles are born, allowing the initial source sites to be
sampled preferentially from important regions of phase space (space, angle,
energy, and time) with an accompanying weight adjustment. Weight windows, by
contrast, apply population control during transport (splitting and Russian
roulette) to help particles reach and contribute in important regions as they
move through the system. Because particle transport proceeds as usual after a
biased source is sampled, particle attenuation in optically thick regions
outside the source volume will not be affected by source biasing; in such
scenarios, transport biasing techniques such as weight windows are often more
effective.

View file

@ -26,6 +26,7 @@ Simulation Settings
openmc.FileSource
openmc.CompiledSource
openmc.MeshSource
openmc.TokamakSource
openmc.SourceParticle
openmc.VolumeCalculation
openmc.Settings
@ -37,7 +38,6 @@ Simulation Settings
openmc.read_source_file
openmc.write_source_file
openmc.wwinp_to_wws
Material Specification
----------------------
@ -129,9 +129,11 @@ Constructing Tallies
openmc.SurfaceFilter
openmc.MeshFilter
openmc.MeshBornFilter
openmc.MeshMaterialFilter
openmc.MeshSurfaceFilter
openmc.EnergyFilter
openmc.EnergyoutFilter
openmc.ParticleProductionFilter
openmc.MuFilter
openmc.MuSurfaceFilter
openmc.PolarFilter
@ -143,21 +145,32 @@ Constructing Tallies
openmc.SpatialLegendreFilter
openmc.SphericalHarmonicsFilter
openmc.TimeFilter
openmc.WeightFilter
openmc.ZernikeFilter
openmc.ZernikeRadialFilter
openmc.ParentNuclideFilter
openmc.ParticleFilter
openmc.RegularMesh
openmc.RectilinearMesh
openmc.CylindricalMesh
openmc.SphericalMesh
openmc.UnstructuredMesh
openmc.ReactionFilter
openmc.MeshMaterialVolumes
openmc.Trigger
openmc.TallyDerivative
openmc.Tally
openmc.Tallies
Meshes
------
.. autosummary::
:toctree: generated
:nosignatures:
:template: myclassinherit.rst
openmc.RegularMesh
openmc.RectilinearMesh
openmc.CylindricalMesh
openmc.SphericalMesh
openmc.UnstructuredMesh
Geometry Plotting
-----------------
@ -166,7 +179,8 @@ Geometry Plotting
:nosignatures:
:template: myclass.rst
openmc.Plot
openmc.SlicePlot
openmc.VoxelPlot
openmc.WireframeRayTracePlot
openmc.SolidRayTracePlot
openmc.Plots
@ -206,6 +220,9 @@ Post-processing
:nosignatures:
:template: myfunction.rst
openmc.read_collision_track_file
openmc.read_collision_track_hdf5
openmc.read_collision_track_mcpl
openmc.voxel_to_vtk
The following classes and functions are used for functional expansion reconstruction.
@ -248,8 +265,16 @@ Variance Reduction
:template: myclass
openmc.WeightWindows
openmc.WeightWindowsList
openmc.WeightWindowGenerator
.. autosummary::
:toctree: generated
:nosignatures:
:template: myfunction.rst
openmc.hdf5_to_wws
openmc.wwinp_to_wws
Coarse Mesh Finite Difference Acceleration

View file

@ -40,6 +40,7 @@ Functions
reset_timers
run
run_in_memory
run_random_ray
sample_external_source
simulation_finalize
simulation_init
@ -81,16 +82,21 @@ Classes
Nuclide
ParentNuclideFilter
ParticleFilter
ParticleProductionFilter
PolarFilter
ReactionFilter
RectilinearMesh
RegularMesh
SpatialLegendreFilter
SphericalHarmonicsFilter
SphericalMesh
SolidRayTracePlot
SurfaceFilter
Tally
TemporarySession
UniverseFilter
UnstructuredMesh
WeightFilter
WeightWindows
ZernikeFilter
ZernikeRadialFilter
@ -122,6 +128,12 @@ Data
:type: dict
.. data:: plots
Mapping of plot ID to :class:`openmc.lib.SolidRayTracePlot` instances.
:type: dict
.. data:: nuclides
Mapping of nuclide name to :class:`openmc.lib.Nuclide` instances.

View file

@ -71,6 +71,8 @@ Core Functions
isotopes
kalbach_slope
linearize
mass_attenuation_coefficient
mass_energy_absorption_coefficient
thin
water_density
zam

View file

@ -78,20 +78,18 @@ A minimal example for performing depletion would be:
>>> import openmc.deplete
>>> geometry = openmc.Geometry.from_xml()
>>> settings = openmc.Settings.from_xml()
>>> model = openmc.model.Model(geometry, settings)
>>> model = openmc.Model(geometry, settings)
# Representation of a depletion chain
>>> chain_file = "chain_casl.xml"
>>> operator = openmc.deplete.CoupledOperator(
... model, chain_file)
>>> operator = openmc.deplete.CoupledOperator(model, chain_file)
# Set up 5 time steps of one day each
>>> dt = [24 * 60 * 60] * 5
>>> power = 1e6 # constant power of 1 MW
# Deplete using mid-point predictor-corrector
>>> cecm = openmc.deplete.CECMIntegrator(
... operator, dt, power)
>>> cecm = openmc.deplete.CECMIntegrator(operator, dt, power)
>>> cecm.integrate()
Internal Classes and Functions
@ -208,14 +206,15 @@ total system energy.
The :class:`openmc.deplete.IndependentOperator` uses inner classes subclassed
from those listed above to perform similar calculations.
The following classes are used to define transfer rates to model continuous
removal or feed of nuclides during depletion.
The following classes are used to define external source rates or transfer rates
to model continuous removal or feed of nuclides during depletion.
.. autosummary::
:toctree: generated
:nosignatures:
:template: myclass.rst
transfer_rates.ExternalSourceRates
transfer_rates.TransferRates
Intermediate Classes
@ -288,6 +287,16 @@ the following abstract base classes:
abc.SIIntegrator
abc.DepSystemSolver
R2S Automation
--------------
.. autosummary::
:toctree: generated
:nosignatures:
:template: myclass.rst
R2SManager
D1S Functions
-------------

View file

@ -11,6 +11,16 @@ Module Variables
.. autodata:: openmc.mgxs.GROUP_STRUCTURES
:annotation:
Functions
+++++++++
.. autosummary::
:toctree: generated
:nosignatures:
:template: myfunction.rst
openmc.mgxs.convert_flux_groups
Classes
+++++++

View file

@ -22,6 +22,7 @@ Univariate Probability Distributions
openmc.stats.Legendre
openmc.stats.Mixture
openmc.stats.Normal
openmc.stats.DecaySpectrum
.. autosummary::
:toctree: generated
@ -29,6 +30,7 @@ Univariate Probability Distributions
:template: myfunction.rst
openmc.stats.delta_function
openmc.stats.fusion_neutron_spectrum
openmc.stats.muir
Angular Distributions
@ -67,3 +69,4 @@ Spatial Distributions
:template: myfunction.rst
openmc.stats.spherical_uniform
openmc.stats.cylindrical_uniform

View file

@ -35,6 +35,13 @@ you wish) with OpenMC installed.
conda create --name openmc-env openmc
conda activate openmc-env
If you are installing on macOS with an Apple silicon ARM-based processor, you
will also need to specify the `--platform` option:
.. code-block:: sh
conda create --name openmc-env --platform osx-64 openmc
You are now in a conda environment called `openmc-env` that has OpenMC
installed.
@ -112,7 +119,7 @@ packages should be installed, for example in Homebrew via:
.. code-block:: sh
brew install llvm cmake xtensor hdf5 python libomp libpng
brew install llvm cmake hdf5 python libomp libpng
The compiler provided by the above LLVM package should be used in place of the
one provisioned by XCode, which does not support the multithreading library used

View file

@ -0,0 +1,226 @@
====================
What's New in 0.15.3
====================
.. currentmodule:: openmc
-------
Summary
-------
This release of OpenMC includes many bug fixes, performance improvements, and
several notable new features. The major highlights of this release include a new
:class:`~openmc.deplete.R2SManager` class that automates the workflow for
rigorous 2-step (R2S) shutdown dose rate calculations, the ability to collect
higher moments for tally results that can be used to test normality, a new
uncertainty-aware criticality search method, a new collision tracking feature
that enables detailed tracking of particle interactions, support for distributed
cell densities, and several new tally filters. The random ray solver also
continues to receive significant updates, including automatic setup
capabilities, improved geometry handling, and better weight window support.
Depletion capabilities have been expanded with thermochemical redox control,
external transfer rates, and improved performance.
------------------------------------
Compatibility Notes and Deprecations
------------------------------------
MCPL has been changed from a build-time dependency to a runtime optional
dependency, which means OpenMC will attempt to load the MCPL library at
runtime when needed rather than requiring it at build time.
The ``openmc.mgxs.Library.add_to_tallies_file`` method has been renamed to
:meth:`openmc.mgxs.Library.add_to_tallies`.
------------
New Features
------------
- A new collision tracking feature enables detailed tracking of particle
interactions (`#3417 <https://github.com/openmc-dev/openmc/pull/3417>`_)
- Added :meth:`~openmc.model.Model.keff_search` method for automated criticality
searches (`#3569 <https://github.com/openmc-dev/openmc/pull/3569>`_)
- Introduced automated workflow for mesh- or cell-based R2S calculations
(`#3508 <https://github.com/openmc-dev/openmc/pull/3508>`_)
- Ability to source electron/positrons directly for charged particle
simulations (`#3404 <https://github.com/openmc-dev/openmc/pull/3404>`_)
- Multi-group capability for kinetics parameter calculations with Iterated
Fission Probability (`#3425
<https://github.com/openmc-dev/openmc/pull/3425>`_)
- Introduced a new :class:`openmc.MeshMaterialFilter` class (`#3406
<https://github.com/openmc-dev/openmc/pull/3406>`_)
- Added support for distributed cell densities (`#3546
<https://github.com/openmc-dev/openmc/pull/3546>`_)
- Implemented a :class:`openmc.WeightWindowsList` class that enables export to
HDF5 (`#3456 <https://github.com/openmc-dev/openmc/pull/3456>`_)
- Added :meth:`openmc.Material.mean_free_path` method (`#3469
<https://github.com/openmc-dev/openmc/pull/3469>`_)
- Introduced :func:`openmc.lib.TemporarySession` context manager (`#3475
<https://github.com/openmc-dev/openmc/pull/3475>`_)
- Added material depletion function for tracking individual material depletion
(`#3420 <https://github.com/openmc-dev/openmc/pull/3420>`_)
- Added methods on :class:`~openmc.Material` class for waste disposal rating /
classification (`#3366 <https://github.com/openmc-dev/openmc/pull/3366>`_,
`#3376 <https://github.com/openmc-dev/openmc/pull/3376>`_)
- Support for thermochemical redox control transfer rates in depletion
(`#2783 <https://github.com/openmc-dev/openmc/pull/2783>`_)
- Support for external transfer rates source term in depletion (`#3088
<https://github.com/openmc-dev/openmc/pull/3088>`_)
- Added combing capability for fission site sampling and delayed neutron
emission time (`#2992 <https://github.com/openmc-dev/openmc/pull/2992>`_)
- Ability to specify reference direction for azimuthal angle in
:class:`~openmc.stats.PolarAzimuthal` distribution (`#3582
<https://github.com/openmc-dev/openmc/pull/3582>`_)
- Allow spatial constraints on element sources within
:class:`~openmc.MeshSource` (`#3431
<https://github.com/openmc-dev/openmc/pull/3431>`_)
- Added VTK HDF (.vtkhdf) format support for writing VTK data (`#3252
<https://github.com/openmc-dev/openmc/pull/3252>`_)
- Implemented filter weight capability (`#3345
<https://github.com/openmc-dev/openmc/pull/3345>`_)
- Optionally collect higher moments for tallies (`#3363
<https://github.com/openmc-dev/openmc/pull/3363>`_)
- Several random ray solver enhancements:
- Random Ray AutoMagic Setup for automatic configuration (`#3351 <https://github.com/openmc-dev/openmc/pull/3351>`_)
- Point source locator for random ray mode (`#3360 <https://github.com/openmc-dev/openmc/pull/3360>`_)
- Support for DAGMC geometries (`#3374 <https://github.com/openmc-dev/openmc/pull/3374>`_)
- Optimized mapping of source regions to tallies (`#3465 <https://github.com/openmc-dev/openmc/pull/3465>`_)
- Base source region refactor (`#3576 <https://github.com/openmc-dev/openmc/pull/3576>`_)
---------------------------
Bug Fixes and Small Changes
---------------------------
- Add two MPI barriers in R2S workflow (`#3646 <https://github.com/openmc-dev/openmc/pull/3646>`_)
- Fix a few warnings, rename add_to_tallies_file (`#3639 <https://github.com/openmc-dev/openmc/pull/3639>`_)
- Fix typo in DAGMC lost particle test (`#3634 <https://github.com/openmc-dev/openmc/pull/3634>`_)
- Avoid multiprocessing Pool when running depletion tests with MPI (`#3633 <https://github.com/openmc-dev/openmc/pull/3633>`_)
- Support MPI parallelism in R2SManager (`#3632 <https://github.com/openmc-dev/openmc/pull/3632>`_)
- Update documentation for particle tracks (`#3627 <https://github.com/openmc-dev/openmc/pull/3627>`_)
- Adding variance of variance and normality tests for tally statistics (`#3454 <https://github.com/openmc-dev/openmc/pull/3454>`_)
- Avoid divide-by-zero in ``from_multigroup_flux`` when flux is zero (`#3624 <https://github.com/openmc-dev/openmc/pull/3624>`_)
- Write particle states as separate lines in track VTK files (`#3628 <https://github.com/openmc-dev/openmc/pull/3628>`_)
- Reset DAGMC history when reviving from source (`#3601 <https://github.com/openmc-dev/openmc/pull/3601>`_)
- Add energy group structure: SCALE-999 (`#3564 <https://github.com/openmc-dev/openmc/pull/3564>`_)
- Fix bug in normalization of tally results with no_reduce (`#3619 <https://github.com/openmc-dev/openmc/pull/3619>`_)
- Enable nuclide filters with get_decay_photon_energy (`#3614 <https://github.com/openmc-dev/openmc/pull/3614>`_)
- Update ``check_type`` calls to accept both ``str`` and ``os.PathLike`` objects (`#3618 <https://github.com/openmc-dev/openmc/pull/3618>`_)
- Speed up ``apply_time_correction`` by reducing file I/O and deepcopies (`#3617 <https://github.com/openmc-dev/openmc/pull/3617>`_)
- FW-CADIS Disregard Max Realizations Setting (`#3616 <https://github.com/openmc-dev/openmc/pull/3616>`_)
- Random Ray Geometry Debug Mode Fix (`#3615 <https://github.com/openmc-dev/openmc/pull/3615>`_)
- Don't write reaction rates in depletion results by default (`#3609 <https://github.com/openmc-dev/openmc/pull/3609>`_)
- Allow Path objects in MGXSLibrary.export_to_hdf5 (`#3608 <https://github.com/openmc-dev/openmc/pull/3608>`_)
- Clip mixture distributions based on mean times integral (`#3603 <https://github.com/openmc-dev/openmc/pull/3603>`_)
- Allow V0 in atomic_mass function (for ENDF/B-VII.0 data) (`#3607 <https://github.com/openmc-dev/openmc/pull/3607>`_)
- Re-run flaky tests when needed (`#3604 <https://github.com/openmc-dev/openmc/pull/3604>`_)
- Ability to load mesh objects from weight_windows.h5 file (`#3598 <https://github.com/openmc-dev/openmc/pull/3598>`_)
- Switch to using coveralls github action for reporting (`#3594 <https://github.com/openmc-dev/openmc/pull/3594>`_)
- Add user setting for free gas threshold (`#3593 <https://github.com/openmc-dev/openmc/pull/3593>`_)
- Speed up time correction factors (`#3592 <https://github.com/openmc-dev/openmc/pull/3592>`_)
- Fix caching issue when using NCrystal materials (`#3538 <https://github.com/openmc-dev/openmc/pull/3538>`_)
- Fix random ray source region mesh export when using model.export_to_xml() (`#3579 <https://github.com/openmc-dev/openmc/pull/3579>`_)
- Ensure weight_windows_file information is read from XML (`#3587 <https://github.com/openmc-dev/openmc/pull/3587>`_)
- Add missing documentation on <source> in depletion chain file format (`#3590 <https://github.com/openmc-dev/openmc/pull/3590>`_)
- Adding tally filter type option to statepoint get_tally (`#3584 <https://github.com/openmc-dev/openmc/pull/3584>`_)
- Optional separation of mesh-material-volume calc from get_homogenized_materials (`#3581 <https://github.com/openmc-dev/openmc/pull/3581>`_)
- Fix IFP implementation (`#3580 <https://github.com/openmc-dev/openmc/pull/3580>`_)
- Remove several TODOs related to C++17 support (`#3574 <https://github.com/openmc-dev/openmc/pull/3574>`_)
- Fix performance regression in libMesh unstructured mesh tallies (`#3577 <https://github.com/openmc-dev/openmc/pull/3577>`_)
- Update find_package calls in OpenMCConfig.cmake (`#3572 <https://github.com/openmc-dev/openmc/pull/3572>`_)
- Ensure ``n_dimension_`` attribute is set for unstructured meshes (`#3575 <https://github.com/openmc-dev/openmc/pull/3575>`_)
- Allow newer Sphinx version and fix docbuild warnings (`#3571 <https://github.com/openmc-dev/openmc/pull/3571>`_)
- Fixed a bug when combining TimeFilter, MeshFilter, and tracklength estimator (`#3525 <https://github.com/openmc-dev/openmc/pull/3525>`_)
- PowerLaw raises an error if sampling interval contains negative values (`#3542 <https://github.com/openmc-dev/openmc/pull/3542>`_)
- depletion: fix performance of chain matrix construction (`#3567 <https://github.com/openmc-dev/openmc/pull/3567>`_)
- Do not apply boundary conditions when initialized in volume calculation mode (`#3562 <https://github.com/openmc-dev/openmc/pull/3562>`_)
- Bump up tolerance for flaky activation test (`#3560 <https://github.com/openmc-dev/openmc/pull/3560>`_)
- Fixed a bug in plotting cross sections with S(a,b) data (`#3558 <https://github.com/openmc-dev/openmc/pull/3558>`_)
- Change test order to run unit tests first (`#3533 <https://github.com/openmc-dev/openmc/pull/3533>`_)
- adding ecco 33 (`#3556 <https://github.com/openmc-dev/openmc/pull/3556>`_)
- Refactor endf_data to be a fixture (`#3539 <https://github.com/openmc-dev/openmc/pull/3539>`_)
- Revert "fix broken CI" (`#3554 <https://github.com/openmc-dev/openmc/pull/3554>`_)
- fix broken CI (`#3551 <https://github.com/openmc-dev/openmc/pull/3551>`_)
- Leverage particle.move_distance in event advance (`#3544 <https://github.com/openmc-dev/openmc/pull/3544>`_)
- fix tests that accidentaly got broken (`#3543 <https://github.com/openmc-dev/openmc/pull/3543>`_)
- not printing nuclides with 0 percent to terminal (option 2 ) (`#3448 <https://github.com/openmc-dev/openmc/pull/3448>`_)
- Fix a bug in time cutoff behavior (`#3526 <https://github.com/openmc-dev/openmc/pull/3526>`_)
- Avoid duplicate materials written to XML (`#3536 <https://github.com/openmc-dev/openmc/pull/3536>`_)
- Use cached property for openmc.data.Decay.sources (`#3535 <https://github.com/openmc-dev/openmc/pull/3535>`_)
- more helpful error message for dose_coefficients (`#3534 <https://github.com/openmc-dev/openmc/pull/3534>`_)
- Adding 616 group structure (`#3531 <https://github.com/openmc-dev/openmc/pull/3531>`_)
- Remove unused special accessors for tallies (`#3527 <https://github.com/openmc-dev/openmc/pull/3527>`_)
- Consistent XML parsing using functions from _xml module (`#3517 <https://github.com/openmc-dev/openmc/pull/3517>`_)
- Add stat:sum field to MCPL files for proper weight normalization (`#3522 <https://github.com/openmc-dev/openmc/pull/3522>`_)
- Remove reorder_attributes from openmc._xml (`#3519 <https://github.com/openmc-dev/openmc/pull/3519>`_)
- fixed a bug in MeshMaterialFilter.from_volumes (`#3520 <https://github.com/openmc-dev/openmc/pull/3520>`_)
- Fixed a bug in distribcell offsets logic (`#3424 <https://github.com/openmc-dev/openmc/pull/3424>`_)
- Add test for FW-CADIS based WW generation on a DAGMC model (`#3504 <https://github.com/openmc-dev/openmc/pull/3504>`_)
- Fix for Weight Window Scaling Bug (`#3511 <https://github.com/openmc-dev/openmc/pull/3511>`_)
- Fix: ``materials``, ``plots``, and ``tallies`` cannot be passed as lists (`#3513 <https://github.com/openmc-dev/openmc/pull/3513>`_)
- Allow already-initialized openmc.lib in TemporarySession (`#3505 <https://github.com/openmc-dev/openmc/pull/3505>`_)
- Update DAGMC and libMesh precompiler definitions (`#3510 <https://github.com/openmc-dev/openmc/pull/3510>`_)
- Avoid adding ParentNuclideFilter twice when calling prepare_tallies (`#3506 <https://github.com/openmc-dev/openmc/pull/3506>`_)
- Enabling MCPL source files to be read when using surf_source_read (`#3472 <https://github.com/openmc-dev/openmc/pull/3472>`_)
- Boundary info accessors (`#3496 <https://github.com/openmc-dev/openmc/pull/3496>`_)
- automatically finding appropriate dimension when making regular mesh from domain (`#3468 <https://github.com/openmc-dev/openmc/pull/3468>`_)
- Add accessor methods for LocalCoord (`#3494 <https://github.com/openmc-dev/openmc/pull/3494>`_)
- Make MCPL a Runtime Optional Dependency (`#3429 <https://github.com/openmc-dev/openmc/pull/3429>`_)
- Use auto-chunking for StepResult HDF5 writing (`#3498 <https://github.com/openmc-dev/openmc/pull/3498>`_)
- Provide a way to get ID maps from plot parameters on the Model class (`#3481 <https://github.com/openmc-dev/openmc/pull/3481>`_)
- Update OSX install instructions to point to x64 platform (`#3501 <https://github.com/openmc-dev/openmc/pull/3501>`_)
- Update conda install instructions for macOS Apple silicon (`#3488 <https://github.com/openmc-dev/openmc/pull/3488>`_)
- Only show warning if in restart mode (`#3478 <https://github.com/openmc-dev/openmc/pull/3478>`_)
- Add flag to CMakeLists to use submodules instead of searching (`#3480 <https://github.com/openmc-dev/openmc/pull/3480>`_)
- Added citation metadata file (`#3409 <https://github.com/openmc-dev/openmc/pull/3409>`_)
- fix zam parsing (`#3484 <https://github.com/openmc-dev/openmc/pull/3484>`_)
- Support flux collapse method in ``get_microxs_and_flux`` (`#3466 <https://github.com/openmc-dev/openmc/pull/3466>`_)
- Stabilize Adjoint Source (`#3476 <https://github.com/openmc-dev/openmc/pull/3476>`_)
- Refactor and Harden Configuration Management (`#3461 <https://github.com/openmc-dev/openmc/pull/3461>`_)
- Updated Docs to Not Give Specific Python Version Requirement (`#3473 <https://github.com/openmc-dev/openmc/pull/3473>`_)
- Parallelization of Weight Window Update (`#3467 <https://github.com/openmc-dev/openmc/pull/3467>`_)
- Limit Random Ray Weight Window Generation to Final Batch (`#3464 <https://github.com/openmc-dev/openmc/pull/3464>`_)
- Fix Dockerfile DAGMC build (`#3463 <https://github.com/openmc-dev/openmc/pull/3463>`_)
- Fix Weight Window Infinite Loop Bug (`#3457 <https://github.com/openmc-dev/openmc/pull/3457>`_)
- Weight Window Birth Scaling (`#3459 <https://github.com/openmc-dev/openmc/pull/3459>`_)
- Adding checks to geometry.plot to avoid material name overlaps (`#3458 <https://github.com/openmc-dev/openmc/pull/3458>`_)
- Fixing crash when calling Geometry.plot when DAGMCUniverse in geometry (`#3455 <https://github.com/openmc-dev/openmc/pull/3455>`_)
- fixing expansion of elemental Ta bug (`#3443 <https://github.com/openmc-dev/openmc/pull/3443>`_)
- Prevent Adjoint Sources from Trending towards Infinity (`#3449 <https://github.com/openmc-dev/openmc/pull/3449>`_)
- adding plot function to DAGMCUnvierse (`#3451 <https://github.com/openmc-dev/openmc/pull/3451>`_)
- Allow specifying number of equiprobable angles for thermal scattering data generation (`#3346 <https://github.com/openmc-dev/openmc/pull/3346>`_)
- Change Dockerfile from debian:bookworm-slim to ubuntu:24.04 (`#3442 <https://github.com/openmc-dev/openmc/pull/3442>`_)
- Fix Resetting of Auto IDs When Generating MGXS (`#3437 <https://github.com/openmc-dev/openmc/pull/3437>`_)
- Allowing chain_file to be chain object to save reloading time (`#3436 <https://github.com/openmc-dev/openmc/pull/3436>`_)
- update units for flux (`#3441 <https://github.com/openmc-dev/openmc/pull/3441>`_)
- Fix raytrace infinite loop (`#3423 <https://github.com/openmc-dev/openmc/pull/3423>`_)
- Apply Max Number of Events Check to Random Rays (`#3438 <https://github.com/openmc-dev/openmc/pull/3438>`_)
- Add user setting for source rejection fraction (`#3433 <https://github.com/openmc-dev/openmc/pull/3433>`_)
- Adding fix and tests for spherical mesh as spatial distribution (`#3428 <https://github.com/openmc-dev/openmc/pull/3428>`_)
- Random Ray Missed Cell Policy Change for Adjoint Mode (`#3434 <https://github.com/openmc-dev/openmc/pull/3434>`_)
- Random Ray External Source Plotting Fix (`#3430 <https://github.com/openmc-dev/openmc/pull/3430>`_)
- Avoid negative heating values during pair production and bremsstrahlung (`#3426 <https://github.com/openmc-dev/openmc/pull/3426>`_)
- Fix no serialization of periodic_surface_id bug (`#3421 <https://github.com/openmc-dev/openmc/pull/3421>`_)
- Update _get_start_data to always grab the beginning of timestep time (`#3414 <https://github.com/openmc-dev/openmc/pull/3414>`_)
- Fixed a bug in charged particle energy deposition (`#3416 <https://github.com/openmc-dev/openmc/pull/3416>`_)
- Fix bug where the same mesh is written multiple times to settings.xml (`#3418 <https://github.com/openmc-dev/openmc/pull/3418>`_)
- small typo - spelling of Debian (`#3411 <https://github.com/openmc-dev/openmc/pull/3411>`_)
- added test for dagmc geometry plot (`#3375 <https://github.com/openmc-dev/openmc/pull/3375>`_)
- Random Ray Misc Memory Error Fixes (`#3405 <https://github.com/openmc-dev/openmc/pull/3405>`_)
- added type hints to model file (`#3399 <https://github.com/openmc-dev/openmc/pull/3399>`_)
- Apply resolve paths to path values in ``config`` (`#3400 <https://github.com/openmc-dev/openmc/pull/3400>`_)
- Fixing an incorrect computation of CDF of bremsstrahlung photons (`#3396 <https://github.com/openmc-dev/openmc/pull/3396>`_)
- Fix weight modification for uniform source sampling (`#3395 <https://github.com/openmc-dev/openmc/pull/3395>`_)
- Updates to VTK data checks (`#3371 <https://github.com/openmc-dev/openmc/pull/3371>`_)
- Map Compton subshell data to atomic relaxation data (`#3392 <https://github.com/openmc-dev/openmc/pull/3392>`_)
- Skip atomic relaxation if binding energy is larger than photon energy (`#3391 <https://github.com/openmc-dev/openmc/pull/3391>`_)
- Fix extremely large yields from Bremsstrahlung (`#3386 <https://github.com/openmc-dev/openmc/pull/3386>`_)
- corrected tally name in D1S example (`#3383 <https://github.com/openmc-dev/openmc/pull/3383>`_)
- Install MCPL using same build type as OpenMC in CI (`#3388 <https://github.com/openmc-dev/openmc/pull/3388>`_)
- using reduce chain level to remove need for reduce chain (`#3377 <https://github.com/openmc-dev/openmc/pull/3377>`_)
- Fix negative distances from bins_crossed for CylindricalMesh (`#3370 <https://github.com/openmc-dev/openmc/pull/3370>`_)
- Add check for equal value bins in an EnergyFilter (`#3372 <https://github.com/openmc-dev/openmc/pull/3372>`_)
- Fix for Issue Loading MGXS Data Files with LLVM 20 or Newer (`#3368 <https://github.com/openmc-dev/openmc/pull/3368>`_)
- Report plot ID instead of index for unsupported plot types in random ray mode (`#3361 <https://github.com/openmc-dev/openmc/pull/3361>`_)
- Handle Missing Tags in Versioning by Setting Default to 0 (`#3359 <https://github.com/openmc-dev/openmc/pull/3359>`_)
- added kg units to doc string in results class (`#3358 <https://github.com/openmc-dev/openmc/pull/3358>`_)

View file

@ -7,6 +7,7 @@ Release Notes
.. toctree::
:maxdepth: 1
0.15.3
0.15.2
0.15.1
0.15.0

View file

@ -30,7 +30,8 @@ responsible for specifying one or more of the following:
Each of the above files can specified in several ways. In the Python API, a
:ref:`runtime configuration variable <usersguide_data_runtime>`
:data:`openmc.config` can be used to specify any of the above and is initialized
using a set of environment variables.
using a set of environment variables. Data configuration paths set in
:data:`openmc.config` will be expanded to absolute paths.
.. _usersguide_data_runtime:

View file

@ -6,42 +6,223 @@ Decay Sources
Through the :ref:`depletion <usersguide_depletion>` capabilities in OpenMC, it
is possible to simulate radiation emitted from the decay of activated materials.
For fusion energy systems, this is commonly done using what is known as the
`rigorous 2-step <https://doi.org/10.1016/S0920-3796(02)00144-8>`_ (R2S) method.
In this method, a neutron transport calculation is used to determine the neutron
flux and reaction rates over a cell- or mesh-based spatial discretization of the
model. Then, the neutron flux in each discrete region is used to predict the
activated material composition using a depletion solver. Finally, a photon
transport calculation with a source based on the activity and energy spectrum of
the activated materials is used to determine a desired physical response (e.g.,
a dose rate) at one or more locations of interest.
For fusion energy systems, this is commonly done using either the `rigorous
2-step <https://doi.org/10.1016/S0920-3796(02)00144-8>`_ (R2S) method or the
`direct 1-step <https://doi.org/10.1016/S0920-3796(01)00188-0>`_ (D1S) method.
In the R2S method, a neutron transport calculation is used to determine the
neutron flux and reaction rates over a cell- or mesh-based spatial
discretization of the model. Then, the neutron flux in each discrete region is
used to predict the activated material composition using a depletion solver.
Finally, a photon transport calculation with a source based on the activity and
energy spectrum of the activated materials is used to determine a desired
physical response (e.g., a dose rate) at one or more locations of interest.
OpenMC includes automation for both the R2S and D1S methods as described in the
following sections.
Once a depletion simulation has been completed in OpenMC, the intrinsic decay
source can be determined as follows. First the activated material composition
can be determined using the :class:`openmc.deplete.Results` object. Indexing an
instance of this class with the timestep index returns a
:class:`~openmc.deplete.StepResult` object, which itself has a
:meth:`~openmc.deplete.StepResult.get_material` method. Once the activated
:class:`~openmc.Material` has been obtained, the
:meth:`~openmc.Material.get_decay_photon_energy` method will give the energy
spectrum of the decay photon source. The integral of the spectrum also indicates
the intensity of the source in units of [Bq]. Altogether, the workflow looks as
follows::
Rigorous 2-Step (R2S) Calculations
==================================
OpenMC includes an :class:`openmc.deplete.R2SManager` class that fully automates
cell- and mesh-based R2S calculations. Before we describe this class, it is
useful to understand the basic mechanics of how an R2S calculation works.
Generally, it involves the following steps:
1. The :meth:`openmc.deplete.get_microxs_and_flux` function is called to run a
neutron transport calculation that determines fluxes and microscopic cross
sections in each activation region.
2. The :class:`openmc.deplete.IndependentOperator` and
:class:`openmc.deplete.PredictorIntegrator` classes are used to carry out a
depletion (activation) calculation in order to determine predicted material
compositions based on a set of timesteps and source rates.
3. The activated material composition is determined using the
:class:`openmc.deplete.Results` class. Indexing an instance of this class
with the timestep index returns a :class:`~openmc.deplete.StepResult` object,
which itself has a :meth:`~openmc.deplete.StepResult.get_material` method
returning an activated material.
4. The :meth:`openmc.Material.get_decay_photon_energy` method is used to obtain
the energy spectrum of the decay photon source. The integral of the spectrum
also indicates the intensity of the source in units of [Bq].
5. A new photon source is defined using one of OpenMC's source classes with the
energy distribution set equal to the object returned by the
:meth:`openmc.Material.get_decay_photon_energy` method. The source is then
assigned to a photon :class:`~openmc.Model`.
6. A photon transport calculation is run with ``model.run()``.
Altogether, the workflow looks as follows::
# Run neutron transport calculation
fluxes, micros = openmc.deplete.get_microxs_and_flux(model, domains)
# Run activation calculation
op = openmc.deplete.IndependentOperator(mats, fluxes, micros)
timesteps = ...
source_rates = ...
integrator = openmc.deplete.Integrator(op, timesteps, source_rates)
integrator.integrate()
# Get decay photon source at last timestep
results = openmc.deplete.Results("depletion_results.h5")
# Get results at last timestep
step = results[-1]
# Get activated material composition for ID=1
activated_mat = step.get_material('1')
# Determine photon source
photon_energy = activated_mat.get_decay_photon_energy()
photon_source = openmc.IndependentSource(
space=...,
energy=photon_energy,
particle='photon',
strength=photon_energy.integral()
)
By default, the :meth:`~openmc.Material.get_decay_photon_energy` method will
eliminate spectral lines with very low intensity, but this behavior can be
configured with the ``clip_tolerance`` argument.
# Run photon transport calculation
model.settings.source = photon_source
model.run()
Note that by default, the :meth:`~openmc.Material.get_decay_photon_energy`
method will eliminate spectral lines with very low intensity, but this behavior
can be configured with the ``clip_tolerance`` argument.
Cell-based R2S
--------------
In practice, users do not need to manually go through each of the steps in an R2S
calculation described above. The :class:`~openmc.deplete.R2SManager` fully
automates the execution of neutron transport, depletion, decay source
generation, and photon transport. For a cell-based R2S calculation, once you
have a :class:`~openmc.Model` that has been defined, simply create an instance
of :class:`~openmc.deplete.R2SManager` by passing the model and a list of cells
to activate::
r2s = openmc.deplete.R2SManager(model, [cell1, cell2, cell3])
Note that the ``volume`` attribute must be set for any cell that is to be
activated. The :class:`~openmc.deplete.R2SManager` class allows you to
optionally specify a separate photon model; if not given as an argument, it will
create a shallow copy of the original neutron model (available as the
``neutron_model`` attribute) and store it in the ``photon_model`` attribute. We
can use this to define tallies specific to the photon model::
dose_tally = openmc.Tally()
...
r2s.photon_model.tallies = [dose_tally]
Next, define the timesteps and source rates for the activation calculation::
timesteps = [(3.0, 'd'), (5.0, 'h')]
source_rates = [1e12, 0.0]
In this case, the model is irradiated for 3 days with a source rate of
:math:`10^{12}` neutron/sec and then the source is turned off and the activated
materials are allowed to decay for 5 hours. These parameters should be passed to
the :meth:`~openmc.deplete.R2SManager.run` method to execute the full R2S
calculation. Before we can do that though, for a cell-based calculation, the one
other piece of information that is needed is bounding boxes of the activated
cells::
bounding_boxes = {
cell1.id: cell1.bounding_box,
cell2.id: cell2.bounding_box,
cell3.id: cell3.bounding_box
}
Note that calling the ``bounding_box`` attribute may not work for all
constructive solid geometry regions (for example, a cell that uses a
non-axis-aligned plane). In these cases, the bounding box will need to be
specified manually. Once you have a set of bounding boxes, the R2S calculation
can be run::
r2s.run(timesteps, source_rates, bounding_boxes=bounding_boxes)
If not specified otherwise, a photon transport calculation is run at each time
in the depletion schedule for which a decay photon source exists. Times without
a decay photon source, such as the initial state of a model containing only
stable nuclides, are omitted. To specify particular times at which photon
transport calculations should be run, pass the ``photon_time_indices`` argument.
For example, if we wanted to run a photon transport calculation only on the last
time (after the 5 hour decay), we would run::
r2s.run(timesteps, source_rates, bounding_boxes=bounding_boxes,
photon_time_indices=[2])
To attribute photon tally results to their parent radionuclides, set
``by_parent_nuclide=True``. This automatically adds a
:class:`openmc.ParentNuclideFilter` to every photon tally that does not already
have one. The filter bins are the union of radionuclides contributing to the
prepared decay photon sources. The resulting bins can be used directly when
inspecting the tally results::
r2s.run(timesteps, source_rates, bounding_boxes=bounding_boxes,
photon_time_indices=[2], by_parent_nuclide=True)
photon_tally = r2s.results['photon_tallies'][2][0]
tally_by_parent = photon_tally.get_pandas_dataframe()
After an R2S calculation has been run, the :class:`~openmc.deplete.R2SManager`
instance will have a ``results`` dictionary that allows you to directly access
results from each of the steps. It will also write out all the output files into
a directory that is named "r2s_<timestamp>/". The ``output_dir`` argument to the
:meth:`~openmc.deplete.R2SManager.run` method enables you to override the
default output directory name if desired.
The :meth:`~openmc.deplete.R2SManager.run` method actually runs four
lower-level methods under the hood::
r2s.step1_neutron_transport(...)
r2s.step2_activation(...)
r2s.step3_photon_source(...)
r2s.step4_photon_transport(...)
For users looking for more control over the calculation, these lower-level
methods can be used in lieu of the :meth:`openmc.deplete.R2SManager.run` method.
Mesh-based R2S
--------------
Executing a mesh-based R2S calculation looks nearly identical to the cell-based
R2S workflow described above. The only difference is that instead of passing a
list of cells to the ``domains`` argument of
:class:`~openmc.deplete.R2SManager`, you need to define a mesh object and pass
that instead. This might look like the following::
# Define a regular Cartesian mesh
mesh = openmc.RegularMesh()
mesh.lower_left = (-50., -50., 0.)
mesh.upper_right = (50., 50., 75.)
mesh.dimension = (10, 10, 5)
r2s = openmc.deplete.R2SManager(model, mesh)
Executing the R2S calculation is then performed by adding photon tallies and
calling the :meth:`~openmc.deplete.R2SManager.run` method with the appropriate
timesteps and source rates. Note that in this case we do not need to define cell
volumes or bounding boxes as is required for a cell-based R2S calculation.
Instead, during the neutron transport step, OpenMC will run a raytracing
calculation to determine material volume fractions within each mesh element
using the :meth:`openmc.MeshBase.material_volumes` method. Arguments to this
method can be customized via the ``mat_vol_kwargs`` argument to the
:meth:`~openmc.deplete.R2SManager.run` method. Most often, this would involve
customizing the number of rays traced to obtain better estimates of volumes. As
an example, if we wanted to run the raytracing calculation with 10 million rays,
we would run::
r2s.run(timesteps, source_rates, mat_vol_kwargs={'n_samples': 10_000_000})
It is also possible to use multiple meshes by passing a list of meshes instead
of a single mesh. This can be useful, for example, when different regions of the
model require different mesh resolutions. The meshes are assumed to be
**non-overlapping**; each element--material combination across all meshes is
treated as an independent activation region, and all meshes are handled in a
single neutron transport solve. For example::
# Fine mesh near the activation target
mesh_fine = openmc.RegularMesh()
mesh_fine.dimension = (10, 10, 10)
...
# Coarse mesh for the surrounding region
mesh_coarse = openmc.RegularMesh()
mesh_coarse.dimension = (5, 5, 5)
...
r2s = openmc.deplete.R2SManager(model, [mesh_fine, mesh_coarse])
Direct 1-Step (D1S) Calculations
================================
@ -88,5 +269,4 @@ relevant tallies. This can be done with the aid of the
dose_tally = sp.get_tally(name='dose tally')
# Apply time correction factors
tally = d1s.apply_time_correction(tally, factors, time_index)
tally = d1s.apply_time_correction(dose_tally, factors, time_index)

View file

@ -449,3 +449,42 @@ to transfer xenon from one material to another, you'd use::
...
integrator.add_transfer_rate(mat1, ['Xe'], 0.1, destination_material=mat2)
Comparing to Other Codes
========================
Comparing depletion results from OpenMC with those from another code, such as
MCNP or Serpent, requires more than constructing equivalent transport models.
At each depletion step, differences in the transport solution, nuclear data,
reaction rate normalization, and numerical integration can all affect the
result. Small differences can also accumulate over successive depletion steps.
For a meaningful comparison, align as many of the following inputs and methods
as possible:
- Geometry and material definitions and associated physical properties such as
temperature
- Neutron cross section library (e.g., ENDF/B-VIII.0)
- Treatment of thermal scattering and unresolved resonance probability tables
- Neutron reactions accounted for in the depletion chain
- Decay data in the depletion chain
- Isomeric branching ratios for reactions in the depletion chain
- Fission product yields in the depletion chain
- Fission product yield interpolation method
(``CoupledOperator(fission_yield_mode=...)``)
- Reaction rate normalization, including fission Q values
(``CoupledOperator(fission_q=...)``)
- Depletion integration method (``PredictorIntegrator``, ``CECMIntegrator``,
etc.) and time-step sizes
When comparing to codes that use ACE format cross sections, it is recommended to
directly convert the ACE files to HDF5 format using functionality from the
:mod:`openmc.data` module (see :ref:`create_xs_library`). Some of the
LANL-distributed ACE libraries used with MCNP have also been converted to HDF5
format and are available for download at https://openmc.org/data.
Even after these choices have been aligned, exact agreement should not be
expected. Codes may use different approximations or numerical methods that
cannot be configured identically. When investigating a discrepancy, first
compare transport results and one-group reaction rates at the initial time, then
compare changes over subsequent timesteps.

View file

@ -182,6 +182,8 @@ boundary condition.
Periodic boundary conditions can be applied to pairs of planar surfaces.
If there are only two periodic surfaces they will be matched automatically.
Otherwise it is necessary to specify pairs explicitly using the
:attr:`Surface.periodic_surface` attribute as in the following example::
@ -192,7 +194,7 @@ Otherwise it is necessary to specify pairs explicitly using the
Both rotational and translational periodic boundary conditions are specified in
the same fashion. If both planes have the same normal vector, a translational
periodicity is assumed; rotational periodicity is assumed otherwise. Currently,
only rotations about the :math:`z`-axis are supported.
rotations must be about the :math:`x`-, :math:`y`-, or :math:`z`-axis.
For a rotational periodic BC, the normal vectors of each surface must point
inwards---towards the valid geometry. For example, a :class:`XPlane` and
@ -246,6 +248,28 @@ The classes :class:`Halfspace`, :class:`Intersection`, :class:`Union`, and
:class:`Complement` and all instances of :class:`openmc.Region` and can be
assigned to the :attr:`Cell.region` attribute.
Cells also contain :attr:`Cell.temperature` and :attr:`Cell.density`
attributes which override the temperature and density of the fill. These can
be quite useful when temperatures and densities are spatially varying, as the
alternative would be to add a unique :class:`Material` for each permutation of
temperature, density, and composition. You can set the temperature (K) and
density (g/cc) of a cell like so::
fuel.temperature = 800.0
fuel.density = 10.0
The real utility of cell temperatures and densities occurs when a cell is
replicated across the geometry, such as when a cell is the root geometric element
in a replicated :ref:`universe<usersguide_universes>` or :ref:`lattice
<usersguide_lattices>`. In those cases, you can provide a list of temperatures
and densities to apply a temperature/density field to all of the distributed cells::
fuel.temperature = [800.0, 900.0, 800.0, 900.0]
fuel.density = [10.0, 9.0, 10.0, 9.0]
In this example, the fuel cell is distributed four times in the geometry. Each
distributed instance then receives its own temperature and density.
.. _usersguide_universes:
---------
@ -413,11 +437,11 @@ to help figure out how to place universes::
Note that by default, hexagonal lattices are positioned such that each lattice
element has two faces that are parallel to the :math:`y` axis. As one example,
to create a three-ring lattice centered at the origin with a pitch of 10 cm
where all the lattice elements centered along the :math:`y` axis are filled with
universe ``u`` and the remainder are filled with universe ``q``, the following
code would work::
element has two faces that are perpendicular to the :math:`y` axis. As one
example, to create a three-ring lattice centered at the origin with a pitch of
10 cm where all the lattice elements centered along the :math:`y` axis are
filled with universe ``u`` and the remainder are filled with universe ``q``, the
following code would work::
hexlat = openmc.HexLattice()
hexlat.center = (0, 0)
@ -530,6 +554,89 @@ UWUW and OpenMC material ID space will cause an error. To automatically resolve
these ID overlaps, ``auto_ids`` can be set to ``True`` to append the UWUW
material IDs to the OpenMC material ID space.
Material overrides and differentiation
--------------------------------------
Programmatic access to DAGMC cell information for material overrides
and differentiation requires synchronization of the DAGMC universe
representation across Python and C-API::
model.init_lib()
model.sync_dagmc_universes()
model.finalize_lib()
Upon completion of these steps, the :attr:`DAGMCUniverse.cells` attribute will
be populated with :class:`DAGMCCell` proxy objects that represent the cells
defined in the DAGMC model. The :class:`DAGMCCell` objects will have
:class:`openmc.Material`'s' applied according to the assignments upon
initialization of the model. These materials can be replaced in the same manner
as :class:`openmc.Cell` objects to override material assignments in the DAGMC
model.
Depletion with DAGMC geometry
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The synchronization of :class:`openmc.DAGMCUniverse`'s is important for
depletion calculations using DAGMC geometry when materials need to be
differentiated to perform material burnup independently in each DAGMC cell. See
:meth:`openmc.model.Model.differentiate_mats`.
Material overrides
~~~~~~~~~~~~~~~~~~
OpenMC supports overriding material assignments defined inside a DAGMC HDF5
model so that CAD-assigned materials can be replaced by :class:`openmc.Material`
objects. This is useful when the CAD geometry provides the shape but OpenMC
materials (specific nuclide content, densities, or depletion behavior) are
required.
Replacing materials by name
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If a DAGMC file includes material name tags, you can replace all cells that
reference a particular name with an :class:`openmc.Material` using
:meth:`~openmc.DAGMCUniverse.replace_material_assignment`::
import openmc
dag_univ = openmc.DAGMCUniverse('dagmc.h5m')
fuel = openmc.Material(name='fuel')
fuel.add_nuclide('U235', 0.05)
fuel.add_nuclide('U238', 0.95)
fuel.set_density('g/cm3', 10.5)
dag_univ.replace_material_assignment('Fuel', fuel)
This lets you keep CAD geometry while adopting OpenMC material definitions.
Per-cell material overrides
^^^^^^^^^^^^^^^^^^^^^^^^^^^
To assign overrides without initializing :class:`openmc.Model`, the
:meth:`openmc.DAGMCUniverse.add_material_override` method can be used to assign
materials to particular DAGMC cells. The method accepts either an integer cell
ID::
dag_univ = openmc.DAGMCUniverse('dagmc.h5m')
enriched = openmc.Material(name='fuel_enriched')
enriched.add_nuclide('U235', 0.10)
enriched.add_nuclide('U238', 0.90)
enriched.set_density('g/cm3', 10.5)
dag_univ.add_material_override(1, enriched)
In the case that the :class:`openmc.DAGMCUniverse` has already been synchronized,
a :class:`openmc.DAGMCCell` object can also be provide to assign the material.
Overrides are written to the `<material_overrides>` element of the
:ref:`<dagmc_universe> <dagmc_element>` XML element so the C++ core can apply
them on initialization.
.. _Direct Accelerated Geometry Monte Carlo: https://svalinn.github.io/DAGMC/
.. _University of Wisconsin Unified Workflow: https://svalinn.github.io/DAGMC/usersguide/uw2.html

View file

@ -22,6 +22,7 @@ essential aspects of using OpenMC to perform simulations.
plots
depletion
decay_sources
kinetics
scripts
processing
parallel

View file

@ -35,6 +35,13 @@ you wish) with OpenMC installed.
conda create --name openmc-env openmc
conda activate openmc-env
If you are installing on macOS with an Apple silicon ARM-based processor, you
will also need to specify the `--platform` option:
.. code-block:: sh
conda create --name openmc-env --platform osx-64 openmc
You are now in a conda environment called `openmc-env` that has OpenMC
installed.
@ -151,6 +158,75 @@ feature can be used to access the installed packages.
.. _Spack: https://spack.readthedocs.io/en/latest/
.. _setup guide: https://spack.readthedocs.io/en/latest/getting_started.html
.. _install_aur:
------------------------------------
Installing on Arch Linux via the AUR
------------------------------------
On Arch Linux and Arch-based distributions, OpenMC can be installed from the
`Arch User Repository (AUR) <https://aur.archlinux.org/>`_. An AUR package named
``openmc-git`` is available, which builds OpenMC directly from the latest
development sources.
This package provides a full-featured OpenMC stack, including:
* MPI and DAGMC-enabled OpenMC build
* User-selected nuclear data libraries
* The `CAD_to_OpenMC <https://github.com/united-neux/CAD_to_OpenMC>`_ meshing tool
* All required dependencies for the above components
To install the package, you will need an AUR helper such as `yay`_ or `paru`_.
For example, using ``yay``::
yay -S openmc-git
Alternatively, you can manually clone and build the package::
git clone https://aur.archlinux.org/openmc-git.git
cd openmc-git
makepkg -si
Note, ``makepkg`` uses ``pacman`` to resolve dependencies. Therefore, AUR-based
dependencies need to be installed separately with ``yay`` or ``paru`` before
running ``makepkg``. The PKGBUILD will automatically handle all required
dependencies and build OpenMC with MPI and DAGMC support enabled.
.. tip::
If there are failing checks during the build process, you can bypass them
with the ``--nocheck`` flag::
yay -S openmc-git --mflags "--nocheck"
Or::
git clone https://aur.archlinux.org/openmc-git.git
cd openmc-git
makepkg -si --nocheck
.. note::
The ``openmc-git`` package tracks the latest development version from the
upstream repository. As such, it may include new features and bug fixes, but
could also introduce instability compared to official releases.
.. tip::
OpenMC is installed under ``/opt``. If you are installing and using it in
the same terminal session, you may need to reload your environment
variables::
source /etc/profile
Alternatively, start a new shell session.
Once installed, the ``openmc`` executable, nuclear data libraries, and
associated tools will be available in your system :envvar:`PATH`.
.. _yay: https://github.com/Jguer/yay
.. _paru: https://github.com/Morganamilo/paru
.. _install_source:
@ -221,7 +297,7 @@ Prerequisites
OpenMC's built-in plotting capabilities use the libpng library to produce
compressed PNG files. In the absence of this library, OpenMC will fallback
to writing PPM files, which are uncompressed and only supported by select
image viewers. libpng can be installed on Ddebian derivates with::
image viewers. libpng can be installed on Debian derivates with::
sudo apt install libpng-dev
@ -255,11 +331,11 @@ Prerequisites
This option allows OpenMC to read and write MCPL (Monte Carlo Particle
Lists) files instead of .h5 files for sources (external source
distribution, k-eigenvalue source distribution, and surface sources). To
turn this option on in the CMake configuration step, add the following
option::
cmake -DOPENMC_USE_MCPL=on ..
distribution, k-eigenvalue source distribution, and surface sources).
OpenMC does not need any particular build option to use this, but MCPL
must be installed on the system in order to do so. Refer to the
`MCPL documentation <https://github.com/mctools/mcpl/blob/HEAD/INSTALL.md>`_
for instructions on how to accomplish this.
* NCrystal_ library for defining materials with enhanced thermal neutron transport
@ -368,10 +444,6 @@ OPENMC_USE_DAGMC
should also be defined as `DAGMC_ROOT` in the CMake configuration command.
(Default: off)
OPENMC_USE_MCPL
Turns on support for reading MCPL_ source files and writing MCPL source points
and surface sources. (Default: off)
OPENMC_USE_LIBMESH
Enables the use of unstructured mesh tallies with libMesh_. (Default: off)
@ -380,6 +452,25 @@ OPENMC_USE_MPI
options, please see the `FindMPI.cmake documentation
<https://cmake.org/cmake/help/latest/module/FindMPI.html>`_.
.. _cmake_strict_fp:
OPENMC_ENABLE_STRICT_FP
Disables compiler optimizations that change floating-point results relative to
unoptimized builds, improving cross-platform and cross-optimization-level
reproducibility. This disables FMA contraction (``-ffp-contract=off``) and
compiler builtin replacements of math functions like ``pow``, ``exp``, ``log``
(``-fno-builtin``). It also keeps C/C++ assertions active by removing the
``-DNDEBUG`` flag from ``RelWithDebInfo`` builds. Without this flag, these
optimizations can produce bit-level differences across platforms, compilers,
and optimization levels. This option should be used when running the test
suite. By default (off), the compiler is free to use all optimizations for
best performance. (Default: off)
OPENMC_FORCE_VENDORED_LIBS
Forces OpenMC to use the submodules located in the vendor directory, as
opposed to searching the system for already installed versions of those
modules.
To set any of these options (e.g., turning on profiling), the following form
should be used:
@ -407,7 +498,10 @@ Release
RelWithDebInfo
(Default if no type is specified.) Enable optimization and debug. On most
platforms/compilers, this is equivalent to `-O2 -g`.
platforms/compilers, this is equivalent to `-O2 -g`. When
:ref:`OPENMC_ENABLE_STRICT_FP <cmake_strict_fp>` is enabled, OpenMC removes the
``-DNDEBUG`` flag that CMake normally adds for this build type, so that
C/C++ assertions remain active.
Example of configuring for Debug mode:
@ -515,10 +609,13 @@ to install the Python package in :ref:`"editable" mode <devguide_editable>`.
Prerequisites
-------------
The Python API works with Python 3.8+. In addition to Python itself, the API
relies on a number of third-party packages. All prerequisites can be installed
using Conda_ (recommended), pip_, or through the package manager in most Linux
distributions.
In addition to Python itself, the OpenMC Python API relies on a number of
third-party packages. All prerequisites can be installed using Conda_
(recommended), pip_, or through the package manager in most Linux distributions.
The current required Python version and up-to-date list of package dependencies
can be found in the `pyproject.toml <https://github.com/openmc-dev/openmc/blob/develop/pyproject.toml>`_
file in the root directory of the OpenMC repository. An overview of these
dependencies is provided below.
.. admonition:: Required
:class: error

View file

@ -0,0 +1,133 @@
.. _kinetics:
===================
Kinetics parameters
===================
OpenMC has the capability to estimate the following adjoint-weighted effective
generation time :math:`\Lambda_{\text{eff}}` and the effective delayed neutron
fraction :math:`\beta_{\text{eff}}`. These parameters are calculated using the
iterated fission probability (IFP) method [Hurwitz_1964]_ based on a similar
approach as in `Serpent 2 <https://doi.org/10.1016/j.anucene.2013.10.032>`_. The
implementation in OpenMC is limited to eigenvalue calculations and is described
in more details in [Dorville_2025]_.
----------------------------------
Iterated Fission Probability (IFP)
----------------------------------
With IFP, additional information needs to be recorded during the simulation
compared to a typical eigenvalue calculation. OpenMC stores an additional
set of values (neutron lifetime or delayed neutron group number for
:math:`\Lambda_{\text{eff}}` or :math:`\beta_{\text{eff}}`, respectively)
for every fission neutron simulated. Each set of values corresponds to
the values that are associated to the :math:`N_{\text{gen}}` direct ancestors
of any given fission neutron.
:math:`N_{\text{gen}}` is referred to as the number of generations in the
IFP method and corresponds to the number of generations between the birth of
a fission neutron and the time its score is added to the IFP tally. By default,
OpenMC considers 10 generations but this value can be modified by the user via
the ``ifp_n_generation`` settings in the Python API::
settings.ifp_n_generation = 5
``ifp_n_generation`` should be greater than 0, but should also be lower than
or equal to the number of inactive batches declared for the calculation.
The respect of these constraints is verified by OpenMC before any calculation.
OpenMC will automatically detect the type of data that needs to be stored based
on the tally scores selected by the user. This guarantees that only information
of interest are stored during a simulation and avoids using extra memory when
only one parameter is needed. The following table shows the tally scores that
are needed to compute kinetics parameters in OpenMC:
.. table:: **OpenMC tally scores needed to calculate adjoint-weighted kinetics parameters**
:align: center
=============================== ============================ ========================== ========
OpenMC tally score \\ Parameter :math:`\Lambda_{\text{eff}}` :math:`\beta_{\text{eff}}` Both
=============================== ============================ ========================== ========
``ifp-time-numerator`` X X
``ifp-beta-numerator`` X X
``ifp-denominator`` X X X
=============================== ============================ ========================== ========
|
.. note:: Because the memory footprint of additional data is generally non-negligible
with IFP, it is recommended to choose the value for ``ifp_n_generation`` carefully.
For example, using one generation for both kinetics parameters corresponds to store
one additional integer (for the delayed neutron group number used with
:math:`\beta_{\text{eff}}`) and one floating point value (for the neutron lifetime
used with :math:`\Lambda_{\text{eff}}`) for every fission neutron simulated once the
asymptotic regime is reached.
-----------------------------
Obtaining kinetics parameters
-----------------------------
The ``Model`` class can be used to automatically generate all IFP tallies using
the Python API with :attr:`openmc.Settings.ifp_n_generation` greater than 0 and
the :meth:`openmc.Model.add_ifp_kinetics_tallies` method::
model = openmc.Model(geometry, settings=settings)
model.add_kinetics_parameters_tallies(num_groups=6) # Add 6 precursor groups
Alternatively, each of the tallies can be manually defined using group-wise or
total :math:`\beta_{\text{eff}}` specified by providing a 6-group
:class:`openmc.DelayedGroupFilter`::
beta_tally = openmc.Tally(name="group-beta-score")
beta_tally.scores = ["ifp-beta-numerator"]
# Add DelayedGroupFilter to enable group-wise tallies
beta_tally.filters = [openmc.DelayedGroupFilter(list(range(1, 7)))]
Here is an example showing how to declare the three available IFP scores in a
single tally::
tally = openmc.Tally(name="ifp-scores")
tally.scores = [
"ifp-time-numerator",
"ifp-beta-numerator",
"ifp-denominator"
]
The effective generation time :math:`\Lambda_{\text{eff}}` is calculated
by dividing the result of the ``ifp-time-numerator`` score by the one obtained
for ``ifp-denominator`` and by the :math:`k_{\text{eff}}` of the simulation:
.. math::
:label: lambda_eff
\Lambda_{\text{eff}} = \frac{S_{\text{ifp-time-numerator}}}{S_{\text{ifp-denominator}} \times k_{\text{eff}}}
The effective delayed neutron fraction :math:`\beta_{\text{eff}}` is calculated
by dividing the result of the ``ifp-beta-numerator`` score by the one obtained
for ``ifp-denominator``:
.. math::
:label: beta_eff
\beta_{\text{eff}} = \frac{S_{\text{ifp-beta-numerator}}}{S_{\text{ifp-denominator}}}
The kinetics parameters can be retrieved directly from a statepoint file using
the :meth:`openmc.StatePoint.ifp_results` method::
with openmc.StatePoint(output_path) as sp:
generation_time, beta_eff = sp.get_kinetics_parameters()
.. only:: html
.. rubric:: References
.. [Hurwitz_1964] H. Hurwitz Jr., "Naval Reactors Physics Handbook", volume 1, p. 864.
Radkowsky, A. (Ed.), Naval Reactors, Division of Reactor Development, U.S.
Atomic Energy Commission (1964).
.. [Dorville_2025] J. Dorville, L. Labrie-Cleary, and P. K. Romano, "Implementation
of the Iterated Fission Probability Method in OpenMC to Compute Adjoint-Weighted
Kinetics Parameters", International Conference on Mathematics and Computational
Methods Applied to Nuclear Science and Engineering (M&C 2025), Denver, April 27-30,
2025.

View file

@ -6,13 +6,14 @@ Geometry Visualization
.. currentmodule:: openmc
OpenMC is capable of producing two-dimensional slice plots of a geometry as well
as three-dimensional voxel plots using the geometry plotting :ref:`run mode
<usersguide_run_modes>`. The geometry plotting mode relies on the presence of a
:ref:`plots.xml <io_plots>` file that indicates what plots should be created. To
create this file, one needs to create one or more :class:`openmc.Plot`
instances, add them to a :class:`openmc.Plots` collection, and then use the
:class:`Plots.export_to_xml` method to write the ``plots.xml`` file.
OpenMC is capable of producing two-dimensional slice plots of a geometry,
three-dimensional voxel plots, and three-dimensional raytrace plots using the
geometry plotting :ref:`run mode <usersguide_run_modes>`. The geometry plotting
mode relies on the presence of a :ref:`plots.xml <io_plots>` file that indicates
what plots should be created. To create this file, one needs to create one or
more instances of the various plot classes described below, add them to a
:class:`openmc.Plots` collection, and then use the :class:`Plots.export_to_xml`
method to write the ``plots.xml`` file.
-----------
Slice Plots
@ -21,15 +22,14 @@ Slice Plots
.. image:: ../_images/atr.png
:width: 300px
By default, when an instance of :class:`openmc.Plot` is created, it indicates
that a 2D slice plot should be made. You can specify the origin of the plot
(:attr:`Plot.origin`), the width of the plot in each direction
(:attr:`Plot.width`), the number of pixels to use in each direction
(:attr:`Plot.pixels`), and the basis directions for the plot. For example, to
create a :math:`x` - :math:`z` plot centered at (5.0, 2.0, 3.0) with a width of
(50., 50.) and 400x400 pixels::
The :class:`openmc.SlicePlot` class indicates that a 2D slice plot should be
made. You can specify the origin of the plot (:attr:`SlicePlot.origin`), the
width of the plot in each direction (:attr:`SlicePlot.width`), the number of
pixels to use in each direction (:attr:`SlicePlot.pixels`), and the basis
directions for the plot. For example, to create a :math:`x` - :math:`z` plot
centered at (5.0, 2.0, 3.0) with a width of (50., 50.) and 400x400 pixels::
plot = openmc.Plot()
plot = openmc.SlicePlot()
plot.basis = 'xz'
plot.origin = (5.0, 2.0, 3.0)
plot.width = (50., 50.)
@ -47,7 +47,7 @@ that location.
By default, a unique color will be assigned to each cell in the geometry. If you
want your plot to be colored by material instead, change the
:attr:`Plot.color_by` attribute::
:attr:`SlicePlot.color_by` attribute::
plot.color_by = 'material'
@ -68,8 +68,8 @@ particular cells/materials should be given colors of your choosing::
Note that colors can be given as RGB tuples or by a string indicating a valid
`SVG color <https://www.w3.org/TR/SVG11/types.html#ColorKeywords>`_.
When you're done creating your :class:`openmc.Plot` instances, you need to then
assign them to a :class:`openmc.Plots` collection and export it to XML::
When you're done creating your :class:`openmc.SlicePlot` instances, you need to
then assign them to a :class:`openmc.Plots` collection and export it to XML::
plots = openmc.Plots([plot1, plot2, plot3])
plots.export_to_xml()
@ -97,13 +97,11 @@ Voxel Plots
.. image:: ../_images/3dba.png
:width: 200px
The :class:`openmc.Plot` class can also be told to generate a 3D voxel plot
instead of a 2D slice plot. Simply change the :attr:`Plot.type` attribute to
'voxel'. In this case, the :attr:`Plot.width` and :attr:`Plot.pixels` attributes
should be three items long, e.g.::
The :class:`openmc.VoxelPlot` class enables the generation of a 3D voxel plot
instead of a 2D slice plot. In this case, the :attr:`VoxelPlot.width` and
:attr:`VoxelPlot.pixels` attributes should be three items long, e.g.::
vox_plot = openmc.Plot()
vox_plot.type = 'voxel'
vox_plot = openmc.VoxelPlot()
vox_plot.width = (100., 100., 50.)
vox_plot.pixels = (400, 400, 200)

View file

@ -68,17 +68,17 @@ generation, and particle number of the desired particle. For example, to create
a track file for particle 4 of batch 1 and generation 2::
settings = openmc.Settings()
settings.track = (1, 2, 4)
settings.track = [(1, 2, 4)]
To specify multiple particles, the length of the iterable should be a multiple
of three, e.g., if we wanted particles 3 and 4 from batch 1 and generation 2::
To specify multiple particles, specify a list of tuples, e.g., if we wanted
particles 3 and 4 from batch 1 and generation 2::
settings.track = (1, 2, 3, 1, 2, 4)
settings.track = [(1, 2, 3), (1, 2, 4)]
After running OpenMC, the working directory will contain a file of the form
"track_(batch #)_(generation #)_(particle #).h5" for each particle tracked.
These track files can be converted into VTK poly data files with the
:class:`openmc.Tracks` class.
After running OpenMC (now, without the ``-t`` argument), the working directory
will contain a file named `tracks.h5`, which contains a collection of particle
tracks. These track files can be converted into VTK poly data files or
matplotlib plots with the :class:`openmc.Tracks` class.
----------------------
Source Site Processing
@ -91,3 +91,90 @@ from a statepoint file, the ``openmc.statepoint`` module can be used. An
`example notebook`_ demontrates how to analyze and plot source information.
.. _example notebook: https://nbviewer.jupyter.org/github/openmc-dev/openmc-notebooks/blob/main/post-processing.ipynb
------------------------
VTK Mesh File Generation
------------------------
VTK files of OpenMC meshes can be created using the
:meth:`openmc.Mesh.write_data_to_vtk` method. This method supports several VTK
formats depending on the mesh type. Structured meshes
(:class:`~openmc.RegularMesh`, :class:`~openmc.RectilinearMesh`,
:class:`~openmc.CylindricalMesh`, and :class:`~openmc.SphericalMesh`) can be
exported to legacy VTK format (``.vtk``). The :class:`~openmc.UnstructuredMesh`
class supports VTK unstructured grid formats (``.vtu``) as well as an HDF5-based
format (``.vtkhdf``) that does not require the ``vtk`` module to write.
Data can be applied to the
elements of the resulting mesh from mesh filter objects. This data can be
provided either as a flat array or, in the case of structured meshes
(:class:`~openmc.RegularMesh`, :class:`~openmc.RectilinearMesh`,
:class:`~openmc.CylindricalMesh`, or :class:`SphericalMesh`), the data can be
shaped with dimensions that match the dimensions of the mesh itself.
.. image:: ../_images/sphere-mesh-vtk.png
:width: 400px
:align: center
:alt: OpenMC spherical mesh exported to VTK
For all mesh types, if a flat data array is provided to the mesh, it is expected
that the data is ordered in the same ordering as the :attr:`openmc.Mesh.indices`
for that mesh object. When providing data directly from a tally, as shown below,
a flat array for a given dataset can be passed directly to this method.
::
# create model above
# create a mesh tally
mesh = openmc.RegularMesh()
mesh.dimension = [10, 20, 30]
mesh.lower_left = [-5, -10, -15]
mesh.upper_right = [5, 10, 15]
mesh_filter = openmc.MeshFilter(mesh)
tally = openmc.Tally()
tally.filters = [mesh_filter]
tally.scores = ['flux']
model.tallies = [tally]
model.run(apply_tally_results=True)
# provide the data as-is to the method
mesh.write_data_to_vtk('flux.vtk', {'flux-mean': tally.mean})
The :class:`~openmc.Tally` object also provides a way to expand the dimensions
of the mesh filter into a meaningful form where indexing the mesh filter
dimensions results in intuitive slicing of structured meshes by setting
``expand_dims=True`` when using :meth:`openmc.Tally.get_reshaped_data`. This
reshaping does cause flat indexing of the data to change, however. As noted
above, provided datasets are allowed to be shaped so long as such datasets have
shapes that match the mesh dimensions. The ability to pass datasets in this way
is useful when additional filters are applied to a tally. The example below
demonstrates such a case for tally with both a :class:`~openmc.MeshFilter` and
:class:`~openmc.EnergyFilter` applied.
::
# create model above
# create a mesh tally with energy filter
mesh = openmc.RegularMesh()
mesh.dimension = [10, 20, 30]
mesh.lower_left = [-5, -10, -15]
mesh.upper_right = [5, 10, 15]
mesh_filter = openmc.MeshFilter(mesh)
energy_filter = openmc.EnergyFilter([0.0, 1.0, 20.0e6])
tally = openmc.Tally()
tally.filters = [mesh_filter, energy_filter]
tally.scores = ['flux']
model.tallies = [tally]
model.run(apply_tally_results=True)
# get the data with mesh dimensions expanded, squeeze out length-one dimensions (nuclides, scores)
flux = tally.get_reshaped_data(expand_dims=True).squeeze() # shape: (10, 20, 30, 2)
# write the lowest energy group to a VTK file
mesh.write_data_to_vtk('flux-group1.vtk', datasets={'flux-mean': flux[..., 0]})

View file

@ -11,6 +11,76 @@ active batches <usersguide_batches>`. However, there are a couple of settings
that are unique to the random ray solver and a few areas that the random ray
run strategy differs, both of which will be described in this section.
.. _quick_start:
-----------
Quick Start
-----------
While this page contains a comprehensive guide to the random ray solver and
its various parameters, the process of converting an existing continuous energy
Monte Carlo model to a random ray model can be largely automated via convenience
functions in OpenMC's Python interface::
# Define continuous energy model as normal
model = openmc.Model()
...
# Convert model to multigroup (will auto-generate MGXS library if needed)
model.convert_to_multigroup()
# Convert model to random ray and initialize random ray parameters
# to reasonable defaults based on the specifics of the geometry
model.convert_to_random_ray()
# (Optional) Overlay source region decomposition mesh to improve fidelity of the
# random ray solver. Adjust 'n' for fidelity vs runtime.
n = 100
mesh = openmc.RegularMesh()
mesh.dimension = (n, n, n)
mesh.lower_left = model.geometry.bounding_box.lower_left
mesh.upper_right = model.geometry.bounding_box.upper_right
model.settings.random_ray['source_region_meshes'] = [(mesh, [model.geometry.root_universe])]
# (Optional) Improve fidelity of the random ray solver by enabling linear sources
model.settings.random_ray['source_shape'] = 'linear'
# (Optional) Increase the number of rays/batch, to reduce uncertainty
model.settings.particles = 500
The above strategy first converts the continuous energy model to a multigroup
one using the :meth:`openmc.Model.convert_to_multigroup` method. By default,
this will internally run a coarsely converged continuous energy Monte Carlo
simulation to produce an estimated multigroup macroscopic cross section set for
each material specified in the model, and store this data into a multigroup
cross section library file (``mgxs.h5``) that can be used by the random ray
solver.
The :meth:`openmc.Model.convert_to_random_ray` method enables random ray mode
and performs an analysis of the model geometry to determine reasonable values
for all required parameters. If default behavior is not satisfactory, the user
can manually adjust the settings in the :attr:`~openmc.Settings.random_ray`
dictionary in the :class:`openmc.Settings` as described in the sections below.
Finally a few optional steps are shown. The first (recommended) step overlays a
mesh over the geometry to create smaller source regions so that source
resolution improves and the random ray solver becomes more accurate. Varying the
mesh resolution can be used to trade off between accuracy and runtime.
High-fidelity fission reactor simulation may require source region sizes below 1
cm, while larger fixed source problems with some tolerance for error may be able
to use source regions of 10 or 100 cm.
We also enable linear sources, which can improve the accuracy of the random ray
solver and/or allow for a much coarser mesh resolution to be overlaid. Finally,
the number of rays per batch is adjusted. The goal here is to ensure that the
source region miss rate is below 1%, which is reported by OpenMC at the end of
the simulation (or before via a warning if it is very high).
.. warning::
If using a mesh filter for tallying or weight window generation, ensure that
the same mesh is used for source region decomposition via
``model.settings.random_ray['source_region_meshes']``.
------------------------
Enabling Random Ray Mode
------------------------
@ -443,6 +513,7 @@ Supported scores:
- total
- fission
- nu-fission
- kappa-fission
- events
Supported Estimators:
@ -557,29 +628,160 @@ variety of problem types (or through a multidimensional parameter sweep of
design variables) with only modest errors and at greatly reduced cost as
compared to using only continuous energy Monte Carlo.
~~~~~~~~~~~~
The Easy Way
~~~~~~~~~~~~
The easiest way to generate a multigroup cross section library is to use the
:meth:`openmc.Model.convert_to_multigroup` method. This method will
automatically output a multigroup cross section library file (``mgxs.h5``) from
a continuous energy Monte Carlo model and alter the material definitions in the
model to use these multigroup cross sections. An example is given below::
# Assume we already have a working continuous energy model
model.convert_to_multigroup(
method="material_wise",
groups="CASMO-2",
nparticles=2000,
overwrite_mgxs_library=False,
mgxs_path="mgxs.h5",
correction=None,
source_energy=None,
temperatures=None,
temperature_settings=None
)
The most important parameter to set is the ``method`` parameter, which can be
either "stochastic_slab", "material_wise", or "infinite_medium". An overview
of these methods is given below:
.. list-table:: Comparison of Automatic MGXS Generation Methods
:header-rows: 1
:widths: 10 30 30 30
* - Method
- Description
- Pros
- Cons
* - ``material_wise`` (default)
- * Higher Fidelity
* Runs a CE simulation with the original geometry and source, tallying
cross sections with a material filter.
- * Typically the most accurate of the three methods
* Accurately captures (averaged over the full problem domain)
both spatial and resonance self shielding effects
- * Potentially slower as the full geometry must be run
* If a material is only present far from the source and doesn't get tallied
to in the CE simulation, the MGXS will be zero for that material.
* - ``stochastic_slab``
- * Medium Fidelity
* Runs a CE simulation with a greatly simplified geometry, where materials
are randomly assigned to layers in a 1D "stochastic slab sandwich" geometry
- * Still captures resonant self shielding and resonance effects between materials
* Fast due to the simplified geometry
* Able to produce cross section data for all materials, regardless of how
far they are from the source in the original geometry
- * Does not capture most spatial self shielding effects, e.g., no lattice physics.
* - ``infinite_medium``
- * Lower Fidelity
* Runs one CE simulation per material independently. Each simulation is just
an infinite medium slowing down problem, with an assumed external source term.
- * Simple
- * Poor accuracy (no spatial information, no lattice physics, no resonance effects
between materials)
* May hang if a material has a k-infinity greater than 1.0
When selecting a non-default energy group structure, you can manually define
group boundaries or specify the name of a known group structure (a list of which
can be found at :data:`openmc.mgxs.GROUP_STRUCTURES`). The ``nparticles``
parameter can be adjusted upward to improve the fidelity of the generated cross
section library. The ``correction`` parameter can be set to ``"P0"`` to enable
P0 transport correction. The ``overwrite_mgxs_library`` parameter can be set to
``True`` to overwrite an existing MGXS library file, or ``False`` to skip
generation and use an existing library file.
.. note::
MGXS transport correction (via setting the ``correction`` parameter in the
:meth:`openmc.Model.convert_to_multigroup` method to ``"P0"``) may
result in negative in-group scattering cross sections, which can cause
numerical instability. To mitigate this, during a random ray solve OpenMC
will automatically apply
`diagonal stabilization <https://doi.org/10.1016/j.anucene.2018.10.036>`_
with a :math:`\rho` default value of 1.0, which can be adjusted with the
``settings.random_ray['diagonal_stabilization_rho']`` parameter.
When generating MGXS data with either the ``stochastic_slab`` or
``infinite_medium`` methods, by default the simulation will use a uniform source
distribution spread evenly over all energy groups. This ensures that all energy
groups receive tallies and therefore produce non-zero total multigroup cross
sections. Additionally, the function will convert any sources in the model into
simplified spatial sources that retain the original energy distributions. If
sources are present, they will be used 99% of the time to sample source energies
during MGXS generation. The other 1% of the time, energies will be sampled
uniformly over all energy groups to ensure that all groups receive some tallies.
However, the user may wish to specify a different source energy spectrum (for
instance, if they are using a FileSource, such that the energy distribution
cannot be extracted from the python source object). This can be done by
providing a :class:`openmc.stats.Univariate` distribution as the
``source_energy`` parameter of the :meth:`openmc.Model.convert_to_multigroup`
method. If provided, it will override any sources present in the model and will
be used 99% of the time to sample source energies during MGXS generation. The
other 1% of the time, energies will be sampled uniformly over all energy groups
to ensure that all groups receive some tallies.
For instance, a D-D fusion simulation may involve a complex file source. In this
case, the user may wish to provide a discrete 2.45 MeV energy source
distribution for MGXS generation as::
source_energy = openmc.stats.delta_function(2.45e6)
The ``temperatures`` parameter can be provided if temperature-dependent
multi-group cross sections are desired for multi-physics simulations. An
individual cross section generation calculation is run for each temperature
provided, where the materials in the model are set to the temperature. The
temperature settings used during cross section generation can be specified with the
``temperature_settings`` parameter. If no ``temperature_settings`` are provided,
the settings contained in the model will be used. The valid keys and values in the
``temperature_settings`` dictionary are identical to
:attr:`openmc.Settings.temperature_settings`; more information can be found in
:class:`openmc.Settings` . This approach yields isothermal cross section interpolation
tables, which can be inaccurate for systems with large differences between temperatures
in each material (often the case in fission reactors). If a more sophisticated
temperature-dependence is required, we recommend generating cross sections manually.
Ultimately, the methods described above are all just approximations.
Approximations in the generated MGXS data will fundamentally limit the potential
accuracy of the random ray solver. However, the methods described above are all
useful in that they can provide a good starting point for a random ray
simulation, and if more fidelity is needed the user may wish to follow the
instructions below or experiment with transport correction techniques to improve
the fidelity of the generated MGXS data.
~~~~~~~~~~~~
The Hard Way
~~~~~~~~~~~~
We give here a quick summary of how to produce a multigroup cross section data
file (``mgxs.h5``) from a starting point of a typical continuous energy Monte
Carlo input file. Notably, continuous energy input files define materials as a
mixture of nuclides with different densities, whereas multigroup materials are
simply defined by which name they correspond to in a ``mgxs.h5`` library file.
Carlo model. Notably, continuous energy models define materials as a mixture of
nuclides with different densities, whereas multigroup materials are simply
defined by which name they correspond to in a ``mgxs.h5`` library file.
To generate the cross section data, we begin with a continuous energy Monte
Carlo input deck and add in the required tallies that will be needed to generate
our library. In this example, we will specify material-wise cross sections and a
two group energy decomposition::
Carlo model and add in the tallies that are needed to generate our library. In
this example, we will specify material-wise cross sections and a two-group
energy decomposition::
# Define geometry
...
...
geometry = openmc.Geometry()
...
...
# Initialize MGXS library with a finished OpenMC geometry object
mgxs_lib = openmc.mgxs.Library(geometry)
# Pick energy group structure
groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES['CASMO-2'])
groups = openmc.mgxs.EnergyGroups('CASMO-2')
mgxs_lib.energy_groups = groups
# Disable transport correction
@ -587,7 +789,7 @@ two group energy decomposition::
# Specify needed cross sections for random ray
mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission', 'fission',
'nu-scatter matrix', 'multiplicity matrix', 'chi']
'nu-scatter matrix', 'multiplicity matrix', 'chi']
# Specify a "cell" domain type for the cross section tally filters
mgxs_lib.domain_type = "material"
@ -606,7 +808,7 @@ two group energy decomposition::
# Create a "tallies.xml" file for the MGXS Library
tallies = openmc.Tallies()
mgxs_lib.add_to_tallies_file(tallies, merge=True)
mgxs_lib.add_to_tallies(tallies, merge=True)
# Export
tallies.export_to_xml()
@ -614,13 +816,13 @@ two group energy decomposition::
...
When selecting an energy decomposition, you can manually define group boundaries
or pick out a group structure already known to OpenMC (a list of which can be
found at :class:`openmc.mgxs.GROUP_STRUCTURES`). Once the above input deck has
been run, the resulting statepoint file will contain the needed flux and
reaction rate tally data so that a MGXS library file can be generated. Below is
the postprocessing script needed to generate the ``mgxs.h5`` library file given
a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
``summary.h5``) that resulted from running our previous example::
or specify the name of known group structure (a list of which can be found at
:data:`openmc.mgxs.GROUP_STRUCTURES`). Once the above model has been run, the
resulting statepoint file will contain the needed flux and reaction rate tally
data so that a MGXS library file can be generated. Below is the postprocessing
script needed to generate the ``mgxs.h5`` library file given a statepoint file
(e.g., ``statepoint.100.h5``) file and summary file (e.g., ``summary.h5``) that
resulted from running our previous example::
import openmc
@ -628,10 +830,7 @@ a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
geom = summary.geometry
mats = summary.materials
statepoint_filename = 'statepoint.100.h5'
sp = openmc.StatePoint(statepoint_filename)
groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES['CASMO-2'])
groups = openmc.mgxs.EnergyGroups('CASMO-2')
mgxs_lib = openmc.mgxs.Library(geom)
mgxs_lib.energy_groups = groups
mgxs_lib.correction = None
@ -653,10 +852,10 @@ a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
# Construct all tallies needed for the multi-group cross section library
mgxs_lib.build_library()
mgxs_lib.load_from_statepoint(sp)
with openmc.StatePoint('statepoint.100.h5') as sp:
mgxs_lib.load_from_statepoint(sp)
names = []
for mat in mgxs_lib.domains: names.append(mat.name)
names = [mat.name for mat in mgxs_lib.domains]
# Create a MGXS File which can then be written to disk
mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=names)
@ -665,8 +864,8 @@ a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
mgxs_file.export_to_hdf5("mgxs.h5")
Notably, the postprocessing script needs to match the same
:class:`openmc.mgxs.Library` settings that were used to generate the tallies,
but otherwise is able to discern the rest of the simulation details from the
:class:`openmc.mgxs.Library` settings that were used to generate the tallies but
is otherwise able to discern the rest of the simulation details from the
statepoint and summary files. Once the postprocessing script is successfully
run, the ``mgxs.h5`` file can be loaded by subsequent runs of OpenMC.
@ -701,11 +900,11 @@ multigroup library instead of defining their isotopic contents, as::
water_data = openmc.Macroscopic('Hot borated water')
# Instantiate some Materials and register the appropriate Macroscopic objects
fuel= openmc.Material(name='UO2 (2.4%)')
fuel = openmc.Material(name='UO2 (2.4%)')
fuel.set_density('macro', 1.0)
fuel.add_macroscopic(fuel_data)
water= openmc.Material(name='Hot borated water')
water = openmc.Material(name='Hot borated water')
water.set_density('macro', 1.0)
water.add_macroscopic(water_data)
@ -745,6 +944,8 @@ as::
which will greatly improve the quality of the linear source term in 2D
simulations.
.. _usersguide_random_ray_run_modes:
---------------------------------
Fixed Source and Eigenvalue Modes
---------------------------------
@ -763,9 +964,12 @@ Monte Carlo solver.
Currently, all of the following conditions must be met for the particle source
to be valid in random ray mode:
- One or more domain ids must be specified that indicate which cells, universes,
or materials the source applies to. This implicitly limits the source type to
being volumetric. This is specified via the ``domains`` constraint placed on the
- Either a point source must be used, or a domain constraint must be specified
that indicates which cells, universes, or materials the source applies to. In
either case, this implicitly limits the source type to being volumetric, as
even in the point source case the source will be "smeared" throughout the
source region that contains the point source coordinate. A source domain is
specified via the ``domains`` constraint placed on the
:class:`openmc.IndependentSource` Python class.
- The source must be isotropic (default for a source)
- The source must use a discrete (i.e., multigroup) energy distribution. The
@ -871,22 +1075,52 @@ The adjoint flux random ray solver mode can be enabled as::
settings.random_ray['adjoint'] = True
When enabled, OpenMC will first run a forward transport simulation followed by
an adjoint transport simulation. The purpose of the forward solve is to compute
the adjoint external source when an external source is present in the
simulation. Simulation settings (e.g., number of rays, batches, etc.) will be
identical for both simulations. At the conclusion of the run, all results (e.g.,
tallies, plots, etc.) will be derived from the adjoint flux rather than the
forward flux but are not labeled any differently. The initial forward flux
solution will not be stored or available in the final statepoint file. Those
wishing to do analysis requiring both the forward and adjoint solutions will
need to run two separate simulations and load both statepoint files.
When enabled, OpenMC will first run a forward transport simulation if there are
no user-specified adjoint sources present, followed by an adjoint transport
simulation. Fixed adjoint sources can be specified on the
:attr:`openmc.Settings.random_ray` dictionary as follows::
# Geometry definition
...
detector_cell = openmc.Cell(fill=detector_mat, name='cell where detector will be')
...
# Define fixed adjoint neutron source
strengths = [1.0]
midpoints = [1.0e-4]
energy_distribution = openmc.stats.Discrete(x=midpoints, p=strengths)
adj_source = openmc.IndependentSource(
energy=energy_distribution,
constraints={'domains': [detector_cell]}
)
# Add to random_ray dict
settings.random_ray['adjoint_source'] = adj_source
The same constraints apply to the user-defined adjoint source as to the forward
source, described in the :ref:`Fixed Source and Eigenvalue section
<usersguide_random_ray_run_modes>`. If this source is not provided, a forward
solve must take place to compute the adjoint external source when a forward
external source is present in the problem. Simulation settings (e.g., number of
rays, batches, etc.) will be identical for both calculations. At the
conclusion of the run, all results (e.g., tallies, plots, etc.) will be
derived from the adjoint flux rather than the forward flux but are not labeled
any differently. When an initial forward solve is performed (i.e., when no
user-specified adjoint source is present), its output files are also written to
disk with a ``forward`` infix, so they are not overwritten by the subsequent
adjoint solve. This applies to the statepoint, ``tallies.out``, and any voxel
plots, e.g., ``statepoint.forward.N.h5`` and ``tallies.forward.out``; the
adjoint solve keeps the usual file names. This allows analyses requiring both
the forward and adjoint solutions to be performed from a single run. When
generating FW-CADIS weight windows, no weight window file is written for the
forward solve, as only the final adjoint-derived weight windows are meaningful.
.. note::
When adjoint mode is selected, OpenMC will always perform a full forward
solve and then run a full adjoint solve immediately afterwards. Statepoint
and tally results will be derived from the adjoint flux, but will not be
labeled any differently.
Use of the automated
:ref:`FW-CADIS weight window generator<usersguide_fw_cadis>` is not
currently compatible with user-defined adjoint sources. Instead, the
initial forward calculation is used to assign "forward-weighted" adjoint
sources to the tally regions of interest.
---------------------------------------
Putting it All Together: Example Inputs
@ -946,11 +1180,10 @@ given below:
tallies.export_to_xml()
# Create voxel plot
plot = openmc.Plot()
plot = openmc.VoxelPlot()
plot.origin = [0, 0, 0]
plot.width = [2*pitch, 2*pitch, 1]
plot.pixels = [1000, 1000, 1]
plot.type = 'voxel'
# Instantiate a Plots collection and export to XML
plots = openmc.Plots([plot])
@ -1030,11 +1263,10 @@ given below:
tallies.export_to_xml()
# Create voxel plot
plot = openmc.Plot()
plot = openmc.VoxelPlot()
plot.origin = [0, 0, 0]
plot.width = [2*pitch, 2*pitch, 1]
plot.pixels = [1000, 1000, 1]
plot.type = 'voxel'
# Instantiate a Plots collection and export to XML
plots = openmc.Plots([plot])

View file

@ -48,6 +48,7 @@ flags:
restart file
-s, --threads N Run with *N* OpenMP threads
-t, --track Write tracks for all particles (up to max_tracks)
-q, --verbosity V Set the output verbosity to *V*
-v, --version Show version information
-h, --help Show help message

View file

@ -272,6 +272,12 @@ option::
settings.source = [src1, src2]
settings.uniform_source_sampling = True
Additionally, sampling from an :class:`openmc.IndependentSource` may be biased
for local or global variance reduction by modifying the
:attr:`~openmc.IndependentSource.bias` attribute of each of its four main
distributions. Further discussion of source biasing can be found in
:ref:`source_biasing`.
Finally, the :attr:`IndependentSource.particle` attribute can be used to
indicate the source should be composed of particles other than neutrons. For
example, the following would generate a photon source::
@ -285,6 +291,53 @@ example, the following would generate a photon source::
For a full list of all classes related to statistical distributions, see
:ref:`pythonapi_stats`.
Tokamak Plasma Sources
----------------------
For fusion applications, the :class:`openmc.TokamakSource` class provides a
native parametric neutron source for tokamak plasmas. Rather than specifying
spatial, angular, and energy distributions separately, the source is defined by
the plasma geometry (using a `Miller-style flux-surface parameterization
<https://doi.org/10.1063/1.872666>`_) and a radial emission profile. Source
sites are sampled directly from the plasma volume without rejection.
The plasma shape is described by the major radius :math:`R_0`, minor radius
:math:`a`, elongation :math:`\kappa`, triangularity :math:`\delta`, and
Shafranov shift :math:`\Delta`. The neutron birth profile is given as an
emission density :math:`S(r/a)` tabulated on a normalized minor-radius grid that
runs from 0 (magnetic axis) to 1 (last closed flux surface); only the shape of
the profile matters, since it is normalized internally. The emission density is
linearly interpolated between the supplied points and refined internally for
radial sampling. For example::
import numpy as np
r_over_a = np.linspace(0.0, 1.0, 50)
emission = (1.0 - r_over_a**2)**2 # peaked on-axis profile
source = openmc.TokamakSource(
major_radius=620.0, # cm
minor_radius=200.0, # cm
elongation=1.8,
triangularity=0.45,
shafranov_shift=10.0, # cm
r_over_a=r_over_a,
emission_density=emission,
energy=openmc.stats.muir(e0=14.08e6, m_rat=5.0, kt=20000.0),
)
settings.source = source
The ``energy`` argument accepts either a single
:class:`~openmc.stats.Univariate` distribution applied at all radii, or a
sequence with one distribution per ``r_over_a`` grid point to model a
radially-varying neutron spectrum (energies are then sampled by stochastic
interpolation between the two distributions bracketing the sampled radius). A
time distribution can be given with the ``time`` argument; by default, particles
are born at :math:`t=0`. The toroidal extent can be restricted with
``phi_start`` and ``phi_extent`` to model a sector of the plasma, and
``vertical_shift`` translates the plasma center along the z-axis.
File-based Sources
------------------
@ -394,7 +447,7 @@ below.
{
openmc::SourceSite particle;
// weight
particle.particle = openmc::ParticleType::neutron;
particle.particle = openmc::ParticleType::neutron();
particle.wgt = 1.0;
// position
double angle = 2.0 * M_PI * openmc::prn(seed);
@ -471,7 +524,7 @@ parameters to the source class when it is created:
{
openmc::SourceSite particle;
// weight
particle.particle = openmc::ParticleType::neutron;
particle.particle = openmc::ParticleType::neutron();
particle.wgt = 1.0;
// position
particle.r.x = 0.0;
@ -598,6 +651,13 @@ transport::
settings.photon_transport = True
Atomic relaxation (the cascade of fluorescence photons and Auger electrons
emitted when an inner-shell vacancy is filled) is enabled by default whenever
photon transport is on. It can be disabled using the
:attr:`Settings.atomic_relaxation` attribute::
settings.atomic_relaxation = False
The way in which OpenMC handles secondary charged particles can be specified
with the :attr:`Settings.electron_treatment` attribute. By default, the
:ref:`thick-target bremsstrahlung <ttb>` (TTB) approximation is used to generate
@ -756,6 +816,67 @@ instance, whereas the :meth:`openmc.Track.filter` method returns a new
track_files = [f"tracks_p{rank}.h5" for rank in range(32)]
openmc.Tracks.combine(track_files, "tracks.h5")
Collision Track File
---------------------
OpenMC can generate a collision track file that contains detailed collision
information (position, direction, energy, deposited energy, time, weight, cell
ID, material ID, universe ID, nuclide ZAID, particle type, particle delayed
group and particle ID) for each particle collision depending on user-defined
parameters. To invoke this feature, set the
:attr:`~openmc.Settings.collision_track` attribute as shown in this example::
settings.collision_track = {
"max_collisions": 300,
"reactions": ["(n,fission)", "(n,2n)"],
"material_ids": [1,2],
"nuclides": ["U238", "O16"],
"cell_ids": [5, 12]
}
In this example, collision track information is written to the
collision_track.h5 file at the end of the simulation. The file contains
300 recorded collisions that occurred in materials with IDs 1 or 2, involving
fission or (n,2n) reactions on the nuclides U-238 or O-16, within cells
with IDs 5 and 12.
.. note::
Electron and positron collision-track events are not associated with a
specific nuclide. If a ``nuclides`` entry is specified, these events are omitted.
The file can be read using :func:`openmc.read_collision_track_file`.
The example below shows how to extract the data from the collision_track
feature and displays the fields stored in the file:
>>> data = openmc.read_collision_track_file('collision_track.h5')
>>> data.dtype
dtype([('r', [('x', '<f8'), ('y', '<f8'), ('z', '<f8')]),
('u', [('x', '<f8'), ('y', '<f8'), ('z', '<f8')]), ('E', '<f8'),
('dE', '<f8'), ('time', '<f8'), ('wgt', '<f8'), ('event_mt', '<i4'),
('delayed_group', '<i4'), ('cell_id', '<i4'), ('nuclide_id', '<i4'),
('material_id', '<i4'), ('universe_id', '<i4'), ('n_collision', '<i4'),
('particle', '<i4'), ('parent_id', '<i8'), ('progeny_id', '<i8')])
The full list of fields is as follows:
:r: Position (each direction in [cm])
:u: Direction
:E: Energy in [eV]
:dE: Energy deposited during collision in [eV]
:time: Time in [s]
:wgt: Weight of the particle
:event_mt: Reaction MT number
:delayed_group: Delayed group of the particle
:cell_id: Cell ID
:nuclide_id: Nuclide ID (10000×Z + 10×A + M)
:material_id: Material ID
:universe_id: Universe ID
:n_collision: Number of collision suffered by the particle
:particle: Particle type
:parent_id: Source particle ID
:progeny_id: Progeny ID
-----------------------
Restarting a Simulation
-----------------------

View file

@ -105,109 +105,124 @@ The following tables show all valid scores:
.. table:: **Reaction scores: units are reactions per source particle.**
+----------------------+---------------------------------------------------+
|Score | Description |
+======================+===================================================+
|absorption |Total absorption rate. For incident neutrons, this |
| |accounts for all reactions that do not produce |
| |secondary neutrons as well as fission. For incident|
| |photons, this includes photoelectric and pair |
| |production. |
+----------------------+---------------------------------------------------+
|elastic |Elastic scattering reaction rate. |
+----------------------+---------------------------------------------------+
|fission |Total fission reaction rate. |
+----------------------+---------------------------------------------------+
|scatter |Total scattering rate. |
+----------------------+---------------------------------------------------+
|total |Total reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2nd) |(n,2nd) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2n) |(n,2n) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,3n) |(n,3n) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,np) |(n,np) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,nd) |(n,nd) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,nt) |(n,nt) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,n3He) |(n,n\ :sup:`3`\ He) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,4n) |(n,4n) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2np) |(n,2np) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,3np) |(n,3np) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,n2p) |(n,n2p) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,n*X*) |Level inelastic scattering reaction rate. The *X* |
| |indicates what which inelastic level, e.g., (n,n3) |
| |is third-level inelastic scattering. |
+----------------------+---------------------------------------------------+
|(n,nc) |Continuum level inelastic scattering reaction rate.|
+----------------------+---------------------------------------------------+
|(n,gamma) |Radiative capture reaction rate. |
+----------------------+---------------------------------------------------+
|(n,p) |(n,p) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,d) |(n,d) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,t) |(n,t) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,3He) |(n,\ :sup:`3`\ He) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,2p) |(n,2p) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,pd) |(n,pd) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,pt) |(n,pt) reaction rate. |
+----------------------+---------------------------------------------------+
|(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. |
+----------------------+---------------------------------------------------+
|coherent-scatter |Coherent (Rayleigh) scattering reaction rate. |
+----------------------+---------------------------------------------------+
|incoherent-scatter |Incoherent (Compton) scattering reaction rate. |
+----------------------+---------------------------------------------------+
|photoelectric |Photoelectric absorption reaction rate. |
+----------------------+---------------------------------------------------+
|pair-production |Pair production reaction rate. |
+----------------------+---------------------------------------------------+
|*Arbitrary integer* |An arbitrary integer is interpreted to mean the |
| |reaction rate for a reaction with a given ENDF MT |
| |number. |
+----------------------+---------------------------------------------------+
+------------------------+-------------------------------------------------+
|Score |Description |
+========================+=================================================+
|absorption |Total absorption rate. For incident neutrons, |
| |this accounts for all reactions that do not |
| |produce secondary neutrons as well as fission. |
| |For incident photons, this includes |
| |photoelectric and pair production. |
+------------------------+-------------------------------------------------+
|elastic |Elastic scattering reaction rate. |
+------------------------+-------------------------------------------------+
|fission |Total fission reaction rate. |
+------------------------+-------------------------------------------------+
|scatter |Total scattering rate. |
+------------------------+-------------------------------------------------+
|total |Total reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2nd) |(n,2nd) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2n) |(n,2n) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,3n) |(n,3n) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,na) |(n,n\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,n3a) |(n,n3\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2na) |(n,2n\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,3na) |(n,3n\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,np) |(n,np) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,n2a) |(n,n2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2n2a) |(n,2n2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,nd) |(n,nd) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,nt) |(n,nt) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,n3He) |(n,n\ :sup:`3`\ He) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,nd2a) |(n,nd2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,nt2a) |(n,nt2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,4n) |(n,4n) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2np) |(n,2np) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,3np) |(n,3np) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,n2p) |(n,n2p) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,npa) |(n,np\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,n*X*) |Level inelastic scattering reaction rate. The |
| |*X* indicates which inelastic level, e.g., |
| |(n,n3) is third-level inelastic scattering. |
+------------------------+-------------------------------------------------+
|(n,nc) |Continuum level inelastic scattering |
| |reaction rate. |
+------------------------+-------------------------------------------------+
|(n,gamma) |Radiative capture reaction rate. |
+------------------------+-------------------------------------------------+
|(n,p) |(n,p) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,d) |(n,d) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,t) |(n,t) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,3He) |(n,\ :sup:`3`\ He) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,a) |(n,\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2a) |(n,2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,3a) |(n,3\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,2p) |(n,2p) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,pa) |(n,p\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,t2a) |(n,t2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,d2a) |(n,d2\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,pd) |(n,pd) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,pt) |(n,pt) reaction rate. |
+------------------------+-------------------------------------------------+
|(n,da) |(n,d\ :math:`\alpha`\ ) reaction rate. |
+------------------------+-------------------------------------------------+
|photon-total |Total photo-atomic reaction rate. |
+------------------------+-------------------------------------------------+
|coherent-scatter |Coherent (Rayleigh) scattering reaction rate. |
+------------------------+-------------------------------------------------+
|incoherent-scatter |Incoherent (Compton) scattering reaction rate. |
+------------------------+-------------------------------------------------+
|photoelectric |Photoelectric absorption reaction rate. |
+------------------------+-------------------------------------------------+
|photoelectric-*S* |Subshell photoelectric absorption rate for the |
| |*S* shell. For example, "photoelectric-N3" is the|
| |rate for the N3 subshell. |
+------------------------+-------------------------------------------------+
|pair-production |Pair production reaction rate (total). |
+------------------------+-------------------------------------------------+
|pair-production-electron|Pair production reaction rate in the electron |
| |field. |
+------------------------+-------------------------------------------------+
|pair-production-nuclear |Pair production reaction rate in the nuclear |
| |field. |
+------------------------+-------------------------------------------------+
|*Arbitrary integer* |An arbitrary integer is interpreted to mean the |
| |reaction rate for a reaction with a given ENDF |
| |MT number. |
+------------------------+-------------------------------------------------+
.. table:: **Particle production scores: units are particles produced per
source particles.**
@ -246,18 +261,21 @@ The following tables show all valid scores:
+----------------------+---------------------------------------------------+
|Score | Description |
+======================+===================================================+
|current |Used in combination with a meshsurface filter: |
|current |It may not be used in conjunction with any other |
| |score except flux. |
| | |
| |When used in combination with a meshsurface filter:|
| |Partial currents on the boundaries of each cell in |
| |a mesh. It may not be used in conjunction with any |
| |other score. Only energy and mesh filters may be |
| |used. |
| |Used in combination with a surface filter: |
| |a mesh. |
| | |
| |When used in combination with a surface filter: |
| |Net currents on any surface previously defined in |
| |the geometry. It may be used along with any other |
| |filter, except meshsurface filters. |
| |Surfaces can alternatively be defined with cell |
| |from and cell filters thereby resulting in tallying|
| |partial currents. |
| | |
| |Units are particles per source particle. |
+----------------------+---------------------------------------------------+
|events |Number of scoring events. Units are events per |
@ -322,6 +340,24 @@ The following tables show all valid scores:
| |particle. Note that this score can only be combined|
| |with a cell filter and an energy filter. |
+----------------------+---------------------------------------------------+
|ifp-time-numerator |Adjoint-weighted lifetime of neutron produced by |
| |fission in units of seconds per source particle. |
| |This score is used to compute kinetics parameters |
| |using the iterated fission probability (IFP) |
| |method. |
+----------------------+---------------------------------------------------+
|ifp-beta-numerator |Adjoint-weighted number of delayed fission events |
| |in units of number of delayed fission event per |
| |source particle. This score is used to compute |
| |kinetics parameters using the iterated fission |
| |probability (IFP) method. |
+----------------------+---------------------------------------------------+
|ifp-denominator |Weights corresponding to the number of fission |
| |events in units of number of fission event per |
| |source particle. This score is used to compute |
| |kinetics parameters using the iterated fission |
| |probability (IFP) method. |
+----------------------+---------------------------------------------------+
.. _usersguide_tally_normalization:

View file

@ -4,24 +4,27 @@
Variance Reduction
==================
Global variance reduction in OpenMC is accomplished by weight windowing
techniques. OpenMC is capable of generating weight windows using either the
MAGIC or FW-CADIS methods. Both techniques will produce a ``weight_windows.h5``
file that can be loaded and used later on. In this section, we break down the
steps required to both generate and then apply weight windows.
Global and local variance reduction are possible in OpenMC through both weight
windowing and source biasing techniques. OpenMC is capable of generating weight
windows using either the MAGIC or FW-CADIS methods, the latter with an optional
capability for local variance reduction. Both techniques will produce a
``weight_windows.h5`` file that can be loaded and used later on. In
this section, we first break down the steps required to generate and apply
weight windows, then describe how source biasing may be applied.
.. _ww_generator:
------------------------------------
Generating Weight Windows with MAGIC
------------------------------------
-------------------------------------------
Generating Global Weight Windows with MAGIC
-------------------------------------------
As discussed in the :ref:`methods section <methods_variance_reduction>`, MAGIC
is an iterative method that uses flux tally information from a Monte Carlo
simulation to produce weight windows for a user-defined mesh. While generating
the weight windows, OpenMC is capable of applying the weight windows generated
from a previous batch while processing the next batch, allowing for progressive
improvement in the weight window quality across iterations.
simulation to produce weight windows for a user-defined mesh with the objective
of global variance reduction. While generating the weight windows, OpenMC is
capable of applying the weight windows generated from a previous batch while
processing the next batch, allowing for progressive improvement in the weight
window quality across iterations.
The typical way of generating weight windows is to define a mesh and then add an
:class:`openmc.WeightWindowGenerator` object to an :attr:`openmc.Settings`
@ -51,7 +54,7 @@ With the :class:`~openmc.WeightWindowGenerator` instance added to the
:attr:`~openmc.Settings`, the rest of the problem can be defined as normal. When
running, note that the second iteration and beyond may be several orders of
magnitude slower than the first. As the weight windows are applied in each
iteration, particles may be agressively split, resulting in a large number of
iteration, particles may be aggressively split, resulting in a large number of
secondary (split) particles being generated per initial source particle. This is
not necessarily a bad thing, as the split particles are much more efficient at
exploring low flux regions of phase space as compared to initial particles.
@ -69,15 +72,20 @@ At the end of the simulation, a ``weight_windows.h5`` file will be saved to disk
for later use. Loading it in another subsequent simulation will be discussed in
the "Using Weight Windows" section below.
------------------------------------------------------
Generating Weight Windows with FW-CADIS and Random Ray
------------------------------------------------------
.. _usersguide_fw_cadis:
----------------------------------------------------------------------
Generating Global or Local Weight Windows with FW-CADIS and Random Ray
----------------------------------------------------------------------
Weight window generation with FW-CADIS and random ray in OpenMC uses the same
exact strategy as with MAGIC. An :class:`openmc.WeightWindowGenerator` object is
added to the :attr:`openmc.Settings` object, and a ``weight_windows.h5`` will be
generated at the end of the simulation. The only difference is that the code
must be run in random ray mode. A full description of how to enable and setup
exact strategy as with MAGIC. Using FW-CADIS, however, also enables
local variance reduction in fixed source problems through the :attr:`targets`
attribute, which is described later in this section. To enable FW-CADIS, an
:class:`openmc.WeightWindowGenerator` object is added to the
:attr:`openmc.Settings` object, and a ``weight_windows.h5`` will be generated
at the end of the simulation. The only procedural difference is that the code
must be run in random ray mode. A full description of how to enable and setup
random ray mode can be found in the :ref:`Random Ray User Guide <random_ray>`.
.. note::
@ -88,59 +96,111 @@ random ray mode can be found in the :ref:`Random Ray User Guide <random_ray>`.
ray solver. A high level overview of the current workflow for generation of
weight windows with FW-CADIS using random ray is given below.
1. Produce approximate multigroup cross section data (stored in a ``mgxs.h5``
library). There is more information on generating multigroup cross sections
via OpenMC in the :ref:`multigroup materials <create_mgxs>` user guide, and a
specific example of generating cross section data for use with random ray in
the :ref:`random ray MGXS guide <mgxs_gen>`.
1. Begin by making a deep copy of your continuous energy Python model and then
convert the copy to be multigroup and use the random ray transport solver.
The conversion process can largely be automated as described in more detail
in the :ref:`random ray quick start guide <quick_start>`, summarized below::
2. Make a copy of your continuous energy Python input file. You'll edit the new
file to work in multigroup mode with random ray for producing weight windows.
# Define continuous energy model
ce_model = openmc.pwr_pin_cell() # example, replace with your model
3. Adjust the material definitions in your new multigroup Python file to utilize
the multigroup cross sections instead of nuclide-wise continuous energy data.
There is a specific example of making this conversion in the :ref:`random ray
MGXS guide <mgxs_gen>`.
# Make a copy to convert to multigroup and random ray
model = copy.deepcopy(ce_model)
4. Configure OpenMC to run in random ray mode (by adding several standard random
ray input flags and settings to the :attr:`openmc.Settings.random_ray`
dictionary). More information can be found in the :ref:`Random Ray User
Guide <random_ray>`.
# Convert model to multigroup (will auto-generate MGXS library if needed)
model.convert_to_multigroup()
5. Add in a :class:`~openmc.WeightWindowGenerator` in a similar manner as for
# Convert model to random ray and initialize random ray parameters
# to reasonable defaults based on the specifics of the geometry
model.convert_to_random_ray()
# (Optional) Overlay source region decomposition mesh to improve fidelity of the
# random ray solver. Adjust 'n' for fidelity vs runtime.
n = 10
mesh = openmc.RegularMesh()
mesh.dimension = (n, n, n)
mesh.lower_left = model.geometry.bounding_box.lower_left
mesh.upper_right = model.geometry.bounding_box.upper_right
model.settings.random_ray['source_region_meshes'] = [(mesh, [model.geometry.root_universe])]
# (Optional) Improve fidelity of the random ray solver by enabling linear sources
model.settings.random_ray['source_shape'] = 'linear'
# (Optional) Increase the number of rays/batch, to reduce uncertainty
model.settings.particles = 500
If you need to improve the fidelity of the MGXS library, there is more
information on generating multigroup cross sections via OpenMC in the
:ref:`random ray MGXS guide <mgxs_gen>`.
2. Add in a :class:`~openmc.WeightWindowGenerator` in a similar manner as for
MAGIC generation with Monte Carlo and set the :attr:`method` attribute set to
``"fw_cadis"``::
# Define weight window spatial mesh
ww_mesh = openmc.RegularMesh()
ww_mesh.dimension = (10, 10, 10)
ww_mesh.lower_left = (0.0, 0.0, 0.0)
ww_mesh.upper_right = (100.0, 100.0, 100.0)
# Create weight window object and adjust parameters
# Create weight window object and adjust parameters, using the same mesh
# we used for source region decomposition
wwg = openmc.WeightWindowGenerator(
method='fw_cadis',
mesh=ww_mesh,
max_realizations=settings.batches
mesh=mesh
)
# Add generator to openmc.settings object
settings.weight_window_generators = wwg
.. warning::
If using FW-CADIS weight window generation, ensure that the selected weight
window mesh does not subdivide any source regions in the problem. This can
be ensured by assigning the weight window tally mesh to the root universe so
as to create source region boundaries that conform to the mesh, as in the
example below.
be ensured by using the same mesh for both source region subdivision (i.e.,
assigning to ``model.settings.random_ray['source_region_meshes']``) and for
weight window generation.
::
3. (Optional) If local variance reduction is desired in a fixed-source problem,
populate the :attr:`targets` attribute with an :class:`openmc.Tallies`
instance or an iterable of tally IDs indicating the tallies of interest for
variance reduction::
# Build a new example and WWG for local variance reduction
from openmc.examples import random_ray_three_region_cube_with_detectors
new_model = random_ray_three_region_cube_with_detectors()
ww_mesh = openmc.RegularMesh()
n = 7
width = 35.0
ww_mesh.dimension = (n, n, n)
ww_mesh.lower_left = (0.0, 0.0, 0.0)
ww_mesh.upper_right = (width, width, width)
wwg = openmc.WeightWindowGenerator(
method="fw_cadis",
mesh=ww_mesh,
max_realizations=new_model.settings.batches
)
new_model.settings.weight_window_generators = wwg
new_model.settings.random_ray['volume_estimator'] = 'naive'
# Get the tallies of interest
target_tallies = openmc.Tallies()
for tally in list(new_model.tallies):
if tally.name in {"Detector 1 Tally", "Detector 2 Tally"}:
target_tallies.append(tally)
root = model.geometry.root_universe
settings.random_ray['source_region_meshes'] = [(ww_mesh, [root])]
# Add to WeightWindowGenerator
wwg.targets = target_tallies
6. When running your multigroup random ray input deck, OpenMC will automatically
.. warning::
The tallies designated as FW-CADIS targets to the
:class:`~openmc.WeightWindowGenerator` must be present under the
:class:`~openmc.model.Model.tallies` attribute of the
:class:`~openmc.model.Model` as well in order to be recognized as valid
local variance reduction targets. This check is performed when the
:func:`openmc.model.Model.export_to_model_xml` or
:func:`openmc.model.Model.export_to_xml` functions are called, meaning
that the standalone :func:`openmc.Settings.export_to_xml` and
:func:`openmc.Tallies.export_to_xml` methods should not be used with
FW-CADIS local variance reduction.
4. When running your multigroup random ray input deck, OpenMC will automatically
run a forward solve followed by an adjoint solve, with a
``weight_windows.h5`` file generated at the end. The ``weight_windows.h5``
file will contain FW-CADIS generated weight windows. This file can be used in
@ -155,7 +215,7 @@ solver, the Python input just needs to load the h5 file::
settings.weight_window_checkpoints = {'collision': True, 'surface': True}
settings.survival_biasing = False
settings.weight_windows = openmc.hdf5_to_wws('weight_windows.h5')
settings.weight_windows_file = "weight_windows.h5"
settings.weight_windows_on = True
The :class:`~openmc.WeightWindowGenerator` instance is not needed to load an
@ -166,3 +226,148 @@ Weight window mesh information is embedded into the weight window file, so the
mesh does not need to be redefined. Monte Carlo solves that load a weight window
file as above will utilize weight windows to reduce the variance of the
simulation.
.. _source_biasing:
--------------
Source Biasing
--------------
In fixed source problems, source biasing provides a means to reduce the variance
on global or localized responses, depending on the biasing scheme. In either
case, the premise of the method is to sample source sites from a biased
distribution that directs a larger fraction of the simulated histories towards
phase space regions of interest than would be found there under analog sampling.
In order to preserve an unbiased estimate of the tally mean, the weight of these
with analog sampling, divided by the probability assigned by the biased
distribution. While the assignment of statistical weights is outlined in the
:ref:`methods section <methods_source_biasing>`, this section demonstrates the
implementation of source biasing to problems in OpenMC.
Source biasing in OpenMC is accomplished by applying a distribution to the
:attr:`bias` attribute of one or more of the univariate or independent
multivariate distributions which make up an :class:`~openmc.IndependentSource`
instance as follows::
# First create the biased distribution
biased_dist = openmc.stats.PowerLaw(a=0, b=3, n=3)
# Construct a new distribution with the bias applied
dist = openmc.stats.PowerLaw(a=0, b=3, n=2, bias=biased_dist)
# The bias attribute can also be set on an existing "analog" distribution:
sphere_dist = openmc.stats.spherical_uniform(r_outer=3)
sphere_dist.r.bias = biased_dist
Univariate distributions may be sampled via the Python API, returning the
sample(s) along with the associated weight(s)::
sample_vec, wgt_vec = dist.sample(n_samples=100)
Here, if the distribution is unbiased, the weight of each sample will be unity.
Finally, :class:`~openmc.IndependentSource` instances can be constructed with
biased distributions::
# Create a source with a biased spatial distribution
source = openmc.IndependentSource(space=sphere_dist)
During the simulation, source sites are then sampled using the biased
distributions where available and given starting statistical weights
corresponding to the cumulative product of the weights assigned by each
distribution in the source object. Hence multiple source variables (e.g.,
direction and energy) may be biased and the resulting source sites will have
their weights adjusted accordingly.
.. note::
Combining source biasing with weight windows can be a powerful variance
reduction technique if each is constructed appropriately for the response
of interest. For example, if a source biasing scheme is devised for
variance reduction of a specific localized response, the user may be able
to specify their own weight window structure that results in more efficient
transport than if weight windows were generated by either of OpenMC's
automatic weight window generators, which are intended for global variance
reduction.
Biased distributions that could result in degenerate weight mappings are not
recommended; this is most commonly seen when biasing the :math:`\phi`-coordinate
of spherical or cylindrical independent multivariate distributions. In such
cases degenerate behavior will be observed at the pole about which :math:`\phi`
is measured, with all values of :math:`\phi` (hence many possible statistical
weights) mapping to the same point for :math:`r=0` or :math:`\mu=0`, and large
weight gradients in the vicinity. In most cases requiring a spherical
independent source, it would be preferable to reorient the reference vector of
the distribution such that biasing could be applied to the
:math:`\mu`-coordinate instead.
When biasing a distribution, care should also be taken to ensure that both the
unbiased and biased distribution share a common support---that is, every region
of phase space mapped to a nonzero probability density by the unbiased
distribution should likewise map to nonzero probability under the biased
distribution, and vice versa. In OpenMC, this places restrictions on the set of
compatible distributions that may be used to bias sampling of each distribution
type. The following table summarizes the method for each distribution in OpenMC
that permits biased sampling.
.. list-table:: **Distributions that support biased sampling**
:header-rows: 1
:widths: 35 65
* - Discrete Univariate PDFs
- Biasing Method
* - :class:`openmc.stats.Discrete`
- Apply a vector of alternative probabilities to the :attr:`bias`
attribute
.. list-table::
:header-rows: 1
:widths: 35 65
* - Continuous Univariate PDFs
- Biasing Method
* - :class:`openmc.stats.Uniform`,
:class:`openmc.stats.PowerLaw`,
:class:`openmc.stats.Maxwell`,
:class:`openmc.stats.Watt`,
:class:`openmc.stats.Normal`,
:class:`openmc.stats.Tabular`
- Apply a second, unbiased continous univariate PDF to the :attr:`bias`
attribute, ensuring that the :attr:`support` attribute of each
distribution is the same
.. list-table::
:header-rows: 1
:widths: 35 65
* - Mixed Univariate PDFs
- Biasing Method
* - :class:`openmc.stats.Mixture`
- May be constructed from multiple biased univariate distributions, or a
second, unbiased continous univariate PDF may be applied to the
:attr:`bias` attribute
.. list-table::
:header-rows: 1
:widths: 35 65
* - Discrete Multivariate PDFs
- Biasing Method
* - :class:`openmc.stats.PointCloud`,
:class:`openmc.stats.MeshSpatial`
- Apply a vector of the new relative probabilities of each point or mesh
element under biased sampling to the :attr:`bias` attribute
.. list-table::
:header-rows: 1
:widths: 35 65
* - Continuous Multivariate PDFs
- Biasing Method
* - :class:`openmc.stats.CartesianIndependent`,
:class:`openmc.stats.CylindricalIndependent`,
:class:`openmc.stats.SphericalIndependent`,
:class:`openmc.stats.PolarAzimuthal`
- Construct from biased univariate distributions for :attr:`x`, :attr:`y`,
:attr:`z`, etc.
* - :class:`openmc.stats.Isotropic`
- Apply an unbiased :class:`openmc.stats.PolarAzimuthal` to the
:attr:`bias` attribute

View file

@ -1,17 +1,17 @@
#include <cmath> // for M_PI
#define _USE_MATH_DEFINES
#include <cmath> // for M_PI
#include <memory> // for unique_ptr
#include "openmc/particle.h"
#include "openmc/random_lcg.h"
#include "openmc/source.h"
#include "openmc/particle.h"
class RingSource : public openmc::Source
{
class RingSource : public openmc::Source {
openmc::SourceSite sample(uint64_t* seed) const
{
openmc::SourceSite particle;
// particle type
particle.particle = openmc::ParticleType::neutron;
particle.particle = openmc::ParticleType::neutron();
// position
double angle = 2.0 * M_PI * openmc::prn(seed);
double radius = 3.0;
@ -25,10 +25,11 @@ class RingSource : public openmc::Source
}
};
// A function to create a unique pointer to an instance of this class when generated
// via a plugin call using dlopen/dlsym.
// You must have external C linkage here otherwise dlopen will not find the file
extern "C" std::unique_ptr<RingSource> openmc_create_source(std::string parameters)
// A function to create a unique pointer to an instance of this class when
// generated via a plugin call using dlopen/dlsym. You must have external C
// linkage here otherwise dlopen will not find the file
extern "C" std::unique_ptr<RingSource> openmc_create_source(
std::string parameters)
{
return std::make_unique<RingSource>();
}

View file

@ -128,14 +128,14 @@ settings_file.export_to_xml()
# Exporting to OpenMC plots.xml file
###############################################################################
plot_xy = openmc.Plot(plot_id=1)
plot_xy = openmc.SlicePlot(plot_id=1)
plot_xy.filename = 'plot_xy'
plot_xy.origin = [0, 0, 0]
plot_xy.width = [6, 6]
plot_xy.pixels = [400, 400]
plot_xy.color_by = 'material'
plot_yz = openmc.Plot(plot_id=2)
plot_yz = openmc.SlicePlot(plot_id=2)
plot_yz.filename = 'plot_yz'
plot_yz.basis = 'yz'
plot_yz.origin = [0, 0, 0]

Some files were not shown because too many files have changed in this diff Show more