From 489a03c648bb7914b69c2813f996ac37c1f65b77 Mon Sep 17 00:00:00 2001 From: amandalund Date: Thu, 25 Apr 2019 20:07:53 -0500 Subject: [PATCH] Get value from either attribute or element when reading settings from XML --- openmc/mesh.py | 13 +- openmc/settings.py | 468 +++++++++++++++++++---------------- openmc/source.py | 19 +- openmc/stats/multivariate.py | 13 +- openmc/stats/univariate.py | 17 +- 5 files changed, 289 insertions(+), 241 deletions(-) diff --git a/openmc/mesh.py b/openmc/mesh.py index a30b333fb3..fb59053aea 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -7,6 +7,7 @@ import numpy as np import openmc.checkvalue as cv import openmc +from openmc._xml import get_text from openmc.mixin import EqualityMixin, IDManagerMixin @@ -261,23 +262,23 @@ class Mesh(IDManagerMixin): Mesh generated from XML element """ - mesh_id = int(elem.get('id')) + mesh_id = int(get_text(elem, 'id')) mesh = cls(mesh_id) - mesh.type = elem.get('type') + mesh.type = get_text(elem, 'type') - dimension = elem.findtext('dimension') + dimension = get_text(elem, 'dimension') if dimension is not None: mesh.dimension = [int(x) for x in dimension.split()] - lower_left = elem.findtext('lower_left') + lower_left = get_text(elem, 'lower_left') if lower_left is not None: mesh.lower_left = [float(x) for x in lower_left.split()] - upper_right = elem.findtext('upper_right') + upper_right = get_text(elem, 'upper_right') if upper_right is not None: mesh.upper_right = [float(x) for x in upper_right.split()] - width = elem.findtext('width') + width = get_text(elem, 'width') if width is not None: mesh.width = [float(x) for x in width.split()] diff --git a/openmc/settings.py b/openmc/settings.py index a7ec086792..39312899b1 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -7,7 +7,7 @@ import sys import numpy as np -from openmc._xml import clean_indentation +from openmc._xml import clean_indentation, get_text import openmc.checkvalue as cv from openmc import VolumeCalculation, Source, Mesh @@ -927,6 +927,228 @@ class Settings(object): elem = ET.SubElement(root, "dagmc") elem.text = str(self._dagmc).lower() + def _eigenvalue_from_xml_element(self, root): + elem = root.find('eigenvalue') + if elem is not None: + self._run_mode_from_xml_element(elem) + self._particles_from_xml_element(elem) + self._batches_from_xml_element(elem) + self._inactive_from_xml_element(elem) + self._generations_per_batch_from_xml_element(elem) + + def _run_mode_from_xml_element(self, root): + text = get_text(root, 'run_mode') + if text is not None: + self.run_mode = text + + def _particles_from_xml_element(self, root): + text = get_text(root, 'particles') + if text is not None: + self.particles = int(text) + + def _batches_from_xml_element(self, root): + text = get_text(root, 'batches') + if text is not None: + self.batches = int(text) + + def _inactive_from_xml_element(self, root): + text = get_text(root, 'inactive') + if text is not None: + self.inactive = int(text) + + def _generations_per_batch_from_xml_element(self, root): + text = get_text(root, 'generations_per_batch') + if text is not None: + self.generations_per_batch = int(text) + + def _keff_trigger_from_xml_element(self, root): + elem = root.find('keff_trigger') + if elem is not None: + trigger = get_text(elem, 'type') + threshold = float(get_text(elem, 'threshold')) + self.keff_trigger = {'type': trigger, 'threshold': threshold} + + def _source_from_xml_element(self, root): + for elem in root.findall('source'): + self.source.append(Source.from_xml_element(elem)) + + def _output_from_xml_element(self, root): + elem = root.find('output') + if elem is not None: + self.output = {} + for key in ('summary', 'tallies', 'path'): + value = get_text(elem, key) + if value is not None: + if key in ('summary', 'tallies'): + value = value == 'true' + self.output[key] = value + + def _statepoint_from_xml_element(self, root): + elem = root.find('state_point') + if elem is not None: + text = get_text(elem, 'batches') + if text is not None: + self.statepoint['batches'] = [int(x) for x in text.split()] + + def _sourcepoint_from_xml_element(self, root): + elem = root.find('source_point') + if elem is not None: + for key in ('separate', 'write', 'overwrite', 'batches'): + value = get_text(elem, key) + if value is not None: + if key in ('separate', 'write', 'overwrite'): + value = value == 'true' + else: + value = [int(x) for x in value.split()] + self.sourcepoint[key] = value + + def _confidence_intervals_from_xml_element(self, root): + text = get_text(root, 'confidence_intervals') + if text is not None: + self.confidence_intervals = text == 'true' + + def _electron_treatment_from_xml_element(self, root): + text = get_text(root, 'electron_treatment') + if text is not None: + self.electron_treatment = text + + def _energy_mode_from_xml_element(self, root): + text = get_text(root, 'energy_mode') + if text is not None: + self.energy_mode = text + + def _max_order_from_xml_element(self, root): + text = get_text(root, 'max_order') + if text is not None: + self.max_order = int(text) + + def _photon_transport_from_xml_element(self, root): + text = get_text(root, 'photon_transport') + if text is not None: + self.photon_transport = text == 'true' + + def _ptables_from_xml_element(self, root): + text = get_text(root, 'ptables') + if text is not None: + self.ptables = text == 'true' + + def _seed_from_xml_element(self, root): + text = get_text(root, 'seed') + if text is not None: + self.seed = int(text) + + def _survival_biasing_from_xml_element(self, root): + text = get_text(root, 'survival_biasing') + if text is not None: + self.survival_biasing = text == 'true' + + def _cutoff_from_xml_element(self, root): + elem = root.find('cutoff') + if elem is not None: + self.cutoff = {} + for key in ('energy_neutron', 'energy_photon', 'energy_electron', + 'energy_positron', 'weight', 'weight_avg'): + value = get_text(elem, key) + if value is not None: + self.cutoff[key] = float(value) + + def _entropy_mesh_from_xml_element(self, root): + elem = root.find('entropy_mesh') + if elem is not None: + self.entropy_mesh = Mesh.from_xml_element(elem) + + def _trigger_from_xml_element(self, root): + elem = root.find('trigger') + if elem is not None: + self.trigger_active = get_text(elem, 'active') == 'true' + text = get_text(elem, 'max_batches') + if text is not None: + self.trigger_max_batches = int(text) + text = get_text(elem, 'batch_interval') + if text is not None: + self.trigger_batch_interval = int(text) + + def _no_reduce_from_xml_element(self, root): + text = get_text(root, 'no_reduce') + if text is not None: + self.no_reduce = text == 'true' + + def _verbosity_from_xml_element(self, root): + text = get_text(root, 'verbosity') + if text is not None: + self.verbosity = int(text) + + def _tabular_legendre_from_xml_element(self, root): + elem = root.find('tabular_legendre') + if elem is not None: + text = get_text(elem, 'enable') + self.tabular_legendre['enable'] = text == 'true' + text = get_text(elem, 'num_points') + if text is not None: + self.tabular_legendre['num_points'] = int(text) + + def _temperature_from_xml_element(self, root): + text = get_text(root, 'temperature_default') + if text is not None: + self.temperature['default'] = float(text) + text = get_text(root, 'temperature_tolerance') + if text is not None: + self.temperature['tolerance'] = float(text) + text = get_text(root, 'temperature_method') + if text is not None: + self.temperature['method'] = text + text = get_text(root, 'temperature_range') + if text is not None: + self.temperature['range'] = [float(x) for x in text.split()] + text = get_text(root, 'temperature_multipole') + if text is not None: + self.temperature['multipole'] = text == 'true' + + def _trace_from_xml_element(self, root): + text = get_text(root, 'trace') + if text is not None: + self.trace = [int(x) for x in text.split()] + + def _track_from_xml_element(self, root): + text = get_text(root, 'track') + if text is not None: + self.track = [int(x) for x in text.split()] + + def _ufs_mesh_from_xml_element(self, root): + elem = root.find('ufs_mesh') + if elem is not None: + self.ufs_mesh = Mesh.from_xml_element(elem) + + def _resonance_scattering_from_xml_element(self, root): + elem = root.find('resonance_scattering') + if elem is not None: + keys = ('enable', 'method', 'energy_min', 'energy_max', 'nuclides') + for key in keys: + value = get_text(elem, key) + if value is not None: + if key == 'enable': + value = value == 'true' + elif key in ('energy_min', 'energy_max'): + value = float(value) + elif key == 'nuclides': + value = value.split() + self.resonance_scattering[key] = value + + def _create_fission_neutrons_from_xml_element(self, root): + text = get_text(root, 'create_fission_neutrons') + if text is not None: + self.create_fission_neutrons = text == 'true' + + def _log_grid_bins_from_xml_element(self, root): + text = get_text(root, 'log_grid_bins') + if text is not None: + self.log_grid_bins = int(text) + + def _dagmc_from_xml_element(self, root): + text = get_text(root, 'dagmc') + if text is not None: + self.dagmc = text == 'true' + def export_to_xml(self, path='settings.xml'): """Export simulation settings to an XML file. @@ -1005,218 +1227,40 @@ class Settings(object): root = tree.getroot() settings = cls() - - # Get the run mode - elem = root.find('run_mode') - if elem is not None: - settings.run_mode = elem.text - - # Get number of particles - elem = root.find('particles') - if elem is not None: - settings.particles = int(elem.text) - - # Get number of batches - elem = root.find('batches') - if elem is not None: - settings.batches = int(elem.text) - - # Get number of inactive batches - elem = root.find('inactive') - if elem is not None: - settings.inactive = int(elem.text) - - # Get number of generations per batch - elem = root.find('generations_per_batch') - if elem is not None: - settings.generations_per_batch = int(elem.text) - - # Get keff trigger - elem = root.find('keff_trigger') - if elem is not None: - trigger = elem.findtext('type') - threshold = float(elem.findtext('threshold')) - settings.keff_trigger = {'type': trigger, 'threshold': threshold} - - # Get the source - for elem in root.findall('source'): - settings.source.append(Source.from_xml_element(elem)) - - # Get the output - elem = root.find('output') - if elem is not None: - settings.output = {} - for entry in elem: - key = entry.tag - if key in ('summary', 'tallies'): - value = entry.text == 'true' - else: - value = entry.text - settings.output[key] = value - - # Get the statepoint - elem = root.find('state_point') - if elem is not None: - batches = elem.findtext('batches') - if batches is not None: - settings.statepoint['batches'] = [int(x) for x in batches.split()] - - # Get the sourcepoint - elem = root.find('source_point') - if elem is not None: - for entry in elem: - key = entry.tag - if key in ('separate', 'write', 'overwrite'): - value = entry.text == 'true' - else: - value = [int(x) for x in entry.text.split()] - settings.sourcepoint[key] = value - - # Get confidence intervals - elem = root.find('confidence_intervals') - if elem is not None: - settings.confidence_intervals = elem.text == 'true' - - # Get electron treatment - elem = root.find('electron_treatment') - if elem is not None: - settings.electron_treatment = elem.text - - # Get energy mode - elem = root.find('energy_mode') - if elem is not None: - settings.energy_mode = elem.text - - # Get max order - elem = root.find('max_order') - if elem is not None: - settings.max_order = int(elem.text) - - # Get photon transport - elem = root.find('photon_transport') - if elem is not None: - settings.photon_transport = elem.text == 'true' - - # Get probability tables - elem = root.find('ptables') - if elem is not None: - settings.ptables = elem.text == 'true' - - # Get seed - elem = root.find('seed') - if elem is not None: - settings.seed = int(elem.text) - - # Get survival biasing - elem = root.find('survival_biasing') - if elem is not None: - settings.survival_biasing = elem.text == 'true' - - # Get cutoff - elem = root.find('cutoff') - if elem is not None: - settings.cutoff = {x.tag: float(x.text) for x in elem} - - # Get entropy mesh - elem = root.find('entropy_mesh') - if elem is not None: - settings.entropy_mesh = Mesh.from_xml_element(elem) - - # Get trigger - elem = root.find('trigger') - if elem is not None: - active = elem.find('active') - settings.trigger_active = active.text == 'true' - max_batches = elem.find('max_batches') - if max_batches is not None: - settings.trigger_max_batches = int(max_batches.text) - batch_interval = elem.find('batch_interval') - if batch_interval is not None: - settings.trigger_batch_interval = int(batch_interval.text) - - # Get no reduce - elem = root.find('no_reduce') - if elem is not None: - settings.no_reduce = elem.text == 'true' - - # Get verbosity - elem = root.find('verbosity') - if elem is not None: - settings.verbosity = int(elem.text) - - # Get tabular legendre - elem = root.find('tabular_legendre') - if elem is not None: - enable = elem.findtext('eneable') - settings.tabular_legendre['enable'] = enable == 'true' - num_points = elem.findtext('num_points') - if num_points is not None: - settings.tabular_legendre['num_points'] = int(num_points) - - # Get temperature - elem = root.findtext('temperature_default') - if elem is not None: - settings.temperature['default'] = float(elem) - elem = root.findtext('temperature_tolerance') - if elem is not None: - settings.temperature['tolerance'] = float(elem) - elem = root.findtext('temperature_method') - if elem is not None: - settings.temperature['method'] = elem - elem = root.findtext('temperature_range') - if elem is not None: - settings.temperature['range'] = [float(x) for x in elem.split()] - elem = root.findtext('temperature_multipole') - if elem is not None: - settings.temperature['multipole'] = elem == 'true' - - # Get trace - elem = root.find('trace') - if elem is not None: - settings.trace = [int(x) for x in elem.text.split()] - - # Get track - elem = root.find('track') - if elem is not None: - settings.track = [int(x) for x in elem.text.split()] - - # Get UFS mesh - elem = root.find('ufs_mesh') - if elem is not None: - settings.ufs_mesh = Mesh.from_xml_element(elem) - - # Get resonance scattering - elem = root.find('resonance_scattering') - if elem is not None: - for entry in elem: - key = entry.tag - if key == 'enable': - value = entry.text == 'true' - elif key == 'method': - value = entry.text - elif key == 'energy_min': - value = float(entry.text) - elif key == 'energy_max': - value = float(entry.text) - elif key == 'nuclides': - value = entry.text.split() - settings.resonance_scattering[key] = value + settings._eigenvalue_from_xml_element(root) + settings._run_mode_from_xml_element(root) + settings._particles_from_xml_element(root) + settings._batches_from_xml_element(root) + settings._inactive_from_xml_element(root) + settings._generations_per_batch_from_xml_element(root) + settings._keff_trigger_from_xml_element(root) + settings._source_from_xml_element(root) + settings._output_from_xml_element(root) + settings._statepoint_from_xml_element(root) + settings._sourcepoint_from_xml_element(root) + settings._confidence_intervals_from_xml_element(root) + settings._electron_treatment_from_xml_element(root) + settings._energy_mode_from_xml_element(root) + settings._max_order_from_xml_element(root) + settings._photon_transport_from_xml_element(root) + settings._ptables_from_xml_element(root) + settings._seed_from_xml_element(root) + settings._survival_biasing_from_xml_element(root) + settings._cutoff_from_xml_element(root) + settings._entropy_mesh_from_xml_element(root) + settings._trigger_from_xml_element(root) + settings._no_reduce_from_xml_element(root) + settings._verbosity_from_xml_element(root) + settings._tabular_legendre_from_xml_element(root) + settings._temperature_from_xml_element(root) + settings._trace_from_xml_element(root) + settings._track_from_xml_element(root) + settings._ufs_mesh_from_xml_element(root) + settings._resonance_scattering_from_xml_element(root) + settings._create_fission_neutrons_from_xml_element(root) + settings._log_grid_bins_from_xml_element(root) + settings._dagmc_from_xml_element(root) # TODO: Get volume calculations - # Get fission neutrons - elem = root.find('create_fission_neutrons') - if elem is not None: - settings.create_fission_neutrons = elem.text == 'true' - - # Get log grid bins - elem = root.find('log_grid_bins') - if elem is not None: - settings.log_grid_bins = int(elem.text) - - # Get dagmc - elem = root.find('dagmc') - if elem is not None: - settings.dagmc = elem.text == 'true' - return settings diff --git a/openmc/source.py b/openmc/source.py index e278d80892..5bafaf6984 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -2,6 +2,7 @@ from numbers import Real import sys from xml.etree import ElementTree as ET +from openmc._xml import get_text from openmc.stats.univariate import (Univariate, Discrete, Uniform, Maxwell, Watt, Normal, Muir, Tabular) from openmc.stats.multivariate import (UnitSphere, Spatial, PolarAzimuthal, @@ -158,21 +159,21 @@ class Source(object): """ source = cls() - strength = elem.find('strength') + strength = get_text(elem, 'strength') if strength is not None: - source.strength = float(strength.text) + source.strength = float(strength) - particle = elem.find('particle') + particle = get_text(elem, 'particle') if particle is not None: - source.particle = particle.text + source.particle = particle - filename = elem.find('file') + filename = get_text(elem, 'file') if filename is not None: - source.file = filename.text + source.file = filename space = elem.find('space') if space is not None: - space_type = space.get('type') + space_type = get_text(space, 'type') if space_type == 'cartesian': source.space = CartesianIndependent.from_xml_element(space) elif space_type == 'box' or space_type == 'fission': @@ -182,7 +183,7 @@ class Source(object): angle = elem.find('angle') if angle is not None: - angle_type = angle.get('type') + angle_type = get_text(angle, 'type') if angle_type == 'mu-phi': source.angle = PolarAzimuthal.from_xml_element(angle) elif angle_type == 'isotropic': @@ -192,7 +193,7 @@ class Source(object): energy = elem.find('energy') if energy is not None: - energy_type = energy.get('type') + energy_type = get_text(energy, 'type') if energy_type == 'discrete': source.energy = Discrete.from_xml_element(energy) elif energy_type == 'uniform': diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index 61122ada21..5a836ab63b 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -8,6 +8,7 @@ from xml.etree import ElementTree as ET import numpy as np import openmc.checkvalue as cv +from openmc._xml import get_text from openmc.stats.univariate import Univariate, Uniform @@ -142,7 +143,7 @@ class PolarAzimuthal(UnitSphere): """ mu_phi = cls() - params = elem.findtext('parameters') + params = get_text(elem, 'parameters') if params is not None: mu_phi.reference_uvw = [float(x) for x in params.split()] mu_phi.mu = openmc.stats.Univariate.from_xml_element(elem.find('mu')) @@ -239,7 +240,7 @@ class Monodirectional(UnitSphere): """ monodirectional = cls() - params = elem.findtext('parameters') + params = get_text(elem, 'parameters') if params is not None: monodirectional.reference_uvw = [float(x) for x in params.split()] return monodirectional @@ -457,10 +458,10 @@ class Box(Spatial): Box distribution generated from XML element """ - only_fissionable = elem.get('type') == 'fission' - params = [float(x) for x in elem.findtext('parameters').split()] + only_fissionable = get_text(elem, 'type') == 'fission' + params = [float(x) for x in get_text(elem, 'parameters').split()] lower_left = params[:len(params)//2] - upper_right = paramx[len(params)//2:] + upper_right = params[len(params)//2:] return cls(lower_left, upper_right, only_fissionable) @@ -526,5 +527,5 @@ class Point(Spatial): Point distribution generated from XML element """ - xyz = [float(x) for x in elem.findtext('parameters').split()] + xyz = [float(x) for x in get_text(elem, 'parameters').split()] return cls(xyz) diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 6a83cc780e..3088f8c779 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -7,6 +7,7 @@ from xml.etree import ElementTree as ET import numpy as np import openmc.checkvalue as cv +from openmc._xml import get_text from openmc.mixin import EqualityMixin @@ -130,7 +131,7 @@ class Discrete(Univariate): Discrete distribution generated from XML element """ - params = [float(x) for x in elem.findtext('parameters').split()] + params = [float(x) for x in get_text(elem, 'parameters').split()] x = params[:len(params)//2] p = params[len(params)//2:] return cls(x, p) @@ -221,7 +222,7 @@ class Uniform(Univariate): Uniform distribution generated from XML element """ - params = elem.findtext('parameters').split() + params = get_text(elem, 'parameters').split() a = float(params[0]) b = float(params[1]) return cls(a, b) @@ -297,7 +298,7 @@ class Maxwell(Univariate): Maxwellian distribution generated from XML element """ - theta = float(elem.findtext('parameters')) + theta = float(get_text(elem, 'parameters')) return cls(theta) @@ -386,7 +387,7 @@ class Watt(Univariate): Watt distribution generated from XML element """ - params = elem.findtext('parameters').split() + params = get_text(elem, 'parameters').split() a = float(params[0]) b = float(params[1]) return watt(a, b) @@ -476,7 +477,7 @@ class Normal(Univariate): Normal distribution generated from XML element """ - params = elem.findtext('parameters').split() + params = get_text(elem, 'parameters').split() mean_value = float(params[0]) std_dev = float(params[1]) return cls(mean_value, std_dev) @@ -585,7 +586,7 @@ class Muir(Univariate): Muir distribution generated from XML element """ - params = elem.findtext('parameters').split() + params = get_text(elem, 'parameters').split() e0 = float(params[0]) m_rat = float(params[1]) kt = float(params[2]) @@ -702,8 +703,8 @@ class Tabular(Univariate): Tabular distribution generated from XML element """ - interpolation = elem.get('interpolation') - params = [float(x) for x in elem.findtext('parameters').split()] + interpolation = get_text(elem, 'interpolation') + params = [float(x) for x in get_text(elem, 'parameters').split()] x = params[:len(params)//2] p = paramx[len(params)//2:] return cls(x, p, interpolation)