Skip to content

WIP - Forced collisions variance reduction technique#407

Draft
nglaser3 wants to merge 56 commits intomcdc-project:devfrom
nglaser3:forced-collisions
Draft

WIP - Forced collisions variance reduction technique#407
nglaser3 wants to merge 56 commits intomcdc-project:devfrom
nglaser3:forced-collisions

Conversation

@nglaser3
Copy link
Copy Markdown
Member

@nglaser3 nglaser3 commented Apr 18, 2026

Summary of changes

Forced collisions can be implemented in two ways: where a particle is forced to collide only once upon entering a region of interest, or where particles are repeatedly forced to collide within the region. This PR uses the latter, as it provides better VR and was simpler to integrate into the existing transport kernel. To prevent the simulation from running forever and tracking exceedingly tiny weighted particles, weight roulette is applied within forced-collision cells.

This technique works well at reducing variance for collision estimators, but can worsen variance for tracklength and surface estimators immediately surrounding the region of interest. This is because the particle splits into collided and transmitted components, which follow different transport paths and contribute differently to these estimators.

To enable this technique, I added a few tangentially related methods. The first was a get_forced_collision_distance method to the physics interface. I also pulled out the tracklength tally scoring in simulation into a helper method and put this in tally.score as score_tracklength_tallies. Also, I made a copy_run_state helper to the particle module, as this was needed to falsify the transport step of the transmitted particle.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Organization and beautification (changes which improve readability and/or accessibility)

Developer Checklist

  • I have read the contributing guide.
  • My code follows the code style of this project.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests pass

Associated Issues and PRs

Associated Developers

@nglaser3 nglaser3 self-assigned this Apr 18, 2026
@nglaser3 nglaser3 marked this pull request as draft April 18, 2026 03:55
@nglaser3
Copy link
Copy Markdown
Member Author

nglaser3 commented Apr 18, 2026

This PR is marked as a WIP because I still need to do the following:

  • add docs, comments, and docstrings
  • add unit tests

Though I am unsure how to do the unit tests for the added technique methods at the moment, as they all rely on the geometry module in some way or another.

Additionally, this PR loosely builds off of #394, only using the generalized weight roulette method. If need be, that dependency can be ripped out, and all weight window commits can be removed

@nglaser3
Copy link
Copy Markdown
Member Author

Brief demonstration of the technique, running the added regression test and printing the results:

With forced_collisions enabled:

  __  __  ____  __ ____   ____ 
 |  \/  |/ ___|/ /_  _ \ / ___|
 | |\/| | |   /_  / | | | |    
 | |  | | |___ / /| |_| | |___ 
 |_|  |_|\____|// |____/ \____|

           Mode | Python
  MPI Processes | 1

 Now running the particle transport...

Batch 1/2
 [============================] 100%
Batch 2/2
 [============================] 100%
 Generating output HDF5 files...

 Runtime report:
   Total       | 4.52 seconds (100.0%)
   Preparation | 0.04 seconds (0.9%)
   Simulation  | 4.28 seconds (94.7%)
   Output      | 0.20 seconds (4.4%)



=== Tally Summary ===
Energy Deposition:
  Mean: 213.47281108317114
  Std Dev: 2.7570958432762374
Net-Current:
  Mean: 0.9997750099953866
  Std Dev: 2.7877519926234643e-08
Flux:
  Mean: 0.9999568360431565
  Std Dev: 3.9732841923279545e-05

and without:

  __  __  ____  __ ____   ____ 
 |  \/  |/ ___|/ /_  _ \ / ___|
 | |\/| | |   /_  / | | | |    
 | |  | | |___ / /| |_| | |___ 
 |_|  |_|\____|// |____/ \____|

           Mode | Python
  MPI Processes | 1

 Now running the particle transport...

Batch 1/2
 [============================] 100%
Batch 2/2
 [============================] 100%
 Generating output HDF5 files...

 Runtime report:
   Total       | 2.32 seconds (100.0%)
   Preparation | 0.04 seconds (1.7%)
   Simulation  | 2.07 seconds (89.4%)
   Output      | 0.20 seconds (8.8%)



=== Tally Summary ===
Energy Deposition:
  Mean: 179.97560666130664
  Std Dev: 179.97560666130664
Net-Current:
  Mean: 1.0
  Std Dev: 0.0
Flux:
  Mean: 1.0000809232288144
  Std Dev: 8.092322917668003e-05

@nglaser3 nglaser3 force-pushed the forced-collisions branch from 2cd661a to 0430bad Compare April 18, 2026 21:46
@nglaser3 nglaser3 force-pushed the forced-collisions branch from 0430bad to 575f1e2 Compare April 18, 2026 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Forced collision variance reduction technique

1 participant