Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
881a544
added evaluate and bias to power law
j-fletcher Apr 23, 2025
310e29f
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher May 23, 2025
b90c960
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Jun 3, 2025
061074b
Added sample, evaluate and bias; to_xml and from_xml for Univariates …
j-fletcher Jun 3, 2025
2a5153a
Merge branch 'source_bias' of github.com:j-fletcher/openmc into sourc…
j-fletcher Jun 3, 2025
4c7cd13
Added to_xml_element in stats.Univariate
j-fletcher Jun 3, 2025
27d4476
Added sample and evaluate functions for remaining distributions
j-fletcher Jun 6, 2025
6aec995
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Jun 6, 2025
f5464fd
Added documentation for Sample functions returning (double,double). R…
j-fletcher Jun 11, 2025
b5c32fe
Changed sample return type to std::pair for ease of access
j-fletcher Jun 12, 2025
450fefc
Added biased sampling for multivariate position and direction distrib…
j-fletcher Jun 15, 2025
4b61490
Add sample_as_bias function for PolarAzimuthal to return mu,phi
j-fletcher Jun 15, 2025
0a2e205
Added XML read/write for biased Multivariate
j-fletcher Jun 15, 2025
fd37222
Initial changes to sample() calls so that sampled value and weight ar…
j-fletcher Jun 17, 2025
154e365
Updating tests to parse sampling output
j-fletcher Jun 17, 2025
eadc7af
Added intermediary variables for parsing of sample(seed) output
j-fletcher Jun 18, 2025
4d90ed8
Modified apply-bias functions for const correctness; added a default …
j-fletcher Jun 18, 2025
6e21b74
Corrected return type of sample calls returning both value and weight…
j-fletcher Jun 18, 2025
2993888
Fixed bias setter types
j-fletcher Jun 19, 2025
2e87b2f
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Jun 21, 2025
6fdb367
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Jul 23, 2025
dc94a71
Added documentation
j-fletcher Jul 23, 2025
4e5cc48
Fixed table in variance reduction users guide
j-fletcher Jul 23, 2025
d8f8aa6
Changed table to list-table
j-fletcher Jul 23, 2025
d46d8eb
Fixed typo in table
j-fletcher Jul 23, 2025
1771a01
Ran clang-format
j-fletcher Jul 23, 2025
ed9cd79
Fixed return type of sampling a MeshElementSpatial
j-fletcher Jul 24, 2025
65775b7
Fixed Isotropic bias setter and univariate Mixture.sample()
j-fletcher Jul 26, 2025
6d31cb0
Isotropic (cpp) constructor should read whole node; fixed Isotropic (…
j-fletcher Jul 28, 2025
3cc0945
Merge branch 'develop' into source_bias
j-fletcher Aug 25, 2025
0ab7881
Initialize r_wgt = 1.0
j-fletcher Sep 2, 2025
8291f4f
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Sep 2, 2025
d0825da
Intermediate variable to make sure CorrelatedEnergyAngle modifies val…
j-fletcher Sep 2, 2025
abf19f3
Merge branch 'openmc-dev:develop' into source_bias
j-fletcher Sep 3, 2025
5e7a2ea
Rewrote source reg test because PolarAzimuthal now always samples phi
j-fletcher Sep 3, 2025
ea03c34
Warn/Error when ray source biased, unsupported ops on biased dists, d…
j-fletcher Sep 8, 2025
194876c
Enforce shared support between parent and bias distributions
j-fletcher Oct 7, 2025
1dfd023
Mixture and Discrete refactor
j-fletcher Oct 20, 2025
1fa04be
Merge branch 'develop' into source_bias
j-fletcher Oct 20, 2025
e6e04c9
Run clang-format
j-fletcher Oct 20, 2025
c68bd79
Unit tests, bias XML element fix, Tabular normalization, biased Mixtu…
j-fletcher Oct 21, 2025
125941a
Correct exponent in Watt test
j-fletcher Oct 21, 2025
9029312
Fixed typos in distribution.cpp
j-fletcher Oct 31, 2025
33f242d
Merge branch 'develop' into pr/j-fletcher/3460
paulromano Jan 6, 2026
5642f5d
Update documentation for source biasing
paulromano Jan 6, 2026
4341f3c
Refactor biased sampling to reduce code duplication
paulromano Jan 7, 2026
0db4b20
Have sample_unbiased return a single value
paulromano Jan 7, 2026
9829afe
Fix normalization constant in Watt PDF
paulromano Jan 7, 2026
062b107
Optimize biased sampling for Discrete
paulromano Jan 7, 2026
aea8ee3
Add tests for C++ source biasing
paulromano Jan 7, 2026
9f176d0
Avoid mutating inputs in Discrete.merge with bias
paulromano Jan 8, 2026
66e848a
Vectorize evaluation of f/g ratio for biased sampling
paulromano Jan 8, 2026
1d7c08c
Have sample_unbiased return samples only
paulromano Jan 8, 2026
8fa92f1
Simplify Distrbution::sample
paulromano Jan 8, 2026
05289af
Rename prob_actual to prob_norm
paulromano Jan 8, 2026
e037c4f
Refactor DiscreteIndex and Discrete to separate concerns better
paulromano Jan 8, 2026
2ed3c10
Factor out compute_importance_weights
paulromano Jan 8, 2026
3659af1
Clean up duplicated code in to/from_xml_element
paulromano Jan 9, 2026
d420de6
Update io_formats documentation to account for <bias>
paulromano Jan 9, 2026
0a0b0ba
General cleanup
paulromano Jan 9, 2026
47e833a
Fix Univariate.sample
paulromano Jan 9, 2026
c1bc033
Simplify check for bias in ray_source
paulromano Jan 9, 2026
cbb8a03
Fix docstring that should be raw
paulromano Jan 9, 2026
86869c2
Fix return value of Mixture.support
paulromano Jan 9, 2026
f0e05ea
Remove note about consistency of birth weight and WW
paulromano Jan 10, 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
34 changes: 30 additions & 4 deletions docs/source/io_formats/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -844,13 +844,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:
Expand Down Expand Up @@ -883,6 +888,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
Expand All @@ -906,6 +915,10 @@ 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.

.. 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
Expand Down Expand Up @@ -998,13 +1011,26 @@ 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.

: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*: None

---------------------------------------
``<source_rejection_fraction>`` Element
Expand Down
82 changes: 76 additions & 6 deletions docs/source/methods/variance_reduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -132,3 +134,71 @@ aware of this.
:label: variance_fom

\text{FOM} = \frac{1}{\text{Time} \times \sigma^2}

.. _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.
6 changes: 6 additions & 0 deletions docs/source/usersguide/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down
155 changes: 151 additions & 4 deletions docs/source/usersguide/variance_reduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ 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.
or source biasing techniques, the latter of which additionally provides a
local variance reduction capability. 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 first break down the steps required to generate and apply
weight windows, then describe how source biasing may be applied.

.. _ww_generator:

Expand Down Expand Up @@ -172,3 +174,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
Loading
Loading