def test_xcylinder(): y, z, r = 3, 5, 2 s = openmc.XCylinder(y0=y, z0=z, r=r) assert s.y0 == y assert s.z0 == z assert s.r == r # Check bounding box ll, ur = (+s).bounding_box assert np.all(np.isinf(ll)) assert np.all(np.isinf(ur)) ll, ur = (-s).bounding_box assert ll == pytest.approx((-np.inf, y - r, z - r)) assert ur == pytest.approx((np.inf, y + r, z + r)) # evaluate method assert s.evaluate((0, y, z)) == pytest.approx(-r**2) # translate method st = s.translate((1.0, 1.0, 1.0)) assert st.y0 == s.y0 + 1 assert st.z0 == s.z0 + 1 assert st.r == s.r # rotate method sr = s.rotate((90, 90, 90)) R = np.array([[0, 0, 1], [0, 1, 0], [-1, 0, 0]]) assert sr._origin == pytest.approx(R @ s._origin) assert sr._axis == pytest.approx(R @ s._axis) # test passing in rotation matrix sr2 = s.rotate(R) assert sr2._get_base_coeffs() == pytest.approx(sr._get_base_coeffs()) # Make sure repr works repr(s)
def test_xcylinder(): y, z, r = 3, 5, 2 s = openmc.XCylinder(y0=y, z0=z, r=r) assert s.y0 == y assert s.z0 == z assert s.r == r # Check bounding box ll, ur = (+s).bounding_box assert np.all(np.isinf(ll)) assert np.all(np.isinf(ur)) ll, ur = (-s).bounding_box assert ll == pytest.approx((-np.inf, y-r, z-r)) assert ur == pytest.approx((np.inf, y+r, z+r)) # evaluate method assert s.evaluate((0, y, z)) == pytest.approx(-r**2) # translate method st = s.translate((1.0, 1.0, 1.0)) assert st.y0 == s.y0 + 1 assert st.z0 == s.z0 + 1 assert st.r == s.r # Make sure repr works repr(s)
def test_failure(pin_mats, good_radii): """Check for various failure modes""" good_surfaces = [openmc.ZCylinder(r=r) for r in good_radii] # Bad material type with pytest.raises(TypeError): pin(good_surfaces, [mat.name for mat in pin_mats]) # Incorrect lengths with pytest.raises(ValueError, match="length"): pin(good_surfaces[:len(pin_mats) - 2], pin_mats) # Non-positive radii rad = [openmc.ZCylinder(r=-0.1)] + good_surfaces[1:] with pytest.raises(ValueError, match="index 0"): pin(rad, pin_mats) # Non-increasing radii surfs = tuple(reversed(good_surfaces)) with pytest.raises(ValueError, match="index 1"): pin(surfs, pin_mats) # Bad orientation surfs = [openmc.XCylinder(r=good_surfaces[0].r)] + good_surfaces[1:] with pytest.raises(TypeError, match="surfaces"): pin(surfs, pin_mats) # Passing cells argument with pytest.raises(SyntaxError, match="Cells"): pin(surfs, pin_mats, cells=[])
def centers_x_cylinder(): cylinder = openmc.XCylinder(r=1, y0=1, z0=2) min_x = openmc.XPlane(0) max_x = openmc.XPlane(1) region = +min_x & -max_x & -cylinder return openmc.model.pack_spheres(radius=_RADIUS, region=region, pf=_PACKING_FRACTION, initial_pf=0.2)
def __init__(self, center_base, height, radius, axis='z', **kwargs): cx, cy, cz = center_base check_greater_than('cylinder height', height, 0.0) check_greater_than('cylinder radius', radius, 0.0) check_value('cylinder axis', axis, ('x', 'y', 'z')) if axis == 'x': self.cyl = openmc.XCylinder(y0=cy, z0=cz, r=radius, **kwargs) self.bottom = openmc.XPlane(x0=cx, **kwargs) self.top = openmc.XPlane(x0=cx + height, **kwargs) elif axis == 'y': self.cyl = openmc.YCylinder(x0=cx, z0=cz, r=radius, **kwargs) self.bottom = openmc.YPlane(y0=cy, **kwargs) self.top = openmc.YPlane(y0=cy + height, **kwargs) elif axis == 'z': self.cyl = openmc.ZCylinder(x0=cx, y0=cy, r=radius, **kwargs) self.bottom = openmc.ZPlane(z0=cz, **kwargs) self.top = openmc.ZPlane(z0=cz + height, **kwargs)
def get_openmc_surface(opencg_surface): """Return an OpenMC surface corresponding to an OpenCG surface. Parameters ---------- opencg_surface : opencg.Surface OpenCG surface Returns ------- openmc_surface : openmc.surface.Surface Equivalent OpenMC surface """ if not isinstance(opencg_surface, opencg.Surface): msg = 'Unable to create an OpenMC Surface from "{0}" which ' \ 'is not an OpenCG Surface'.format(opencg_surface) raise ValueError(msg) global openmc_surface surface_id = opencg_surface._id # If this Surface was already created, use it if surface_id in OPENMC_SURFACES: return OPENMC_SURFACES[surface_id] # Create an OpenMC Surface to represent this OpenCG Surface name = opencg_surface._name # Correct for OpenMC's syntax for Surfaces dividing Cells boundary = opencg_surface._boundary_type if boundary == 'interface': boundary = 'transmission' if opencg_surface._type == 'plane': A = opencg_surface._coeffs['A'] B = opencg_surface._coeffs['B'] C = opencg_surface._coeffs['C'] D = opencg_surface._coeffs['D'] openmc_surface = openmc.Plane(surface_id, boundary, A, B, C, D, name) elif opencg_surface._type == 'x-plane': x0 = opencg_surface._coeffs['x0'] openmc_surface = openmc.XPlane(surface_id, boundary, x0, name) elif opencg_surface._type == 'y-plane': y0 = opencg_surface._coeffs['y0'] openmc_surface = openmc.YPlane(surface_id, boundary, y0, name) elif opencg_surface._type == 'z-plane': z0 = opencg_surface._coeffs['z0'] openmc_surface = openmc.ZPlane(surface_id, boundary, z0, name) elif opencg_surface._type == 'x-cylinder': y0 = opencg_surface._coeffs['y0'] z0 = opencg_surface._coeffs['z0'] R = opencg_surface._coeffs['R'] openmc_surface = openmc.XCylinder(surface_id, boundary, y0, z0, R, name) elif opencg_surface._type == 'y-cylinder': x0 = opencg_surface._coeffs['x0'] z0 = opencg_surface._coeffs['z0'] R = opencg_surface._coeffs['R'] openmc_surface = openmc.YCylinder(surface_id, boundary, x0, z0, R, name) elif opencg_surface._type == 'z-cylinder': x0 = opencg_surface._coeffs['x0'] y0 = opencg_surface._coeffs['y0'] R = opencg_surface._coeffs['R'] openmc_surface = openmc.ZCylinder(surface_id, boundary, x0, y0, R, name) else: msg = 'Unable to create an OpenMC Surface from an OpenCG ' \ 'Surface of type "{0}" since it is not a compatible ' \ 'Surface type in OpenMC'.format(opencg_surface._type) raise ValueError(msg) # Add the OpenMC Surface to the global collection of all OpenMC Surfaces OPENMC_SURFACES[surface_id] = openmc_surface # Add the OpenCG Surface to the global collection of all OpenCG Surfaces OPENCG_SURFACES[surface_id] = opencg_surface return openmc_surface
def _read_surfaces(self): self.n_surfaces = self._f['geometry/n_surfaces'].value # Initialize dictionary for each Surface # Keys - Surface keys # Values - Surfacee objects self.surfaces = {} for key in self._f['geometry/surfaces'].keys(): if key == 'n_surfaces': continue surface_id = int(key.lstrip('surface ')) index = self._f['geometry/surfaces'][key]['index'].value name = self._f['geometry/surfaces'][key]['name'].value.decode() surf_type = self._f['geometry/surfaces'][key]['type'].value.decode( ) bc = self._f['geometry/surfaces'][key][ 'boundary_condition'].value.decode() coeffs = self._f['geometry/surfaces'][key]['coefficients'][...] # Create the Surface based on its type if surf_type == 'x-plane': x0 = coeffs[0] surface = openmc.XPlane(surface_id, bc, x0, name) elif surf_type == 'y-plane': y0 = coeffs[0] surface = openmc.YPlane(surface_id, bc, y0, name) elif surf_type == 'z-plane': z0 = coeffs[0] surface = openmc.ZPlane(surface_id, bc, z0, name) elif surf_type == 'plane': A = coeffs[0] B = coeffs[1] C = coeffs[2] D = coeffs[3] surface = openmc.Plane(surface_id, bc, A, B, C, D, name) elif surf_type == 'x-cylinder': y0 = coeffs[0] z0 = coeffs[1] R = coeffs[2] surface = openmc.XCylinder(surface_id, bc, y0, z0, R, name) elif surf_type == 'y-cylinder': x0 = coeffs[0] z0 = coeffs[1] R = coeffs[2] surface = openmc.YCylinder(surface_id, bc, x0, z0, R, name) elif surf_type == 'z-cylinder': x0 = coeffs[0] y0 = coeffs[1] R = coeffs[2] surface = openmc.ZCylinder(surface_id, bc, x0, y0, R, name) elif surf_type == 'sphere': x0 = coeffs[0] y0 = coeffs[1] z0 = coeffs[2] R = coeffs[3] surface = openmc.Sphere(surface_id, bc, x0, y0, z0, R, name) elif surf_type in ['x-cone', 'y-cone', 'z-cone']: x0 = coeffs[0] y0 = coeffs[1] z0 = coeffs[2] R2 = coeffs[3] if surf_type == 'x-cone': surface = openmc.XCone(surface_id, bc, x0, y0, z0, R2, name) if surf_type == 'y-cone': surface = openmc.YCone(surface_id, bc, x0, y0, z0, R2, name) if surf_type == 'z-cone': surface = openmc.ZCone(surface_id, bc, x0, y0, z0, R2, name) elif surf_type == 'quadric': a, b, c, d, e, f, g, h, j, k = coeffs surface = openmc.Quadric(surface_id, bc, a, b, c, d, e, f, g, h, j, k, name) # Add Surface to global dictionary of all Surfaces self.surfaces[index] = surface
def get_openmc_surface(opencg_surface): """Return an OpenMC surface corresponding to an OpenCG surface. Parameters ---------- opencg_surface : opencg.Surface OpenCG surface Returns ------- openmc_surface : openmc.surface.Surface Equivalent OpenMC surface """ cv.check_type('opencg_surface', opencg_surface, opencg.Surface) surface_id = opencg_surface.id # If this Surface was already created, use it if surface_id in OPENMC_SURFACES: return OPENMC_SURFACES[surface_id] # Create an OpenMC Surface to represent this OpenCG Surface name = opencg_surface.name # Correct for OpenMC's syntax for Surfaces dividing Cells boundary = opencg_surface.boundary_type if boundary == 'interface': boundary = 'transmission' if opencg_surface.type == 'plane': A = opencg_surface.a B = opencg_surface.b C = opencg_surface.c D = opencg_surface.d openmc_surface = openmc.Plane(surface_id, boundary, A, B, C, D, name) elif opencg_surface.type == 'x-plane': x0 = opencg_surface.x0 openmc_surface = openmc.XPlane(surface_id, boundary, x0, name) elif opencg_surface.type == 'y-plane': y0 = opencg_surface.y0 openmc_surface = openmc.YPlane(surface_id, boundary, y0, name) elif opencg_surface.type == 'z-plane': z0 = opencg_surface.z0 openmc_surface = openmc.ZPlane(surface_id, boundary, z0, name) elif opencg_surface.type == 'x-cylinder': y0 = opencg_surface.y0 z0 = opencg_surface.z0 R = opencg_surface.r openmc_surface = openmc.XCylinder(surface_id, boundary, y0, z0, R, name) elif opencg_surface.type == 'y-cylinder': x0 = opencg_surface.x0 z0 = opencg_surface.z0 R = opencg_surface.r openmc_surface = openmc.YCylinder(surface_id, boundary, x0, z0, R, name) elif opencg_surface.type == 'z-cylinder': x0 = opencg_surface.x0 y0 = opencg_surface.y0 R = opencg_surface.r openmc_surface = openmc.ZCylinder(surface_id, boundary, x0, y0, R, name) else: msg = 'Unable to create an OpenMC Surface from an OpenCG ' \ 'Surface of type "{0}" since it is not a compatible ' \ 'Surface type in OpenMC'.format(opencg_surface.type) raise ValueError(msg) # Add the OpenMC Surface to the global collection of all OpenMC Surfaces OPENMC_SURFACES[surface_id] = openmc_surface # Add the OpenCG Surface to the global collection of all OpenCG Surfaces OPENCG_SURFACES[surface_id] = opencg_surface return openmc_surface
def _make_openmc_input(self): """Generate the OpenMC input XML """ # Define material mat = openmc.Material() for nuclide, fraction in self.nuclides: mat.add_nuclide(nuclide, fraction) mat.set_density('g/cm3', self.density) materials = openmc.Materials([mat]) if self.xsdir is not None: xs_path = (self.openmc_dir / 'cross_sections.xml').resolve() materials.cross_sections = str(xs_path) materials.export_to_xml(self.openmc_dir / 'materials.xml') # Instantiate surfaces cyl = openmc.XCylinder(boundary_type='vacuum', r=1.e-6) px1 = openmc.XPlane(boundary_type='vacuum', x0=-1.) px2 = openmc.XPlane(boundary_type='transmission', x0=1.) px3 = openmc.XPlane(boundary_type='vacuum', x0=1.e9) # Instantiate cells inner_cyl_left = openmc.Cell() inner_cyl_right = openmc.Cell() outer_cyl = openmc.Cell() # Set cells regions and materials inner_cyl_left.region = -cyl & +px1 & -px2 inner_cyl_right.region = -cyl & +px2 & -px3 outer_cyl.region = ~(-cyl & +px1 & -px3) inner_cyl_right.fill = mat # Create root universe and export to XML geometry = openmc.Geometry( [inner_cyl_left, inner_cyl_right, outer_cyl]) geometry.export_to_xml(self.openmc_dir / 'geometry.xml') # Define source source = openmc.Source() source.space = openmc.stats.Point((0, 0, 0)) source.angle = openmc.stats.Monodirectional() source.energy = openmc.stats.Discrete([self.energy], [1.]) source.particle = 'neutron' # Settings settings = openmc.Settings() if self._temperature is not None: settings.temperature = {'default': self._temperature} settings.source = source settings.particles = self.particles // self._batches settings.run_mode = 'fixed source' settings.batches = self._batches settings.photon_transport = True settings.electron_treatment = self.electron_treatment settings.cutoff = {'energy_photon': self._cutoff_energy} settings.export_to_xml(self.openmc_dir / 'settings.xml') # Define filters surface_filter = openmc.SurfaceFilter(cyl) particle_filter = openmc.ParticleFilter('photon') energy_bins = np.logspace(np.log10(self._cutoff_energy), np.log10(self.max_energy), self._bins + 1) energy_filter = openmc.EnergyFilter(energy_bins) # Create tallies and export to XML tally = openmc.Tally(name='tally') tally.filters = [surface_filter, energy_filter, particle_filter] tally.scores = ['current'] tallies = openmc.Tallies([tally]) tallies.export_to_xml(self.openmc_dir / 'tallies.xml')
def _build_openmc(self): """Generate the OpenMC input XML """ # Directory from which openmc is run os.makedirs('openmc', exist_ok=True) # Define material mat = openmc.Material() for nuclide, fraction in self.nuclides: mat.add_nuclide(nuclide, fraction) mat.set_density('g/cm3', self.density) materials = openmc.Materials([mat]) materials.export_to_xml(os.path.join('openmc', 'materials.xml')) # Instantiate surfaces cyl = openmc.XCylinder(boundary_type='vacuum', R=1.e-6) px1 = openmc.XPlane(boundary_type='vacuum', x0=-1.) px2 = openmc.XPlane(boundary_type='transmission', x0=1.) px3 = openmc.XPlane(boundary_type='vacuum', x0=1.e9) # Instantiate cells inner_cyl_left = openmc.Cell() inner_cyl_right = openmc.Cell() outer_cyl = openmc.Cell() # Set cells regions and materials inner_cyl_left.region = -cyl & +px1 & -px2 inner_cyl_right.region = -cyl & +px2 & -px3 outer_cyl.region = ~(-cyl & +px1 & -px3) inner_cyl_right.fill = mat # Create root universe and export to XML geometry = openmc.Geometry( [inner_cyl_left, inner_cyl_right, outer_cyl]) geometry.export_to_xml(os.path.join('openmc', 'geometry.xml')) # Define source source = openmc.Source() source.space = openmc.stats.Point((0, 0, 0)) source.angle = openmc.stats.Monodirectional() source.energy = openmc.stats.Discrete([self.energy], [1.]) source.particle = 'neutron' # Settings settings = openmc.Settings() settings.source = source settings.particles = self.particles settings.run_mode = 'fixed source' settings.batches = 1 settings.photon_transport = True settings.electron_treatment = self.electron_treatment settings.cutoff = {'energy_photon': 1000.} settings.export_to_xml(os.path.join('openmc', 'settings.xml')) # Define filters surface_filter = openmc.SurfaceFilter(cyl) particle_filter = openmc.ParticleFilter('photon') energy_bins = np.logspace(3, np.log10(2 * self.energy), 500) energy_filter = openmc.EnergyFilter(energy_bins) # Create tallies and export to XML tally = openmc.Tally(name='photon current') tally.filters = [surface_filter, energy_filter, particle_filter] tally.scores = ['current'] tallies = openmc.Tallies([tally]) tallies.export_to_xml(os.path.join('openmc', 'tallies.xml'))
def _build_inputs(self): mat = openmc.Material() mat.set_density('g/cm3', 2.6989) mat.add_nuclide('Al27', 1.0) materials = openmc.Materials([mat]) materials.export_to_xml() cyl = openmc.XCylinder(r=1.0, boundary_type='vacuum') x_plane_left = openmc.XPlane(-1.0, 'vacuum') x_plane_center = openmc.XPlane(1.0) x_plane_right = openmc.XPlane(1.0e9, 'vacuum') inner_cyl_left = openmc.Cell() inner_cyl_right = openmc.Cell() outer_cyl = openmc.Cell() inner_cyl_left.region = -cyl & +x_plane_left & -x_plane_center inner_cyl_right.region = -cyl & +x_plane_center & -x_plane_right outer_cyl.region = ~(-cyl & +x_plane_left & -x_plane_right) inner_cyl_right.fill = mat geometry = openmc.Geometry( [inner_cyl_left, inner_cyl_right, outer_cyl]) geometry.export_to_xml() source = openmc.Source() source.space = openmc.stats.Point((0, 0, 0)) source.angle = openmc.stats.Monodirectional() source.energy = openmc.stats.Discrete([14.0e6], [1.0]) source.particle = 'neutron' settings = openmc.Settings() settings.particles = 10000 settings.run_mode = 'fixed source' settings.batches = 1 settings.photon_transport = True settings.electron_treatment = 'ttb' settings.cutoff = {'energy_photon': 1000.0} settings.source = source settings.export_to_xml() surface_filter = openmc.SurfaceFilter(cyl) particle_filter = openmc.ParticleFilter('photon') current_tally = openmc.Tally() current_tally.filters = [surface_filter, particle_filter] current_tally.scores = ['current'] tally_tracklength = openmc.Tally() tally_tracklength.filters = [particle_filter] tally_tracklength.scores = ['total', 'heating'] tally_tracklength.nuclides = ['Al27', 'total'] tally_tracklength.estimator = 'tracklength' tally_collision = openmc.Tally() tally_collision.filters = [particle_filter] tally_collision.scores = ['total', 'heating'] tally_collision.nuclides = ['Al27', 'total'] tally_collision.estimator = 'collision' tally_analog = openmc.Tally() tally_analog.filters = [particle_filter] tally_analog.scores = ['total', 'heating'] tally_analog.nuclides = ['Al27', 'total'] tally_analog.estimator = 'analog' tallies = openmc.Tallies( [current_tally, tally_tracklength, tally_collision, tally_analog]) tallies.export_to_xml()
def model(): model = openmc.model.Model() mat = openmc.Material() mat.set_density('g/cm3', 2.6989) mat.add_nuclide('Al27', 1.0) model.materials.append(mat) cyl = openmc.XCylinder(r=1.0, boundary_type='vacuum') x_plane_left = openmc.XPlane(-1.0, boundary_type='vacuum') x_plane_center = openmc.XPlane(1.0) x_plane_right = openmc.XPlane(1.0e9, boundary_type='vacuum') inner_cyl_left = openmc.Cell() inner_cyl_right = openmc.Cell() outer_cyl = openmc.Cell() inner_cyl_left.region = -cyl & +x_plane_left & -x_plane_center inner_cyl_right.region = -cyl & +x_plane_center & -x_plane_right outer_cyl.region = ~(-cyl & +x_plane_left & -x_plane_right) inner_cyl_right.fill = mat model.geometry = openmc.Geometry( [inner_cyl_left, inner_cyl_right, outer_cyl]) source = openmc.Source() source.space = openmc.stats.Point((0, 0, 0)) source.angle = openmc.stats.Monodirectional() source.energy = openmc.stats.Discrete([14.0e6], [1.0]) source.particle = 'neutron' model.settings.particles = 10000 model.settings.run_mode = 'fixed source' model.settings.batches = 1 model.settings.photon_transport = True model.settings.electron_treatment = 'ttb' model.settings.cutoff = {'energy_photon': 1000.0} model.settings.source = source surface_filter = openmc.SurfaceFilter(cyl) particle_filter = openmc.ParticleFilter( ['neutron', 'photon', 'electron', 'positron']) current_tally = openmc.Tally() current_tally.filters = [surface_filter, particle_filter] current_tally.scores = ['current'] tally_tracklength = openmc.Tally() tally_tracklength.filters = [particle_filter] tally_tracklength.scores = ['total', '(n,gamma)' ] # heating doesn't work with tracklength tally_tracklength.nuclides = ['Al27', 'total'] tally_tracklength.estimator = 'tracklength' tally_collision = openmc.Tally() tally_collision.filters = [particle_filter] tally_collision.scores = ['total', 'heating', '(n,gamma)'] tally_collision.nuclides = ['Al27', 'total'] tally_collision.estimator = 'collision' tally_analog = openmc.Tally() tally_analog.filters = [particle_filter] tally_analog.scores = ['total', 'heating', '(n,gamma)'] tally_analog.nuclides = ['Al27', 'total'] tally_analog.estimator = 'analog' model.tallies.extend( [current_tally, tally_tracklength, tally_collision, tally_analog]) return model