Skip to content

Commit fb74398

Browse files
Copilotjtramm
andcommitted
Fix random ray source region mesh export bug in Settings
Co-authored-by: jtramm <1009059+jtramm@users.noreply.github.com>
1 parent 026093b commit fb74398

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

openmc/settings.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,9 +1714,12 @@ def _create_random_ray_subelement(self, root, mesh_memo=None):
17141714
domain_elem = ET.SubElement(mesh_elem, 'domain')
17151715
domain_elem.set('id', str(domain.id))
17161716
domain_elem.set('type', domain.__class__.__name__.lower())
1717-
if mesh_memo is not None and mesh.id not in mesh_memo:
1717+
# See if a <mesh> element already exists -- if not, add it
1718+
path = f"./mesh[@id='{mesh.id}']"
1719+
if root.find(path) is None:
17181720
root.append(mesh.to_xml_element())
1719-
mesh_memo.add(mesh.id)
1721+
if mesh_memo is not None:
1722+
mesh_memo.add(mesh.id)
17201723
else:
17211724
subelement = ET.SubElement(element, key)
17221725
subelement.text = str(value)

tests/unit_tests/test_settings.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import openmc
22
import openmc.stats
3+
import xml.etree.ElementTree as ET
34

45

56
def test_export_to_xml(run_in_tmpdir):
@@ -147,3 +148,60 @@ def test_export_to_xml(run_in_tmpdir):
147148
assert s.random_ray['ray_source'].space.upper_right == [1., 1., 1.]
148149
assert s.max_secondaries == 1_000_000
149150
assert s.source_rejection_fraction == 0.01
151+
152+
153+
def test_random_ray_source_region_meshes_export(run_in_tmpdir):
154+
"""Test that random ray source region meshes are properly exported to XML
155+
156+
This is a regression test for the bug where meshes were not included in
157+
settings.xml when using export_to_xml() but worked correctly with
158+
export_to_model_xml().
159+
"""
160+
# Create minimal settings
161+
s = openmc.Settings()
162+
s.particles = 1000
163+
s.batches = 10
164+
s.inactive = 5
165+
s.run_mode = 'eigenvalue'
166+
167+
# Create a mesh for random ray source region meshes
168+
mesh = openmc.RegularMesh()
169+
mesh.dimension = [2, 2, 2]
170+
mesh.lower_left = [-1, -1, -1]
171+
mesh.upper_right = [1, 1, 1]
172+
173+
# Create a simple universe
174+
root_universe = openmc.Universe()
175+
176+
# Set up random ray with source region meshes
177+
s.random_ray = {
178+
'source_region_meshes': [(mesh, [root_universe])]
179+
}
180+
181+
# Test 1: Export to XML using export_to_xml (the problematic case)
182+
s.export_to_xml()
183+
184+
# Parse the settings XML and check for mesh elements
185+
tree = ET.parse('settings.xml')
186+
root = tree.getroot()
187+
mesh_elements = root.findall('.//mesh')
188+
189+
# There should be 2 mesh elements:
190+
# 1. The mesh reference inside source_region_meshes
191+
# 2. The actual mesh definition at the top level
192+
assert len(mesh_elements) == 2, f"Expected 2 mesh elements, found {len(mesh_elements)}"
193+
194+
# Check that we have the mesh definition with all required data
195+
mesh_defs = [elem for elem in mesh_elements if elem.find('dimension') is not None]
196+
assert len(mesh_defs) == 1, f"Expected 1 mesh definition, found {len(mesh_defs)}"
197+
198+
mesh_def = mesh_defs[0]
199+
assert mesh_def.get('id') == str(mesh.id)
200+
assert mesh_def.find('dimension').text == '2 2 2'
201+
assert mesh_def.find('lower_left').text == '-1 -1 -1'
202+
assert mesh_def.find('upper_right').text == '1 1 1'
203+
204+
# Test 2: Also verify that to_xml_element works with mesh_memo=None
205+
xml_element = s.to_xml_element(mesh_memo=None)
206+
mesh_elements_direct = xml_element.findall('.//mesh')
207+
assert len(mesh_elements_direct) == 2, f"Expected 2 mesh elements with mesh_memo=None, found {len(mesh_elements_direct)}"

0 commit comments

Comments
 (0)