Add MG particle speed getter and delayed fission neutron emission
Description
Add MG particle speed getter and delayed fission neutron emission. This extends OpenMC's capability to run autonomous problems accurately, such as neutron pulse experiments.
Input for settings.max_secondaries is added with the default (originally hard-coded) value of 10000. This allows users to set up buffers to run near-critical or super-critical time-dependent problems (accompanied by time_cutoff, of course).
Fixes #2885
This PR changes the simulation random number stream, so a revision of regression test answer keys would be needed. The plan is to group this PR along with other PRs that also change the simulation random number stream: https://github.com/openmc-dev/openmc/pull/2992.
cc: @gridley
Checklist
- [x] I have performed a self-review of my own code
- [x] I have run clang-format (version 15) on any C++ source files (if applicable)
- [x] I have followed the style guidelines for Python source files (if applicable)
- [x] I have made corresponding changes to the documentation (if applicable)
- [x] I have added tests that prove my fix is effective or that my feature works (if applicable)
Verification
MG test
Here is the result of a pulsed infinite homogeneous 361-group problem, where the MGXS is generated from the pincell example:
The "analytical" reference solution is also shown for verification. The simulation was run in 10 batches with 100k particles per batch.
CE test
Here is the result of the jezebel example pulsed with 2 MeV isotropic point source at the origin:
The simulation was run in 10 batches with 100k particles per batch.
Estimates of neutron inverse period, or time constant $\alpha$, can be naively calculated from two consecutive data points:
Experimental value for the prompt neutron time constant ($\alpha_p$ = -640 +- 10 /ms) is also shown above for verification.
Note: In running this Jezebel problem, I had to increase the secondary bank size limit from the default value 10k to 100k.
The additional step of sampling delayed emission time shifts the random number sequence used in the rest of the random walk, which would make some (if not most) of the regression tests fail.
Is revising the regression test keys an option?
If not, the solution would be to only perform the delayed time sampling if a time-dependent problem is run (i.e., if TimeFilter is used in at least one tally).
Thanks @ilhamv! I believe that we should be consuming that extra random number to sample the delayed group emission time, so I'm going to tie @paulromano into this to put it on his radar. I think typically, in the past, people have let a few proposed changes accrue before changing the RNG stream. At that point some statistical equivalence testing is done between the two versions, and all the tests get updated.
If we're tracking particle times during normal simulation, the delayed emission times should not be incorrect, IMO. Correctness should not be an option that's off by default--this was the same principle that guided the decision of having resonance upscattering turned on by default, in contrast to most other CE MC codes.
By the way, I think the code here to simulate the transient pulse would be worth including in the examples section. Would you want to include it as part of this PR?
If we're tracking particle times during normal simulation, the delayed emission times should not be incorrect, IMO. Correctness should not be an option that's off by default--this was the same principle that guided the decision of having resonance upscattering turned on by default, in contrast to most other CE MC codes.
I really like that principle. 👍🏽
By the way, I think the code here to simulate the transient pulse would be worth including in the examples section. Would you want to include it as part of this PR?
Sure, I'll add the example as part of this PR. Thanks, @gridley!
There was a little bug in the use of MG_mode + collision estimator + survival_biasing: https://github.com/openmc-dev/openmc/pull/2898/commits/6ca1ae09547dd78684b31a1bfe155d6eed141b2b
@gridley @nelsonag
(Note: I had to use the collision estimator due to the current limitation of MeshFilter + TimeFilter).
Paul, that's great to hear, because I have had this other change on my radar to change the random number stream. We assume target nuclei are stationary above a certain energy threshold, and there's this recent paper that shows it introduces some non-negligible error for systems with finely distributed resonant material like TRISO or cracked MSR moderator.
The asymptotic form of the target velocity should just be to sample directly from Maxwell-Boltzmann, i.e. x y and z velocities are normally distributed. We should fall back to that rather than stationarity. The authors said it's like a 6% slowdown by always sampling the target motion, but so using some asymptotic form might be helpful in that case.
https://arxiv.org/abs/2403.14486
Ah yes, thanks for bringing that up @gridley. I did talk to the authors of that paper so I'm aware of the issue at hand.
No problem, @paulromano. Thanks!
I think that is the only change needed in the random number stream for analog time-dependent simulations. Unless there are other reactions that produce delayed particles (neutron/photon)..?
Some other items that I want to bring up for consideration (not directly related to this PR, though):
- To get the track-length estimator working properly for tallying with both time and mesh filters, would it make sense to make the mesh filter 4D (x,y,z,t)?
- Currently, the weight cutoff can not be set to zero. However, I see that in certain time-dependent problems where the neutron population decreases significantly in time, we do want to set the weight cutoff to zero (no cutoff) and instead set the time cutoff to a time range of interest. Would it be a good idea to allow users to do that? If it is a good idea, I can push a commit where I just removed the last argument in
cv.check_greater_than('weight cutoff', cutoff[key], 0.0, True).