mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
adding back files to be reviewed
This commit is contained in:
parent
ae28233110
commit
bc09d1ef55
1244 changed files with 301904 additions and 0 deletions
301
scripts/openmc-update-inputs
Executable file
301
scripts/openmc-update-inputs
Executable file
|
|
@ -0,0 +1,301 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Update OpenMC's input XML files to the latest format.
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
from difflib import get_close_matches
|
||||
from itertools import chain
|
||||
from random import randint
|
||||
from shutil import move
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import openmc.data
|
||||
|
||||
|
||||
description = "Update OpenMC's input XML files to the latest format."
|
||||
epilog = """\
|
||||
If any of the given files do not match the most up-to-date formatting, then they
|
||||
will be automatically rewritten. The old out-of-date files will not be deleted;
|
||||
they will be moved to a new file with '.original' appended to their name.
|
||||
|
||||
Formatting changes that will be made:
|
||||
|
||||
geometry.xml: Lattices containing 'outside' attributes/tags will be replaced
|
||||
with lattices containing 'outer' attributes, and the appropriate
|
||||
cells/universes will be added. Any 'surfaces' attributes/elements on a cell
|
||||
will be renamed 'region'.
|
||||
|
||||
materials.xml: Nuclide names will be changed from ACE aliases (e.g., Am-242m) to
|
||||
HDF5/GND names (e.g., Am242_m1). Thermal scattering table names will be
|
||||
changed from ACE aliases (e.g., HH2O) to HDF5/GND names (e.g., c_H_in_H2O).
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def parse_args():
|
||||
"""Read the input files from the commandline."""
|
||||
# Create argument parser.
|
||||
parser = argparse.ArgumentParser(
|
||||
description=description,
|
||||
epilog=epilog,
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument('input', metavar='IN', type=str, nargs='+',
|
||||
help='Input XML file(s).')
|
||||
|
||||
# Parse and return commandline arguments.
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def get_universe_ids(geometry_root):
|
||||
"""Return a set of universe id numbers."""
|
||||
root = geometry_root
|
||||
out = set()
|
||||
|
||||
# Get the ids of universes defined by cells.
|
||||
for cell in root.iter('cell'):
|
||||
# Get universe attributes/elements
|
||||
if 'universe' in cell.attrib:
|
||||
uid = cell.attrib['universe']
|
||||
out.add(int(uid))
|
||||
elif cell.find('universe') is not None:
|
||||
elem = cell.find('universe')
|
||||
uid = elem.text
|
||||
out.add(int(uid))
|
||||
else:
|
||||
# Default to universe 0
|
||||
out.add(0)
|
||||
|
||||
# Get the ids of universes defined by lattices.
|
||||
for lat in root.iter('lattice'):
|
||||
# Get id attributes.
|
||||
if 'id' in lat.attrib:
|
||||
uid = lat.attrib['id']
|
||||
out.add(int(uid))
|
||||
|
||||
# Get id elements.
|
||||
elif lat.find('id') is not None:
|
||||
elem = lat.find('id')
|
||||
uid = elem.text
|
||||
out.add(int(uid))
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_cell_ids(geometry_root):
|
||||
"""Return a set of cell id numbers."""
|
||||
root = geometry_root
|
||||
out = set()
|
||||
|
||||
# Get the ids of universes defined by cells.
|
||||
for cell in root.iter('cell'):
|
||||
# Get id attributes.
|
||||
if 'id' in cell.attrib:
|
||||
cid = cell.attrib['id']
|
||||
out.add(int(cid))
|
||||
|
||||
# Get id elements.
|
||||
elif cell.find('id') is not None:
|
||||
elem = cell.find('id')
|
||||
cid = elem.text
|
||||
out.add(int(cid))
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def find_new_id(current_ids, preferred=None):
|
||||
"""Return a new id that is not already present in current_ids."""
|
||||
distance_from_preferred = 21
|
||||
max_random_attempts = 10000
|
||||
|
||||
# First, try to find an id near the preferred number.
|
||||
if preferred is not None:
|
||||
assert isinstance(preferred, int)
|
||||
for i in range(1, distance_from_preferred):
|
||||
if (preferred - i not in current_ids) and (preferred - i > 0):
|
||||
return preferred - i
|
||||
if (preferred + i not in current_ids) and (preferred + i > 0):
|
||||
return preferred + i
|
||||
|
||||
# If that was unsuccessful, attempt to randomly guess a new id number.
|
||||
for i in range(max_random_attempts):
|
||||
num = randint(1, 2147483647)
|
||||
if num not in current_inds:
|
||||
return num
|
||||
|
||||
# Raise an error if an id was not found.
|
||||
raise RuntimeError('Could not find a unique id number for a new universe.')
|
||||
|
||||
|
||||
def get_lat_id(lattice_element):
|
||||
"""Return the id integer of the lattice_element."""
|
||||
assert isinstance(lattice_element, ET.Element)
|
||||
if 'id' in lattice_element.attrib:
|
||||
return int(lattice_element.attrib['id'].strip())
|
||||
elif any([child.tag == 'id' for child in lattice_element]):
|
||||
elem = lattice_element.find('id')
|
||||
return int(elem.text.strip())
|
||||
else:
|
||||
raise RuntimeError('Could not find the id for a lattice.')
|
||||
|
||||
|
||||
def pop_lat_outside(lattice_element):
|
||||
"""Return lattice's outside material and remove from attributes/elements."""
|
||||
assert isinstance(lattice_element, ET.Element)
|
||||
|
||||
# Check attributes.
|
||||
if 'outside' in lattice_element.attrib:
|
||||
material = lattice_element.attrib['outside'].strip()
|
||||
del lattice_element.attrib['outside']
|
||||
|
||||
# Check subelements.
|
||||
elif any([child.tag == 'outside' for child in lattice_element]):
|
||||
elem = lattice_element.find('outside')
|
||||
material = elem.text.strip()
|
||||
lattice_element.remove(elem)
|
||||
|
||||
# No 'outside' specified. This means the outside is a void.
|
||||
else:
|
||||
material = 'void'
|
||||
|
||||
return material
|
||||
|
||||
|
||||
def update_geometry(geometry_root):
|
||||
"""Update the given XML geometry tree. Return True if changes were made."""
|
||||
root = geometry_root
|
||||
was_updated = False
|
||||
|
||||
# Get a set of already-used universe and cell ids.
|
||||
uids = get_universe_ids(root)
|
||||
cids = get_cell_ids(root)
|
||||
taken_ids = uids.union(cids)
|
||||
|
||||
# Replace 'outside' with 'outer' in lattices.
|
||||
for lat in chain(root.iter('lattice'), root.iter('hex_lattice')):
|
||||
# Get the lattice's id.
|
||||
lat_id = get_lat_id(lat)
|
||||
|
||||
# Ignore lattices that have 'outer' specified.
|
||||
if any([child.tag == 'outer' for child in lat]): continue
|
||||
if 'outer' in lat.attrib: continue
|
||||
|
||||
# Pop the 'outside' material.
|
||||
material = pop_lat_outside(lat)
|
||||
|
||||
# Get an id number for a new outer universe. Ideally, the id should
|
||||
# be close to the lattice's id.
|
||||
new_uid = find_new_id(taken_ids, preferred=lat_id)
|
||||
assert new_uid not in taken_ids
|
||||
|
||||
# Add the new universe filled with the old 'outside' material to the
|
||||
# geometry.
|
||||
new_cell = ET.Element('cell')
|
||||
new_cell.attrib['id'] = str(new_uid)
|
||||
new_cell.attrib['universe'] = str(new_uid)
|
||||
new_cell.attrib['material'] = material
|
||||
root.append(new_cell)
|
||||
taken_ids.add(new_uid)
|
||||
|
||||
# Add the new universe to the lattice's 'outer' attribute.
|
||||
lat.attrib['outer'] = str(new_uid)
|
||||
|
||||
was_updated = True
|
||||
|
||||
# Remove 'type' from lattice definitions.
|
||||
for lat in root.iter('lattice'):
|
||||
elem = lat.find('type')
|
||||
if elem is not None:
|
||||
lat.remove(elem)
|
||||
was_updated = True
|
||||
if 'type' in lat.attrib:
|
||||
del lat.attrib['type']
|
||||
was_updated = True
|
||||
|
||||
# Change 'width' to 'pitch' in lattice definitions.
|
||||
for lat in root.iter('lattice'):
|
||||
elem = lat.find('width')
|
||||
if elem is not None:
|
||||
elem.tag = 'pitch'
|
||||
was_updated = True
|
||||
if 'width' in lat.attrib:
|
||||
lat.attrib['pitch'] = lat.attrib['width']
|
||||
del lat.attrib['width']
|
||||
was_updated = True
|
||||
|
||||
# Change 'surfaces' to 'region' in cell definitions
|
||||
for cell in root.iter('cell'):
|
||||
elem = cell.find('surfaces')
|
||||
if elem is not None:
|
||||
elem.tag = 'region'
|
||||
was_updated = True
|
||||
if 'surfaces' in cell.attrib:
|
||||
cell.attrib['region'] = cell.attrib['surfaces']
|
||||
del cell.attrib['surfaces']
|
||||
was_updated = True
|
||||
|
||||
return was_updated
|
||||
|
||||
def update_materials(root):
|
||||
"""Update the given XML materials tree. Return True if changes were made."""
|
||||
was_updated = False
|
||||
|
||||
for material in root.findall('material'):
|
||||
for nuclide in material.findall('nuclide'):
|
||||
if 'name' in nuclide.attrib:
|
||||
nucname = nuclide.attrib['name']
|
||||
nucname = nucname.replace('-', '')
|
||||
# If a nuclide name is in the ZAID notation (e.g., a number),
|
||||
# convert it to the proper nuclide name.
|
||||
if nucname.strip().isnumeric():
|
||||
nucname = openmc.data.ace.get_metadata(int(nucname))[0]
|
||||
nucname = nucname.replace('Nat', '0')
|
||||
if nucname.endswith('m'):
|
||||
nucname = nucname[:-1] + '_m1'
|
||||
nuclide.set('name', nucname)
|
||||
was_updated = True
|
||||
|
||||
elif nuclide.find('name') is not None:
|
||||
name_elem = nuclide.find('name')
|
||||
nucname = name_elem.text
|
||||
nucname = nucname.replace('-', '')
|
||||
nucname = nucname.replace('Nat', '0')
|
||||
if nucname.endswith('m'):
|
||||
nucname = nucname[:-1] + '_m1'
|
||||
name_elem.text = nucname
|
||||
was_updated = True
|
||||
|
||||
for sab in material.findall('sab'):
|
||||
if 'name' in sab.attrib:
|
||||
sabname = sab.attrib['name']
|
||||
sab.set('name', openmc.data.get_thermal_name(sabname))
|
||||
was_updated = True
|
||||
|
||||
elif sab.find('name') is not None:
|
||||
name_elem = sab.find('name')
|
||||
sabname = name_elem.text
|
||||
name_elem.text = openmc.data.get_thermal_name(sabname)
|
||||
was_updated = True
|
||||
|
||||
return was_updated
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args()
|
||||
for fname in args.input:
|
||||
# Parse the XML data.
|
||||
tree = ET.parse(fname)
|
||||
root = tree.getroot()
|
||||
was_updated = False
|
||||
|
||||
if root.tag == 'geometry':
|
||||
was_updated = update_geometry(root)
|
||||
elif root.tag == 'materials':
|
||||
was_updated = update_materials(root)
|
||||
|
||||
if was_updated:
|
||||
# Move the original geometry file to preserve it.
|
||||
move(fname, fname + '.original')
|
||||
|
||||
# Write a new geometry file.
|
||||
tree.write(fname)
|
||||
Loading…
Add table
Add a link
Reference in a new issue