mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Merge pull request #1273 from drewejohnson/feat-op-qvalues
Option to pass fission q values to Chain, Operator, Model
This commit is contained in:
commit
3952f5bba1
7 changed files with 68 additions and 15 deletions
|
|
@ -49,6 +49,9 @@ class TransportOperator(metaclass=ABCMeta):
|
|||
Path to the depletion chain XML file. Defaults to the file
|
||||
listed under ``depletion_chain`` in
|
||||
:envvar:`OPENMC_CROSS_SECTIONS` environment variable.
|
||||
fission_q : dict, optional
|
||||
Dictionary of nuclides and their fission Q values [eV]. If not given,
|
||||
values will be pulled from the ``chain_file``.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
|
@ -58,7 +61,7 @@ class TransportOperator(metaclass=ABCMeta):
|
|||
nuclides with reaction rates. Defaults to 1.0e3.
|
||||
|
||||
"""
|
||||
def __init__(self, chain_file=None):
|
||||
def __init__(self, chain_file=None, fission_q=None):
|
||||
self.dilute_initial = 1.0e3
|
||||
self.output_dir = '.'
|
||||
|
||||
|
|
@ -81,7 +84,7 @@ class TransportOperator(metaclass=ABCMeta):
|
|||
warn("Use of OPENMC_DEPLETE_CHAIN is deprecated in favor "
|
||||
"of adding depletion_chain to OPENMC_CROSS_SECTIONS",
|
||||
FutureWarning)
|
||||
self.chain = Chain.from_xml(chain_file)
|
||||
self.chain = Chain.from_xml(chain_file, fission_q)
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self, vec, print_out=True):
|
||||
|
|
|
|||
|
|
@ -4,16 +4,18 @@ This module contains information about a depletion chain. A depletion chain is
|
|||
loaded from an .xml file and all the nuclides are linked together.
|
||||
"""
|
||||
|
||||
from collections import OrderedDict, defaultdict
|
||||
from io import StringIO
|
||||
from itertools import chain
|
||||
import math
|
||||
import re
|
||||
import os
|
||||
from collections import OrderedDict, defaultdict
|
||||
from collections.abc import Mapping
|
||||
|
||||
from openmc.checkvalue import check_type
|
||||
|
||||
# Try to use lxml if it is available. It preserves the order of attributes and
|
||||
# provides a pretty-printer by default. If not available, use OpenMC function to
|
||||
# pretty print.
|
||||
# provides a pretty-printer by default. If not available,
|
||||
# use OpenMC function to pretty print.
|
||||
try:
|
||||
import lxml.etree as ET
|
||||
_have_lxml = True
|
||||
|
|
@ -312,22 +314,32 @@ class Chain(object):
|
|||
return chain
|
||||
|
||||
@classmethod
|
||||
def from_xml(cls, filename):
|
||||
def from_xml(cls, filename, fission_q=None):
|
||||
"""Reads a depletion chain XML file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : str
|
||||
The path to the depletion chain XML file.
|
||||
fission_q : dict, optional
|
||||
Dictionary of nuclides and their fission Q values [eV].
|
||||
If not given, values will be pulled from ``filename``
|
||||
|
||||
"""
|
||||
chain = cls()
|
||||
|
||||
if fission_q is not None:
|
||||
check_type("fission_q", fission_q, Mapping)
|
||||
else:
|
||||
fission_q = {}
|
||||
|
||||
# Load XML tree
|
||||
root = ET.parse(str(filename))
|
||||
|
||||
for i, nuclide_elem in enumerate(root.findall('nuclide')):
|
||||
nuc = Nuclide.from_xml(nuclide_elem)
|
||||
this_q = fission_q.get(nuclide_elem.get("name"))
|
||||
|
||||
nuc = Nuclide.from_xml(nuclide_elem, this_q)
|
||||
chain.nuclide_dict[nuc.name] = i
|
||||
|
||||
# Check for reaction paths
|
||||
|
|
|
|||
|
|
@ -112,13 +112,16 @@ class Nuclide(object):
|
|||
return len(self.reactions)
|
||||
|
||||
@classmethod
|
||||
def from_xml(cls, element):
|
||||
def from_xml(cls, element, fission_q=None):
|
||||
"""Read nuclide from an XML element.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
element : xml.etree.ElementTree.Element
|
||||
XML element to write nuclide data to
|
||||
fission_q : None or float
|
||||
User-supplied fission Q value [eV].
|
||||
Will be read from the element if not given
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -153,6 +156,8 @@ class Nuclide(object):
|
|||
target = reaction_elem.get('target')
|
||||
else:
|
||||
target = None
|
||||
if fission_q is not None:
|
||||
Q = fission_q
|
||||
|
||||
# Append reaction
|
||||
nuc.reactions.append(ReactionTuple(
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ class Operator(TransportOperator):
|
|||
in the previous results.
|
||||
diff_burnable_mats : bool, optional
|
||||
Whether to differentiate burnable materials with multiple instances
|
||||
fission_q : dict, optional
|
||||
Dictionary of nuclides and their fission Q values [eV]. If not given,
|
||||
values will be pulled from the ``chain_file``.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
|
@ -110,14 +113,14 @@ class Operator(TransportOperator):
|
|||
|
||||
"""
|
||||
def __init__(self, geometry, settings, chain_file=None, prev_results=None,
|
||||
diff_burnable_mats=False):
|
||||
super().__init__(chain_file)
|
||||
diff_burnable_mats=False, fission_q=None):
|
||||
super().__init__(chain_file, fission_q)
|
||||
self.round_number = False
|
||||
self.settings = settings
|
||||
self.geometry = geometry
|
||||
self.diff_burnable_mats = diff_burnable_mats
|
||||
|
||||
if prev_results != None:
|
||||
if prev_results is not None:
|
||||
# Reload volumes into geometry
|
||||
prev_results[-1].transfer_volumes(geometry)
|
||||
|
||||
|
|
@ -149,7 +152,6 @@ class Operator(TransportOperator):
|
|||
self.reaction_rates = ReactionRates(
|
||||
self.local_mats, self._burnable_nucs, self.chain.reactions)
|
||||
|
||||
|
||||
def __call__(self, vec, power, print_out=True):
|
||||
"""Runs a simulation.
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class Model(object):
|
|||
self._plots.append(plot)
|
||||
|
||||
def deplete(self, timesteps, chain_file=None, method='cecm',
|
||||
**kwargs):
|
||||
fission_q=None, **kwargs):
|
||||
"""Deplete model using specified timesteps/power
|
||||
|
||||
Parameters
|
||||
|
|
@ -138,6 +138,9 @@ class Model(object):
|
|||
:envvar:`OPENMC_CROSS_SECTIONS` environment variable if it exists.
|
||||
method : str
|
||||
Integration method used for depletion (e.g., 'cecm', 'predictor')
|
||||
fission_q : dict, optional
|
||||
Dictionary of nuclides and their fission Q values [eV].
|
||||
If not given, values will be pulled from the ``chain_file``.
|
||||
**kwargs
|
||||
Keyword arguments passed to integration function (e.g.,
|
||||
:func:`openmc.deplete.integrator.cecm`)
|
||||
|
|
@ -149,7 +152,10 @@ class Model(object):
|
|||
import openmc.deplete as dep
|
||||
|
||||
# Create OpenMC transport operator
|
||||
op = dep.Operator(self.geometry, self.settings, chain_file)
|
||||
op = dep.Operator(
|
||||
self.geometry, self.settings, chain_file,
|
||||
fission_q=fission_q,
|
||||
)
|
||||
|
||||
# Perform depletion
|
||||
check_value('method', method, ('cecm', 'predictor', 'cf4', 'epc_rk4',
|
||||
|
|
|
|||
|
|
@ -231,3 +231,15 @@ def test_getitem():
|
|||
assert "NucA" == chain["NucA"]
|
||||
assert "NucB" == chain["NucB"]
|
||||
assert "NucC" == chain["NucC"]
|
||||
|
||||
|
||||
def test_set_fiss_q():
|
||||
"""Make sure new fission q values can be set on the chain"""
|
||||
new_q = {"U235": 2.0E8, "U238": 2.0E8, "U234": 5.0E7}
|
||||
chain_file = Path(__file__).parents[1] / "chain_simple.xml"
|
||||
mod_chain = Chain.from_xml(chain_file, new_q)
|
||||
for name, q in new_q.items():
|
||||
chain_nuc = mod_chain[name]
|
||||
for rx in chain_nuc.reactions:
|
||||
if rx.type == 'fission':
|
||||
assert rx.Q == q
|
||||
|
|
|
|||
|
|
@ -68,3 +68,16 @@ def test_operator_init(bare_xs):
|
|||
'decay_modes', 'yield_data', 'yield_energies',
|
||||
]:
|
||||
assert getattr(act_nuc, prop) == getattr(ref_nuc, prop), prop
|
||||
|
||||
|
||||
def test_operator_fiss_q():
|
||||
"""Make sure fission q values can be set"""
|
||||
new_q = {"U235": 2.0E8, "U238": 2.0E8, "U234": 5.0E7}
|
||||
chain_file = Path(__file__).parents[1] / "chain_simple.xml"
|
||||
operator = BareDepleteOperator(chain_file=chain_file, fission_q=new_q)
|
||||
mod_chain = operator.chain
|
||||
for name, q in new_q.items():
|
||||
chain_nuc = mod_chain[name]
|
||||
for rx in chain_nuc.reactions:
|
||||
if rx.type == 'fission':
|
||||
assert rx.Q == q
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue