Skip to content

Commit b4a796e

Browse files
authored
Avoid writing subnormal nuclide densities to XML (#3144)
1 parent 91fd60b commit b4a796e

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

openmc/material.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from numbers import Real
66
from pathlib import Path
77
import re
8+
import sys
89
import warnings
910

1011
import lxml.etree as ET
@@ -26,6 +27,9 @@
2627
DENSITY_UNITS = ('g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum',
2728
'macro')
2829

30+
# Smallest normalized floating point number
31+
_SMALLEST_NORMAL = sys.float_info.min
32+
2933

3034
NuclideTuple = namedtuple('NuclideTuple', ['name', 'percent', 'percent_type'])
3135

@@ -1339,10 +1343,16 @@ def _get_nuclide_xml(self, nuclide: NuclideTuple) -> ET.Element:
13391343
xml_element = ET.Element("nuclide")
13401344
xml_element.set("name", nuclide.name)
13411345

1346+
# Prevent subnormal numbers from being written to XML, which causes an
1347+
# exception on the C++ side when calling std::stod
1348+
val = nuclide.percent
1349+
if abs(val) < _SMALLEST_NORMAL:
1350+
val = 0.0
1351+
13421352
if nuclide.percent_type == 'ao':
1343-
xml_element.set("ao", str(nuclide.percent))
1353+
xml_element.set("ao", str(val))
13441354
else:
1345-
xml_element.set("wo", str(nuclide.percent))
1355+
xml_element.set("wo", str(val))
13461356

13471357
return xml_element
13481358

tests/unit_tests/test_material.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,3 +683,17 @@ def intensity(src):
683683
stable.add_nuclide('Gd156', 1.0)
684684
stable.volume = 1.0
685685
assert stable.get_decay_photon_energy() is None
686+
687+
688+
def test_avoid_subnormal(run_in_tmpdir):
689+
# Write a materials.xml with a material that has a nuclide density that is
690+
# represented as a subnormal floating point value
691+
mat = openmc.Material()
692+
mat.add_nuclide('H1', 1.0)
693+
mat.add_nuclide('H2', 1.0e-315)
694+
mats = openmc.Materials([mat])
695+
mats.export_to_xml()
696+
697+
# When read back in, the density should be zero
698+
mats = openmc.Materials.from_xml()
699+
assert mats[0].get_nuclide_atom_densities()['H2'] == 0.0

0 commit comments

Comments
 (0)