Adding import for single or multiple XMLs

This commit is contained in:
Patrick Shriwise 2022-11-03 22:29:36 -05:00
parent 81aa653d50
commit 9391f17cff
6 changed files with 232 additions and 110 deletions

View file

@ -162,13 +162,13 @@ class Geometry:
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml(cls, path='geometry.xml', materials=None):
"""Generate geometry from XML file
def from_xml_element(cls, elem, materials=None):
"""Generate geometry from an XML element
Parameters
----------
path : str, optional
Path to geometry XML file
elem : xml.etree.ElementTree.Element
XML element
materials : openmc.Materials or None
Materials used to assign to cells. If None, an attempt is made to
generate it from the materials.xml file.
@ -187,13 +187,10 @@ class Geometry:
universes[univ_id] = univ
return universes[univ_id]
tree = ET.parse(path)
root = tree.getroot()
# Get surfaces
surfaces = {}
periodic = {}
for surface in root.findall('surface'):
for surface in elem.findall('surface'):
s = openmc.Surface.from_xml_element(surface)
surfaces[s.id] = s
@ -207,15 +204,15 @@ class Geometry:
surfaces[s1].periodic_surface = surfaces[s2]
# Add any DAGMC universes
for elem in root.findall('dagmc_universe'):
for elem in elem.findall('dagmc_universe'):
dag_univ = openmc.DAGMCUniverse.from_xml_element(elem)
universes[dag_univ.id] = dag_univ
# Dictionary that maps each universe to a list of cells/lattices that
# contain it (needed to determine which universe is the root)
# contain it (needed to determine which universe is the elem)
child_of = defaultdict(list)
for elem in root.findall('lattice'):
for elem in elem.findall('lattice'):
lat = openmc.RectLattice.from_xml_element(elem, get_universe)
universes[lat.id] = lat
if lat.outer is not None:
@ -223,7 +220,7 @@ class Geometry:
for u in lat.universes.ravel():
child_of[u].append(lat)
for elem in root.findall('hex_lattice'):
for elem in elem.findall('hex_lattice'):
lat = openmc.HexLattice.from_xml_element(elem, get_universe)
universes[lat.id] = lat
if lat.outer is not None:
@ -245,7 +242,7 @@ class Geometry:
mats = {str(m.id): m for m in materials}
mats['void'] = None
for elem in root.findall('cell'):
for elem in elem.findall('cell'):
c = openmc.Cell.from_xml_element(elem, surfaces, mats, get_universe)
if c.fill_type in ('universe', 'lattice'):
child_of[c.fill].append(c)
@ -258,6 +255,29 @@ class Geometry:
else:
raise ValueError('Error determining root universe.')
@classmethod
def from_xml(cls, path='geometry.xml', materials=None):
"""Generate geometry from XML file
Parameters
----------
path : str, optional
Path to geometry XML file
materials : openmc.Materials or None
Materials used to assign to cells. If None, an attempt is made to
generate it from the materials.xml file.
Returns
-------
openmc.Geometry
Geometry object
"""
tree = ET.parse(path)
root = tree.getroot()
return cls.from_xml_element(root, materials)
def find(self, point):
"""Find cells/universes/lattices which contain a given point

View file

@ -1508,6 +1508,34 @@ class Materials(cv.CheckedList):
errors='xmlcharrefreplace') as fh:
self._write_xml(fh)
@classmethod
def from_xml_element(cls, elem):
"""Generate materials collection from XML file
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Materials
Materials collection
"""
# Generate each material
materials = cls()
for material in elem.findall('material'):
materials.append(Material.from_xml_element(material))
# Check for cross sections settings
xs = elem.find('cross_sections')
if xs is not None:
materials.cross_sections = xs.text
return materials
@classmethod
def from_xml(cls, path: PathLike = 'materials.xml'):
"""Generate materials collection from XML file
@ -1526,14 +1554,4 @@ class Materials(cv.CheckedList):
tree = ET.parse(path)
root = tree.getroot()
# Generate each material
materials = cls()
for material in root.findall('material'):
materials.append(Material.from_xml_element(material))
# Check for cross sections settings
xs = tree.find('cross_sections')
if xs is not None:
materials.cross_sections = xs.text
return materials
return cls.from_xml_element(root)

View file

@ -208,7 +208,42 @@ class Model:
self._plots.append(plot)
@classmethod
def from_xml(cls, geometry='geometry.xml', materials='materials.xml',
def from_xml(cls, separate_xmls=True, **kwargs):
if separate_xmls:
return cls.from_separate_xmls(**kwargs)
else:
return cls.from_model_xml(**kwargs)
@classmethod
def from_model_xml(cls, path='model.xml'):
"""Create model from single XML file
Parameters
----------
path : str or Pathlike
Path to model.xml file
"""
tree = ET.parse(path)
root = tree.getroot()
model = cls()
model.settings = openmc.Settings.from_xml_element(root.find('settings'))
model.materials = openmc.Materials.from_xml_element(root.find('materials'))
model.geometry = \
openmc.Geometry.from_xml_element(root.find('geometry'), model.materials)
if tally_node := root.find('tallies'):
print(tally_node)
model.tallies = openmc.Tallies.from_xml_element(tally_node)
if plots_node := root.find('plots'):
model.plots = openmc.Plots.from_xml_element(plots_node)
return model
@classmethod
def from_separate_xmls(cls, geometry='geometry.xml', materials='materials.xml',
settings='settings.xml', tallies='tallies.xml',
plots='plots.xml'):
"""Create model from existing XML files

View file

@ -941,6 +941,27 @@ class Plots(cv.CheckedList):
tree = ET.ElementTree(self._plots_file)
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml_element(cls, elem):
"""Generate plots collection from XML file
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Plots
Plots collection
"""
# Generate each plot
plots = cls()
for elem in elem.findall('plot'):
plots.append(Plot.from_xml_element(elem))
return plots
@classmethod
def from_xml(cls, path='plots.xml'):
"""Generate plots collection from XML file
@ -958,9 +979,6 @@ class Plots(cv.CheckedList):
"""
tree = ET.parse(path)
root = tree.getroot()
return cls.from_xml_element(root)
# Generate each plot
plots = cls()
for elem in root.findall('plot'):
plots.append(Plot.from_xml_element(elem))
return plots

View file

@ -1595,7 +1595,7 @@ class Settings:
clean_indentation(element)
return element
def export_to_xml(self, path: PathLike = 'settings.xml'):
"""Export simulation settings to an XML file.
@ -1617,6 +1617,71 @@ class Settings:
tree = ET.ElementTree(root_element)
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml_element(cls, elem):
"""Generate settings from XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Settings
Settings object
"""
settings = cls()
settings._eigenvalue_from_xml_element(elem)
settings._run_mode_from_xml_element(elem)
settings._particles_from_xml_element(elem)
settings._batches_from_xml_element(elem)
settings._inactive_from_xml_element(elem)
settings._max_lost_particles_from_xml_element(elem)
settings._rel_max_lost_particles_from_xml_element(elem)
settings._generations_per_batch_from_xml_element(elem)
settings._keff_trigger_from_xml_element(elem)
settings._source_from_xml_element(elem)
settings._volume_calcs_from_xml_element(elem)
settings._output_from_xml_element(elem)
settings._statepoint_from_xml_element(elem)
settings._sourcepoint_from_xml_element(elem)
settings._surf_source_read_from_xml_element(elem)
settings._surf_source_write_from_xml_element(elem)
settings._confidence_intervals_from_xml_element(elem)
settings._electron_treatment_from_xml_element(elem)
settings._energy_mode_from_xml_element(elem)
settings._max_order_from_xml_element(elem)
settings._photon_transport_from_xml_element(elem)
settings._ptables_from_xml_element(elem)
settings._seed_from_xml_element(elem)
settings._survival_biasing_from_xml_element(elem)
settings._cutoff_from_xml_element(elem)
settings._entropy_mesh_from_xml_element(elem)
settings._trigger_from_xml_element(elem)
settings._no_reduce_from_xml_element(elem)
settings._verbosity_from_xml_element(elem)
settings._tabular_legendre_from_xml_element(elem)
settings._temperature_from_xml_element(elem)
settings._trace_from_xml_element(elem)
settings._track_from_xml_element(elem)
settings._ufs_mesh_from_xml_element(elem)
settings._resonance_scattering_from_xml_element(elem)
settings._create_fission_neutrons_from_xml_element(elem)
settings._delayed_photon_scaling_from_xml_element(elem)
settings._event_based_from_xml_element(elem)
settings._max_particles_in_flight_from_xml_element(elem)
settings._material_cell_offsets_from_xml_element(elem)
settings._log_grid_bins_from_xml_element(elem)
settings._write_initial_source_from_xml_element(elem)
settings._weight_windows_from_xml_element(elem)
settings._max_splits_from_xml_element(elem)
settings._max_tracks_from_xml_element(elem)
# TODO: Get volume calculations
return settings
@classmethod
def from_xml(cls, path: PathLike = 'settings.xml'):
"""Generate settings from XML file
@ -1636,54 +1701,4 @@ class Settings:
"""
tree = ET.parse(path)
root = tree.getroot()
settings = cls()
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._max_lost_particles_from_xml_element(root)
settings._rel_max_lost_particles_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._volume_calcs_from_xml_element(root)
settings._output_from_xml_element(root)
settings._statepoint_from_xml_element(root)
settings._sourcepoint_from_xml_element(root)
settings._surf_source_read_from_xml_element(root)
settings._surf_source_write_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._delayed_photon_scaling_from_xml_element(root)
settings._event_based_from_xml_element(root)
settings._max_particles_in_flight_from_xml_element(root)
settings._material_cell_offsets_from_xml_element(root)
settings._log_grid_bins_from_xml_element(root)
settings._write_initial_source_from_xml_element(root)
settings._weight_windows_from_xml_element(root)
settings._max_splits_from_xml_element(root)
settings._max_tracks_from_xml_element(root)
# TODO: Get volume calculations
return settings
return cls.from_xml_element(root)

View file

@ -3191,6 +3191,49 @@ class Tallies(cv.CheckedList):
tree = ET.ElementTree(root_element)
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml_element(cls, elem):
"""Generate tallies from an XML element
Parameters
----------
elem : xml.etree.ElementTree.Element
XML element
Returns
-------
openmc.Tallies
Tallies object
"""
# Read mesh elements
meshes = {}
for elem in elem.findall('mesh'):
mesh = MeshBase.from_xml_element(elem)
meshes[mesh.id] = mesh
# Read filter elements
filters = {}
for elem in elem.findall('filter'):
filter = openmc.Filter.from_xml_element(elem, meshes=meshes)
filters[filter.id] = filter
# Read derivative elements
derivatives = {}
for elem in elem.findall('derivative'):
deriv = openmc.TallyDerivative.from_xml_element(elem)
derivatives[deriv.id] = deriv
# Read tally elements
tallies = []
for elem in elem.findall('tally'):
tally = openmc.Tally.from_xml_element(
elem, filters=filters, derivatives=derivatives
)
tallies.append(tally)
return cls(tallies)
@classmethod
def from_xml(cls, path='tallies.xml'):
"""Generate tallies from XML file
@ -3208,31 +3251,4 @@ class Tallies(cv.CheckedList):
"""
tree = ET.parse(path)
root = tree.getroot()
# Read mesh elements
meshes = {}
for elem in root.findall('mesh'):
mesh = MeshBase.from_xml_element(elem)
meshes[mesh.id] = mesh
# Read filter elements
filters = {}
for elem in root.findall('filter'):
filter = openmc.Filter.from_xml_element(elem, meshes=meshes)
filters[filter.id] = filter
# Read derivative elements
derivatives = {}
for elem in root.findall('derivative'):
deriv = openmc.TallyDerivative.from_xml_element(elem)
derivatives[deriv.id] = deriv
# Read tally elements
tallies = []
for elem in root.findall('tally'):
tally = openmc.Tally.from_xml_element(
elem, filters=filters, derivatives=derivatives
)
tallies.append(tally)
return cls(tallies)
return cls.from_xml_element(root)