Skip to content

Commit 9d127e1

Browse files
makecleanAndrew Davis
authored andcommitted
Allows input of OpenMC geometry
1 parent a54e88d commit 9d127e1

5 files changed

Lines changed: 228 additions & 8 deletions

File tree

python/CellCard.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(self,card_string):
2727
self.cell_material_number = 0
2828
self.cell_importance = 1 # note any importance - we assume everything else is 0
2929
self.cell_text_description = ""
30-
self.cell_interpreted = ""
30+
self.cell_interpreted = "" #this it the generalised form of the cell
3131
self.cell_fill = 0
3232
self.cell_universe = 0
3333
self.cell_universe_offset = 0

python/OpenMCCell.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,58 @@ def write_openmc_cell(cell, geometry_tree):
107107
universe = str(universe))
108108

109109

110+
# take the xml attributes and populate the
111+
# cell
112+
def cell_from_attribute(xml_attribute):
113+
cell = OpenMCCell("")
114+
cell.cell_id = xml_attribute["id"]
115+
116+
# todo if name based materials are used will need
117+
# a helper function
118+
if xml_attribute["material"] == "void":
119+
cell.cell_material_number = 0
120+
else:
121+
cell.cell_material_number = xml_attribute["material"]
122+
123+
cell.cell_text_description = xml_attribute["region"]
124+
cell.cell_universe = xml_attribute["universe"]
125+
cell.cell_fill = xml_attribute["fill"]
110126

127+
cell.generalise()
128+
return cell
111129

112-
#
130+
# base constructor
113131
class OpenMCCell(CellCard):
114132
def __init__(self, card_string):
115133
CellCard.__init__(self, card_string)
134+
135+
# turn the text representation of the cell
136+
# into a generic description
137+
def generalise(self):
138+
# make an interable list of the components
139+
cell_description = list(self.cell_text_description)
140+
# first lets sanisise the text description - remove
141+
# double spaces trailing and leading white space
142+
idx = 0
143+
while True:
144+
# breakout condition
145+
if idx >= len(cell_description):
146+
break
147+
# part of the cell we're looking at
148+
s = cell_description[idx]
149+
if s is "|":
150+
cell_description[idx] = CellCard.OperationType["UNION"]
151+
idx += 1
152+
continue
153+
elif s is "~":
154+
cell_description[idx] = CellCard.OperationType["NOT"]
155+
idx += 1
156+
continue
157+
elif s is " ":
158+
cell_description[idx] = CellCard.OperationType["AND"]
159+
idx += 1
160+
continue
161+
idx += 1
162+
# set the generalised cell description
163+
self.cell_interpreted = cell_description
164+
return

python/OpenMCInput.py

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import sys
77
import xml.etree.ElementTree as ET
88

