Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
c79ef14
Squash delta tracking commits.
nuclearkevin Feb 28, 2026
169ae84
Fix non-vacuum BCs.
nuclearkevin May 18, 2026
0b0fa73
Make non-vacuum BCs more robust.
nuclearkevin May 19, 2026
f457665
Allow for the import of majorant cross sections from CSV files.
nuclearkevin May 22, 2026
bf22543
Missing setting.
nuclearkevin May 22, 2026
62ad66f
Turn ptable sampling on for delta tracking.
nuclearkevin May 23, 2026
8f8abf3
Begin majorant refactor.
nuclearkevin May 26, 2026
9180237
Finish the "new" majorant implementation.
nuclearkevin May 27, 2026
55c4894
Better error messages.
nuclearkevin May 27, 2026
57dc600
Fix issues with URR cross sections. Make error messages better
nuclearkevin May 27, 2026
f14c647
Prep for photon majorants.
nuclearkevin May 27, 2026
039b0d3
Photon majorants & delta tracking for photon transport.
nuclearkevin May 28, 2026
6315c2a
Errors for settings unsupported by delta tracking (for now).
nuclearkevin May 28, 2026
8ad35d3
Compute majorants for all materials contained in a universe.
nuclearkevin May 29, 2026
24a9fb1
Fix delta tracking photon loop.
nuclearkevin May 29, 2026
4ab17a0
Minor changes.
nuclearkevin May 29, 2026
d4aa6f2
Fix bug with universe majorants & reset majorants when finalizing a s…
nuclearkevin May 30, 2026
fe55fd6
Support distrib densities.
nuclearkevin May 30, 2026
fcaa20f
Rename delta tracking functions.
nuclearkevin May 30, 2026
cbf4b8e
Support delta tracking with a shared secondary bank.
nuclearkevin May 30, 2026
ad9b9c5
Remove CSV majorant cross sections.
nuclearkevin Jun 1, 2026
3e438c2
Revert to most conservative URR treatment.
nuclearkevin Jun 1, 2026
598d9c5
Honestly, I don't know anymore...
nuclearkevin Jun 2, 2026
6fa8d09
Refactor history-based delta tracking to prepare for event-based.
nuclearkevin Jun 2, 2026
903a676
First cut of event-based transport. Works for neutrons
nuclearkevin Jun 2, 2026
12522db
Fixes for event-based delta tracking photon transport.
nuclearkevin Jun 3, 2026
6ace8a9
More shuffling, add some extra division comments.
nuclearkevin Jun 3, 2026
97ab572
Remove unnecessary cross section calculation event on particle initia…
nuclearkevin Jun 3, 2026
8e16bba
Forgot the coord reset.
nuclearkevin Jun 3, 2026
0c1508c
Use FP_REL_PRECISION when advancing to boundaries.
nuclearkevin Jun 4, 2026
b6d567f
Fix grid lookup.
nuclearkevin Jun 4, 2026
f8e7143
Fix majorants, again...
nuclearkevin Jun 4, 2026
071d613
Remove unused code.
nuclearkevin Jun 8, 2026
34bf3f9
More cleanup.
nuclearkevin Jun 8, 2026
c966bf9
More cleanup.
nuclearkevin Jun 8, 2026
80fe9ba
URR fix.
nuclearkevin Jun 8, 2026
341431d
Have majorants conform to OpenMC's indexing approach. Also add a time…
nuclearkevin Jun 8, 2026
9f5da74
Remove ascii file writes.
nuclearkevin Jun 8, 2026
d8957f1
Pretty formatting.
nuclearkevin Jun 8, 2026
3685d2b
Restrict delta tracking tallies to collision estimators.
nuclearkevin Jun 10, 2026
c703da4
Remove unnecessary coord reset.
nuclearkevin Jun 10, 2026
5db41fb
Clean up combined estimate for k.
nuclearkevin Jun 10, 2026
d44c720
Clean up majorant and remove random duplicate code.
nuclearkevin Jun 10, 2026
928e877
Shouldn't need this going into a boundary crossing.
nuclearkevin Jun 10, 2026
2a81af2
Remove more duplicate flagging.
nuclearkevin Jun 10, 2026
0ec8d38
More cleanup.
nuclearkevin Jun 10, 2026
d4f4250
Round trip delta_tracking alongside the majorant build time in the SP.
nuclearkevin Jun 10, 2026
44f141c
Remove event limit.
nuclearkevin Jun 10, 2026
d2ced05
Delta tracking theory.
nuclearkevin Jun 11, 2026
6b76379
Test round tripping the delta tracking setting.
nuclearkevin Jun 11, 2026
25846ed
Fix distributed density majorant bug.
nuclearkevin Jun 11, 2026
c7bb7a6
More majorant fixes.
nuclearkevin Jun 11, 2026
449167b
Test for distributed densities with delta tracking.
nuclearkevin Jun 11, 2026
24f9b08
Add history-based and event-based tests with/without photons.
nuclearkevin Jun 11, 2026
fbcfdd5
Revert "Remove unnecessary coord reset."
nuclearkevin Jun 11, 2026
de6c8e3
Regold to account for coord fix.
nuclearkevin Jun 11, 2026
92bce71
Fix periodic boundary conditions.
nuclearkevin Jun 11, 2026
ef9fab3
Add tests for delta tracking boundary conditions.
nuclearkevin Jun 11, 2026
22130d2
Only need the tolerance on the translational periodic BC.
nuclearkevin Jun 12, 2026
ca484fe
Update tests to account for the removal of duplicate code & consolida…
nuclearkevin Jun 12, 2026
5b7d804
Fix gold inputs.
nuclearkevin Jun 12, 2026
344d65d
Final review.
nuclearkevin Jun 12, 2026
3b7c336
Style changes.
nuclearkevin Jun 12, 2026
f0367b1
URR grid index fix.
nuclearkevin Jun 13, 2026
c15f701
More fixes for rare bugs that happen when finding a grid index.
nuclearkevin Jun 13, 2026
68d7c4f
Catch void majorants, clean up majorant killswitch.
nuclearkevin Jun 16, 2026
5fe9d56
Build majorant in parallel with OpenMP threads.
nuclearkevin Jun 16, 2026
6190363
Style changes.
nuclearkevin Jun 16, 2026
a8ffa1e
Consistent BC tolerance application.
nuclearkevin Jun 17, 2026
daf4003
Advancing in time.
nuclearkevin Jun 17, 2026
abf3966
Catch void materials.
nuclearkevin Jun 18, 2026
20fe314
Apply more maxes to URRs.
nuclearkevin Jun 24, 2026
f57eae5
Minor improvements, document statepoint changes.
nuclearkevin Jul 6, 2026
0e26571
Apply suggestions from code review
nuclearkevin Jul 8, 2026
bd79708
Keep the linter happy.
nuclearkevin Jul 8, 2026
a56127a
Documentation.
nuclearkevin Jul 8, 2026
1b7c152
Address non-majorant review.
nuclearkevin Jul 8, 2026
12c97b9
Address majorant comments.
nuclearkevin Jul 8, 2026
2db2fa8
Formatting.
nuclearkevin Jul 8, 2026
b03e8c7
Fix copy-paste error.
nuclearkevin Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ list(APPEND libopenmc_SOURCES
src/ifp.cpp
src/initialize.cpp
src/lattice.cpp
src/majorant.cpp
src/material.cpp
src/math_functions.cpp
src/mcpl_interface.cpp
Expand Down
6 changes: 6 additions & 0 deletions docs/source/io_formats/statepoint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ The current version of the statepoint file format is 18.2.
'continuous-energy' or 'multi-group'.
- **run_mode** (*char[]*) -- Run mode used, either 'eigenvalue' or
'fixed source'.
- **photon_transport** (*bool*) -- Whether photon transport was enabled
or not.
- **delta_tracking** (*bool*) -- Whether delta tracking was enabled
or not.
- **n_particles** (*int8_t*) -- Number of particles used per generation.
- **n_batches** (*int*) -- Number of batches to simulate.
- **current_batch** (*int*) -- The number of batches already simulated.
Expand Down Expand Up @@ -178,6 +182,8 @@ All values are given in seconds and are measured on the master process.
allocating arrays, etc.
- **reading cross sections** (*double*) -- Time spent loading cross
section libraries (this is a subset of initialization).
- **build majorant** (*double*) -- Time spent constructing the majorant
cross sections. This is only saved if running with delta tracking.
- **simulation** (*double*) -- Time spent between initialization and
finalization.
- **transport** (*double*) -- Time spent transporting particles.
Expand Down
121 changes: 121 additions & 0 deletions docs/source/methods/neutron_physics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,111 @@ the formula usually used to calculate the distance to next collision is

\ell = -\frac{\ln \xi}{\Sigma_t}

.. _surface_tracking:

~~~~~~~~~~~~~~~~~~~~~~~~~
Surface Tracking
~~~~~~~~~~~~~~~~~~~~~~~~~

The development of Equation :eq:`sample-distance-2` requires the assumption
that the medium under consideration is homogeneous. To accomodate heterogeneous
geometries, a resampling scheme is used. First, the distance to the next
collision is sampled with Equation :eq:`sample-distance-2`. Then, the distance
to the nearest surface from the particle position along its current trajectory
is computed (discussed in the :ref:`methods_geometry` section). If the distance
to the nearest surface is smaller than the distance to the next collision, the
sampled distance is not statistically valid. The particle is moved to the
surface and is considered to be contained by the next geometric region. Cross
sections are recomputed, and a new distance to the next collision is sampled
with Equation :eq:`sample-distance-2`. This process repeats until the distance
to the next collision is smaller than the distance to the nearest surface,
which is when a collision is accepted. This procedure is known as surface
tracking.

Surface tracking is quite efficient when used in problems with short mean free
paths relative to the size of individual regions in the problem geometry.
Surface tracking also admits the use of the track length estimator (discussed
in the :ref:`methods_tallies` section). In problems with long mean free paths
relative to the size of geometry regions, surface tracking will require a large
number of surface distance calculations per collision. The cost of finding the
nearest surface is also non-trivial for problems that contain many geometric
regions at the same cell level (e.g. TRISO-fueled fission reactors).

.. _delta_tracking:

~~~~~~~~~~~~~~~~~~~~~~~~~
Delta Tracking
~~~~~~~~~~~~~~~~~~~~~~~~~

The disadvantages of surface tracking for certain classes of problems motivates
the development of alternative approaches which do not require distance
to surface checks. Delta tracking (also known by Woodcock tracking,
delta scattering, and null scattering) is one approach to
avoid surface geometry queries [Woodcock]_. In delta tracking, the domain is
homogenized to a majorant cross section (:math:`\Sigma_{maj}(E)`) which is
computed as the maximum total cross section over the entire problem

.. math::
:label: majorant-xs-1

\Sigma_{maj}(E) = \max_{\mathbf{r}}\left(\Sigma_{t}(\mathbf{r}, E)\right).

Particles move through this homogenized problem by sampling a distance to the
next collision with the majorant cross section instead of the total cross section

.. math::
:label: sample-distance-maj

\ell = -\frac{\ln \xi}{\Sigma_{maj}(E)}.

To recover the spatial heterogeneity present in the original simulation, the
delta tracking method formally defines the majorant cross section to be the
sum of the total cross section and a spatially-varying fictitious delta
scattering cross sections :math:`\Sigma_{\delta}(\mathbf{r}, E)`

.. math::
:label: majorant-xs-2

\Sigma_{maj}(E) = \Sigma_{t}(\mathbf{r}, E) + \Sigma_{\delta}(\mathbf{r},
E).

At the collision point computed from :eq:`sample-distance-maj` one of
two reactions could occur. The first is a real collision, which is processed
as usual. The second is known as a delta scatter event (also referred to
as a virtual or null collision), which is the reaction type associated with
:math:`\Sigma_{\delta}(\mathbf{r}, E)`. A rejection sampling test is used to
determine which collision type occurs; a random number :math:`\xi` on the
interval :math:`[0,1)` is drawn and used to check

.. math::
:label: delta-real-collision

\xi < \frac{\Sigma_t (\mathbf{r}, E)}{\Sigma_{maj} (E)}.

If the condition above is true, the collision is accepted as real. If the condition
is false, a delta scatter event has occurred and the particle continues along
its trajectory with the same energy and direction. Boundary conditions
are applied by testing the distance to the nearest external boundary and
comparing this to the distance sampled with Equation :eq:`sample-distance-maj`.
If the distance to the nearest boundary is less than the sampled distance to
the next collision, the particle crosses the external boundary.

Delta tracking is advantageous as it only requires point location checks to
determine the total cross section at each collision point to test
:eq:`delta-real-collision`. This allows for the use of continuously-varying
material properties and avoids computationally expensive distance-to-nearest-surface
calculations. Problems which contain small regions with large total
cross sections (such as burnable absorbers) will have majorant cross sections
several orders of magnitude larger than the total cross section over the majority
of the domain [Leppänen]_. This decreases the number of real collisions, and
therefore the effectiveness of delta tracking. Material discontinuities are not
considered in delta tracking, which prohibits the use of track length
estimators for quantities restricted to material/geometric subdomains (such as
reaction rates) and forces the use of the higher-variance collision
estimator (discussed in detail in the :ref:`methods_tallies` section). When compared
with surface tracking, delta tracking often performs better in problems where
the particle mean free path is larger than the distance between surfaces.

----------------------------------------------------
:math:`(n,\gamma)` and Other Disappearance Reactions
----------------------------------------------------
Expand Down Expand Up @@ -1631,6 +1736,13 @@ the unresolved range to get the actual cross sections. Lastly, the total cross
section is calculated as the sum of the elastic, fission, capture, and inelastic
cross sections.

Unresolved resonance probability tables pose a challenge when computing a majorant
cross section for :ref:`delta_tracking`. OpenMC implements a conservative approach:
the maximum total cross section is computed over all bands, which is then
interpolated to the corresponding energy using either linear or logarithmic
interpolation. This ensures the majorant bounds the total cross section at the
cost of increasing the number of delta scatters in the unresolved range.

-----------------------------
Variance Reduction Techniques
-----------------------------
Expand Down Expand Up @@ -1735,13 +1847,22 @@ types.
.. [Gelbard] Ely M. Gelbard, "Epithermal Scattering in VIM," FRA-TM-123, Argonne
National Laboratory (1979).

.. [Leppänen] J. Leppänen. "Performance of Woodcock Delta-Tracking in Lattice
Physics Applications using the Serpent Monte Carlo Reactor Physics Burnup
Calculation Code", *Annals of Nuclear Energy*, 37:715-722, 2010.

.. [Squires] G. L. Squires, *Introduction to the Theory of Thermal Neutron
Scattering*, Cambridge University Press (1978).

.. [Williams] M. M. R. Williams, *The Slowing Down and Thermalization of
Neutrons*, North-Holland Publishing Co., Amsterdam (1966). **Note:** This
book can be obtained for free from the OECD_.

.. [Woodcock] E.R. Woodcock, T. Murphy, P.J. Hemmings, and T.C. Longworth.
"Techniques used in the GEM Code for Monte Carlo Neutronics Calculations
in Reactors and other Systems of Complex Geometry", ANL-7050,
Argonne National Laboratory (1965).

.. |sab| replace:: S(:math:`\alpha,\beta,T`)

.. _SIGMA1 method: https://doi.org/10.13182/NSE76-1
Expand Down
51 changes: 46 additions & 5 deletions include/openmc/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ void free_event_queues(void);
//! \param buffer_idx The particle's actual index in the particle buffer
void dispatch_xs_event(int64_t buffer_idx);

//! Execute the death event for all particles
//
//! \param n_particles The number of particles in the particle buffer
void process_death_events(int64_t n_particles);

//==============================================================================
// Surface tracking
//==============================================================================

//! Execute the initialization event for all particles
//
//! \param n_particles The number of particles in the particle buffer
Expand All @@ -107,11 +116,6 @@ void process_surface_crossing_events();
//! Execute the collision event for all particles in this event's buffer
void process_collision_events();

//! Execute the death event for all particles
//
//! \param n_particles The number of particles in the particle buffer
void process_death_events(int64_t n_particles);

//! Process event queues until all are empty. Each iteration processes the
//! longest queue first to maximize vectorization efficiency.
void process_transport_events();
Expand All @@ -125,6 +129,43 @@ void process_transport_events();
void process_init_secondary_events(int64_t n_particles, int64_t offset,
const SharedArray<SourceSite>& shared_secondary_bank);

//==============================================================================
// Delta tracking
//==============================================================================

//! Specialization of process_init_events() for delta tracking.
//
//! \param n_particles The number of particles in the particle buffer
//! \param source_offset The offset index in the source bank to use
void process_delta_init_events(int64_t n_particles, int64_t source_offset);

//! Specialization of process_calculate_xs_events() for delta tracking.
//
//! \param queue A reference to the desired XS lookup queue
void process_delta_calculate_xs_events(SharedArray<EventQueueItem>& queue);

//! Execute the delta advance particle event for all particles in this advance
//! buffer
void process_delta_advance_particle_events();

//! Specialization of process_surface_crossing_events() for delta tracking.
void process_delta_surface_crossing_events();

//! Execute the delta tracking collision event for all particles in this event's
//! buffer
void process_delta_collision_events();

//! Specialization of process_transport_events() for delta tracking.
void process_delta_transport_events();

//! Specialization of process_init_secondary_events() for delta tracking.
//
//! \param n_particles The number of particles to initialize
//! \param offset The offset index in the shared secondary bank
//! \param shared_secondary_bank The shared secondary bank to read from
void process_delta_init_secondary_events(int64_t n_particles, int64_t offset,
const SharedArray<SourceSite>& shared_secondary_bank);

} // namespace openmc

#endif // OPENMC_EVENT_H
13 changes: 13 additions & 0 deletions include/openmc/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ namespace model {
extern int root_universe; //!< Index of root universe
extern "C" int n_coord_levels; //!< Number of CSG coordinate levels

extern vector<int> boundary_surfaces; //!< The surfaces with boundary conditions

extern vector<int64_t> overlap_check_count;

// Overlap data structures get cleared every slice_data run
Expand Down Expand Up @@ -107,10 +109,21 @@ void cross_lattice(

//==============================================================================
//! Find the next boundary a particle will intersect.
//! \param p A geometry state to compute distances with.
//! \return Boundary information corresponding to the nearest surface.
//==============================================================================

BoundaryInfo distance_to_boundary(GeometryState& p);

//==============================================================================
//! Find the next external boundary a particle will intersect.
//!
//! \param p A geometry state to compute distances with.
//! \return Boundary information corresponding to the nearest external boundary.
//==============================================================================

BoundaryInfo distance_to_external_boundary(GeometryState& p);

} // namespace openmc

#endif // OPENMC_GEOMETRY_H
Loading
Loading