mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 05:35:49 -04:00
Add temperature range user option to load cross sections within a range of
temperatures.
This commit is contained in:
parent
efe1457589
commit
6fec79d9c2
8 changed files with 75 additions and 12 deletions
|
|
@ -661,6 +661,17 @@ methods like "nearest" and "interpolation" in the resolved resonance range.
|
|||
|
||||
*Default*: False
|
||||
|
||||
-------------------------------
|
||||
``<temperature_range>`` Element
|
||||
-------------------------------
|
||||
|
||||
The ``<temperature_range>`` element specifies a minimum and maximum temperature
|
||||
in Kelvin above and below which cross sections should be loaded for all nuclides
|
||||
and thermal scattering tables. This can be used for multi-physics simulations
|
||||
where the temperatures might change from one iteration to the next.
|
||||
|
||||
*Default*: None
|
||||
|
||||
.. _temperature_tolerance:
|
||||
|
||||
-----------------------------------
|
||||
|
|
|
|||
|
|
@ -125,13 +125,16 @@ class Settings(object):
|
|||
temperature : dict
|
||||
Defines a default temperature and method for treating intermediate
|
||||
temperatures at which nuclear data doesn't exist. Accepted keys are
|
||||
'default', 'method', 'tolerance', and 'multipole'. The value for
|
||||
'default' should be a float representing the default temperature in
|
||||
'default', 'method', 'range', 'tolerance', and 'multipole'. The value
|
||||
for 'default' should be a float representing the default temperature in
|
||||
Kelvin. The value for 'method' should be 'nearest' or 'interpolation'.
|
||||
If the method is 'nearest', 'tolerance' indicates a range of temperature
|
||||
within which cross sections may be used. 'multipole' is a boolean
|
||||
indicating whether or not the windowed multipole method should be used
|
||||
to evaluate resolved resonance cross sections.
|
||||
within which cross sections may be used. The value for 'range' should be
|
||||
a pair a minimum and maximum temperatures which are used to indicate
|
||||
that cross sections be loaded at all temperatures within the
|
||||
range. 'multipole' is a boolean indicating whether or not the windowed
|
||||
multipole method should be used to evaluate resolved resonance cross
|
||||
sections.
|
||||
threads : int
|
||||
Number of OpenMP threads
|
||||
trace : tuple or list
|
||||
|
|
@ -639,7 +642,8 @@ class Settings(object):
|
|||
cv.check_type('temperature settings', temperature, Mapping)
|
||||
for key, value in temperature.items():
|
||||
cv.check_value('temperature key', key,
|
||||
['default', 'method', 'tolerance', 'multipole'])
|
||||
['default', 'method', 'tolerance', 'multipole',
|
||||
'range'])
|
||||
if key == 'default':
|
||||
cv.check_type('default temperature', value, Real)
|
||||
elif key == 'method':
|
||||
|
|
@ -649,6 +653,11 @@ class Settings(object):
|
|||
cv.check_type('temperature tolerance', value, Real)
|
||||
elif key == 'multipole':
|
||||
cv.check_type('temperature multipole', value, bool)
|
||||
elif key == 'range':
|
||||
cv.check_length('temperature range', value, 2)
|
||||
for T in value:
|
||||
cv.check_type('temperature', T, Real)
|
||||
|
||||
self._temperature = temperature
|
||||
|
||||
@threads.setter
|
||||
|
|
@ -999,6 +1008,8 @@ class Settings(object):
|
|||
"temperature_{}".format(key))
|
||||
if isinstance(value, bool):
|
||||
element.text = str(value).lower()
|
||||
elif key == 'range':
|
||||
element.text = ' '.join(str(T) for T in value)
|
||||
else:
|
||||
element.text = str(value)
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ module global
|
|||
logical :: temperature_multipole = .false.
|
||||
real(8) :: temperature_tolerance = 10.0_8
|
||||
real(8) :: temperature_default = 293.6_8
|
||||
real(8) :: temperature_range(2) = [ZERO, ZERO]
|
||||
|
||||
! ============================================================================
|
||||
! MULTI-GROUP CROSS SECTION RELATED VARIABLES
|
||||
|
|
|
|||
|
|
@ -951,6 +951,9 @@ contains
|
|||
if (check_for_node(root, "temperature_multipole")) then
|
||||
call get_node_value(root, "temperature_multipole", temperature_multipole)
|
||||
end if
|
||||
if (check_for_node(root, "temperature_range")) then
|
||||
call get_node_array(root, "temperature_range", temperature_range)
|
||||
end if
|
||||
|
||||
! Check for tabular_legendre options
|
||||
if (check_for_node(root, "tabular_legendre")) then
|
||||
|
|
@ -5273,7 +5276,8 @@ contains
|
|||
! Read nuclide data from HDF5
|
||||
group_id = open_group(file_id, name)
|
||||
call nuclides(i_nuclide) % from_hdf5(group_id, nuc_temps(i_nuclide), &
|
||||
temperature_method, temperature_tolerance, master)
|
||||
temperature_method, temperature_tolerance, temperature_range, &
|
||||
master)
|
||||
call close_group(group_id)
|
||||
call file_close(file_id)
|
||||
|
||||
|
|
@ -5325,7 +5329,7 @@ contains
|
|||
! Read S(a,b) data from HDF5
|
||||
group_id = open_group(file_id, name)
|
||||
call sab_tables(i_sab) % from_hdf5(group_id, sab_temps(i_sab), &
|
||||
temperature_method, temperature_tolerance)
|
||||
temperature_method, temperature_tolerance, temperature_range)
|
||||
call close_group(group_id)
|
||||
call file_close(file_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -168,12 +168,13 @@ module nuclide_header
|
|||
end subroutine nuclide_clear
|
||||
|
||||
subroutine nuclide_from_hdf5(this, group_id, temperature, method, tolerance, &
|
||||
master)
|
||||
minmax, master)
|
||||
class(Nuclide), intent(inout) :: this
|
||||
integer(HID_T), intent(in) :: group_id
|
||||
type(VectorReal), intent(in) :: temperature ! list of desired temperatures
|
||||
type(VectorReal), intent(in) :: temperature ! list of desired temperatures
|
||||
integer, intent(inout) :: method
|
||||
real(8), intent(in) :: tolerance
|
||||
real(8), intent(in) :: minmax(2) ! range of temperatures
|
||||
logical, intent(in) :: master ! if this is the master proc
|
||||
|
||||
integer :: i
|
||||
|
|
@ -233,7 +234,18 @@ module nuclide_header
|
|||
method = TEMPERATURE_NEAREST
|
||||
end if
|
||||
|
||||
! Determine actual temperatures to read
|
||||
! Determine actual temperatures to read -- start by checking whether a
|
||||
! temperature range was given, in which case all temperatures in the range
|
||||
! are loaded irrespective of what temperatures actually appear in the model
|
||||
if (minmax(2) > ZERO) then
|
||||
do i = 1, size(temps_available)
|
||||
temp_actual = temps_available(i)
|
||||
if (minmax(1) <= temp_actual .and. temp_actual <= minmax(2)) then
|
||||
call temps_to_read % push_back(nint(temp_actual))
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
select case (method)
|
||||
case (TEMPERATURE_NEAREST)
|
||||
! Find nearest temperatures
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ element settings {
|
|||
|
||||
element temperature_multipole { xsd:boolean }? &
|
||||
|
||||
element temperature_range { list { xsd:double, xsd:double } }? &
|
||||
|
||||
element temperature_tolerance { xsd:double }? &
|
||||
|
||||
element threads { xsd:positiveInteger }? &
|
||||
|
|
|
|||
|
|
@ -517,6 +517,14 @@
|
|||
<data type="boolean"/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="temperature_range">
|
||||
<list>
|
||||
<data type="double"/>
|
||||
<data type="double"/>
|
||||
</list>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="temperature_tolerance">
|
||||
<data type="double"/>
|
||||
|
|
|
|||
|
|
@ -80,12 +80,14 @@ module sab_header
|
|||
|
||||
contains
|
||||
|
||||
subroutine salphabeta_from_hdf5(this, group_id, temperature, method, tolerance)
|
||||
subroutine salphabeta_from_hdf5(this, group_id, temperature, method, &
|
||||
tolerance, minmax)
|
||||
class(SAlphaBeta), intent(inout) :: this
|
||||
integer(HID_T), intent(in) :: group_id
|
||||
type(VectorReal), intent(in) :: temperature ! list of temperatures
|
||||
integer, intent(in) :: method
|
||||
real(8), intent(in) :: tolerance
|
||||
real(8), intent(in) :: minmax(2)
|
||||
|
||||
integer :: i, j
|
||||
integer :: t
|
||||
|
|
@ -143,6 +145,18 @@ contains
|
|||
end do
|
||||
call sort(temps_available)
|
||||
|
||||
! Determine actual temperatures to read -- start by checking whether a
|
||||
! temperature range was given, in which case all temperatures in the range
|
||||
! are loaded irrespective of what temperatures actually appear in the model
|
||||
if (minmax(2) > ZERO) then
|
||||
do i = 1, size(temps_available)
|
||||
temp_actual = temps_available(i)
|
||||
if (minmax(1) <= temp_actual .and. temp_actual <= minmax(2)) then
|
||||
call temps_to_read % push_back(nint(temp_actual))
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
select case (method)
|
||||
case (TEMPERATURE_NEAREST)
|
||||
! Determine actual temperatures to read
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue