Making sure meshes are only written once to a model.xml file

This commit is contained in:
Patrick Shriwise 2022-11-10 00:01:40 -06:00
parent 662d83a7dd
commit 1e7dbe99cf
3 changed files with 34 additions and 23 deletions

View file

@ -5,11 +5,8 @@ import os
from pathlib import Path
from numbers import Integral
from tempfile import NamedTemporaryFile
<<<<<<< HEAD
import warnings
=======
from xml.etree import ElementTree as ET
>>>>>>> d42935a08 (Writing all main nodes to a single XML file)
import h5py
@ -234,8 +231,16 @@ class Model:
model.geometry = \
openmc.Geometry.from_xml_element(root.find('geometry'), materials)
# gather meshses from other classes before reading the tally node
meshes = {}
if model.settings.entropy_mesh is not None:
meshes[model.settings.entropy_mesh.id] = model.settings.entropy_mesh
for ww in model.settings.weight_windows:
meshes[ww.mesh.id] = ww.mesh
if root.find('tallies'):
model.tallies = openmc.Tallies.from_xml_element(root.find('tallies'))
model.tallies = openmc.Tallies.from_xml_element(root.find('tallies'), meshes)
if root.find('plots'):
model.plots = openmc.Plots.from_xml_element(root.find('plots'))
@ -524,7 +529,8 @@ class Model:
# Can be used to modify tallies in case any surfaces are redundant
redundant_surfaces = self.geometry.remove_redundant_surfaces()
settings_element = self.settings.to_xml_element()
memo = set()
settings_element = self.settings.to_xml_element(memo)
geometry_element = self.geometry.to_xml_element()
# If a materials collection was specified, export it. Otherwise, look
@ -549,7 +555,7 @@ class Model:
ET.ElementTree(settings_element).write(fh, encoding='unicode')
if self.tallies:
tallies_element = self.tallies.to_xml_element()
tallies_element = self.tallies.to_xml_element(memo)
ET.ElementTree(tallies_element).write(fh, encoding='unicode')
if self.plots:
plots_element = self.plots.to_xml_element()

View file

@ -1073,7 +1073,7 @@ class Settings:
subelement = ET.SubElement(element, key)
subelement.text = str(value)
def _create_entropy_mesh_subelement(self, root):
def _create_entropy_mesh_subelement(self, root, memo=None):
if self.entropy_mesh is not None:
# use default heuristic for entropy mesh if not set by user
if self.entropy_mesh.dimension is None:
@ -1207,15 +1207,20 @@ class Settings:
elem = ET.SubElement(root, "write_initial_source")
elem.text = str(self._write_initial_source).lower()
def _create_weight_windows_subelement(self, root):
def _create_weight_windows_subelement(self, root, memo=None):
for ww in self._weight_windows:
# Add weight window information
root.append(ww.to_xml_element())
# check the memo for a mesh
if memo and ww.mesh.id in memo:
continue
# See if a <mesh> element already exists -- if not, add it
path = f"./mesh[@id='{ww.mesh.id}']"
if root.find(path) is None:
root.append(ww.mesh.to_xml_element())
if memo is not None: memo.add(ww.mesh.id)
if self._weight_windows_on is not None:
elem = ET.SubElement(root, "weight_windows_on")
@ -1539,7 +1544,7 @@ class Settings:
if text is not None:
self.max_tracks = int(text)
def to_xml_element(self):
def to_xml_element(self, memo=None):
"""Create a 'settings' element to be written to an XML file.
"""
@ -1569,7 +1574,7 @@ class Settings:
self._create_seed_subelement(element)
self._create_survival_biasing_subelement(element)
self._create_cutoff_subelement(element)
self._create_entropy_mesh_subelement(element)
self._create_entropy_mesh_subelement(element, memo)
self._create_trigger_subelement(element)
self._create_no_reduce_subelement(element)
self._create_verbosity_subelement(element)
@ -1587,7 +1592,7 @@ class Settings:
self._create_material_cell_offsets_subelement(element)
self._create_log_grid_bins_subelement(element)
self._create_write_initial_source_subelement(element)
self._create_weight_windows_subelement(element)
self._create_weight_windows_subelement(element, memo)
self._create_max_splits_subelement(element)
self._create_max_tracks_subelement(element)

View file

@ -3119,17 +3119,17 @@ class Tallies(cv.CheckedList):
for tally in self:
root_element.append(tally.to_xml_element())
def _create_mesh_subelements(self, root_element):
already_written = set()
def _create_mesh_subelements(self, root_element, memo=None):
already_written = memo if memo else set()
for tally in self:
for f in tally.filters:
if isinstance(f, openmc.MeshFilter):
if f.mesh.id not in already_written:
if len(f.mesh.name) > 0:
root_element.append(ET.Comment(f.mesh.name))
root_element.append(f.mesh.to_xml_element())
already_written.add(f.mesh.id)
if f.mesh.id in already_written:
continue
if len(f.mesh.name) > 0:
root_element.append(ET.Comment(f.mesh.name))
root_element.append(f.mesh.to_xml_element())
already_written.add(f.mesh.id)
def _create_filter_subelements(self, root_element):
already_written = dict()
@ -3155,11 +3155,11 @@ class Tallies(cv.CheckedList):
for d in derivs:
root_element.append(d.to_xml_element())
def to_xml_element(self):
def to_xml_element(self, memo=None):
"""Creates a 'tallies' element to be written to an XML file.
"""
element = ET.Element("tallies")
self._create_mesh_subelements(element)
self._create_mesh_subelements(element, memo)
self._create_filter_subelements(element)
self._create_tally_subelements(element)
self._create_derivative_subelements(element)
@ -3192,7 +3192,7 @@ class Tallies(cv.CheckedList):
tree.write(str(p), xml_declaration=True, encoding='utf-8')
@classmethod
def from_xml_element(cls, elem):
def from_xml_element(cls, elem, meshes=None):
"""Generate tallies from an XML element
Parameters
@ -3207,7 +3207,7 @@ class Tallies(cv.CheckedList):
"""
# Read mesh elements
meshes = {}
meshes = {} if meshes is None else meshes
for e in elem.findall('mesh'):
mesh = MeshBase.from_xml_element(e)
meshes[mesh.id] = mesh