9-
from OpenMCSurface import write_openmc_surface
10-
from OpenMCCell import write_openmc_cell
11-
from OpenMCMaterial import write_openmc_material
9+
from OpenMCSurface import SurfaceCard,surface_from_attribute, write_openmc_surface
10+
from OpenMCCell import cell_from_attribute, write_openmc_cell
11+
from OpenMCMaterial import material_from_attribute, write_openmc_material
1212
'''
1313
copy and paste from http://effbot.org/zone/element-lib.htm#prettyprint
1414
it basically walks your tree and adds spaces and newlines so the tree is
@@ -35,8 +35,75 @@ class OpenMCInput(InputDeck):
3535
xml elements directly
3636
"""
3737
# constructor
38-
def __init__(self, filename = ""):
39-
InputDeck.__init__(self, filename)
38+
def __init__(self,geometry_file="geometry.xml",material_file="materials.xml"):
39+
self.geometry = geometry_file
40+
self.material = material_file
41+
self.xml_geom = None
42+
self.xml_material = None
43+
# make a new input deck
44+
InputDeck.__init__(self,filename="")
45+
46+
# read the openmc files
47+
def read(self):
48+
self.xml_geom = self.__read_geometry_xml(self.geometry)
49+
self.xml_material = self.__read_material_xml(self.material)
50+
51+
# read the geometry file
52+
def __read_geometry_xml(self, geometry_filename):
53+
geom = ET.parse(geometry_filename)
54+
geom_root = geom.getroot()
55+
return geom_root
56+
57+
# read the material file
58+
def __read_material_xml(self, material_filename):
59+
mat = ET.parse(material_filename)
60+
mat_root = mat.getroot()
61+
return mat_root
62+
63+
# process the files
64+
def process(self):
65+
# do materials first
66+
self.__process_materials()
67+
self.__process_geometry()
68+
69+
70+
# process the geometry
71+
def __process_geometry(self):
72+
for child in self.xml_geom:
73+
if child.tag == "surface":
74+
surface = surface_from_attribute(child.attrib)
75+
InputDeck.surface_list.append(surface)
76+
elif child.tag == "cell":
77+
cell = cell_from_attribute(child.attrib)
78+
InputDeck.cell_list.append(cell)
79+
80+
# loop over the cells and set the material
81+
# density for each cell
82+
for cell in InputDeck.cell_list:
83+
cell_mat = cell.cell_material_number
84+
if cell_mat is not 0:
85+
density = InputDeck.material_list[cell_mat].density
86+
cell.cell_density = density
87+
88+
# identify the cells that have a surface with a vacuum
89+
# boundary condition, they mark the end of the universe
90+
boundary_surfs = []
91+
for surface in InputDeck.surface_list:
92+
if surface.boundary_condition == SurfaceCard.BoundaryCondition["VACUUM"]:
93+
boundary_surfs.append(surface.surface_id)
94+
95+
# now loop through the cells and mark as importance 0 where
96+
# appropriate
97+
for cell in InputDeck.cell_list:
98+
if set(boundary_surfs) & set(cell.cell_interpreted) == set(boundary_surfs):
99+
cell.cell_importance = 0
100+
101+
# process the materials
102+
def __process_materials(self):
103+
for child in self.xml_material:
104+
if child.tag == "material":
105+
material = material_from_attribute(child.attrib, child.getchildren())
106+
InputDeck.material_list[material.material_number] = material
40107

41108
# write the collection of OpenMC surface definitions
42109
def __write_openmc_surfaces(self, geometry_tree):

python/OpenMCMaterial.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/env/python3
22

3+
import re
34
from MaterialCard import MaterialCard
45
import xml.etree.ElementTree as ET
56

@@ -24,6 +25,26 @@
2425
109:"Mt",110:"Ds",111:"Rg",112:"Cn",113:"Nh",
2526
114:"Fl",115:"Mc",116:"Lv",117:"Ts",118:"Og"}
2627

28+
# return the zz given a name
29+
def get_zaid(name):
30+
m = re.search('[A-Z]?[a-z]*',name)
31+
element_name = m.group(0)
32+
m = re.search('[0-9]?[0-9]?[0-9]',name)
33+
nucleon_number = int(m.group(0))
34+
35+
for zz,el in name_zaid.items():
36+
if el == element_name:
37+
break
38+
39+
# pad the right number of zeros
40+
if nucleon_number < 10:
41+
nucleon_number = "00" + str(nucleon_number)
42+
elif nucleon_number > 10 and nucleon_number < 100:
43+
nucleon_number = "0" + str(nucleon_number)
44+
45+
46+
return str(zz)+nucleon_number
47+
2748
# convert zaid to a name for openmc
2849
def zaid_to_name(zaid_string):
2950
if len(zaid_string) <= 4:
@@ -41,6 +62,43 @@ def zaid_to_name(zaid_string):
4162
name = name_zaid[zz]
4263
return name+str(aa)
4364

65+
################## input functions #########################
66+
#
67+
def material_from_attribute(xml_element, children):
68+
#
69+
material = MaterialCard()
70+
material.material_number = xml_element["id"]
71+
# loop over the constituents
72+
nucs = {}
73+
atom_fraction = False
74+
75+
for child in children:
76+
# set the density
77+
if "units" in child.attrib:
78+
units = child.attrib["units"]
79+
density = float(child.attrib["value"])
80+
# set the material parameters
81+
if "name" in child.attrib:
82+
nucid = child.attrib["name"]
83+
zaid = get_zaid(nucid)
84+
if "wo" in child.attrib:
85+
# mass fractions are -ve
86+
nucs[zaid] = -1*float(child.attrib["wo"])
87+
if "ao" in child.attrib:
88+
atom_fraction = True
89+
nucs[zaid] = child.attrib["ao"]
90+
91+
if not atom_fraction: density = density*-1.0
92+
93+
material.density = density
94+
material.density_units = units
95+
material.composition_dictionary = nucs
96+
97+
return material
98+
99+
100+
################## output functions #########################
101+
44102
# write the atomic fraction entry
45103
def __write_atomic_fraction(material, nuclide, mass_frac):
46104
ET.SubElement(material, "nuclide", name = nuclide, ao = str(abs(mass_frac)))

python/OpenMCSurface.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55

66
import warnings
77

8+
def boundarystring_to_type(boundary_string):
9+
if boundary_string == "transmission":
10+
boundary_type = SurfaceCard.BoundaryCondition["TRANSMISSION"]
11+
if boundary_string == "vacuum":
12+
boundary_type = SurfaceCard.BoundaryCondition["VACUUM"]
13+
if boundary_string == "reflecting":
14+
boundary_type = SurfaceCard.BoundaryCondition["REFLECTING"]
15+
return boundary_type
16+
817
def boundary_condition(boundaryCondition):
918
if boundaryCondition == SurfaceCard.BoundaryCondition["TRANSMISSION"]:
1019
boundary = "transmission"
@@ -18,6 +27,34 @@ def boundary_condition(boundaryCondition):
1827

1928
return boundary
2029

30+
def type_to_generictype(surface_string):
31+
if surface_string == "sphere":
32+
surface = SurfaceCard.SurfaceType["SPHERE_GENERAL"]
33+
if surface_string == "x-plane":
34+
surface = SurfaceCard.SurfaceType["PLANE_X"]
35+
if surface_string == "y-plane":
36+
surface = SurfaceCard.SurfaceType["PLANE_Y"]
37+
if surface_string == "z-plane":
38+
surface = SurfaceCard.SurfaceType["PLANE_Z"]
39+
if surface_string == "plane":
40+
surface = SurfaceCard.SurfaceType["PLANE_GENERAL"]
41+
if surface_string == "x-cylinder":
42+
surface = SurfaceCard.SurfaceType["CYLINDER_X"]
43+
if surface_string == "y-cylinder":
44+
surface = SurfaceCard.SurfaceType["CYLINDER_Y"]
45+
if surface_string == "z-cylinder":
46+
surface = SurfaceCard.SurfaceType["CYLINDER_Z"]
47+
if surface_string == "x-cone":
48+
surface = SurfaceCard.SurfaceType["CONE_X"]
49+
if surface_string == "y-cone":
50+
surface = SurfaceCard.SurfaceType["CONE_Y"]
51+
if surface_string == "z-cone":
52+
surface = SurfaceCard.SurfaceType["CONE_Z"]
53+
if surface_string == "quadric":
54+
surface = SurfaceCard.SurfaceType["GENERAL_QUADRATIC"]
55+
56+
return surface
57+
2158
def openmc_surface_info(SurfaceCard):
2259
if SurfaceCard.surface_type == SurfaceCard.SurfaceType["PLANE_GENERAL"]:
2360
type_string = "plane"
@@ -77,7 +114,16 @@ def write_openmc_surface(SurfaceCard, geometry_tree):
77114
ET.SubElement(geometry_tree, "surface", id = str(id), type = str(type),
78115
coeffs = str(coeffs),
79116
boundary = boundary_condition(SurfaceCard.boundary_condition))
80-
117+
118+
# import openmc surface functions
119+
def surface_from_attribute(xml_attribute):
120+
surface = SurfaceCard("")
121+
# loop over the surface attributes and build the generic description
122+
surface.boundary_condition = boundarystring_to_type(xml_attribute['boundary'])
123+
surface.surface_coefficients = xml_attribute['coeffs'].split()
124+
surface.surface_id = xml_attribute['id']
125+
surface.surface_type = type_to_generictype(xml_attribute['type'])
126+
return surface
81127

82128
class OpenMCSurfaceCard(SurfaceCard):
83129
""" Class to handle the creation and translation of

0 commit comments

Comments
 (0)