Repository: openmc-dev/openmc

Issue:
<volume_calc> settings.xml element file format outdated
<!--Describe the issue with the documentation and include a URL to the corresponding page-->

https://docs.openmc.org/en/latest/io_formats/settings.html#volume-calc-element

A few elements read by the C++ code are undocumented online:

- `domain_type`
- `threshold`
- `type`
- ~~cells~~ this is present but has been replaced by `domain_ids`

Discussion:

Patch:
diff --git a/README.md b/README.md
index 561bf4e1a..6539ec3c7 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # OpenMC Monte Carlo Particle Transport Code
 
 [![License](https://img.shields.io/badge/license-MIT-green)](https://docs.openmc.org/en/latest/license.html)
-[![GitHub Actions build status (Linux)](https://github.com/openmc-dev/openmc/workflows/CI/badge.svg?branch=develop)](https://github.com/openmc-dev/openmc/actions?query=workflow%3ACI)
+[![GitHub Actions build status (Linux)](https://github.com/openmc-dev/openmc/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/openmc-dev/openmc/actions/workflows/ci.yml)
 [![Code Coverage](https://coveralls.io/repos/github/openmc-dev/openmc/badge.svg?branch=develop)](https://coveralls.io/github/openmc-dev/openmc?branch=develop)
 [![dockerhub-publish-develop-dagmc](https://github.com/openmc-dev/openmc/workflows/dockerhub-publish-develop-dagmc/badge.svg)](https://github.com/openmc-dev/openmc/actions?query=workflow%3Adockerhub-publish-develop-dagmc)
 [![dockerhub-publish-develop](https://github.com/openmc-dev/openmc/workflows/dockerhub-publish-develop/badge.svg)](https://github.com/openmc-dev/openmc/actions?query=workflow%3Adockerhub-publish-develop)
diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst
index 226e9084e..03abe9a3c 100644
--- a/docs/source/io_formats/settings.rst
+++ b/docs/source/io_formats/settings.rst
@@ -1068,8 +1068,14 @@ The ``<volume_calc>`` element indicates that a stochastic volume calculation
 should be run at the beginning of the simulation. This element has the following
 sub-elements/attributes:
 
-  :cells:
-    The unique IDs of cells for which the volume should be estimated.
+  :domain_type:
+    The type of each domain for the volume calculation ("cell", "material", or
+    "universe").
+
+    *Default*: None
+
+  :domain_ids:
+    The unique IDs of domains for which the volume should be estimated.
 
     *Default*: None
 
@@ -1079,16 +1085,41 @@ sub-elements/attributes:
     *Default*: None
 
   :lower_left:
-     The lower-left Cartesian coordinates of a bounding box that is used to
-     sample points within.
+    The lower-left Cartesian coordinates of a bounding box that is used to
+    sample points within.
 
-     *Default*: None
+    *Default*: None
 
   :upper_right:
-     The upper-right Cartesian coordinates of a bounding box that is used to
-     sample points within.
+    The upper-right Cartesian coordinates of a bounding box that is used to
+    sample points within.
 
-     *Default*: None
+    *Default*: None
+
+  :threshold:
+    Presence of a ``<threshold>`` sub-element indicates that the volume
+    calculation will be halted based on a threshold on the error. It has the
+    following sub-elements/attributes:
+
+    :type:
+      The type of the trigger. Accepted options are "variance", "std_dev",
+      and "rel_err".
+
+      :variance:
+        Variance of the mean, :math:`\sigma^2`
+
+      :std_dev:
+        Standard deviation of the mean, :math:`\sigma`
+
+      :rel_err:
+        Relative error of the mean, :math:`\frac{\sigma}{\mu}`
+
+      *Default*: None
+
+    :threshold:
+      The trigger's convergence criterion for the given type.
+
+      *Default*: None
 
 ----------------------------
 ``<weight_windows>`` Element
diff --git a/openmc/mesh.py b/openmc/mesh.py
index d683c8808..a655e7a89 100644
--- a/openmc/mesh.py
+++ b/openmc/mesh.py
@@ -1439,6 +1439,10 @@ class CylindricalMesh(StructuredMesh):
             num=dimension[2]+1
         )
         origin = (cached_bb.center[0], cached_bb.center[1], z_grid[0])
+
+        # make z-grid relative to the origin
+        z_grid -= origin[2]
+
         mesh = cls(
             r_grid=r_grid,
             z_grid=z_grid,
diff --git a/src/source.cpp b/src/source.cpp
index 817847b76..3251ca0d0 100644
--- a/src/source.cpp
+++ b/src/source.cpp
@@ -457,6 +457,11 @@ extern "C" int openmc_sample_external_source(
     return OPENMC_E_INVALID_ARGUMENT;
   }
 
+  if (model::external_sources.empty()) {
+    set_errmsg("No external sources have been defined.");
+    return OPENMC_E_OUT_OF_BOUNDS;
+  }
+
   auto sites_array = static_cast<SourceSite*>(sites);
   for (size_t i = 0; i < n; ++i) {
     sites_array[i] = sample_external_source(seed);


Test patch:
diff --git a/tests/unit_tests/test_mesh_from_domain.py b/tests/unit_tests/test_mesh_from_domain.py
index c75e8fd07..0cbe413e8 100644
--- a/tests/unit_tests/test_mesh_from_domain.py
+++ b/tests/unit_tests/test_mesh_from_domain.py
@@ -30,7 +30,7 @@ def test_cylindrical_mesh_from_cell():
     assert np.array_equal(mesh.dimension, (2, 4, 3))
     assert np.array_equal(mesh.r_grid, [0., 25., 50.])
     assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi, 1.5*np.pi, 2.*np.pi])
-    assert np.array_equal(mesh.z_grid, [10., 20., 30., 40.])
+    assert np.array_equal(mesh.z_grid, [0., 10., 20., 30.])
     assert np.array_equal(mesh.origin, [0., 0., 10.])
 
     # Cell is not centralized on Z or X axis
@@ -83,7 +83,8 @@ def test_cylindrical_mesh_from_region():
     assert np.array_equal(mesh.dimension, (6, 2, 3))
     assert np.array_equal(mesh.r_grid, [0., 1., 2., 3., 4., 5., 6.])
     assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi])
-    assert np.array_equal(mesh.z_grid, [-30., -10., 10., 30.])
+    assert np.array_equal(mesh.z_grid, [0.0, 20., 40., 60])
+    assert np.array_equal(mesh.origin, (0.0, 0.0, -30.))
 
 
 def test_reg_mesh_from_universe():