diff --git a/openmc/settings.py b/openmc/settings.py index 918f97c7da..eb56381b07 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -155,7 +155,7 @@ class Settings(object): self._max_order = None # Source subelement - self._source = None + self._source = cv.CheckedList(Source, 'source distributions') self._confidence_intervals = None self._cross_sections = None @@ -216,12 +216,12 @@ class Settings(object): self._settings_file = ET.Element("settings") self._run_mode_subelement = None - self._source_element = None self._multipole_active = None - self._resonance_scattering = None - self._volume_calculations = cv.CheckedList(VolumeCalculation, - 'volume calculations') + self._resonance_scattering = cv.CheckedList( + ResonanceScattering, 'resonance scattering models') + self._volume_calculations = cv.CheckedList( + VolumeCalculation, 'volume calculations') @property def run_mode(self): @@ -502,11 +502,9 @@ class Settings(object): @source.setter def source(self, source): - if isinstance(source, Source): - self._source = [source,] - else: - cv.check_type('source distribution', source, Iterable, Source) - self._source = source + if not isinstance(source, MutableSequence): + source = [source] + self._source = cv.CheckedList(Source, 'source distributions', source) @output.setter def output(self, output): @@ -810,22 +808,17 @@ class Settings(object): @resonance_scattering.setter def resonance_scattering(self, res): - if isinstance(res, Iterable): - cv.check_type('resonance_scattering', res, Iterable, - ResonanceScattering) - self._resonance_scattering = res - else: - cv.check_type('resonance_scattering', res, ResonanceScattering) - self._resonance_scattering = [res] + if not isinstance(res, MutableSequence): + res = [res] + self._resonance_scattering = cv.CheckedList( + ResonanceScattering, 'resonance scattering models', res) @volume_calculations.setter def volume_calculations(self, vol_calcs): - name = 'stochastic volume calculations' if not isinstance(vol_calcs, MutableSequence): vol_calcs = [vol_calcs] - cv.check_type(name, vol_calcs, MutableSequence) - self._volume_calculations = cv.CheckedList(VolumeCalculation, - name, vol_calcs) + self._volume_calculations = cv.CheckedList( + VolumeCalculation, 'stochastic volume calculations', vol_calcs) def _create_run_mode_subelement(self): @@ -884,13 +877,12 @@ class Settings(object): element.text = str(self._max_order) def _create_source_subelement(self): - if self.source is not None: - for source in self.source: - self._settings_file.append(source.to_xml()) + for source in self.source: + self._settings_file.append(source.to_xml_element()) def _create_volume_calcs_subelement(self): for calc in self.volume_calculations: - self._settings_file.append(calc.to_xml()) + self._settings_file.append(calc.to_xml_element()) def _create_output_subelement(self): if self._output is not None: @@ -1121,18 +1113,15 @@ class Settings(object): "use_windowed_multipole") element.text = str(self._multipole_active) - def _create_resonance_scattering_element(self): - if self.resonance_scattering is None: - return - - element = ET.SubElement(self._settings_file, "resonance_scattering") - - for r in self.resonance_scattering: - if r.nuclide.name != r.nuclide_0K.name: - raise ValueError("The nuclide and nuclide_0K attributes of " - "a ResonantScattering object must have " - "identical names.") - r.create_xml_subelement(element) + def _create_resonance_scattering_subelement(self): + if len(self.resonance_scattering) > 0: + elem = ET.SubElement(self._settings_file, 'resonance_scattering') + for r in self.resonance_scattering: + if r.nuclide.name != r.nuclide_0K.name: + raise ValueError("The nuclide and nuclide_0K attributes of " + "a ResonantScattering object must have " + "identical names.") + elem.append(r.to_xml_element()) def export_to_xml(self): """Create a settings.xml file that can be used for a simulation. @@ -1144,7 +1133,6 @@ class Settings(object): self._source_subelement = None self._trigger_subelement = None self._run_mode_subelement = None - self._source_element = None self._create_run_mode_subelement() self._create_source_subelement() @@ -1172,7 +1160,7 @@ class Settings(object): self._create_ufs_subelement() self._create_dd_subelement() self._create_use_multipole_subelement() - self._create_resonance_scattering_element() + self._create_resonance_scattering_subelement() self._create_volume_calcs_subelement() # Clean the indentation in the file to be user-readable @@ -1261,8 +1249,16 @@ class ResonanceScattering(object): cv.check_greater_than('E_max', E, 0, True) self._E_max = E - def create_xml_subelement(self, xml_element): - scatterer = ET.SubElement(xml_element, "scatterer") + 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: @@ -1278,3 +1274,4 @@ class ResonanceScattering(object): if self.E_max is not None: subelement = ET.SubElement(scatterer, 'E_max') subelement.text = str(self.E_max) + return scatterer diff --git a/openmc/source.py b/openmc/source.py index 7e8a68accf..ee32cd0f4b 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -103,7 +103,7 @@ class Source(object): cv.check_greater_than('source strength', strength, 0.0, True) self._strength = strength - def to_xml(self): + def to_xml_element(self): """Return XML representation of the source Returns @@ -117,9 +117,9 @@ class Source(object): if self.file is not None: element.set("file", self.file) if self.space is not None: - element.append(self.space.to_xml()) + element.append(self.space.to_xml_element()) if self.angle is not None: - element.append(self.angle.to_xml()) + element.append(self.angle.to_xml_element()) if self.energy is not None: - element.append(self.energy.to_xml('energy')) + element.append(self.energy.to_xml_element('energy')) return element diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index e4eadd7aa4..e49a94ee19 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -50,7 +50,7 @@ class UnitSphere(object): self._reference_uvw = uvw/np.linalg.norm(uvw) @abstractmethod - def to_xml(self): + def to_xml_element(self): return '' @@ -109,13 +109,21 @@ class PolarAzimuthal(UnitSphere): cv.check_type('azimuthal angle', phi, Univariate) self._phi = phi - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the angular distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing angular distribution data + + """ element = ET.Element('angle') element.set("type", "mu-phi") if self.reference_uvw is not None: element.set("reference_uvw", ' '.join(map(str, self.reference_uvw))) - element.append(self.mu.to_xml('mu')) - element.append(self.phi.to_xml('phi')) + element.append(self.mu.to_xml_element('mu')) + element.append(self.phi.to_xml_element('phi')) return element @@ -127,7 +135,15 @@ class Isotropic(UnitSphere): def __init__(self): super(Isotropic, self).__init__() - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the isotropic distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing isotropic distribution data + + """ element = ET.Element('angle') element.set("type", "isotropic") return element @@ -152,7 +168,15 @@ class Monodirectional(UnitSphere): def __init__(self, reference_uvw=[1., 0., 0.]): super(Monodirectional, self).__init__(reference_uvw) - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the monodirectional distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing monodirectional distribution data + + """ element = ET.Element('angle') element.set("type", "monodirectional") if self.reference_uvw is not None: @@ -174,7 +198,7 @@ class Spatial(object): pass @abstractmethod - def to_xml(self): + def to_xml_element(self): return '' @@ -238,12 +262,20 @@ class CartesianIndependent(Spatial): cv.check_type('z coordinate', z, Univariate) self._z = z - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the spatial distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing spatial distribution data + + """ element = ET.Element('space') element.set('type', 'cartesian') - element.append(self.x.to_xml('x')) - element.append(self.y.to_xml('y')) - element.append(self.z.to_xml('z')) + element.append(self.x.to_xml_element('x')) + element.append(self.y.to_xml_element('y')) + element.append(self.z.to_xml_element('z')) return element @@ -308,7 +340,15 @@ class Box(Spatial): cv.check_type('only fissionable', only_fissionable, bool) self._only_fissionable = only_fissionable - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the box distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing box distribution data + + """ element = ET.Element('space') if self.only_fissionable: element.set("type", "fission") @@ -352,7 +392,15 @@ class Point(Spatial): cv.check_length('coordinate', xyz, 3) self._xyz = xyz - def to_xml(self): + def to_xml_element(self): + """Return XML representation of the point distribution + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing point distribution location + + """ element = ET.Element('space') element.set("type", "point") params = ET.SubElement(element, "parameters") diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 24ab98895d..3fdd5e4a29 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -29,7 +29,7 @@ class Univariate(object): pass @abstractmethod - def to_xml(self, element_name): + def to_xml_element(self, element_name): return '' @abstractmethod @@ -92,7 +92,20 @@ class Discrete(Univariate): cv.check_greater_than('discrete probability', pk, 0.0, True) self._p = p - def to_xml(self, element_name): + def to_xml_element(self, element_name): + """Return XML representation of the discrete distribution + + Parameters + ---------- + element_name : str + XML element name + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing discrete distribution data + + """ element = ET.Element(element_name) element.set("type", "discrete") @@ -153,7 +166,20 @@ class Uniform(Univariate): t.c = [0., 1.] return t - def to_xml(self, element_name): + def to_xml_element(self, element_name): + """Return XML representation of the uniform distribution + + Parameters + ---------- + element_name : str + XML element name + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing uniform distribution data + + """ element = ET.Element(element_name) element.set("type", "uniform") element.set("parameters", '{} {}'.format(self.a, self.b)) @@ -196,7 +222,20 @@ class Maxwell(Univariate): cv.check_greater_than('Maxwell temperature', theta, 0.0) self._theta = theta - def to_xml(self, element_name): + def to_xml_element(self, element_name): + """Return XML representation of the Maxwellian distribution + + Parameters + ---------- + element_name : str + XML element name + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing Maxwellian distribution data + + """ element = ET.Element(element_name) element.set("type", "maxwell") element.set("parameters", str(self.theta)) @@ -254,7 +293,20 @@ class Watt(Univariate): cv.check_greater_than('Watt b', b, 0.0) self._b = b - def to_xml(self, element_name): + def to_xml_element(self, element_name): + """Return XML representation of the Watt distribution + + Parameters + ---------- + element_name : str + XML element name + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing Watt distribution data + + """ element = ET.Element(element_name) element.set("type", "watt") element.set("parameters", '{} {}'.format(self.a, self.b)) @@ -333,7 +385,20 @@ class Tabular(Univariate): cv.check_value('interpolation', interpolation, _INTERPOLATION_SCHEMES) self._interpolation = interpolation - def to_xml(self, element_name): + def to_xml_element(self, element_name): + """Return XML representation of the tabular distribution + + Parameters + ---------- + element_name : str + XML element name + + Returns + ------- + element : xml.etree.ElementTree.Element + XML element containing tabular distribution data + + """ element = ET.Element(element_name) element.set("type", "tabular") element.set("interpolation", self.interpolation) @@ -386,7 +451,7 @@ class Legendre(Univariate): self._legendre_polynomial = np.polynomial.legendre.Legendre( coefficients) - def to_xml(self, element_name): + def to_xml_element(self, element_name): raise NotImplementedError @@ -440,5 +505,5 @@ class Mixture(Univariate): Iterable, Univariate) self._distribution = distribution - def to_xml(self, element_name): + def to_xml_element(self, element_name): raise NotImplementedError diff --git a/openmc/volume.py b/openmc/volume.py index 511af62ed3..167971bdbd 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -183,7 +183,7 @@ class VolumeCalculation(object): vol.results = results return vol - def to_xml(self): + def to_xml_element(self): """Return XML representation of the volume calculation Returns