Biased multigroup scattering when multiplicity varies with outgoing group
I maintainer di solito rispondono entro 2 giorni
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
Read the linked sampler code in src/scattdata.cpp at the Legendre, Histogram, and Tabular sampling methods, along with the library conversion in openmc/mgxs/library.py. Start by checking how outgoing-group probabilities and multiplicities produce the reported transfer matrix; use the attached reproduce.py cases as regression tests. Done means the variable-multiplicity cases match the analytical flux and k-effective while the constant-multiplicity controls still agree.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Bug Description
I independently reproduced a multigroup transport bias in OpenMC v0.15.3 when the scattering multiplicity varies with the outgoing energy group. The bias affects track-length flux and k-effective, not only scattering tallies.
I would like to contribute a fix and upstream regression tests. I have outlined a possible correction below and would welcome feedback on the intended sampling behavior before preparing a pull request targeting develop.
Expected and implemented transfer
Let:
- $C_{gh}$ be the scattering event cross section from incoming group $g$ to outgoing group $h$.
- $B_{gh}=\nu_{gh}C_{gh}$ be the corresponding neutron-production cross section, where $\nu_{gh}$ is the scattering multiplicity.
- $C_g=\sum_h C_{gh}=\Sigma_{t,g}-\Sigma_{a,g}$ and $B_g=\sum_h B_{gh}$.
The synthetic inputs below explicitly satisfy these consistency relations.
With multiplicity data, the official library conversion supplies the nu-scatter matrix $B$. However, the outgoing-group sampler samples $p_{gh}=B_{gh}/B_g$, and the sample methods then multiply weight by $\nu_{gh}$: Legendre, Histogram, and Tabular.
Since absorption is handled before scattering, the resulting expected production matrix is
$$
B^{\mathrm{actual}}{gh}
= C_g\frac{B{gh}}{B_g}\nu_{gh},
$$
which generally differs from $B_{gh}$. It agrees when the multiplicity is constant across the nonzero outgoing channels of each incoming group.
Proposed correction
Keep the existing outgoing-group probabilities and conditional angular distributions, but precompute a separate incoming-group weight multiplier:
$$
r_g=\frac{B_g}{C_g}
=\left[\sum_h\frac{p_{gh}}{\nu_{gh}}\right]^{-1}.
$$
Use this multiplier in all three sampling methods, so that
$$
C_g \cdot p_{gh} \cdot r_g = B_{gh}.
$$
For the example below, $r=(1.5,1.0)$.
Implementation considerations:
- Preserve
energy(the normalized production distribution) andmult(group-to-group multiplicities), since cross-section queries and matrix reconstruction also use them. - Initialize the separate multiplier consistently after material mixing and Legendre-to-tabular conversion.
- Skip zero-probability terms, handle empty scattering rows, and check consistency with total minus absorption rather than silently renormalizing inconsistent data.
An alternative is to maintain a separate event-based sampling distribution $C_{gh}/C_g$ and retain the group-to-group weight multiplier $\nu_{gh}$.
This correction is an expectation-level derivation. The independent reproduction attached to this report does not include a rebuilt, corrected OpenMC executable. I am willing to implement the agreed approach, add tests that fail before the fix and pass afterward, and address review feedback.
Steps to Reproduce
- Extract the attached archive. It includes
reproduce.py, input files, original statepoints, results, logs, and executable version output. - In an environment with the OpenMC Python package and executable available, run:
python reproduce.py --output results --executable openmc
python reproduce.py --output results_survival --executable openmc --survival-biasing
Use new output directories. No external nuclear-data library is required: the script generates synthetic two-group macroscopic data.
The fixed-source model is a homogeneous, fully reflective cube with isotropic scattering, a unit source in the high-energy group, and no fission. Rows are incoming groups and columns are outgoing groups. Cross sections are in $\mathrm{cm}^{-1}$:
Sigma_t = [1.0, 1.0]
Sigma_a = [0.6, 0.8]
C = [[0.2, 0.2],
[0.0, 0.2]]
B = [[0.2, 0.4],
[0.0, 0.2]]
multiplicity = [[1.0, 2.0],
[1.0, 1.0]]
For the volume-integrated flux per unit external source,
$$
\left[\mathrm{diag}(\Sigma_t)-B^{T}\right]\Phi=(1,0)^{T},
$$
so the expected flux is $(1.25,0.625)$ and total absorption is $1.25$.
The implemented transfer instead gives
$$
B^{\mathrm{actual}}=
\begin{pmatrix}
2/15 & 8/15\
0 & 1/5
\end{pmatrix},
$$
predicting the incorrect flux $(15/13,10/13)=(1.153846,0.769231)$ and absorption $17/13=1.307692$.
Independent results
The following runs use analog absorption. Quoted uncertainties are one standard deviation.
| Case | High-energy group flux | Low-energy group flux |
|---|---|---|
| Correct analytical solution | 1.250000 | 0.625000 |
| Implemented-transfer prediction | 1.153846 | 0.769231 |
| OpenMC Legendre | 1.153274 ± 0.001101 | 0.768011 ± 0.001767 |
| OpenMC Histogram | 1.153138 ± 0.001129 | 0.767005 ± 0.001736 |
| OpenMC Tabular | 1.152969 ± 0.001014 | 0.766982 ± 0.001933 |
Legendre-to-tabular conversion is explicitly disabled, so these cases exercise the respective samplers. Legendre fixed-source absorption is $1.306373\pm0.001336$, consistent with the implemented-transfer prediction.
Repeating with survival biasing reproduces the same bias. Controls with all nonzero multiplicities equal to 1.0 or 1.5 agree with their analytical solutions.
The script also runs a separate eigenvalue case with fission cross sections $(0.16,0.32)$, nu-fission $(0.4,0.8)$, and $\chi=(1,0)$. Fission is included in absorption. The correct $k$ is 1.0; the implemented transfer predicts $14/13=1.076923$. The original executable gives $1.076903\pm0.000609$ with analog absorption.
Environment
- OS: Ubuntu 22.04.4 LTS, x86_64, running under WSL1 on Windows.
- OpenMC executable: v0.15.3, commit
27e38e894697bb32a1dac7848d2618818b6b8daf. - Installation: conda-forge package in Miniforge; package build
dagmc_mpi_openmpi_py313ha0fa856_102. - OpenMC Python package: 0.15.3; Python: 3.13.13.
- Compiler reported by the executable: GNU 14.3.0, Release build.
- Execution: one MPI process, two OpenMP threads.
- Each run: 30,000 particles per batch, 40 batches, seed 71829; eigenvalue runs discard 10 inactive batches.
- Nuclear data: synthetic macroscopic multigroup library generated by the reproducer; no continuous-energy data required.
The complete archive contains both analog and survival-biasing runs, including the constant-multiplicity controls.
- Lingua principale
- Python
- Stelle
- 1.1k
- Fork
- 683
- Merge medio
- 3g 10h
- PR unite (30g)
- 17
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openmc-dev/openmc
-
Bugs
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
openmc-dev/openmc#4222 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
openmc-dev/openmc#4213 ·
I maintainer di solito rispondono entro 2 giorni
-
Documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
openmc-dev/openmc#3996 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 42/100
openmc-dev/openmc#4223 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 24/100
openmc-dev/openmc#4208 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di openmc-dev/openmc
Issue simili
-
S9.7: Methodology pageApertaarea: web priority: P1 story
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
nfiasco/Quant-Time-Machine#151 ·
I maintainer di solito rispondono entro 1 giorno
-
Broken links found in docsApertadocs pydanty:is-working
Difficoltà 1/5 1-3 ore Idoneità per principianti 85/100
pydantic/pydantic-ai#12892 ·
I maintainer di solito rispondono entro 1 giorno
-
needs-triage
Difficoltà 1/5 1-3 ore Idoneità per principianti 72/100
Azure/azure-sdk-for-python#49886 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
[Core] Deprecated(error=True) raises only on the first call; later calls run the removed APIForse già presa @wguo7 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
ray-project/ray#67965 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
btclib-org/btclib#3006 ·
I maintainer di solito rispondono entro 1 giorno