def probability(self, probability): cv.check_type('mixture distribution probabilities', probability, Iterable, Real) for p in probability: cv.check_greater_than('mixture distribution probabilities', p, 0.0, True) self._probability = probability
def set_density(self, units, density=NO_DENSITY): """Set the density of the material Parameters ---------- units : str Physical units of density density : float, optional Value of the density. Must be specified unless units is given as 'sum'. """ check_type('the density for Material ID="{0}"'.format(self._id), density, Real) check_value("density units", units, DENSITY_UNITS) if density == NO_DENSITY and units is not "sum": msg = ( 'Unable to set the density Material ID="{0}" ' "because a density must be set when not using " "sum unit".format(self._id) ) raise ValueError(msg) self._density = density self._density_units = units
def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro'): """This method allows for an openmc.mgxs.FissionXS to be used to set the fission cross section for this XSdata object. Parameters ---------- fission: openmc.mgxs.FissionXS MGXS Object containing the fission cross section for the domain of interest. nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. See also -------- openmc.mgxs.Library.create_mg_library() openmc.mgxs.Library.get_xsdata """ check_type('fission', fission, openmc.mgxs.FissionXS) check_value('energy_groups', fission.energy_groups, [self.energy_groups]) check_value('domain_type', fission.domain_type, ['universe', 'cell', 'material']) if self.representation is 'isotropic': self._fission = fission.get_xs(nuclides=nuclide, xs_type=xs_type) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg)
def mask_background(self, mask_background): cv.check_type('plot mask background', mask_background, Iterable, Integral) cv.check_length('plot mask background', mask_background, 3) for rgb in mask_background: cv.check_greater_than('plot mask background', rgb, 0, True) cv.check_less_than('plot mask background', rgb, 256) self._mask_background = mask_background
def get_openmc_geometry(openmoc_geometry): """Return an OpenMC geometry corresponding to an OpenMOC geometry. Parameters ---------- openmoc_geometry : openmoc.Geometry OpenMOC geometry Returns ------- openmc_geometry : openmc.Geometry Equivalent OpenMC geometry """ cv.check_type('openmoc_geometry', openmoc_geometry, openmoc.Geometry) # Clear dictionaries and auto-generated ID OPENMC_SURFACES.clear() OPENMOC_SURFACES.clear() OPENMC_CELLS.clear() OPENMOC_CELLS.clear() OPENMC_UNIVERSES.clear() OPENMOC_UNIVERSES.clear() OPENMC_LATTICES.clear() OPENMOC_LATTICES.clear() openmoc_root_universe = openmoc_geometry.getRootUniverse() openmc_root_universe = get_openmc_universe(openmoc_root_universe) openmc_geometry = openmc.Geometry() openmc_geometry.root_universe = openmc_root_universe return openmc_geometry
def p(self, p): if isinstance(p, Real): p = [p] cv.check_type('discrete probabilities', p, Iterable, Real) for pk in p: cv.check_greater_than('discrete probability', pk, 0.0, True) self._p = p
def trace(self, trace): check_type("trace", trace, Iterable, Integral) check_length("trace", trace, 3) check_greater_than("trace batch", trace[0], 0) check_greater_than("trace generation", trace[1], 0) check_greater_than("trace particle", trace[2], 0) self._trace = trace
def multipole_library(self, multipole_library): warnings.warn('Settings.multipole_library has been deprecated and will ' 'be removed in a future version. ' 'Materials.multipole_library should defined instead.', DeprecationWarning) cv.check_type('multipole library', multipole_library, string_types) self._multipole_library = multipole_library
def fit_order(self, fit_order): if fit_order is not None: cv.check_type('fit_order', fit_order, Integral) cv.check_greater_than('fit_order', fit_order, 2, equality=True) # _broaden_wmp_polynomials assumes the curve fit has at least 3 # terms. self._fit_order = fit_order
def num_l(self, num_l): if num_l is not None: cv.check_type('num_l', num_l, Integral) cv.check_greater_than('num_l', num_l, 1, equality=True) cv.check_less_than('num_l', num_l, 4, equality=True) # There is an if block in _evaluate that assumes num_l <= 4. self._num_l = num_l
def colorize(self, geometry, seed=1): """Generate a color scheme for each domain in the plot. This routine may be used to generate random, reproducible color schemes. The colors generated are based upon cell/material IDs in the geometry. Parameters ---------- geometry : openmc.Geometry The geometry for which the plot is defined seed : Integral The random number seed used to generate the color scheme """ cv.check_type('geometry', geometry, openmc.Geometry) cv.check_type('seed', seed, Integral) cv.check_greater_than('seed', seed, 1, equality=True) # Get collections of the domains which will be plotted if self.color_by == 'material': domains = geometry.get_all_materials().values() else: domains = geometry.get_all_cells().values() # Set the seed for the random number generator np.random.seed(seed) # Generate random colors for each feature for domain in domains: self.colors[domain] = np.random.randint(0, 256, (3,))
def albedo(self, albedo): check_type('CMFD mesh albedo', albedo, Iterable, Real) check_length('CMFD mesh albedo', albedo, 6) for a in albedo: check_greater_than('CMFD mesh albedo', a, 0, True) check_less_than('CMFD mesh albedo', a, 1, True) self._albedo = albedo
def name(self, name): if name is not None: cv.check_type('name for mesh ID="{0}"'.format(self._id), name, basestring) self._name = name else: self._name = ''
def set_density(self, units, density=None): """Set the density of the material Parameters ---------- units : {'g/cm3', 'g/cc', 'km/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'} Physical units of density. density : float, optional Value of the density. Must be specified unless units is given as 'sum'. """ cv.check_value('density units', units, DENSITY_UNITS) self._density_units = units if units is 'sum': if density is not None: msg = 'Density "{0}" for Material ID="{1}" is ignored ' \ 'because the unit is "sum"'.format(density, self.id) warnings.warn(msg) else: if density is None: msg = 'Unable to set the density for Material ID="{0}" ' \ 'because a density value must be given when not using ' \ '"sum" unit'.format(self.id) raise ValueError(msg) cv.check_type('the density for Material ID="{0}"'.format(self.id), density, Real) self._density = density
def set_source_angle(self, stype, params=[]): """Defined the angular distribution of the external/starting source. Parameters ---------- stype : str The type of angular distribution. Valid options are "isotropic" and "monodirectional". The angle of the particle emitted from a source site is isotropic if the "isotropic" option is given. The angle of the particle emitted from a source site is the direction specified in ``params`` if the "monodirectional" option is given. params : Iterable of float For an "isotropic" angular distribution, ``params`` should not be specified. For a "monodirectional" angular distribution, ``params`` should be given as three floats which specify the angular cosines with respect to each axis. """ check_type("source angle type", stype, basestring) check_value("source angle type", stype, ["isotropic", "monodirectional"]) check_type("source angle parameters", params, Iterable, Real) if stype == "isotropic" and params is not None: msg = ( "Unable to set source angle parameters since they are not " "it is not supported for isotropic type sources" ) raise ValueError(msg) elif stype == "monodirectional": check_length("source angle parameters for a monodirectional " "source", params, 3) self._source_angle_type = stype self._source_angle_params = params
def trace(self, trace): cv.check_type('trace', trace, Iterable, Integral) cv.check_length('trace', trace, 3) cv.check_greater_than('trace batch', trace[0], 0) cv.check_greater_than('trace generation', trace[1], 0) cv.check_greater_than('trace particle', trace[2], 0) self._trace = trace
def set_source_space(self, stype, params): """Defined the spatial bounds of the external/starting source. Parameters ---------- stype : str The type of spatial distribution. Valid options are "box", "fission", and "point". A "box" spatial distribution has coordinates sampled uniformly in a parallelepiped. A "fission" spatial distribution samples locations from a "box" distribution but only locations in fissionable materials are accepted. A "point" spatial distribution has coordinates specified by a triplet. params : Iterable of float For a "box" or "fission" spatial distribution, ``params`` should be given as six real numbers, the first three of which specify the lower-left corner of a parallelepiped and the last three of which specify the upper-right corner. Source sites are sampled uniformly through that parallelepiped. For a "point" spatial distribution, ``params`` should be given as three real numbers which specify the (x,y,z) location of an isotropic point source """ check_type("source space type", stype, basestring) check_value("source space type", stype, ["box", "fission", "point"]) check_type("source space parameters", params, Iterable, Real) if stype in ["box", "fission"]: check_length("source space parameters for a " "box/fission distribution", params, 6) elif stype == "point": check_length("source space parameters for a point source", params, 3) self._source_space_type = stype self._source_space_params = params
def get_openmc_material(openmoc_material): """Return an OpenMC material corresponding to an OpenMOC material. Parameters ---------- openmoc_material : openmoc.Material OpenMOC material Returns ------- openmc_material : openmc.Material Equivalent OpenMC material """ cv.check_type('openmoc_material', openmoc_material, openmoc.Material) material_id = openmoc_material.getId() # If this Material was already created, use it if material_id in OPENMC_MATERIALS: return OPENMC_MATERIALS[material_id] # Create an OpenMC Material to represent this OpenMOC Material name = openmoc_material.getName() openmc_material = openmc.Material(material_id=material_id, name=name) # Add the OpenMOC Material to the global collection of all OpenMOC Materials OPENMOC_MATERIALS[material_id] = openmoc_material # Add the OpenMC Material to the global collection of all OpenMC Materials OPENMC_MATERIALS[material_id] = openmc_material return openmc_material
def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro'): """This method allows for an openmc.mgxs.ScatterMatrixXS to be used to set the scatter matrix cross section for this XSdata object. If the XSdata.order attribute has not yet been set, then it will be set based on the properties of scatter. Parameters ---------- scatter: openmc.mgxs.ScatterMatrixXS MGXS Object containing the scatter matrix cross section for the domain of interest. nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. See also -------- openmc.mgxs.Library.create_mg_library() openmc.mgxs.Library.get_xsdata """ check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS) check_value('energy_groups', scatter.energy_groups, [self.energy_groups]) check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material']) if self.scatt_type != 'legendre': msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' raise ValueError(msg) # If the user has not defined XSdata.order, then we will set # the order based on the data within scatter. # Otherwise, we will check to see that XSdata.order to match # the order of scatter if self.order is None: self.order = scatter.legendre_order else: check_value('legendre_order', scatter.legendre_order, [self.order]) if self.representation is 'isotropic': # Get the scattering orders in the outermost dimension self._scatter = np.zeros((self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups)) for moment in range(self.num_orders): self._scatter[moment, :, :] = scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=moment) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg)
def name(self, name): if name is not None: cv.check_type('name for Material ID="{}"'.format(self._id), name, string_types) self._name = name else: self._name = ''
def background(self, background): cv.check_type('plot background', background, Iterable, Integral) cv.check_length('plot background', background, 3) for rgb in background: cv.check_greater_than('plot background',rgb, 0, True) cv.check_less_than('plot background', rgb, 256) self._background = background
def dump_to_file(self, filename='mgxs', directory='mgxs'): """Store this Library object in a pickle binary file. Parameters ---------- filename : str Filename for the pickle file. Defaults to 'mgxs'. directory : str Directory for the pickle file. Defaults to 'mgxs'. See also -------- Library.load_from_file(filename, directory) """ cv.check_type('filename', filename, basestring) cv.check_type('directory', directory, basestring) # Make directory if it does not exist if not os.path.exists(directory): os.makedirs(directory) full_filename = os.path.join(directory, filename + '.pkl') full_filename = full_filename.replace(' ', '-') # Load and return pickled Library object pickle.dump(self, open(full_filename, 'wb'))
def coefficients(self, coefficients): cv.check_type('Legendre expansion coefficients', coefficients, Iterable, Real) for l in range(len(coefficients)): coefficients[l] *= (2.*l + 1.)/2. self._legendre_polynomial = np.polynomial.legendre.Legendre( coefficients)
def load_from_file(filename='mgxs', directory='mgxs'): """Load a Library object from a pickle binary file. Parameters ---------- filename : str Filename for the pickle file. Defaults to 'mgxs'. directory : str Directory for the pickle file. Defaults to 'mgxs'. Returns ------- Library A Library object loaded from the pickle binary file See also -------- Library.dump_to_file(mgxs_lib, filename, directory) """ cv.check_type('filename', filename, basestring) cv.check_type('directory', directory, basestring) # Make directory if it does not exist if not os.path.exists(directory): os.makedirs(directory) full_filename = os.path.join(directory, filename + '.pkl') full_filename = full_filename.replace(' ', '-') # Load and return pickled Library object return pickle.load(open(full_filename, 'rb'))
def is_opencg_surface_compatible(opencg_surface): """Determine whether OpenCG surface is compatible with OpenMC geometry. A surface is considered compatible if there is a one-to-one correspondence between OpenMC and OpenCG surface types. Note that some OpenCG surfaces, e.g. SquarePrism, do not have a one-to-one correspondence with OpenMC surfaces but can still be converted into an equivalent collection of OpenMC surfaces. Parameters ---------- opencg_surface : opencg.Surface OpenCG surface Returns ------- bool Whether OpenCG surface is compatible with OpenMC """ cv.check_type('opencg_surface', opencg_surface, opencg.Surface) if opencg_surface.type in ['x-squareprism', 'y-squareprism', 'z-squareprism']: return False else: return True
def center(self, center): cv.check_type('TRISO center', center, Iterable, Real) self._surface.x0 = center[0] self._surface.y0 = center[1] self._surface.z0 = center[2] self.translation = center self._center = center
def get_openmc_cell(opencg_cell): """Return an OpenMC cell corresponding to an OpenCG cell. Parameters ---------- opencg_cell : opencg.Cell OpenCG cell Returns ------- openmc_cell : openmc.universe.Cell Equivalent OpenMC cell """ cv.check_type('opencg_cell', opencg_cell, opencg.Cell) cell_id = opencg_cell.id # If this Cell was already created, use it if cell_id in OPENMC_CELLS: return OPENMC_CELLS[cell_id] # Create an OpenCG Cell to represent this OpenMC Cell name = opencg_cell.name openmc_cell = openmc.Cell(cell_id, name) fill = opencg_cell.fill if opencg_cell.type == 'universe': openmc_cell.fill = get_openmc_universe(fill) elif opencg_cell.type == 'lattice': openmc_cell.fill = get_openmc_lattice(fill) else: openmc_cell.fill = get_openmc_material(fill) if opencg_cell.rotation is not None: rotation = np.asarray(opencg_cell.rotation, dtype=np.float64) openmc_cell.rotation = rotation if opencg_cell.translation is not None: translation = np.asarray(opencg_cell.translation, dtype=np.float64) openmc_cell.translation = translation surfaces = [] operators = [] for surface, halfspace in opencg_cell.surfaces.values(): surfaces.append(get_openmc_surface(surface)) operators.append(operator.neg if halfspace == -1 else operator.pos) openmc_cell.region = openmc.Intersection( *[op(s) for op, s in zip(operators, surfaces)]) # Add the OpenMC Cell to the global collection of all OpenMC Cells OPENMC_CELLS[cell_id] = openmc_cell # Add the OpenCG Cell to the global collection of all OpenCG Cells OPENCG_CELLS[cell_id] = opencg_cell return openmc_cell
def stride(self, stride): cv.check_type('filter stride', stride, Integral) if stride < 0: msg = 'Unable to set stride "{0}" for a "{1}" Filter since it ' \ 'is a negative value'.format(stride, self.type) raise ValueError(msg) self._stride = stride
def pseudo_k0RS(self, pseudo_k0RS): if pseudo_k0RS is not None: cv.check_type('pseudo_k0RS', pseudo_k0RS, np.ndarray) if len(pseudo_k0RS.shape) != 1: raise ValueError('Multipole pseudo_k0RS arrays must be 1D') if not np.issubdtype(pseudo_k0RS.dtype, float): raise TypeError('Multipole data arrays must be float dtype') self._pseudo_k0RS = pseudo_k0RS
def w_end(self, w_end): if w_end is not None: cv.check_type('w_end', w_end, np.ndarray) if len(w_end.shape) != 1: raise ValueError('Multipole w_end arrays must be 1D') if not np.issubdtype(w_end.dtype, int): raise TypeError('Multipole w_end arrays must be integer dtype') self._w_end = w_end
def width(self, width): cv.check_type('mesh width', width, Iterable, Real) cv.check_length('mesh width', width, 1, 3) self._width = width
def z_grid(self, grid): cv.check_type('mesh z_grid', grid, Iterable, Real) self._z_grid = grid
def size(self, size): cv.check_type("Unstructured mesh size", size, Integral) self._size = size
def volumes(self, volumes): cv.check_type("Unstructured mesh volumes", volumes, Iterable, Real) self._volumes = volumes
def write_data_to_vtk(self, filename, datasets, volume_normalization=True): """Map data to the unstructured mesh element centroids to create a VTK point-cloud dataset. Parameters ---------- filename : str Name of the VTK file to write. datasets : dict Dictionary whose keys are the data labels and values are the data sets. volume_normalization : bool Whether or not to normalize the data by the volume of the mesh elements """ import vtk from vtk.util import numpy_support as vtk_npsup if self.centroids is None: raise RuntimeError("No centroid information is present on this " "unstructured mesh. Please load this " "information from a relevant statepoint file.") if self.volumes is None and volume_normalization: raise RuntimeError("No volume data is present on this " "unstructured mesh. Please load the " " mesh information from a statepoint file.") # check that the data sets are appropriately sized for label, dataset in datasets.items(): if isinstance(dataset, np.ndarray): assert dataset.size == self.n_elements else: assert len(dataset) == self.n_elements cv.check_type('label', label, str) # create data arrays for the cells/points cell_dim = 1 vertices = vtk.vtkCellArray() points = vtk.vtkPoints() for centroid in self.centroids: # create a point for each centroid point_id = points.InsertNextPoint(centroid) # create a cell of type "Vertex" for each point cell_id = vertices.InsertNextCell(cell_dim, (point_id, )) # create a VTK data object poly_data = vtk.vtkPolyData() poly_data.SetPoints(points) poly_data.SetVerts(vertices) # strange VTK nuance: # data must be held in some container # until the vtk file is written data_holder = [] # create VTK arrays for each of # the data sets for label, dataset in datasets.items(): dataset = np.asarray(dataset).flatten() if volume_normalization: dataset /= self.volumes.flatten() array = vtk.vtkDoubleArray() array.SetName(label) array.SetNumberOfComponents(1) array.SetArray(vtk_npsup.numpy_to_vtk(dataset), dataset.size, True) data_holder.append(dataset) poly_data.GetPointData().AddArray(array) # set filename if not filename.endswith(".vtk"): filename += ".vtk" writer = vtk.vtkGenericDataObjectWriter() writer.SetFileName(filename) writer.SetInputData(poly_data) writer.Write()
def right_filter(self, right_filter): cv.check_type('right_filter', right_filter, (Filter, CrossFilter, AggregateFilter)) self._right_filter = right_filter self._bins['right'] = right_filter.bins
def left_score(self, left_score): cv.check_type('left_score', left_score, (str, CrossScore, AggregateScore)) self._left_score = left_score
def right_score(self, right_score): cv.check_type('right_score', right_score, (str, CrossScore, AggregateScore)) self._right_score = right_score
def binary_op(self, binary_op): cv.check_type('binary_op', binary_op, str) cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS) self._binary_op = binary_op
def mu(self, mu): cv.check_type('cosine of polar angle', mu, Univariate) self._mu = mu
def phi(self, phi): cv.check_type('azimuthal angle', phi, Univariate) self._phi = phi
def x(self, x): cv.check_type('x coordinate', x, Univariate) self._x = x
def upper_right(self, upper_right): cv.check_type('mesh upper_right', upper_right, Iterable, Real) cv.check_length('mesh upper_right', upper_right, 1, 3) self._upper_right = upper_right
def z(self, z): cv.check_type('z coordinate', z, Univariate) self._z = z
def node(self, node): check_type('node', node, Region) self._node = node
def aggregate_op(self, aggregate_op): cv.check_type('aggregate_op', aggregate_op, str) cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS) self._aggregate_op = aggregate_op
def left_filter(self, left_filter): cv.check_type('left_filter', left_filter, (Filter, CrossFilter, AggregateFilter)) self._left_filter = left_filter self._bins['left'] = left_filter.bins
def aggregate_filter(self, aggregate_filter): cv.check_type('aggregate_filter', aggregate_filter, (openmc.Filter, CrossFilter)) self._aggregate_filter = aggregate_filter
def centroids(self, centroids): cv.check_type("Unstructured mesh centroids", centroids, Iterable, Real) self._centroids = centroids
def aggregate_op(self, aggregate_op): cv.check_type('aggregate_op', aggregate_op, (str, CrossScore)) cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS) self._aggregate_op = aggregate_op
def output(self, val): cv.check_type("Unstructured mesh output value", val, bool) self._output = val
def right_filter(self, right_filter): cv.check_type('right_filter', right_filter, (openmc.Filter, CrossFilter, AggregateFilter)) self._right_filter = right_filter
def filename(self, filename): cv.check_type('Unstructured Mesh filename', filename, str) self._filename = filename
def left_filter(self, left_filter): cv.check_type('left_filter', left_filter, (openmc.Filter, CrossFilter, AggregateFilter)) self._left_filter = left_filter
def right_nuclide(self, right_nuclide): cv.check_type('right_nuclide', right_nuclide, (openmc.Nuclide, CrossNuclide, AggregateNuclide)) self._right_nuclide = right_nuclide
def left_nuclide(self, left_nuclide): cv.check_type('left_nuclide', left_nuclide, (openmc.Nuclide, CrossNuclide, AggregateNuclide)) self._left_nuclide = left_nuclide
def name(self, name): if name is not None: cv.check_type('name for mesh ID="{0}"'.format(self._id), name, str) self._name = name else: self._name = ''
def __new__(cls, name): cv.check_type('element name', name, string_types) cv.check_length('element name', name, 1, 2) return super(Element, cls).__new__(cls, name)
def lower_left(self, lower_left): cv.check_type('mesh lower_left', lower_left, Iterable, Real) cv.check_length('mesh lower_left', lower_left, 1, 3) self._lower_left = lower_left
def y(self, y): cv.check_type('y coordinate', y, Univariate) self._y = y