diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py
index efe8dbe84..8ab052b0d 100644
--- a/openmc/mgxs/library.py
+++ b/openmc/mgxs/library.py
@@ -72,6 +72,11 @@ class Library:
Number of equi-width polar angle bins for angle discretization
num_azimuthal : Integral
Number of equi-width azimuthal angle bins for angle discretization
+ nuclides : Iterable of str or 'sum'
+ The optional user-specified nuclides for which to compute cross
+ sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides
+ are not specified by the user, all nuclides in the domain
+ are included.
estimator : str or None
The tally estimator used to compute multi-group cross sections.
If None, the default for each MGXS type is used.
@@ -107,6 +112,7 @@ class Library:
self._energy_groups = None
self._num_polar = 1
self._num_azimuthal = 1
+ self._nuclides = None
self._num_delayed_groups = 0
self._correction = 'P0'
self._scatter_format = 'legendre'
@@ -145,6 +151,7 @@ class Library:
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._num_polar = self.num_polar
clone._num_azimuthal = self.num_azimuthal
+ clone._nuclides = self._nuclides
clone._num_delayed_groups = self.num_delayed_groups
clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo)
clone._all_mgxs = copy.deepcopy(self.all_mgxs)
@@ -205,6 +212,10 @@ class Library:
else:
return self._domains
+ @property
+ def nuclides(self):
+ return self._nuclides
+
@property
def energy_groups(self):
return self._energy_groups
@@ -275,6 +286,11 @@ class Library:
cv.check_type('name', name, str)
self._name = name
+ @nuclides.setter
+ def nuclides(self, nuclides):
+ cv.check_iterable_type('nuclides', nuclides, str)
+ self._nuclides = nuclides
+
@mgxs_types.setter
def mgxs_types(self, mgxs_types):
all_mgxs_types = openmc.mgxs.MGXS_TYPES + openmc.mgxs.MDGXS_TYPES + \
@@ -524,6 +540,20 @@ class Library:
mgxs.legendre_order = self.legendre_order
mgxs.histogram_bins = self.histogram_bins
+ if self.by_nuclide:
+ try:
+ domain_nuclides = domain.get_nuclides()
+ except AttributeError:
+ domain_nuclides = None
+ if self.nuclides:
+ if domain_nuclides:
+ mgxs.nuclides = [
+ nuclide for nuclide in self.nuclides
+ if nuclide in domain_nuclides
+ ] + ["total"]
+ else:
+ mgxs.nuclides = self.nuclides
+
self.all_mgxs[domain.id][mgxs_type] = mgxs
def add_to_tallies_file(self, tallies_file, merge=True):
@@ -590,7 +620,7 @@ class Library:
self._sp_filename = statepoint._f.filename
self._geometry = statepoint.summary.geometry
- self._nuclides = statepoint.summary.nuclides
+ self._atomic_weight_ratios = statepoint.summary.nuclides
if statepoint.run_mode == 'eigenvalue':
self._keff = statepoint.keff.n
@@ -1005,7 +1035,7 @@ class Library:
xsdata.num_azimuthal = self.num_azimuthal
if nuclide != 'total':
- xsdata.atomic_weight_ratio = self._nuclides[nuclide]
+ xsdata.atomic_weight_ratio = self._atomic_weight_ratios[nuclide]
if subdomain is None:
subdomain = 'all'
diff --git a/tests/regression_tests/mgxs_library_specific_nuclides/__init__.py b/tests/regression_tests/mgxs_library_specific_nuclides/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/regression_tests/mgxs_library_specific_nuclides/inputs_true.dat b/tests/regression_tests/mgxs_library_specific_nuclides/inputs_true.dat
new file mode 100644
index 000000000..061aa1b95
--- /dev/null
+++ b/tests/regression_tests/mgxs_library_specific_nuclides/inputs_true.dat
@@ -0,0 +1,218 @@
+
+
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ eigenvalue
+ 100
+ 10
+ 5
+
+
+ -0.63 -0.63 -1 0.63 0.63 1
+
+
+
+
+
+
+ 1 2 3
+
+
+ 0.0 0.625 20000000.0
+
+
+ 1
+
+
+ 0.0 0.625 20000000.0
+
+
+ 1
+
+
+ 3
+
+
+ 0.0 20000000.0
+
+
+ 2
+
+
+ 3
+
+
+ 383 2
+ total
+ flux
+ tracklength
+
+
+ 1 2
+ U235 total
+ total absorption (n,2n) (n,3n) (n,4n) fission nu-fission kappa-fission scatter inverse-velocity prompt-nu-fission (n,elastic) (n,level) (n,na) (n,nc) (n,gamma) (n,a) (n,Xa) heating damage-energy (n,n1) (n,a0)
+ tracklength
+
+
+ 383 2
+ total
+ flux
+ analog
+
+
+ 1 5 6
+ U235 total
+ scatter nu-scatter
+ analog
+
+
+ 1 2
+ U235 total
+ nu-scatter
+ analog
+
+
+ 1 2 5 30
+ U235 total
+ scatter nu-scatter
+ analog
+
+
+ 1 2 5
+ U235 total
+ nu-scatter scatter nu-fission prompt-nu-fission (n,nc) (n,n1) (n,2n)
+ analog
+
+
+ 1 54
+ U235 total
+ nu-fission prompt-nu-fission
+ analog
+
+
+ 1 5
+ U235 total
+ nu-fission prompt-nu-fission
+ analog
+
+
+ 106 2
+ Zr90 total
+ total absorption (n,2n) (n,3n) (n,4n) fission nu-fission kappa-fission scatter inverse-velocity prompt-nu-fission (n,elastic) (n,level) (n,na) (n,nc) (n,gamma) (n,a) (n,Xa) heating damage-energy (n,n1) (n,a0)
+ tracklength
+
+
+ 106 5 6
+ Zr90 total
+ scatter nu-scatter
+ analog
+
+
+ 106 2
+ Zr90 total
+ nu-scatter
+ analog
+
+
+ 106 2 5 30
+ Zr90 total
+ scatter nu-scatter
+ analog
+
+
+ 106 2 5
+ Zr90 total
+ nu-scatter scatter nu-fission prompt-nu-fission (n,nc) (n,n1) (n,2n)
+ analog
+
+
+ 106 54
+ Zr90 total
+ nu-fission prompt-nu-fission
+ analog
+
+
+ 106 5
+ Zr90 total
+ nu-fission prompt-nu-fission
+ analog
+
+
+ 251 2
+ H1 total
+ total absorption (n,2n) (n,3n) (n,4n) fission nu-fission kappa-fission scatter inverse-velocity prompt-nu-fission (n,elastic) (n,level) (n,na) (n,nc) (n,gamma) (n,a) (n,Xa) heating damage-energy (n,n1) (n,a0)
+ tracklength
+
+
+ 251 5 6
+ H1 total
+ scatter nu-scatter
+ analog
+
+
+ 251 2
+ H1 total
+ nu-scatter
+ analog
+
+
+ 251 2 5 30
+ H1 total
+ scatter nu-scatter
+ analog
+
+
+ 251 2 5
+ H1 total
+ nu-scatter scatter nu-fission prompt-nu-fission (n,nc) (n,n1) (n,2n)
+ analog
+
+
+ 251 54
+ H1 total
+ nu-fission prompt-nu-fission
+ analog
+
+
+ 251 5
+ H1 total
+ nu-fission prompt-nu-fission
+ analog
+
+
diff --git a/tests/regression_tests/mgxs_library_specific_nuclides/results_true.dat b/tests/regression_tests/mgxs_library_specific_nuclides/results_true.dat
new file mode 100644
index 000000000..05ee40902
--- /dev/null
+++ b/tests/regression_tests/mgxs_library_specific_nuclides/results_true.dat
@@ -0,0 +1 @@
+3e86542d1166b8a0bcc61742b88c9e931d63733477f3274b32b4da64d8f05413fa6330d5615f44f24735c2c2f77d3071f3dce38faba284c321ceab81c1064480
\ No newline at end of file
diff --git a/tests/regression_tests/mgxs_library_specific_nuclides/test.py b/tests/regression_tests/mgxs_library_specific_nuclides/test.py
new file mode 100644
index 000000000..61910e539
--- /dev/null
+++ b/tests/regression_tests/mgxs_library_specific_nuclides/test.py
@@ -0,0 +1,71 @@
+import hashlib
+
+import openmc
+import openmc.mgxs
+from openmc.examples import pwr_pin_cell
+
+from tests.testing_harness import PyAPITestHarness
+
+
+class MGXSTestHarness(PyAPITestHarness):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ # Initialize a two-group structure
+ energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6])
+
+ # Initialize MGXS Library for a few cross section types
+ self.mgxs_lib = openmc.mgxs.Library(self._model.geometry)
+ self.mgxs_lib.by_nuclide = True
+
+ # Test relevant MGXS types
+ relevant_MGXS_TYPES = [item for item in openmc.mgxs.MGXS_TYPES
+ if item != 'current']
+ # Add in a subset of openmc.mgxs.ARBITRARY_VECTOR_TYPES and
+ # openmc.mgxs.ARBITRARY_MATRIX_TYPES so we can see the code works,
+ # but not use too much resources
+ relevant_MGXS_TYPES += [
+ "(n,elastic)", "(n,level)", "(n,2n)", "(n,na)", "(n,nc)",
+ "(n,gamma)", "(n,a)", "(n,Xa)", "heating", "damage-energy",
+ "(n,n1)", "(n,a0)", "(n,nc) matrix", "(n,n1) matrix",
+ "(n,2n) matrix"]
+ self.mgxs_lib.mgxs_types = tuple(relevant_MGXS_TYPES)
+ self.mgxs_lib.energy_groups = energy_groups
+ self.mgxs_lib.legendre_order = 3
+ self.mgxs_lib.domain_type = 'material'
+ self.mgxs_lib.nuclides = ['U235', 'Zr90', 'H1']
+ self.mgxs_lib.build_library()
+
+ # Add tallies
+ self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=True)
+
+ def _get_results(self, hash_output=True):
+ """Digest info in the statepoint and return as a string."""
+
+ # Read the statepoint file.
+ sp = openmc.StatePoint(self._sp_name)
+
+ # Load the MGXS library from the statepoint
+ self.mgxs_lib.load_from_statepoint(sp)
+
+ # Build a string from Pandas Dataframe for each MGXS
+ outstr = ''
+ for domain in self.mgxs_lib.domains:
+ for mgxs_type in self.mgxs_lib.mgxs_types:
+ mgxs = self.mgxs_lib.get_mgxs(domain, mgxs_type)
+ df = mgxs.get_pandas_dataframe()
+ outstr += df.to_string() + '\n'
+
+ # Hash the results if necessary
+ if hash_output:
+ sha512 = hashlib.sha512()
+ sha512.update(outstr.encode('utf-8'))
+ outstr = sha512.hexdigest()
+
+ return outstr
+
+
+def test_mgxs_library_specific_nuclides():
+ model = pwr_pin_cell()
+ harness = MGXSTestHarness('statepoint.10.h5', model)
+ harness.main()