Modify openmc.cmfd.CMFDFile to include several properties that were

missing. Also make various things in the module more Pythonic.
This commit is contained in:
Paul Romano 2015-06-01 14:35:53 +07:00
parent 11ab3b78aa
commit e53fc07b07
2 changed files with 225 additions and 108 deletions

View file

@ -1666,6 +1666,15 @@ The ``<begin>`` element controls what batch CMFD calculations should begin.
*Default*: 1
``<dhat_reset>`` Element
------------------------
The ``<dhat_reset>`` element controls whether :math:`\widehat{D}` nonlinear
CMFD parameters should be reset to zero before solving CMFD eigenproblem.
It can be turned on with "true" and off with "false".
*Default*: false
``<display>`` Element
---------------------
@ -1682,15 +1691,6 @@ The ``<display>`` element sets one additional CMFD output column. Options are:
*Default*: balance
``<dhat_reset>`` Element
------------------------
The ``<dhat_reset>`` element controls whether :math:`\widehat{D}` nonlinear
CMFD parameters should be reset to zero before solving CMFD eigenproblem.
It can be turned on with "true" and off with "false".
*Default*: false
``<downscatter>`` Element
-------------------------

View file

@ -54,7 +54,6 @@ class CMFDMesh(object):
"""
def __init__(self):
self._lower_left = None
self._upper_right = None
self._dimension = None
@ -93,7 +92,6 @@ class CMFDMesh(object):
@lower_left.setter
def lower_left(self, lower_left):
if not isinstance(lower_left, (tuple, list, np.ndarray)):
msg = 'Unable to set CMFD Mesh with lower_left {0} which is ' \
'not a Python list, tuple or NumPy array'.format(lower_left)
@ -105,7 +103,6 @@ class CMFDMesh(object):
raise ValueError(msg)
for coord in lower_left:
if not is_integer(coord) and not is_float(coord):
msg = 'Unable to set CMFD Mesh with lower_left {0} which is ' \
'not an integer or a floating point value'.format(coord)
@ -127,7 +124,6 @@ class CMFDMesh(object):
raise ValueError(msg)
for coord in upper_right:
if not is_integer(coord) and not is_float(coord):
msg = 'Unable to set CMFD Mesh with upper_right {0} which ' \
'is not an integer or floating point value'.format(coord)
@ -137,7 +133,6 @@ class CMFDMesh(object):
@dimension.setter
def dimension(self, dimension):
if not isinstance(dimension, (tuple, list, np.ndarray)):
msg = 'Unable to set CMFD Mesh with dimension {0} which is ' \
'not a Python list, tuple or NumPy array'.format(dimension)
@ -149,7 +144,6 @@ class CMFDMesh(object):
raise ValueError(msg)
for dim in dimension:
if not is_integer(dim):
msg = 'Unable to set CMFD Mesh with dimension {0} which ' \
'is a non-integer'.format(dim)
@ -159,9 +153,7 @@ class CMFDMesh(object):
@width.setter
def width(self, width):
if not width is None:
if not isinstance(width, (tuple, list, np.ndarray)):
msg = 'Unable to set CMFD Mesh with width {0} which ' \
'is not a Python list, tuple or NumPy array'.format(width)
@ -173,7 +165,6 @@ class CMFDMesh(object):
raise ValueError(msg)
for dim in width:
if not is_integer(dim) and not is_float(dim):
msg = 'Unable to set CMFD Mesh with width {0} which is ' \
'not an integer or floating point value'.format(width)
@ -183,19 +174,16 @@ class CMFDMesh(object):
@energy.setter
def energy(self, energy):
if not isinstance(energy, (tuple, list, np.ndarray)):
msg = 'Unable to set CMFD Mesh energy to {0} which is not ' \
'a Python tuple/list or NumPy array'.format(energy)
raise ValueError(msg)
for e in energy:
if not is_integer(e) and not is_float(e):
msg = 'Unable to set CMFD Mesh energy to {0} which is not ' \
'an integer or floating point value'.format(e)
raise ValueError(msg)
elif e < 0:
msg = 'Unable to set CMFD Mesh energy to {0} which is ' \
'is a negative integer'.format(e)
@ -205,7 +193,6 @@ class CMFDMesh(object):
@albedo.setter
def albedo(self, albedo):
if not isinstance(albedo, (tuple, list, np.ndarray)):
msg = 'Unable to set CMFD Mesh albedo to {0} which is not ' \
'a Python tuple/list or NumPy array'.format(albedo)
@ -217,12 +204,10 @@ class CMFDMesh(object):
raise ValueError(msg)
for a in albedo:
if not is_integer(a) and not is_float(a):
msg = 'Unable to set CMFD Mesh albedo to {0} which is not ' \
'an integer or floating point value'.format(a)
raise ValueError(msg)
elif a < 0 or a > 1:
msg = 'Unable to set CMFD Mesh albedo to {0} which is ' \
'is not in [0,1]'.format(a)
@ -239,7 +224,6 @@ class CMFDMesh(object):
raise ValueError(msg)
for m in map:
if m != 1 and m != 2:
msg = 'Unable to set CMFD Mesh map to {0} which is ' \
'is not 1 or 2'.format(m)
@ -250,77 +234,31 @@ class CMFDMesh(object):
def _get_xml_element(self):
element = ET.Element("mesh")
if len(self._lower_left) == 2:
subelement = ET.SubElement(element, "lower_left")
subelement.text = '{0} {1}'.format(self._lower_left[0],
self._lower_left[1])
else:
subelement = ET.SubElement(element, "lower_left")
subelement.text = '{0} {1} {2}'.format(self._lower_left[0],
self._lower_left[1],
self._lower_left[2])
subelement = ET.SubElement(element, "lower_left")
subelement.text = ' '.join(map(str, self._lower_left))
if not self._upper_right is None:
if len(self._upper_right) == 2:
subelement = ET.SubElement(element, "upper_right")
subelement.text = '{0} {1}'.format(self._upper_right[0],
self._upper_right[1])
else:
subelement = ET.SubElement(element, "upper_right")
subelement.text = '{0} {1} {2}'.format(self._upper_right[0],
self._upper_right[1],
self._upper_right[2])
subelement = ET.SubElement(element, "upper_right")
subelement.text = ' '.join(map(str, self._upper_right))
if len(self._dimension) == 2:
subelement = ET.SubElement(element, "dimension")
subelement.text = '{0} {1}'.format(self._dimension[0],
self._dimension[1])
else:
subelement = ET.SubElement(element, "dimension")
subelement.text = '{0} {1} {2}'.format(self._dimension[0],
self._dimension[1],
self._dimension[2])
subelement = ET.SubElement(element, "dimension")
subelement.text = ' '.join(map(str, self._dimension))
if not self._width is None:
if len(self._width) == 2:
subelement = ET.SubElement(element, "width")
subelement.text = '{0} {1}'.format(self._width[0],
self._width[1])
else:
subelement = ET.SubElement(element, "width")
subelement.text = '{0} {1} {2}'.format(self._width[0],
self._width[1],
self._width[2])
subelement = ET.SubElement(element, "width")
subelement.text = ' '.join(map(str, self._width))
if not self._energy is None:
subelement = ET.SubElement(element, "energy")
energy = ''
for e in self._energy:
energy += '{0} '.format(e)
subelement.set("energy", energy.rstrip(' '))
subelement.text = ' '.join(map(str, self._energy))
if not self._albedo is None:
subelement = ET.SubElement(element, "albedo")
albedo = ''
for a in self._albedo:
albedo += '{0} '.format(a)
subelement.set("albedo", albedo.rstrip(' '))
subelement.text = ' '.join(map(str, self._albedo))
if not self._map is None:
subelement = ET.SubElement(element, "map")
map = ''
for m in self._map:
map += '{0} '.format(m)
subelement.set("map", map.rstrip(' '))
subelement.text = ' '.join(map(str, self._map))
return element
@ -333,6 +271,9 @@ class CMFDFile(object):
----------
begin : int
Batch number at which CMFD calculations should begin
dhat_reset : bool
Indicate whether :math:`\widehat{D}` nonlinear CMFD parameters should be
reset to zero before solving CMFD eigenproblem.
display : {'balance', 'dominance', 'entropy', 'source'}
Set one additional CMFD output column. Options are:
@ -343,9 +284,17 @@ class CMFDFile(object):
* "entropy" - prints the *entropy* of the CMFD predicted fission source.
* "source" - prints the RMS [%] between the OpenMC fission source and
CMFD fission source.
downscatter : bool
Indicate whether an effective downscatter cross section should be used
when using 2-group CMFD.
feedback : bool
Indicate or not the CMFD diffusion result is used to adjust the weight
of fission source neutrons on the next OpenMC batch. Defaults to False.
gauss_seidel_tolerance : tuple or list or ndarray of float
Two parameters specifying the absolute inner tolerance and the relative
inner tolerance for Gauss-Seidel iterations when performing CMFD.
ktol : float
Tolerance on the eigenvalue when performing CMFD power iteration
cmfd_mesh : CMFDMesh
Structured mesh to be used for acceleration
norm : float
@ -354,6 +303,16 @@ class CMFDFile(object):
View convergence of power iteration during CMFD acceleration
run_adjoint : bool
Perform adjoint calculation on the last batch
shift : float
Optional Wielandt shift parameter for accelerating power iterations. By
default, it is very large so there is effectively no impact.
spectral : float
Optional spectral radius that can be used to accelerate the convergence
of Gauss-Seidel iterations during CMFD power iteration.
stol : float
Tolerance on the fission source when performing CMFD power iteration
tally_reset : list of int
List of batch numbers at which CMFD tallies should be reset
write_matrices : bool
Write sparse matrices that are used during CMFD acceleration (loss,
production) to file
@ -361,14 +320,21 @@ class CMFDFile(object):
"""
def __init__(self):
self._begin = None
self._dhat_reset = None
self._display = None
self._downscatter = None
self._feedback = None
self._gauss_seidel_tolerance = None
self._ktol = None
self._cmfd_mesh = None
self._norm = None
self._power_monitor = None
self._run_adjoint = None
self._shift = None
self._spectral = None
self._stol = None
self._tally_reset = None
self._write_matrices = None
self._cmfd_file = ET.Element("cmfd")
@ -378,14 +344,30 @@ class CMFDFile(object):
def begin(self):
return self._begin
@property
def dhat_reset(self):
return self._dhat_reset
@property
def display(self):
return self._display
@property
def downscatter(self):
return self._downscatter
@property
def feedback(self):
return self._feedback
@property
def gauss_seidel_tolerance(self):
return self._gauss_seidel_tolerance
@property
def ktol(self):
return self._ktol
@property
def cmfd_mesh(self):
return self._cmfd_mesh
@ -403,8 +385,20 @@ class CMFDFile(object):
return self._run_adjoint
@property
def solver(self):
return self._solver
def shift(self):
return self._shift
@property
def spectral(self):
return self._spectral
@property
def stol(self):
return self._stol
@property
def tally_reset(self):
return self._tally_reset
@property
def write_matrices(self):
@ -412,7 +406,6 @@ class CMFDFile(object):
@begin.setter
def begin(self, begin):
if not is_integer(begin):
msg = 'Unable to set CMFD begin batch to a non-integer ' \
'value {0}'.format(begin)
@ -425,9 +418,17 @@ class CMFDFile(object):
self._begin = begin
@dhat_reset.setter
def dhat_reset(self, dhat_reset):
if not isinstance(dhat_reset, bool):
msg = 'Unable to set Dhat reset to {0} which is ' \
'a non-boolean value'.format(dhat_reset)
raise ValueError(msg)
self._dhat_reset = dhat_reset
@display.setter
def display(self, display):
if not is_string(display):
msg = 'Unable to set CMFD display to a non-string ' \
'value'.format(display)
@ -440,9 +441,17 @@ class CMFDFile(object):
self._display = display
@downscatter.setter
def downscatter(self, downscatter):
if not isinstance(downscatter, bool):
msg = 'Unable to set downscatter to {0} which is ' \
'a non-boolean value'.format(downscatter)
raise ValueError(msg)
self._downscatter = downscatter
@feedback.setter
def feedback(self, feedback):
if not isinstance(feedback, bool):
msg = 'Unable to set CMFD feedback to {0} which is ' \
'a non-boolean value'.format(feedback)
@ -450,9 +459,38 @@ class CMFDFile(object):
self._feedback = feedback
@gauss_seidel_tolerance.setter
def gauss_seidel_tolerance(self, gauss_seidel_tolerance):
if not isinstance(gauss_seidel_tolerance, (float, list, np.ndarray)):
msg = 'Unable to set Gauss-Seidel tolerance to {0} which is ' \
'not a Python tuple/list or NumPy array'.format(
gauss_seidel_tolerance)
raise ValueError(msg)
if len(gauss_seidel_tolerance) != 2:
msg = 'Unable to set Gauss-Seidel tolerance with {0} since ' \
'it must be of length 2'.format(width)
raise ValueError(msg)
for t in gauss_seidel_tolerance:
if not is_integer(t) and not is_float(t):
msg = 'Unable to set Gauss-Seidel tolerance with {0} which ' \
'is not an integer or floating point value'.format(t)
raise ValueError(msg)
self._gauss_seidel_tolerance = gauss_seidel_tolerance
@ktol.setter
def ktol(self, ktol):
if not is_integer(ktol) and not is_float(ktol):
msg = 'Unable to set the eigenvalue tolerance to {0} which is ' \
'not an integer or floating point value'.format(ktol)
raise ValueError(msg)
self._ktol = ktol
@cmfd_mesh.setter
def cmfd_mesh(self, mesh):
if not isinstance(mesh, CMFDMesh):
msg = 'Unable to set CMFD mesh to {0} which is not a ' \
'CMFDMesh object'.format(mesh)
@ -462,7 +500,6 @@ class CMFDFile(object):
@norm.setter
def norm(self, norm):
if not is_integer(norm) and not is_float(norm):
msg = 'Unable to set the CMFD norm to {0} which is not ' \
'an integer or floating point value'.format(norm)
@ -472,7 +509,6 @@ class CMFDFile(object):
@power_monitor.setter
def power_monitor(self, power_monitor):
if not isinstance(power_monitor, bool):
msg = 'Unable to set CMFD power monitor to {0} which is a ' \
'non-boolean value'.format(power_monitor)
@ -482,7 +518,6 @@ class CMFDFile(object):
@run_adjoint.setter
def run_adjoint(self, run_adjoint):
if not isinstance(run_adjoint, bool):
msg = 'Unable to set CMFD run adjoint to {0} which is a ' \
'non-boolean value'.format(run_adjoint)
@ -490,9 +525,51 @@ class CMFDFile(object):
self._run_adjoint = run_adjoint
@shift.setter
def shift(self, shift):
if not is_integer(shift) and not is_float(shift):
msg = 'Unable to set the Wielandt shift to {0} which is ' \
'not an integer or floating point value'.format(shift)
raise ValueError(msg)
self._shift = shift
@spectral.setter
def spectral(self, spectral):
if not is_integer(spectral) and not is_float(spectral):
msg = 'Unable to set the spectral radius to {0} which is ' \
'not an integer or floating point value'.format(spectral)
raise ValueError(msg)
self._spectral = spectral
@stol.setter
def stol(self, stol):
if not is_integer(stol) and not is_float(stol):
msg = 'Unable to set the fission source tolerance to {0} which ' \
'is not an integer or floating point value'.format(stol)
raise ValueError(msg)
self._stol = stol
@tally_reset.setter
def tally_reset(self, tally_reset):
if not isinstance(tally_reset, (tuple, list, np.ndarray)):
msg = 'Unable to set tally reset batches to {0} which is ' \
'not a Python tuple/list or NumPy array'.format(
tally_reset)
raise ValueError(msg)
for t in tally_reset:
if not is_integer(t):
msg = 'Unable to set tally reset batch to {0} which ' \
'is not an integer'.format(t)
raise ValueError(msg)
self._tally_reset = tally_reset
@write_matrices.setter
def write_matrices(self, write_matrices):
if not isinstance(write_matrices, bool):
msg = 'Unable to set CMFD write matrices to {0} which is a ' \
'non-boolean value'.format(write_matrices)
@ -501,52 +578,84 @@ class CMFDFile(object):
self._write_matrices = write_matrices
def _create_begin_subelement(self):
if not self._begin is None:
element = ET.SubElement(self._cmfd_file, "begin")
element.text = '{0}'.format(str(self._begin))
element.text = str(self._begin)
def _create_dhat_reset_subelement(self):
if not self._dhat_reset is None:
element = ET.SubElement(self._cmfd_file, "dhat_reset")
element.text = str(self._dhat_reset).lower()
def _create_display_subelement(self):
if not self._display is None:
element = ET.SubElement(self._cmfd_file, "display")
element.text = '{0}'.format(str(self._display))
element.text = str(self._display)
def _create_downscatter_subelement(self):
if not self._downscatter is None:
element = ET.SubElement(self._cmfd_file, "downscatter")
element.text = str(self._downscatter).lower()
def _create_feedback_subelement(self):
if not self._feedback is None:
element = ET.SubElement(self._cmfd_file, "feeback")
element.text = '{0}'.format(str(self._feedback).lower())
element.text = str(self._feedback).lower()
def _create_gauss_seidel_tolerance_subelement(self):
if not self._gauss_seidel_tolerance is None:
element = ET.SubElement(self._cmfd_file, "gauss_seidel_tolerance")
element.text = ' '.join(map(str, self._gauss_seidel_tolerance))
def _create_ktol_subelement(self):
if not self._ktol is None:
element = ET.SubElement(self._ktol, "ktol")
element.text = str(self._ktol)
def _create_mesh_subelement(self):
if not self._mesh is None:
xml_element = self._mesh._get_xml_element()
self._cmfd_file.append(xml_element)
def _create_norm_subelement(self):
if not self._norm is None:
element = ET.SubElement(self._cmfd_file, "norm")
element.text = '{0}'.format(str(self._norm))
element.text = str(self._norm)
def _create_power_monitor_subelement(self):
if not self._power_monitor is None:
element = ET.SubElement(self._cmfd_file, "power_monitor")
element.text = '{0}'.format(str(self._power_monitor).lower())
element.text = str(self._power_monitor).lower()
def _create_run_adjoint_subelement(self):
if not self._run_adjoint is None:
element = ET.SubElement(self._cmfd_file, "run_adjoint")
element.text = '{0}'.format(str(self._run_adjoint).lower())
element.text = str(self._run_adjoint).lower()
def _create_shift_subelement(self):
if not self._shift is None:
element = ET.SubElement(self._shift, "shift")
element.text = str(self._shift)
def _create_spectral_subelement(self):
if not self._spectral is None:
element = ET.SubElement(self._spectral, "spectral")
element.text = str(self._spectral)
def _create_stol_subelement(self):
if not self._stol is None:
element = ET.SubElement(self._stol, "stol")
element.text = str(self._stol)
def _create_tally_reset_subelement(self):
if not self._tally_reset is None:
element = ET.SubElement(self._tally_reset, "tally_reset")
element.text = ' '.join(map(str, self._tally_reset))
def _create_write_matrices_subelement(self):
if not self._write_matrices is None:
element = ET.SubElement(self._cmfd_file, "write_matrices")
element.text = '{0}'.format(str(self._write_matrices).lower())
element.text = str(self._write_matrices).lower()
def export_to_xml(self):
"""Create a cmfd.xml file using the class data that can be used for an OpenMC
@ -555,12 +664,20 @@ class CMFDFile(object):
"""
self._create_begin_subelement()
self._create_dhat_reset_subelement()
self._create_display_subelement()
self._create_downscatter_subelement()
self._create_feedback_subelement()
self._create_gauss_seidel_tolerance_subelement()
self._create_ktol_subelement()
self._create_mesh_subelement()
self._create_norm_subelement()
self._create_power_monitor_subelement()
self._create_run_adjoint_subelement()
self._create_shift_subelement()
self._create_spectral_subelement()
self._create_stol_subelement()
self._create_tally_reset_subelement()
self._create_write_matrices_subelement()
# Clean the indentation in the file to be user-readable