mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Change how resonance scattering options are specified
This commit is contained in:
parent
8c7ca7afea
commit
474e11e876
14 changed files with 265 additions and 363 deletions
|
|
@ -25,7 +25,8 @@ except ImportError:
|
|||
|
||||
|
||||
MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial',
|
||||
'h5py', 'pandas', 'uncertainties', 'openmoc']
|
||||
'h5py', 'pandas', 'uncertainties', 'openmoc',
|
||||
'openmc.data.reconstruct']
|
||||
sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES)
|
||||
|
||||
import numpy as np
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ Simulation Settings
|
|||
:template: myclass.rst
|
||||
|
||||
openmc.Source
|
||||
openmc.ResonanceScattering
|
||||
openmc.VolumeCalculation
|
||||
openmc.Settings
|
||||
|
||||
|
|
|
|||
|
|
@ -361,54 +361,56 @@ or sub-elements and can be set to either "false" or "true".
|
|||
``<resonance_scattering>`` Element
|
||||
----------------------------------
|
||||
|
||||
The ``resonance_scattering`` element can contain one or more of the following
|
||||
attributes or sub-elements:
|
||||
The ``resonance_scattering`` element indicates to OpenMC that a method be used
|
||||
to properly account for resonance elastic scattering (typically for nuclides
|
||||
with Z > 40). This element can contain one or more of the following attributes
|
||||
or sub-elements:
|
||||
|
||||
:scatterer:
|
||||
An element with attributes/sub-elements called ``nuclide``, ``method``,
|
||||
``E_min``, and ``E_max``. The ``nuclide`` attribute is the name, as given
|
||||
by the ``name`` attribute within the ``nuclide`` sub-element of the
|
||||
``material`` element in ``materials.xml``, of the nuclide to which a
|
||||
resonance scattering treatment is to be applied.
|
||||
The ``method`` attribute gives the type of resonance scattering treatment
|
||||
that is to be applied to the ``nuclide``. Acceptable inputs - none of
|
||||
which are case-sensitive - for the ``method`` attribute are ``ARES``,
|
||||
``CXS``, ``WCM``, and ``DBRC``. Descriptions of each of these methods
|
||||
are documented here_. The ``E_min`` attribute gives the minimum energy
|
||||
above which the ``method`` is applied. The ``E_max`` attribute gives the
|
||||
maximum energy below which the ``method`` is applied. One example would
|
||||
be as follows:
|
||||
:enable:
|
||||
Indicates whether a resonance elastic scattering method should be turned
|
||||
on. Accepts values of "true" or "false".
|
||||
|
||||
*Default*: If the ``<resonance_scattering>`` element is present, "true".
|
||||
|
||||
:method:
|
||||
|
||||
Which resonance elastic scattering method is to be applied: "ares"
|
||||
(accelerated resonance elastic scattering), "dbrc" (Doppler broadening
|
||||
rejection correction), or "wcm" (weight correction method). Descriptions of
|
||||
each of these methods are documented here_.
|
||||
|
||||
.. _here: http://dx.doi.org/10.1016/j.anucene.2014.01.017
|
||||
|
||||
.. code-block:: xml
|
||||
*Default*: "ares"
|
||||
|
||||
<resonance_scattering>
|
||||
<scatterer>
|
||||
<nuclide>U-238</nuclide>
|
||||
<method>ARES</method>
|
||||
<E_min>5.0e-6</E_min>
|
||||
<E_max>40.0e-6</E_max>
|
||||
</scatterer>
|
||||
<scatterer>
|
||||
<nuclide>Pu-239</nuclide>
|
||||
<method>dbrc</method>
|
||||
<E_min>0.01e-6</E_min>
|
||||
<E_max>210.0e-6</E_max>
|
||||
</scatterer>
|
||||
</resonance_scattering>
|
||||
:energy_min:
|
||||
The energy in eV above which the resonance elastic scattering method should
|
||||
be applied.
|
||||
|
||||
.. note:: If the ``resonance_scattering`` element is not given, the free gas,
|
||||
constant cross section (``cxs``) scattering model, which has
|
||||
historically been used by Monte Carlo codes to sample target
|
||||
velocities, is used to treat the target motion of all nuclides. If
|
||||
``resonance_scattering`` is present, the ``cxs`` method is applied
|
||||
below ``E_min`` and the target-at-rest (asymptotic) kernel is used
|
||||
above ``E_max``. An arbitrary number of ``scatterer`` elements may
|
||||
be specified, each corresponding to a single nuclide at a single
|
||||
temperature.
|
||||
*Default*: 0.01 eV
|
||||
|
||||
*Defaults*: None (scatterer), ARES (method), 0.01 eV (E_min), 1.0 keV (E_max)
|
||||
:energy_max:
|
||||
The energy in eV below which the resonance elastic scattering method should
|
||||
be applied.
|
||||
|
||||
*Default*: 1000.0 eV
|
||||
|
||||
:nuclides:
|
||||
|
||||
A list of nuclides to which the resonance elastic scattering method should
|
||||
be applied.
|
||||
|
||||
*Default*: If ``<resonance_scattering>`` is present but the ``<nuclides>``
|
||||
sub-element is not given, the method is applied to all nuclides with 0 K
|
||||
elastic scattering data present.
|
||||
|
||||
.. note:: If the ``resonance_scattering`` element is not given, the free gas,
|
||||
constant cross section scattering model, which has historically been
|
||||
used by Monte Carlo codes to sample target velocities, is used to
|
||||
treat the target motion of all nuclides. If
|
||||
``resonance_scattering`` is present, the constant cross section
|
||||
method is applied below ``energy_min`` and the target-at-rest
|
||||
(asymptotic) kernel is used above ``energy_max``.
|
||||
|
||||
.. note:: This element is not used in the multi-group :ref:`energy_mode`.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ from openmc.clean_xml import clean_xml_indentation
|
|||
import openmc.checkvalue as cv
|
||||
from openmc import Nuclide, VolumeCalculation, Source, Mesh
|
||||
|
||||
_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume',
|
||||
'particle restart']
|
||||
_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart']
|
||||
_RES_SCAT_METHODS = ['dbrc', 'wcm', 'ares']
|
||||
|
||||
|
||||
class Settings(object):
|
||||
|
|
@ -80,8 +80,18 @@ class Settings(object):
|
|||
Number of particles per generation
|
||||
ptables : bool
|
||||
Determine whether probability tables are used.
|
||||
resonance_scattering : ResonanceScattering or iterable of ResonanceScattering
|
||||
The elastic scattering model to use for resonant isotopes
|
||||
resonance_scattering : dict
|
||||
Settings for resonance elastic scattering. Accepted keys are 'enable'
|
||||
(bool), 'method' (str), 'energy_min' (float), 'energy_max' (float), and
|
||||
'nuclides' (list). The 'method' can be set to 'dbrc' (Doppler broadening
|
||||
rejection correction), 'wcm' (weight correction method), and 'ares'
|
||||
(accelerated resonance elastic scattering). If not specified, 'ares' is
|
||||
the default method. The 'energy_min' and 'energy_max' values indicate
|
||||
the minimum and maximum energies above and below which the resonance
|
||||
elastic scattering method is to be applied. The 'nuclides' list
|
||||
indicates what nuclides the method should be applied to. In its absence,
|
||||
the method will be applied to all nuclides with 0 K elastic scattering
|
||||
data present.
|
||||
run_cmfd : bool
|
||||
Indicate if coarse mesh finite difference acceleration is to be used
|
||||
run_mode : {'eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart'}
|
||||
|
|
@ -215,8 +225,7 @@ class Settings(object):
|
|||
self._dd_allow_leakage = False
|
||||
self._dd_count_interactions = False
|
||||
|
||||
self._resonance_scattering = cv.CheckedList(
|
||||
ResonanceScattering, 'resonance scattering models')
|
||||
self._resonance_scattering = {}
|
||||
self._volume_calculations = cv.CheckedList(
|
||||
VolumeCalculation, 'volume calculations')
|
||||
|
||||
|
|
@ -778,10 +787,27 @@ class Settings(object):
|
|||
|
||||
@resonance_scattering.setter
|
||||
def resonance_scattering(self, res):
|
||||
if not isinstance(res, MutableSequence):
|
||||
res = [res]
|
||||
self._resonance_scattering = cv.CheckedList(
|
||||
ResonanceScattering, 'resonance scattering models', res)
|
||||
cv.check_type('resonance scattering settings', res, Mapping)
|
||||
keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides')
|
||||
for key, value in res.items():
|
||||
cv.check_value('resonance scattering dictionary key', key, keys)
|
||||
if key == 'enable':
|
||||
cv.check_type('resonance scattering enable', value, bool)
|
||||
elif key == 'method':
|
||||
cv.check_value('resonance scattering method', value,
|
||||
_RES_SCAT_METHODS)
|
||||
elif key == 'energy_min':
|
||||
name = 'resonance scattering minimum energy'
|
||||
cv.check_type(name, value, float)
|
||||
cv.check_greater_than(name, value, 0)
|
||||
elif key == 'energy_max':
|
||||
name = 'resonance scattering minimum energy'
|
||||
cv.check_type(name, value, float)
|
||||
cv.check_greater_than(name, value, 0)
|
||||
elif key == 'nuclides':
|
||||
cv.check_type('resonance scattering nuclides', value,
|
||||
Iterable, string_types)
|
||||
self._resonance_scattering = res
|
||||
|
||||
@volume_calculations.setter
|
||||
def volume_calculations(self, vol_calcs):
|
||||
|
|
@ -1049,10 +1075,24 @@ class Settings(object):
|
|||
subelement.text = str(self._dd_count_interactions).lower()
|
||||
|
||||
def _create_resonance_scattering_subelement(self, root):
|
||||
if len(self.resonance_scattering) > 0:
|
||||
res = self.resonance_scattering
|
||||
if res:
|
||||
elem = ET.SubElement(root, 'resonance_scattering')
|
||||
for r in self.resonance_scattering:
|
||||
elem.append(r.to_xml_element())
|
||||
if 'enable' in res:
|
||||
subelem = ET.SubElement(elem, 'enable')
|
||||
subelem.text = str(res['enable']).lower()
|
||||
if 'method' in res:
|
||||
subelem = ET.SubElement(elem, 'method')
|
||||
subelem.text = res['method']
|
||||
if 'energy_min' in res:
|
||||
subelem = ET.SubElement(elem, 'energy_min')
|
||||
subelem.text = str(res['energy_min'])
|
||||
if 'energy_max' in res:
|
||||
subelem = ET.SubElement(elem, 'energy_max')
|
||||
subelem.text = str(res['energy_max'])
|
||||
if 'nuclides' in res:
|
||||
subelem = ET.SubElement(elem, 'nuclides')
|
||||
subelem.text = ' '.join(res['nuclides'])
|
||||
|
||||
def _create_create_fission_neutrons_subelement(self, root):
|
||||
if self._create_fission_neutrons is not None:
|
||||
|
|
@ -1113,112 +1153,3 @@ class Settings(object):
|
|||
# Write the XML Tree to the settings.xml file
|
||||
tree = ET.ElementTree(root_element)
|
||||
tree.write(path, xml_declaration=True, encoding='utf-8', method="xml")
|
||||
|
||||
|
||||
class ResonanceScattering(object):
|
||||
"""Specification of the elastic scattering model for resonant isotopes
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nuclide : openmc.Nuclide or str
|
||||
The nuclide affected by this resonance scattering treatment.
|
||||
method : {'ARES', 'CXS', 'DBRC', 'WCM'}
|
||||
The method used to sample outgoing scattering energies. Valid options
|
||||
are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening
|
||||
rejection correction), and 'WCM' (weight correction method).
|
||||
E_min : float
|
||||
The minimum energy in eV above which the specified method is applied.
|
||||
By default, CXS will be used below E_min.
|
||||
E_max : float
|
||||
The maximum energy in eV below which the specified method is applied.
|
||||
By default, the asymptotic target-at-rest model is applied above E_max.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
nuclide : openmc.Nuclide or str
|
||||
The nuclide affected by this resonance scattering treatment.
|
||||
method : {'ARES', 'CXS', 'DBRC', 'WCM'}
|
||||
The method used to sample outgoing scattering energies. Valid options
|
||||
are 'ARES', 'CXS' (constant cross section), 'DBRC' (Doppler broadening
|
||||
rejection correction), and 'WCM' (weight correction method).
|
||||
E_min : float
|
||||
The minimum energy in eV above which the specified method is applied.
|
||||
By default, CXS will be used below E_min.
|
||||
E_max : float
|
||||
The maximum energy in eV below which the specified method is applied.
|
||||
By default, the asymptotic target-at-rest model is applied above E_max.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, nuclide, method='CXS', E_min=None, E_max=None):
|
||||
self._E_min = None
|
||||
self._E_max = None
|
||||
self.nuclide = nuclide
|
||||
self.method = method
|
||||
if E_min is not None:
|
||||
self.E_min = E_min
|
||||
if E_max is not None:
|
||||
self.E_max = E_max
|
||||
|
||||
@property
|
||||
def nuclide(self):
|
||||
return self._nuclide
|
||||
|
||||
@property
|
||||
def method(self):
|
||||
return self._method
|
||||
|
||||
@property
|
||||
def E_min(self):
|
||||
return self._E_min
|
||||
|
||||
@property
|
||||
def E_max(self):
|
||||
return self._E_max
|
||||
|
||||
@nuclide.setter
|
||||
def nuclide(self, nuc):
|
||||
cv.check_type('nuclide', nuc, (Nuclide,) + string_types)
|
||||
if isinstance(nuc, string_types):
|
||||
nuc = Nuclide(nuc)
|
||||
self._nuclide = nuc
|
||||
|
||||
@method.setter
|
||||
def method(self, m):
|
||||
cv.check_value('method', m, ('ARES', 'CXS', 'DBRC', 'WCM'))
|
||||
self._method = m
|
||||
|
||||
@E_min.setter
|
||||
def E_min(self, E):
|
||||
cv.check_type('E_min', E, Real)
|
||||
cv.check_greater_than('E_min', E, 0, True)
|
||||
self._E_min = E
|
||||
|
||||
@E_max.setter
|
||||
def E_max(self, E):
|
||||
cv.check_type('E_max', E, Real)
|
||||
cv.check_greater_than('E_max', E, 0, True)
|
||||
self._E_max = E
|
||||
|
||||
def to_xml_element(self):
|
||||
"""Return XML representation of the resonance scattering model
|
||||
|
||||
Returns
|
||||
-------
|
||||
element : xml.etree.ElementTree.Element
|
||||
XML element containing resonance scattering model
|
||||
|
||||
"""
|
||||
scatterer = ET.Element("scatterer")
|
||||
subelement = ET.SubElement(scatterer, 'nuclide')
|
||||
subelement.text = self.nuclide.name
|
||||
if self.method is not None:
|
||||
subelement = ET.SubElement(scatterer, 'method')
|
||||
subelement.text = self.method
|
||||
if self.E_min is not None:
|
||||
subelement = ET.SubElement(scatterer, 'E_min')
|
||||
subelement.text = str(self.E_min)
|
||||
if self.E_max is not None:
|
||||
subelement = ET.SubElement(scatterer, 'E_max')
|
||||
subelement.text = str(self.E_max)
|
||||
return scatterer
|
||||
|
|
|
|||
|
|
@ -269,6 +269,13 @@ module constants
|
|||
TEMPERATURE_NEAREST = 1, &
|
||||
TEMPERATURE_INTERPOLATION = 2
|
||||
|
||||
! Resonance elastic scattering methods
|
||||
integer, parameter :: &
|
||||
RES_SCAT_ARES = 1, &
|
||||
RES_SCAT_DBRC = 2, &
|
||||
RES_SCAT_WCM = 3, &
|
||||
RES_SCAT_CXS = 4
|
||||
|
||||
! ============================================================================
|
||||
! TALLY-RELATED CONSTANTS
|
||||
|
||||
|
|
|
|||
|
|
@ -429,9 +429,11 @@ module global
|
|||
! ============================================================================
|
||||
! RESONANCE SCATTERING VARIABLES
|
||||
|
||||
logical :: treat_res_scat = .false. ! is resonance scattering treated?
|
||||
integer :: n_res_scatterers_total = 0 ! total number of resonant scatterers
|
||||
type(Nuclide0K), allocatable, target :: nuclides_0K(:) ! 0K nuclides info
|
||||
logical :: res_scat_on = .false. ! is resonance scattering treated?
|
||||
integer :: res_scat_method = RES_SCAT_ARES ! resonance scattering method
|
||||
real(8) :: res_scat_energy_min = 0.01_8
|
||||
real(8) :: res_scat_energy_max = 1000.0_8
|
||||
character(10), allocatable :: res_scat_nuclides(:)
|
||||
|
||||
!$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, &
|
||||
!$omp& trace, thread_id, current_work, matching_bins, &
|
||||
|
|
@ -468,17 +470,11 @@ contains
|
|||
deallocate(nuclides)
|
||||
end if
|
||||
|
||||
if (allocated(nuclides_0K)) then
|
||||
deallocate(nuclides_0K)
|
||||
end if
|
||||
if (allocated(res_scat_nuclides)) deallocate(res_scat_nuclides)
|
||||
|
||||
if (allocated(nuclides_MG)) then
|
||||
deallocate(nuclides_MG)
|
||||
end if
|
||||
if (allocated(nuclides_MG)) deallocate(nuclides_MG)
|
||||
|
||||
if (allocated(macro_xs)) then
|
||||
deallocate(macro_xs)
|
||||
end if
|
||||
if (allocated(macro_xs)) deallocate(macro_xs)
|
||||
|
||||
if (allocated(sab_tables)) deallocate(sab_tables)
|
||||
if (allocated(micro_xs)) deallocate(micro_xs)
|
||||
|
|
|
|||
|
|
@ -94,11 +94,9 @@ contains
|
|||
type(XMLNode) :: node_sp
|
||||
type(XMLNode) :: node_output
|
||||
type(XMLNode) :: node_res_scat
|
||||
type(XMLNode) :: node_scatterer
|
||||
type(XMLNode) :: node_trigger
|
||||
type(XMLNode) :: node_vol
|
||||
type(XMLNode) :: node_tab_leg
|
||||
type(XMLNode), allocatable :: node_scat_list(:)
|
||||
type(XMLNode), allocatable :: node_source_list(:)
|
||||
type(XMLNode), allocatable :: node_vol_list(:)
|
||||
|
||||
|
|
@ -851,59 +849,53 @@ contains
|
|||
! Resonance scattering parameters
|
||||
if (check_for_node(root, "resonance_scattering")) then
|
||||
node_res_scat = root % child("resonance_scattering")
|
||||
call get_node_list(node_res_scat, "scatterer", node_scat_list)
|
||||
|
||||
! check that a nuclide is specified
|
||||
if (size(node_scat_list) >= 1) then
|
||||
treat_res_scat = .true.
|
||||
n_res_scatterers_total = size(node_scat_list)
|
||||
|
||||
! store 0K info for resonant scatterers
|
||||
allocate(nuclides_0K(n_res_scatterers_total))
|
||||
do i = 1, n_res_scatterers_total
|
||||
node_scatterer = node_scat_list(i)
|
||||
|
||||
! check to make sure a nuclide is specified
|
||||
if (.not. check_for_node(node_scatterer, "nuclide")) then
|
||||
call fatal_error("No nuclide specified for scatterer " &
|
||||
// trim(to_str(i)) // " in settings.xml file!")
|
||||
end if
|
||||
call get_node_value(node_scatterer, "nuclide", &
|
||||
nuclides_0K(i) % nuclide)
|
||||
|
||||
if (check_for_node(node_scatterer, "method")) then
|
||||
call get_node_value(node_scatterer, "method", &
|
||||
nuclides_0K(i) % scheme)
|
||||
end if
|
||||
|
||||
if (check_for_node(node_scatterer, "E_min")) then
|
||||
call get_node_value(node_scatterer, "E_min", &
|
||||
nuclides_0K(i) % E_min)
|
||||
end if
|
||||
|
||||
! check that E_min is non-negative
|
||||
if (nuclides_0K(i) % E_min < ZERO) then
|
||||
call fatal_error("Lower resonance scattering energy bound is &
|
||||
&negative")
|
||||
end if
|
||||
|
||||
if (check_for_node(node_scatterer, "E_max")) then
|
||||
call get_node_value(node_scatterer, "E_max", &
|
||||
nuclides_0K(i) % E_max)
|
||||
end if
|
||||
|
||||
! check that E_max is not less than E_min
|
||||
if (nuclides_0K(i) % E_max < nuclides_0K(i) % E_min) then
|
||||
call fatal_error("Lower resonance scattering energy bound exceeds &
|
||||
&upper")
|
||||
end if
|
||||
|
||||
nuclides_0K(i) % nuclide = trim(nuclides_0K(i) % nuclide)
|
||||
nuclides_0K(i) % scheme = to_lower(trim(nuclides_0K(i) % scheme))
|
||||
end do
|
||||
! See if resonance scattering is enabled
|
||||
if (check_for_node(node_res_scat, "enable")) then
|
||||
call get_node_value(node_res_scat, "enable", res_scat_on)
|
||||
else
|
||||
call fatal_error("No resonant scatterers are specified within the &
|
||||
&resonance_scattering element in settings.xml")
|
||||
res_scat_on = .true.
|
||||
end if
|
||||
|
||||
! Determine what method is used
|
||||
if (check_for_node(node_res_scat, "method")) then
|
||||
call get_node_value(node_res_scat, "method", temp_str)
|
||||
select case(to_lower(temp_str))
|
||||
case ('ares')
|
||||
res_scat_method = RES_SCAT_ARES
|
||||
case ('dbrc')
|
||||
res_scat_method = RES_SCAT_DBRC
|
||||
case ('wcm')
|
||||
res_scat_method = RES_SCAT_WCM
|
||||
case default
|
||||
call fatal_error("Unrecognized resonance elastic scattering method: " &
|
||||
// trim(temp_str) // ".")
|
||||
end select
|
||||
end if
|
||||
|
||||
! Minimum energy for resonance scattering
|
||||
if (check_for_node(node_res_scat, "energy_min")) then
|
||||
call get_node_value(node_res_scat, "energy_min", res_scat_energy_min)
|
||||
end if
|
||||
if (res_scat_energy_min < ZERO) then
|
||||
call fatal_error("Lower resonance scattering energy bound is negative")
|
||||
end if
|
||||
|
||||
! Maximum energy for resonance scattering
|
||||
if (check_for_node(node_res_scat, "energy_max")) then
|
||||
call get_node_value(node_res_scat, "energy_max", res_scat_energy_max)
|
||||
end if
|
||||
if (res_scat_energy_max < ZERO) then
|
||||
call fatal_error("Upper resonance scattering energy bound is negative")
|
||||
end if
|
||||
|
||||
! Get nuclides that resonance scattering should be applied to
|
||||
if (check_for_node(node_res_scat, "nuclides")) then
|
||||
n = node_word_count(node_res_scat, "nuclides")
|
||||
allocate(res_scat_nuclides(n))
|
||||
if (n > 0) then
|
||||
call get_node_array(node_res_scat, "nuclides", res_scat_nuclides)
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
|
|
@ -2147,12 +2139,11 @@ contains
|
|||
end do
|
||||
|
||||
! Check that 0K nuclides are listed in the cross_sections.xml file
|
||||
if (allocated(nuclides_0K)) then
|
||||
do i = 1, size(nuclides_0K)
|
||||
if (.not. library_dict % has_key(to_lower(nuclides_0K(i) % nuclide))) then
|
||||
if (allocated(res_scat_nuclides)) then
|
||||
do i = 1, size(res_scat_nuclides)
|
||||
if (.not. library_dict % has_key(to_lower(res_scat_nuclides(i)))) then
|
||||
call fatal_error("Could not find resonant scatterer " &
|
||||
// trim(nuclides_0K(i) % nuclide) &
|
||||
// " in cross_sections.xml file!")
|
||||
// trim(res_scat_nuclides(i)) // " in cross_sections.xml file!")
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
|
@ -5150,8 +5141,7 @@ contains
|
|||
call file_close(file_id)
|
||||
|
||||
! Assign resonant scattering data
|
||||
if (treat_res_scat) &
|
||||
call assign_0K_elastic_scattering(nuclides(i_nuclide))
|
||||
if (res_scat_on) call assign_0K_elastic_scattering(nuclides(i_nuclide))
|
||||
|
||||
! Determine if minimum/maximum energy for this nuclide is greater/less
|
||||
! than the previous
|
||||
|
|
@ -5289,13 +5279,10 @@ contains
|
|||
integer :: i, j
|
||||
real(8) :: xs_cdf_sum
|
||||
|
||||
do i = 1, size(nuclides_0K)
|
||||
if (nuc % name == nuclides_0K(i) % nuclide) then
|
||||
! Copy basic information from settings.xml
|
||||
do i = 1, size(res_scat_nuclides)
|
||||
if (nuc % name == res_scat_nuclides(i)) then
|
||||
! Set nuclide to be resonant
|
||||
nuc % resonant = .true.
|
||||
nuc % scheme = trim(nuclides_0K(i) % scheme)
|
||||
nuc % E_min = nuclides_0K(i) % E_min
|
||||
nuc % E_max = nuclides_0K(i) % E_max
|
||||
|
||||
! Build CDF for 0K elastic scattering
|
||||
xs_cdf_sum = ZERO
|
||||
|
|
|
|||
|
|
@ -65,12 +65,9 @@ module nuclide_header
|
|||
|
||||
! Resonance scattering info
|
||||
logical :: resonant = .false. ! resonant scatterer?
|
||||
character(16) :: scheme ! target velocity sampling scheme
|
||||
real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs
|
||||
real(8), allocatable :: elastic_0K(:) ! Microscopic elastic cross section
|
||||
real(8), allocatable :: xs_cdf(:) ! CDF of v_rel times cross section
|
||||
real(8) :: E_min ! lower cutoff energy for res scattering
|
||||
real(8) :: E_max ! upper cutoff energy for res scattering
|
||||
|
||||
! Fission information
|
||||
logical :: has_partial_fission = .false. ! nuclide has partial fission reactions?
|
||||
|
|
@ -104,18 +101,6 @@ module nuclide_header
|
|||
procedure, private :: create_derived => nuclide_create_derived
|
||||
end type Nuclide
|
||||
|
||||
!===============================================================================
|
||||
! NUCLIDE0K temporarily contains all 0K cross section data and other parameters
|
||||
! needed to treat resonance scattering before transferring them to Nuclide
|
||||
!===============================================================================
|
||||
|
||||
type Nuclide0K
|
||||
character(10) :: nuclide ! name of nuclide, e.g. U238
|
||||
character(16) :: scheme = 'ares' ! target velocity sampling scheme
|
||||
real(8) :: E_min = 0.01_8 ! lower cutoff energy for res scattering
|
||||
real(8) :: E_max = 1000.0_8 ! upper cutoff energy for res scattering
|
||||
end type Nuclide0K
|
||||
|
||||
!===============================================================================
|
||||
! NUCLIDEMICROXS contains cached microscopic cross sections for a
|
||||
! particular nuclide at the current energy
|
||||
|
|
|
|||
|
|
@ -832,24 +832,24 @@ contains
|
|||
|
||||
logical :: reject ! resample if true
|
||||
|
||||
character(80) :: sampling_scheme ! method of target velocity sampling
|
||||
integer :: sampling_method ! method of target velocity sampling
|
||||
|
||||
awr = nuc % awr
|
||||
|
||||
! check if nuclide is a resonant scatterer
|
||||
if (nuc % resonant) then
|
||||
|
||||
! sampling scheme to use
|
||||
sampling_scheme = nuc % scheme
|
||||
! sampling method to use
|
||||
sampling_method = res_scat_method
|
||||
|
||||
! upper resonance scattering energy bound (target is at rest above this E)
|
||||
if (E > nuc % E_max) then
|
||||
if (E > res_scat_energy_max) then
|
||||
v_target = ZERO
|
||||
return
|
||||
|
||||
! lower resonance scattering energy bound (should be no resonances below)
|
||||
else if (E < nuc % E_min) then
|
||||
sampling_scheme = 'cxs'
|
||||
else if (E < res_scat_energy_min) then
|
||||
sampling_method = RES_SCAT_CXS
|
||||
end if
|
||||
|
||||
! otherwise, use free gas model
|
||||
|
|
@ -858,19 +858,18 @@ contains
|
|||
v_target = ZERO
|
||||
return
|
||||
else
|
||||
sampling_scheme = 'cxs'
|
||||
sampling_method = RES_SCAT_CXS
|
||||
end if
|
||||
end if
|
||||
|
||||
! use appropriate target velocity sampling method
|
||||
select case (sampling_scheme)
|
||||
|
||||
case ('cxs')
|
||||
select case (sampling_method)
|
||||
case (RES_SCAT_CXS)
|
||||
|
||||
! sample target velocity with the constant cross section (cxs) approx.
|
||||
call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT)
|
||||
|
||||
case ('wcm')
|
||||
case (RES_SCAT_WCM)
|
||||
|
||||
! sample target velocity with the constant cross section (cxs) approx.
|
||||
call sample_cxs_target_velocity(nuc, v_target, E, uvw, kT)
|
||||
|
|
@ -881,7 +880,7 @@ contains
|
|||
wcf = xs_0K / xs_eff
|
||||
wgt = wcf * wgt
|
||||
|
||||
case ('dbrc')
|
||||
case (RES_SCAT_DBRC)
|
||||
E_red = sqrt((awr * E) / kT)
|
||||
E_low = (((E_red - FOUR)**2) * kT) / awr
|
||||
E_up = (((E_red + FOUR)**2) * kT) / awr
|
||||
|
|
@ -936,7 +935,7 @@ contains
|
|||
if (.not. reject) exit
|
||||
end do
|
||||
|
||||
case ('ares')
|
||||
case (RES_SCAT_ARES)
|
||||
E_red = sqrt((awr * E) / kT)
|
||||
E_low = (((E_red - FOUR)**2) * kT) / awr
|
||||
E_up = (((E_red + FOUR)**2) * kT) / awr
|
||||
|
|
@ -1025,9 +1024,6 @@ contains
|
|||
|
||||
if (.not. reject) exit
|
||||
end do
|
||||
|
||||
case default
|
||||
call fatal_error("Not a recognized resonance scattering treatment!")
|
||||
end select
|
||||
|
||||
end subroutine sample_target_velocity
|
||||
|
|
|
|||
|
|
@ -158,15 +158,11 @@ element settings {
|
|||
}? &
|
||||
|
||||
element resonance_scattering {
|
||||
element scatterer {
|
||||
(element nuclide { xsd:string { maxLength = "12" } } |
|
||||
attribute nuclide { xsd:string { maxLength = "12" } }) &
|
||||
(element method { xsd:string { maxLength = "16" } } |
|
||||
attribute method { xsd:string { maxLength = "16" } }) &
|
||||
(element E_min { xsd:double } |
|
||||
attribute E_min { xsd:double }) &
|
||||
(element E_max { xsd:double } |
|
||||
attribute E_max { xsd:double })?
|
||||
}*
|
||||
(element enable { xsd:boolean } | attribute enable { xsd:boolean })? &
|
||||
(element method { xsd:string } | attribute method { xsd:string })? &
|
||||
(element energy_min { xsd:double } | attribute energy_min { xsd:double })? &
|
||||
(element energy_max { xsd:double } | attribute energy_max { xsd:double })? &
|
||||
(element nuclides { list { xsd:string+ } } |
|
||||
attribute nuclides { list { xsd:string+ } })?
|
||||
}?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -715,54 +715,66 @@
|
|||
</optional>
|
||||
<optional>
|
||||
<element name="resonance_scattering">
|
||||
<zeroOrMore>
|
||||
<element name="scatterer">
|
||||
<interleave>
|
||||
<choice>
|
||||
<element name="nuclide">
|
||||
<data type="string">
|
||||
<param name="maxLength">12</param>
|
||||
</data>
|
||||
</element>
|
||||
<attribute name="nuclide">
|
||||
<data type="string">
|
||||
<param name="maxLength">12</param>
|
||||
</data>
|
||||
</attribute>
|
||||
</choice>
|
||||
<choice>
|
||||
<element name="method">
|
||||
<data type="string">
|
||||
<param name="maxLength">16</param>
|
||||
</data>
|
||||
</element>
|
||||
<attribute name="method">
|
||||
<data type="string">
|
||||
<param name="maxLength">16</param>
|
||||
</data>
|
||||
</attribute>
|
||||
</choice>
|
||||
<choice>
|
||||
<element name="E_min">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="E_min">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="E_max">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="E_max">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<interleave>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="enable">
|
||||
<data type="boolean"/>
|
||||
</element>
|
||||
<attribute name="enable">
|
||||
<data type="boolean"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="method">
|
||||
<data type="string"/>
|
||||
</element>
|
||||
<attribute name="method">
|
||||
<data type="string"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="energy_min">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="energy_min">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="energy_max">
|
||||
<data type="double"/>
|
||||
</element>
|
||||
<attribute name="energy_max">
|
||||
<data type="double"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<element name="nuclides">
|
||||
<list>
|
||||
<oneOrMore>
|
||||
<data type="string"/>
|
||||
</oneOrMore>
|
||||
</list>
|
||||
</element>
|
||||
<attribute name="nuclides">
|
||||
<list>
|
||||
<oneOrMore>
|
||||
<data type="string"/>
|
||||
</oneOrMore>
|
||||
</list>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
|
|
|
|||
|
|
@ -25,23 +25,10 @@
|
|||
</space>
|
||||
</source>
|
||||
<resonance_scattering>
|
||||
<scatterer>
|
||||
<nuclide>U238</nuclide>
|
||||
<method>DBRC</method>
|
||||
<E_min>1.0</E_min>
|
||||
<E_max>210.0</E_max>
|
||||
</scatterer>
|
||||
<scatterer>
|
||||
<nuclide>U235</nuclide>
|
||||
<method>WCM</method>
|
||||
<E_min>1.0</E_min>
|
||||
<E_max>210.0</E_max>
|
||||
</scatterer>
|
||||
<scatterer>
|
||||
<nuclide>Pu239</nuclide>
|
||||
<method>ARES</method>
|
||||
<E_min>1.0</E_min>
|
||||
<E_max>210.0</E_max>
|
||||
</scatterer>
|
||||
<enable>true</enable>
|
||||
<method>ares</method>
|
||||
<energy_min>1.0</energy_min>
|
||||
<energy_max>210.0</energy_max>
|
||||
<nuclides>U238 U235 Pu239</nuclides>
|
||||
</resonance_scattering>
|
||||
</settings>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
k-combined:
|
||||
1.399343E+00 1.149372E-01
|
||||
1.439342E+00 1.224486E-02
|
||||
|
|
|
|||
|
|
@ -27,20 +27,23 @@ class ResonanceScatteringTestHarness(PyAPITestHarness):
|
|||
geometry = openmc.Geometry(root_univ)
|
||||
geometry.export_to_xml()
|
||||
|
||||
# Settings
|
||||
res_scatt_dbrc = openmc.ResonanceScattering('U238', 'DBRC', 1.0, 210.0)
|
||||
res_scatt_wcm = openmc.ResonanceScattering('U235', 'WCM', 1.0, 210.0)
|
||||
res_scatt_ares = openmc.ResonanceScattering('Pu239', 'ARES', 1.0, 210.0)
|
||||
# Resonance elastic scattering settings
|
||||
res_scat_settings = {
|
||||
'enable': True,
|
||||
'energy_min': 1.0,
|
||||
'energy_max': 210.0,
|
||||
'method': 'ares',
|
||||
'nuclides': ['U238', 'U235', 'Pu239']
|
||||
}
|
||||
|
||||
sets_file = openmc.Settings()
|
||||
sets_file.batches = 10
|
||||
sets_file.inactive = 5
|
||||
sets_file.particles = 1000
|
||||
sets_file.source = openmc.source.Source(
|
||||
settings = openmc.Settings()
|
||||
settings.batches = 10
|
||||
settings.inactive = 5
|
||||
settings.particles = 1000
|
||||
settings.source = openmc.source.Source(
|
||||
space=openmc.stats.Box([-4, -4, -4], [4, 4, 4]))
|
||||
sets_file.resonance_scattering = [res_scatt_dbrc, res_scatt_wcm,
|
||||
res_scatt_ares]
|
||||
sets_file.export_to_xml()
|
||||
settings.resonance_scattering = res_scat_settings
|
||||
settings.export_to_xml()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue