From 2025306f9a32cbcc611cbe1f4916d211888ea8e1 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Aug 2016 06:43:25 -0400 Subject: [PATCH 01/17] Added capability to use MGXS with a mesh domain in create_mg_mode and create_mg_library. --- openmc/filter.py | 2 +- openmc/mesh.py | 104 +++++++++++++++ openmc/mgxs/library.py | 285 +++++++++++++++++++++++++++++------------ openmc/mgxs/mgxs.py | 3 +- openmc/mgxs_library.py | 124 ++++++++++++++---- 5 files changed, 403 insertions(+), 115 deletions(-) diff --git a/openmc/filter.py b/openmc/filter.py index 8a54e05ce..f9f4f7476 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -376,7 +376,7 @@ class Filter(object): cell instance ID for 'distribcell' Filters. The bin is a 2-tuple of floats for 'energy' and 'energyout' filters corresponding to the energy boundaries of the bin of interest. The bin is an (x,y,z) - 3-tuple for 'mesh' filters corresponding to the mesh cell + 3-tuple for 'mesh' filters corresponding to the mesh cell of interest. Returns diff --git a/openmc/mesh.py b/openmc/mesh.py index 169e7705c..9496a0651 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -6,6 +6,8 @@ import sys import numpy as np import openmc.checkvalue as cv +import openmc.surface +import openmc.cell if sys.version_info[0] >= 3: @@ -181,6 +183,21 @@ class Mesh(object): string += '{0: <16}{1}{2}\n'.format('\tPixels', '=\t', self._width) return string + def cell_generator(self): + """Generator function to traverse through every [i,j,k] index + of the mesh. + + """ + if len(self.dimension) == 2: + for x in range(self.dimension[0]): + for y in range(self.dimension[1]): + yield [x + 1, y + 1, 1] + else: + for x in range(self.dimension[0]): + for y in range(self.dimension[1]): + for z in range(self.dimension[2]): + yield [x + 1, y + 1, z + 1] + def get_mesh_xml(self): """Return XML representation of the mesh @@ -210,3 +227,90 @@ class Mesh(object): subelement.text = ' '.join(map(str, self._width)) return element + + def build_cells(self, bc=['reflective'] * 6): + """Generates a list of cells which mimic the mesh geometry. + + Parameters + ---------- + bc : iterable of {'reflective', 'periodic', or 'vacuum'} + Boundary conditions for each of the six faces of a parallelopiped: + North, East, South, West, Up, and Down. + + Returns + ------- + root_cell : openmc.Cell + The cell containing the lattice mimicking the mesh geometry. + cells : iterable of openmc.Cell + The list of cells within each lattice position mimicking the mesh + geometry. + + """ + + cv.check_length('bc', bc, length_min=6, length_max=6) + for entry in bc: + cv.check_value('bc', entry, ['transmission', 'vacuum', + 'reflective', 'periodic']) + + if len(self.dimension) == 2: + twod = True + else: + twod = False + + # Build enclosing cell + xplanes = [openmc.XPlane(x0=self.lower_left[0], + boundary_type=bc[3]), + openmc.XPlane(x0=self.upper_right[0], + boundary_type=bc[1])] + yplanes = [openmc.YPlane(y0=self.lower_left[1], + boundary_type=bc[2]), + openmc.YPlane(y0=self.upper_right[1], + boundary_type=bc[0])] + if twod: + zplanes = [openmc.ZPlane(z0=-1.E50, boundary_type=bc[5]), + openmc.ZPlane(z0=+1.E50, boundary_type=bc[5])] + else: + zplanes = [openmc.ZPlane(z0=self.lower_left[2], + boundary_type=bc[5]), + openmc.ZPlane(z0=self.upper_right[2], + boundary_type=bc[5])] + root_cell = openmc.Cell() + root_cell.region = ((+xplanes[0] & -xplanes[1]) & + (+yplanes[0] & -yplanes[1]) & + (+zplanes[0] & -zplanes[1])) + + # Build our universes + universes = np.ndarray(self.dimension[::-1], dtype=np.object) + cells = [] + for [i, j, k] in self.cell_generator(): + if twod: + universes[j - 1, i - 1] = openmc.Universe() + cells.append(openmc.Cell()) + universes[j - 1, i - 1].add_cells([cells[-1]]) + else: + universes[k - 1, j - 1, i - 1] = openmc.Universe() + cells.append(openmc.Cell()) + universes[k - 1, j - 1, i - 1].add_cells([cells[-1]]) + + lattice = openmc.RectLattice() + lattice.lower_left = self.lower_left + + if self.width is not None: + lattice.pitch = self.width + else: + dx = ((self.upper_right[0] - self.lower_left[0]) / + self.dimension[0]) + dy = ((self.upper_right[1] - self.lower_left[1]) / + self.dimension[1]) + if twod: + lattice.pitch = [dx, dy] + else: + dz = ((self.upper_right[2] - self.lower_left[2]) / + self.dimension[2]) + lattice.pitch = [dx, dy, dz] + lattice.universes = universes + + # Fill Cell with the Lattice + root_cell.fill = lattice + + return root_cell, cells diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 84571ce23..c5e039cea 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -756,14 +756,14 @@ class Library(object): def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro', xs_id='1m', order=None, tabular_legendre=None, - tabular_points=33): + tabular_points=33, subdomain=None): """Generates an openmc.XSdata object describing a multi-group cross section data set for eventual combination in to an openmc.MGXSLibrary object (i.e., the library). Parameters ---------- - domain : openmc.Material or openmc.Cell or openmc.Universe + domain : openmc.Material, openmc.Cell, openmc.Universe, or openmc.Mesh The domain for spatial homogenization xsdata_name : str Name to apply to the "xsdata" entry produced by this method @@ -792,6 +792,10 @@ class Library(object): parameter is set to `True`. In this case, this parameter sets the number of equally-spaced points in the domain of [-1,1] to be used in building the tabular distribution. Default is `33`. + subdomain : iterable of int + This parameter is not used unless using a mesh domain. In that + case, the subdomain is an [i,j,k] index (1-based indexing) of the + mesh cell of interest in the openmc.Mesh object. Returns ------- @@ -811,7 +815,7 @@ class Library(object): """ cv.check_type('domain', domain, (openmc.Material, openmc.Cell, - openmc.Cell)) + openmc.Universe, openmc.Mesh)) cv.check_type('xsdata_name', xsdata_name, basestring) cv.check_type('nuclide', nuclide, basestring) cv.check_value('xs_type', xs_type, ['macro', 'micro']) @@ -824,6 +828,9 @@ class Library(object): (type(None), bool)) if tabular_points is not None: cv.check_greater_than('tabular_points', tabular_points, 1) + if subdomain is not None: + cv.check_iterable_type('subdomain', subdomain, Integral, + max_depth=2) # Make sure statepoint has been loaded if self._sp_filename is None: @@ -865,38 +872,43 @@ class Library(object): xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) elif 'total' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'total') - xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], + subdomain=subdomain) if 'absorption' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'absorption') xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], subdomain=subdomain) if 'fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'fission') xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], subdomain=subdomain) if 'kappa-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'kappa-fission') xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], + subdomain=subdomain) # For chi and nu-fission we can either have only a nu-fission matrix # provided, or vectors of chi and nu-fission provided if 'nu-fission matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission matrix') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], subdomain=subdomain) else: if 'chi' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'chi') - xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], + subdomain=subdomain) if 'nu-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], + subdomain=subdomain) # If multiplicity matrix is available, prefer that if 'multiplicity matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'multiplicity matrix') xsdata.set_multiplicity_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], + subdomain=subdomain) using_multiplicity = True # multiplicity wil fall back to using scatter and nu-scatter elif ((('scatter matrix' in self.mgxs_types) and @@ -904,7 +916,8 @@ class Library(object): scatt_mgxs = self.get_mgxs(domain, 'scatter matrix') nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs, - xs_type=xs_type, nuclide=[nuclide]) + xs_type=xs_type, nuclide=[nuclide], + subdomain=subdomain) using_multiplicity = True else: using_multiplicity = False @@ -912,12 +925,12 @@ class Library(object): if using_multiplicity: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], subdomain=subdomain) else: if 'nu-scatter matrix' in self.mgxs_types: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide]) + nuclide=[nuclide], subdomain=subdomain) # Since we are not using multiplicity, then # scattering multiplication (nu-scatter) must be @@ -988,15 +1001,6 @@ class Library(object): cv.check_value('xs_type', xs_type, ['macro', 'micro']) if xsdata_names is not None: cv.check_iterable_type('xsdata_names', xsdata_names, basestring) - if xs_ids is not None: - if isinstance(xs_ids, basestring): - # If we only have a string lets convert it now to a list - # of strings. - xs_ids = [xs_ids for i in range(len(self.domains))] - else: - cv.check_iterable_type('xs_ids', xs_ids, basestring) - else: - xs_ids = ['1m' for i in range(len(self.domains))] # If gathering material-specific data, set the xs_type to macro if not self.by_nuclide: @@ -1005,32 +1009,79 @@ class Library(object): # Initialize file mgxs_file = openmc.MGXSLibrary(self.energy_groups) - # Create the xsdata object and add it to the mgxs_file - for i, domain in enumerate(self.domains): - if self.by_nuclide: - nuclides = list(domain.get_all_nuclides().keys()) + if xs_ids is not None: + if isinstance(xs_ids, basestring): + # If we only have a string lets convert it now to a list + # of strings. + xs_id_input = xs_ids + xs_ids = [] + for domain in self.domains: + if self.domain_type is 'mesh': + for subdomain in domain.cell_generator(): + xs_ids.append(xs_id_input) + else: + xs_ids.append(xs_id_input) else: - nuclides = ['total'] - for nuclide in nuclides: - # Build & add metadata to XSdata object - if xsdata_names is None: - xsdata_name = 'set' + str(i + 1) + cv.check_iterable_type('xs_ids', xs_ids, basestring) + else: + xs_ids = [] + for domain in self.domains: + if self.domain_type is 'mesh': + for subdomain in domain.cell_generator(): + xs_ids.append('1m') else: - xsdata_name = xsdata_names[i] - if nuclide is not 'total': - xsdata_name += '_' + nuclide + xs_ids.append('1m') - xsdata = self.get_xsdata(domain, xsdata_name, nuclide=nuclide, - xs_type=xs_type, xs_id=xs_ids[i], - tabular_legendre=tabular_legendre, - tabular_points=tabular_points) + if self.domain_type == 'mesh': + # Create the xsdata objects and add to the mgxs_file + i = 0 + for domain in self.domains: + for subdomain in domain.cell_generator(): + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] - mgxs_file.add_xsdata(xsdata) + # Create XSdata and Macroscopic for this domain + xsdata = self.get_xsdata(domain, xsdata_name, + nuclide='total', + xs_type=xs_type, xs_id=xs_ids[i], + tabular_legendre=tabular_legendre, + tabular_points=tabular_points, + subdomain=subdomain) + mgxs_file.add_xsdata(xsdata) + i += 1 + + else: + # Create the xsdata object and add it to the mgxs_file + for i, domain in enumerate(self.domains): + if self.by_nuclide: + nuclides = list(domain.get_all_nuclides().keys()) + else: + nuclides = ['total'] + for nuclide in nuclides: + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] + if nuclide is not 'total': + xsdata_name += '_' + nuclide + + xsdata = self.get_xsdata(domain, xsdata_name, + nuclide=nuclide, + xs_type=xs_type, xs_id=xs_ids[i], + tabular_legendre=tabular_legendre, + tabular_points=tabular_points) + + mgxs_file.add_xsdata(xsdata) return mgxs_file def create_mg_mode(self, xsdata_names=None, xs_ids=None, - tabular_legendre=None, tabular_points=33): + tabular_legendre=None, tabular_points=33, + bc=['reflective'] * 6): """Creates an openmc.MGXSLibrary object to contain the MGXS data for the Multi-Group mode of OpenMC as well as the associated openmc.Materials and openmc.Geometry objects. The created Geometry is the same as that @@ -1060,6 +1111,9 @@ class Library(object): parameter is set to `True`. In this case, this parameter sets the number of equally-spaced points in the domain of [-1,1] to be used in building the tabular distribution. Default is `33`. + bc : iterable of {'reflective', 'periodic', or 'vacuum'} + Boundary conditions for each of the six faces of a parallelopiped: + North, East, South, Wwest, Up, and Down. Returns ------- @@ -1092,60 +1146,121 @@ class Library(object): if xsdata_names is not None: cv.check_iterable_type('xsdata_names', xsdata_names, basestring) - if xs_ids is not None: - if isinstance(xs_ids, basestring): - # If we only have a string lets convert it now to a list - # of strings. - xs_ids = [xs_ids for i in range(len(self.domains))] - else: - cv.check_iterable_type('xs_ids', xs_ids, basestring) - else: - xs_ids = ['1m' for i in range(len(self.domains))] xs_type = 'macro' # Initialize MGXS File mgxs_file = openmc.MGXSLibrary(self.energy_groups) - # Create a copy of the Geometry to differentiate for these Macroscopics - geometry = copy.deepcopy(self.openmc_geometry) - materials = openmc.Materials() - - # Get all Cells from the Geometry for differentiation - all_cells = geometry.get_all_material_cells() - - # Create the xsdata object and add it to the mgxs_file - for i, domain in enumerate(self.domains): - - # Build & add metadata to XSdata object - if xsdata_names is None: - xsdata_name = 'set' + str(i + 1) + # Set ID names + if xs_ids is not None: + if isinstance(xs_ids, basestring): + # If we only have a string lets convert it now to a list + # of strings. + xs_id_input = xs_ids + xs_ids = [] + for domain in self.domains: + if self.domain_type is 'mesh': + for subdomain in domain.cell_generator(): + xs_ids.append(xs_id_input) + else: + xs_ids.append(xs_id_input) else: - xsdata_name = xsdata_names[i] + cv.check_iterable_type('xs_ids', xs_ids, basestring) + else: + xs_ids = [] + for domain in self.domains: + if self.domain_type is 'mesh': + for subdomain in domain.cell_generator(): + xs_ids.append('1m') + else: + xs_ids.append('1m') - # Create XSdata and Macroscopic for this domain - xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total', - xs_type=xs_type, xs_id=xs_ids[i], - tabular_legendre=tabular_legendre, - tabular_points=tabular_points) - mgxs_file.add_xsdata(xsdata) - macroscopic = openmc.Macroscopic(name=xsdata_name, xs=xs_ids[i]) + if self.domain_type == 'mesh': + # Before continuing, we cant build a model automatically if + # the user provided multiple mesh domains for library generation. + # So check and complain as needed. + cv.check_length("domains", self.domains, 1, 1) - # Create Material and add to collection - material = openmc.Material(name=xsdata_name + '.' + xs_ids[i]) - material.add_macroscopic(macroscopic) - materials.append(material) + # Create the xsdata objects and add to the mgxs_file + # and assign to materials and geometry as we go + materials = openmc.Materials() + root = openmc.Universe(name='root', universe_id=0) + # Add cells representative of the mesh with reflective BC + root_cell, cells = \ + self.domains[0].build_cells(bc) + root.add_cell(root_cell) + geometry = openmc.Geometry() + geometry.root_universe = root - # Differentiate Geometry with new Material - if self.domain_type == 'material': - # Fill all appropriate Cells with new Material - for cell in all_cells: - if cell.fill.id == domain.id: - cell.fill = material + for i, subdomain in enumerate(self.domains[0].cell_generator()): + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] - elif self.domain_type == 'cell': - for cell in all_cells: - if cell.id == domain.id: - cell.fill = material + # Create XSdata and Macroscopic for this domain + xsdata = self.get_xsdata(domain, xsdata_name, + nuclide='total', + xs_type=xs_type, xs_id=xs_ids[i], + tabular_legendre=tabular_legendre, + tabular_points=tabular_points, + subdomain=subdomain) + mgxs_file.add_xsdata(xsdata) + macroscopic = openmc.Macroscopic(name=xsdata_name, + xs=xs_ids[i]) + + # Create Material and add to collection + material = openmc.Material(name=xsdata_name + '.' + + xs_ids[i]) + material.add_macroscopic(macroscopic) + materials.append(material) + + # Set the materials for each of the universes + cells[i].fill = materials[i] + + else: + # Create a copy of the Geometry for these Macroscopics + geometry = copy.deepcopy(self.openmc_geometry) + materials = openmc.Materials() + + # Get all Cells from the Geometry for differentiation + all_cells = geometry.get_all_material_cells() + + # Create the xsdata object and add it to the mgxs_file + for i, domain in enumerate(self.domains): + + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] + + # Create XSdata and Macroscopic for this domain + xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total', + xs_type=xs_type, xs_id=xs_ids[i], + tabular_legendre=tabular_legendre, + tabular_points=tabular_points) + mgxs_file.add_xsdata(xsdata) + macroscopic = openmc.Macroscopic(name=xsdata_name, + xs=xs_ids[i]) + + # Create Material and add to collection + material = openmc.Material(name=xsdata_name + '.' + xs_ids[i]) + material.add_macroscopic(macroscopic) + materials.append(material) + + # Differentiate Geometry with new Material + if self.domain_type == 'material': + # Fill all appropriate Cells with new Material + for cell in all_cells: + if cell.fill.id == domain.id: + cell.fill = material + + elif self.domain_type == 'cell': + for cell in all_cells: + if cell.id == domain.id: + cell.fill = material return mgxs_file, materials, geometry diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index e1c2e6221..608f232b7 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -781,7 +781,8 @@ class MGXS(object): # Construct a collection of the domain filter bins if not isinstance(subdomains, basestring): - cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) + cv.check_iterable_type('subdomains', subdomains, Integral, + max_depth=3) for subdomain in subdomains: filters.append(self.domain_type) filter_bins.append((subdomain,)) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 6f8188b10..fca5f437c 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -603,7 +603,8 @@ class XSdata(object): if np.sum(self._nu_fission) > 0.0: self._fissionable = True - def set_total_mgxs(self, total, nuclide='total', xs_type='macro'): + def set_total_mgxs(self, total, nuclide='total', xs_type='macro', + subdomain=None): """This method allows for an openmc.mgxs.TotalXS or openmc.mgxs.TransportXS to be used to set the total cross section for this XSdata object. @@ -619,6 +620,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -631,16 +635,21 @@ class XSdata(object): openmc.mgxs.TransportXS)) check_value('energy_groups', total.energy_groups, [self.energy_groups]) check_value('domain_type', total.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': - self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type) + self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type, + subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) def set_absorption_mgxs(self, absorption, nuclide='total', - xs_type='macro'): + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.AbsorptionXS to be used to set the absorption cross section for this XSdata object. @@ -655,6 +664,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -667,16 +679,22 @@ class XSdata(object): check_value('energy_groups', absorption.energy_groups, [self.energy_groups]) check_value('domain_type', absorption.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': self._absorption = absorption.get_xs(nuclides=nuclide, - xs_type=xs_type) + xs_type=xs_type, + subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro'): + def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro', + subdomain=None): """This method allows for an openmc.mgxs.FissionXS to be used to set the fission cross section for this XSdata object. @@ -691,6 +709,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -703,17 +724,22 @@ class XSdata(object): check_value('energy_groups', fission.energy_groups, [self.energy_groups]) check_value('domain_type', fission.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': self._fission = fission.get_xs(nuclides=nuclide, - xs_type=xs_type) + xs_type=xs_type, + subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) def set_nu_fission_mgxs(self, nu_fission, nuclide='total', - xs_type='macro'): + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.NuFissionXS to be used to set the nu-fission cross section for this XSdata object. @@ -728,6 +754,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -741,11 +770,16 @@ class XSdata(object): check_value('energy_groups', nu_fission.energy_groups, [self.energy_groups]) check_value('domain_type', nu_fission.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': self._nu_fission = nu_fission.get_xs(nuclides=nuclide, - xs_type=xs_type) + xs_type=xs_type, + subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -759,7 +793,7 @@ class XSdata(object): self._fissionable = True def set_kappa_fission_mgxs(self, k_fission, nuclide='total', - xs_type='macro'): + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.KappaFissionXS to be used to set the kappa-fission cross section for this XSdata object. @@ -775,6 +809,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -787,16 +824,22 @@ class XSdata(object): check_value('energy_groups', k_fission.energy_groups, [self.energy_groups]) check_value('domain_type', k_fission.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': self._kappa_fission = k_fission.get_xs(nuclides=nuclide, - xs_type=xs_type) + xs_type=xs_type, + subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro'): + def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro', + subdomain=None): """This method allows for an openmc.mgxs.Chi to be used to set chi for this XSdata object. @@ -810,6 +853,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -827,11 +873,15 @@ class XSdata(object): check_type('chi', chi, openmc.mgxs.Chi) check_value('energy_groups', chi.energy_groups, [self.energy_groups]) check_value('domain_type', chi.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': self._chi = chi.get_xs(nuclides=nuclide, - xs_type=xs_type) + xs_type=xs_type, subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -839,7 +889,8 @@ class XSdata(object): if self.use_chi is not None: self.use_chi = True - def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro'): + def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro', + subdomain=None): """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 @@ -856,6 +907,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -868,7 +922,7 @@ class XSdata(object): check_value('energy_groups', scatter.energy_groups, [self.energy_groups]) check_value('domain_type', scatter.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) if self.scatt_type != 'legendre': msg = 'Anisotropic scattering representations other than ' \ @@ -886,22 +940,27 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] + 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) + self._scatter[moment, :, :] = \ + scatter.get_xs(nuclides=nuclide, xs_type=xs_type, + moment=moment, subdomains=subdomain_val) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) def set_multiplicity_mgxs(self, nuscatter, scatter=None, nuclide='total', - xs_type='macro'): + xs_type='macro', subdomain=None): """This method allows for either the direct use of only an openmc.mgxs.MultiplicityMatrixXS OR an openmc.mgxs.NuScatterMatrixXS and openmc.mgxs.ScatterMatrixXS to be used to set the scattering @@ -926,6 +985,9 @@ class XSdata(object): xs_type: {'macro', 'micro'} Provide the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + subdomain : iterable of int + If the MGXS contains a mesh domain type, the subdomain parameter + specifies which mesh cell ([i, j, k]) to use. See also -------- @@ -939,7 +1001,7 @@ class XSdata(object): check_value('energy_groups', nuscatter.energy_groups, [self.energy_groups]) check_value('domain_type', nuscatter.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) if scatter is not None: check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS) if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS): @@ -950,16 +1012,22 @@ class XSdata(object): check_value('energy_groups', scatter.energy_groups, [self.energy_groups]) check_value('domain_type', scatter.domain_type, - ['universe', 'cell', 'material']) + ['universe', 'cell', 'material', 'mesh']) + if subdomain is None: + subdomain_val = None + else: + subdomain_val = [subdomain] if self.representation is 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, - xs_type=xs_type, moment=0) + xs_type=xs_type, moment=0, + subdomains=subdomain_val) if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS): self._multiplicity = nuscatt else: scatt = scatter.get_xs(nuclides=nuclide, - xs_type=xs_type, moment=0) + xs_type=xs_type, moment=0, + subdomains=subdomain_val) self._multiplicity = np.divide(nuscatt, scatt) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' From 5c6280b206e031faffb2e068349fc98206d45e9f Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Aug 2016 06:59:17 -0400 Subject: [PATCH 02/17] some cleaning up --- openmc/mgxs/library.py | 33 ++++++++++++++++---------- openmc/mgxs_library.py | 53 ++++++++---------------------------------- 2 files changed, 31 insertions(+), 55 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c5e039cea..9372998a0 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -866,49 +866,57 @@ class Library(object): xsdata.zaid = self._nuclides[nuclide][0] xsdata.awr = self._nuclides[nuclide][1] + if subdomain is None: + subdomain_val = 'all' + else: + subdomain_val = [subdomain] + # Now get xs data itself if 'nu-transport' in self.mgxs_types and self.correction == 'P0': mymgxs = self.get_mgxs(domain, 'nu-transport') - xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], + subdomains=subdomain_val) elif 'total' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'total') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) if 'absorption' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'absorption') xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + nuclide=[nuclide], + subdomain=subdomain_val) if 'fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'fission') xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + nuclide=[nuclide], subdomain=subdomain_val) if 'kappa-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'kappa-fission') xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) # For chi and nu-fission we can either have only a nu-fission matrix # provided, or vectors of chi and nu-fission provided if 'nu-fission matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission matrix') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + nuclide=[nuclide], + subdomain=subdomain_val) else: if 'chi' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'chi') xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) if 'nu-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) # If multiplicity matrix is available, prefer that if 'multiplicity matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'multiplicity matrix') xsdata.set_multiplicity_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) using_multiplicity = True # multiplicity wil fall back to using scatter and nu-scatter elif ((('scatter matrix' in self.mgxs_types) and @@ -917,7 +925,7 @@ class Library(object): nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + subdomain=subdomain_val) using_multiplicity = True else: using_multiplicity = False @@ -925,12 +933,13 @@ class Library(object): if using_multiplicity: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + nuclide=[nuclide], subdomain=subdomain_val) else: if 'nu-scatter matrix' in self.mgxs_types: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + nuclide=[nuclide], + subdomain=subdomain_val) # Since we are not using multiplicity, then # scattering multiplication (nu-scatter) must be diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index fca5f437c..aaea0ce4b 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -604,7 +604,7 @@ class XSdata(object): self._fissionable = True def set_total_mgxs(self, total, nuclide='total', xs_type='macro', - subdomain=None): + subdomain='all'): """This method allows for an openmc.mgxs.TotalXS or openmc.mgxs.TransportXS to be used to set the total cross section for this XSdata object. @@ -636,14 +636,10 @@ class XSdata(object): check_value('energy_groups', total.energy_groups, [self.energy_groups]) check_value('domain_type', total.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain_val) + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -680,15 +676,11 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', absorption.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._absorption = absorption.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain_val) + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -725,15 +717,11 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', fission.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._fission = fission.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain_val) + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -771,15 +759,11 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', nu_fission.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._nu_fission = nu_fission.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain_val) + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -825,15 +809,11 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', k_fission.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._kappa_fission = k_fission.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain_val) + subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -874,14 +854,10 @@ class XSdata(object): check_value('energy_groups', chi.energy_groups, [self.energy_groups]) check_value('domain_type', chi.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': self._chi = chi.get_xs(nuclides=nuclide, - xs_type=xs_type, subdomains=subdomain_val) + xs_type=xs_type, subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -940,11 +916,6 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] - if self.representation is 'isotropic': # Get the scattering orders in the outermost dimension self._scatter = np.zeros((self.num_orders, @@ -953,7 +924,7 @@ class XSdata(object): for moment in range(self.num_orders): self._scatter[moment, :, :] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, - moment=moment, subdomains=subdomain_val) + moment=moment, subdomains=subdomain) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' @@ -1013,21 +984,17 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) - if subdomain is None: - subdomain_val = None - else: - subdomain_val = [subdomain] if self.representation is 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, - subdomains=subdomain_val) + subdomains=subdomain) if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS): self._multiplicity = nuscatt else: scatt = scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, - subdomains=subdomain_val) + subdomains=subdomain) self._multiplicity = np.divide(nuscatt, scatt) elif self.representation is 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' From ef2f6bdc7c36327ccf535780cc07522ccef04c1c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Aug 2016 11:52:55 -0400 Subject: [PATCH 03/17] Addressing comments --- openmc/macroscopic.py | 2 +- openmc/mesh.py | 56 +++++++++++++++------- openmc/mgxs/library.py | 105 ++++++++++++++++++++++------------------- openmc/mgxs_library.py | 4 ++ 4 files changed, 99 insertions(+), 68 deletions(-) diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py index 1dd087903..9f55998e3 100644 --- a/openmc/macroscopic.py +++ b/openmc/macroscopic.py @@ -30,7 +30,7 @@ class Macroscopic(object): self._name = '' self._xs = None - # Set the Material class attributes + # Set the Macroscopic class attributes self.name = name if xs is not None: diff --git a/openmc/mesh.py b/openmc/mesh.py index 9496a0651..c2b23bf1f 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -187,6 +187,17 @@ class Mesh(object): """Generator function to traverse through every [i,j,k] index of the mesh. + For example the following code: + for mesh_index in mymesh.cell_generator(): + print mesh_index + + will produce the following output for a 3-D 2x2x2 mesh in mymesh: + [1, 1, 1] + [1, 1, 2] + [1, 2, 1] + [1, 2, 2] + ... + """ if len(self.dimension) == 2: for x in range(self.dimension[0]): @@ -229,49 +240,56 @@ class Mesh(object): return element def build_cells(self, bc=['reflective'] * 6): - """Generates a list of cells which mimic the mesh geometry. + """Generates a lattice of universes with the same dimensionality + as the mesh object in self. The individual cells/universes produced + will not have material definitions applied and so downstream code + will have to apply that information. Parameters ---------- - bc : iterable of {'reflective', 'periodic', or 'vacuum'} - Boundary conditions for each of the six faces of a parallelopiped: - North, East, South, West, Up, and Down. + bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'} + Boundary conditions for each of the four faces of a rectangle + (if aplying to a 2D mesh) or six faces of a parallelepiped + (if applying to a 3D mesh) provided in the following order: + [x min, x max, y min, y max, z min, z max]. 2-D cells do not + contain the z min and z max entries. Returns ------- root_cell : openmc.Cell - The cell containing the lattice mimicking the mesh geometry. + The cell containing the lattice representing the mesh geometry; + this cell is a single parallelepiped with boundaries matching + the outermost mesh boundary with the boundary conditions from bc + applied. cells : iterable of openmc.Cell The list of cells within each lattice position mimicking the mesh geometry. """ - cv.check_length('bc', bc, length_min=6, length_max=6) + twod = len(self.dimension) == 2 + cv.check_length('bc', bc, length_min=4, length_max=6) for entry in bc: cv.check_value('bc', entry, ['transmission', 'vacuum', 'reflective', 'periodic']) - if len(self.dimension) == 2: - twod = True - else: - twod = False - - # Build enclosing cell + # Build the cell which will contain the lattice xplanes = [openmc.XPlane(x0=self.lower_left[0], - boundary_type=bc[3]), + boundary_type=bc[0]), openmc.XPlane(x0=self.upper_right[0], boundary_type=bc[1])] yplanes = [openmc.YPlane(y0=self.lower_left[1], boundary_type=bc[2]), openmc.YPlane(y0=self.upper_right[1], - boundary_type=bc[0])] + boundary_type=bc[3])] if twod: - zplanes = [openmc.ZPlane(z0=-1.E50, boundary_type=bc[5]), - openmc.ZPlane(z0=+1.E50, boundary_type=bc[5])] + zplanes = [openmc.ZPlane(z0=np.finfo(np.float).min, + boundary_type='reflective'), + openmc.ZPlane(z0=np.finfo(np.float).max, + boundary_type='reflective')] else: zplanes = [openmc.ZPlane(z0=self.lower_left[2], - boundary_type=bc[5]), + boundary_type=bc[4]), openmc.ZPlane(z0=self.upper_right[2], boundary_type=bc[5])] root_cell = openmc.Cell() @@ -279,7 +297,9 @@ class Mesh(object): (+yplanes[0] & -yplanes[1]) & (+zplanes[0] & -zplanes[1])) - # Build our universes + # Build the universes which will be used for each of the [i,j,k] + # locations within the mesh. + # We will also have to build cells to assign to these universes universes = np.ndarray(self.dimension[::-1], dtype=np.object) cells = [] for [i, j, k] in self.cell_generator(): diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 9372998a0..c36034bfc 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -795,7 +795,9 @@ class Library(object): subdomain : iterable of int This parameter is not used unless using a mesh domain. In that case, the subdomain is an [i,j,k] index (1-based indexing) of the - mesh cell of interest in the openmc.Mesh object. + mesh cell of interest in the openmc.Mesh object. Note: + this parameter currently only supports subdomains within a mesh, + and not the subdomains of a distribcell. Returns ------- @@ -918,7 +920,7 @@ class Library(object): nuclide=[nuclide], subdomain=subdomain_val) using_multiplicity = True - # multiplicity wil fall back to using scatter and nu-scatter + # multiplicity will fall back to using scatter and nu-scatter elif ((('scatter matrix' in self.mgxs_types) and ('nu-scatter matrix' in self.mgxs_types))): scatt_mgxs = self.get_mgxs(domain, 'scatter matrix') @@ -1018,33 +1020,33 @@ class Library(object): # Initialize file mgxs_file = openmc.MGXSLibrary(self.energy_groups) + # Get the number of domains to size arrays with + if self.domain_type is 'mesh': + num_domains = np.sum(d.num_mesh_cells for d in self.domains) + else: + num_domains = len(self.domains) + + # Set id names if xs_ids is not None: if isinstance(xs_ids, basestring): # If we only have a string lets convert it now to a list # of strings. - xs_id_input = xs_ids - xs_ids = [] - for domain in self.domains: - if self.domain_type is 'mesh': - for subdomain in domain.cell_generator(): - xs_ids.append(xs_id_input) - else: - xs_ids.append(xs_id_input) + all_xs_ids = [xs_ids] * num_domains else: cv.check_iterable_type('xs_ids', xs_ids, basestring) + cv.check_length('xs_ids', xs_ids, num_domains, num_domains) + all_xs_ids = xs_ids + else: - xs_ids = [] - for domain in self.domains: - if self.domain_type is 'mesh': - for subdomain in domain.cell_generator(): - xs_ids.append('1m') - else: - xs_ids.append('1m') + all_xs_ids = ['1m'] * num_domains if self.domain_type == 'mesh': # Create the xsdata objects and add to the mgxs_file i = 0 for domain in self.domains: + if self.by_nuclide: + raise NotImplementedError("Mesh domains do not currently " + "support nuclidic tallies") for subdomain in domain.cell_generator(): # Build & add metadata to XSdata object if xsdata_names is None: @@ -1055,7 +1057,8 @@ class Library(object): # Create XSdata and Macroscopic for this domain xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total', - xs_type=xs_type, xs_id=xs_ids[i], + xs_type=xs_type, + xs_id=all_xs_ids[i], tabular_legendre=tabular_legendre, tabular_points=tabular_points, subdomain=subdomain) @@ -1079,8 +1082,8 @@ class Library(object): xsdata_name += '_' + nuclide xsdata = self.get_xsdata(domain, xsdata_name, - nuclide=nuclide, - xs_type=xs_type, xs_id=xs_ids[i], + nuclide=nuclide, xs_type=xs_type, + xs_id=all_xs_ids[i], tabular_legendre=tabular_legendre, tabular_points=tabular_points) @@ -1120,9 +1123,12 @@ class Library(object): parameter is set to `True`. In this case, this parameter sets the number of equally-spaced points in the domain of [-1,1] to be used in building the tabular distribution. Default is `33`. - bc : iterable of {'reflective', 'periodic', or 'vacuum'} - Boundary conditions for each of the six faces of a parallelopiped: - North, East, South, Wwest, Up, and Down. + bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'} + Boundary conditions for each of the four faces of a rectangle + (if aplying to a 2D mesh) or six faces of a parallelepiped + (if applying to a 3D mesh) provided in the following order: + [x min, x max, y min, y max, z min, z max]. 2-D cells do not + contain the z min and z max entries. Returns ------- @@ -1160,40 +1166,39 @@ class Library(object): # Initialize MGXS File mgxs_file = openmc.MGXSLibrary(self.energy_groups) - # Set ID names + # Get the number of domains to size arrays with + if self.domain_type is 'mesh': + num_domains = np.sum(d.num_mesh_cells for d in self.domains) + else: + num_domains = len(self.domains) + + # Set id names if xs_ids is not None: if isinstance(xs_ids, basestring): # If we only have a string lets convert it now to a list # of strings. - xs_id_input = xs_ids - xs_ids = [] - for domain in self.domains: - if self.domain_type is 'mesh': - for subdomain in domain.cell_generator(): - xs_ids.append(xs_id_input) - else: - xs_ids.append(xs_id_input) + all_xs_ids = [xs_ids] * num_domains else: cv.check_iterable_type('xs_ids', xs_ids, basestring) + cv.check_length('xs_ids', xs_ids, num_domains, num_domains) + all_xs_ids = xs_ids + else: - xs_ids = [] - for domain in self.domains: - if self.domain_type is 'mesh': - for subdomain in domain.cell_generator(): - xs_ids.append('1m') - else: - xs_ids.append('1m') + all_xs_ids = ['1m'] * num_domains if self.domain_type == 'mesh': - # Before continuing, we cant build a model automatically if - # the user provided multiple mesh domains for library generation. - # So check and complain as needed. + # We cant build a model automatically if the user provided multiple + # mesh domains for library generation since the multiple meshes + # could be overlapping or in disparate regions of the continuous + # energy model. The next step makes sure there is only one before + # continuing. cv.check_length("domains", self.domains, 1, 1) # Create the xsdata objects and add to the mgxs_file # and assign to materials and geometry as we go materials = openmc.Materials() root = openmc.Universe(name='root', universe_id=0) + # Add cells representative of the mesh with reflective BC root_cell, cells = \ self.domains[0].build_cells(bc) @@ -1209,19 +1214,20 @@ class Library(object): xsdata_name = xsdata_names[i] # Create XSdata and Macroscopic for this domain - xsdata = self.get_xsdata(domain, xsdata_name, + xsdata = self.get_xsdata(self.domains[0], xsdata_name, nuclide='total', - xs_type=xs_type, xs_id=xs_ids[i], + xs_type=xs_type, + xs_id=all_xs_ids[i], tabular_legendre=tabular_legendre, tabular_points=tabular_points, subdomain=subdomain) mgxs_file.add_xsdata(xsdata) macroscopic = openmc.Macroscopic(name=xsdata_name, - xs=xs_ids[i]) + xs=all_xs_ids[i]) # Create Material and add to collection material = openmc.Material(name=xsdata_name + '.' + - xs_ids[i]) + all_xs_ids[i]) material.add_macroscopic(macroscopic) materials.append(material) @@ -1247,15 +1253,16 @@ class Library(object): # Create XSdata and Macroscopic for this domain xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total', - xs_type=xs_type, xs_id=xs_ids[i], + xs_type=xs_type, xs_id=all_xs_ids[i], tabular_legendre=tabular_legendre, tabular_points=tabular_points) mgxs_file.add_xsdata(xsdata) macroscopic = openmc.Macroscopic(name=xsdata_name, - xs=xs_ids[i]) + xs=all_xs_ids[i]) # Create Material and add to collection - material = openmc.Material(name=xsdata_name + '.' + xs_ids[i]) + material = openmc.Material(name=xsdata_name + '.' + + all_xs_ids[i]) material.add_macroscopic(macroscopic) materials.append(material) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index aaea0ce4b..c9a7debdc 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1120,6 +1120,10 @@ class MGXSLibrary(object): def energy_groups(self): return self._energy_groups + @property + def xsdatas(self): + return self._xsdatas + @inverse_velocities.setter def inverse_velocities(self, inverse_velocities): check_type('inverse_velocities', inverse_velocities, Iterable, Real) From 72d4496482b7b3d0dcd44010ccb85f312d29a87c Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 6 Aug 2016 12:02:32 -0400 Subject: [PATCH 04/17] Simplified create_mg_mode by making it call create_mg_library to create mgxs_file, leaving only the material and geometry work for create_mg_mode. Also removed subdomain_val --- openmc/mgxs/library.py | 121 +++++++++++++---------------------------- 1 file changed, 37 insertions(+), 84 deletions(-) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c36034bfc..e2964f3fa 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -869,56 +869,56 @@ class Library(object): xsdata.awr = self._nuclides[nuclide][1] if subdomain is None: - subdomain_val = 'all' + subdomain = 'all' else: - subdomain_val = [subdomain] + subdomain = [subdomain] # Now get xs data itself if 'nu-transport' in self.mgxs_types and self.correction == 'P0': mymgxs = self.get_mgxs(domain, 'nu-transport') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomains=subdomain_val) + subdomains=subdomain) elif 'total' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'total') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) if 'absorption' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'absorption') xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) if 'fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'fission') xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain_val) + nuclide=[nuclide], subdomain=subdomain) if 'kappa-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'kappa-fission') xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) # For chi and nu-fission we can either have only a nu-fission matrix # provided, or vectors of chi and nu-fission provided if 'nu-fission matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission matrix') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) else: if 'chi' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'chi') xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) if 'nu-fission' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'nu-fission') xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) # If multiplicity matrix is available, prefer that if 'multiplicity matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'multiplicity matrix') xsdata.set_multiplicity_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) using_multiplicity = True # multiplicity will fall back to using scatter and nu-scatter elif ((('scatter matrix' in self.mgxs_types) and @@ -927,7 +927,7 @@ class Library(object): nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) using_multiplicity = True else: using_multiplicity = False @@ -935,13 +935,13 @@ class Library(object): if using_multiplicity: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain_val) + nuclide=[nuclide], subdomain=subdomain) else: if 'nu-scatter matrix' in self.mgxs_types: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain_val) + subdomain=subdomain) # Since we are not using multiplicity, then # scattering multiplication (nu-scatter) must be @@ -1159,44 +1159,21 @@ class Library(object): # multi-group cross section types self.check_library_for_openmc_mgxs() - if xsdata_names is not None: - cv.check_iterable_type('xsdata_names', xsdata_names, basestring) - xs_type = 'macro' - - # Initialize MGXS File - mgxs_file = openmc.MGXSLibrary(self.energy_groups) - - # Get the number of domains to size arrays with - if self.domain_type is 'mesh': - num_domains = np.sum(d.num_mesh_cells for d in self.domains) - else: - num_domains = len(self.domains) - - # Set id names - if xs_ids is not None: - if isinstance(xs_ids, basestring): - # If we only have a string lets convert it now to a list - # of strings. - all_xs_ids = [xs_ids] * num_domains - else: - cv.check_iterable_type('xs_ids', xs_ids, basestring) - cv.check_length('xs_ids', xs_ids, num_domains, num_domains) - all_xs_ids = xs_ids - - else: - all_xs_ids = ['1m'] * num_domains - + # If the domain type is a mesh, then there can only be one domain for + # this method. Thi is because we can build a model automatically if + # the user provided multiple mesh domains for library generation since + # the multiple meshes could be overlapping or in disparate regions + # of the continuous energy model. The next step makes sure there is + # only one before continuing. if self.domain_type == 'mesh': - # We cant build a model automatically if the user provided multiple - # mesh domains for library generation since the multiple meshes - # could be overlapping or in disparate regions of the continuous - # energy model. The next step makes sure there is only one before - # continuing. cv.check_length("domains", self.domains, 1, 1) - # Create the xsdata objects and add to the mgxs_file - # and assign to materials and geometry as we go - materials = openmc.Materials() + # Get the MGXS File Data + mgxs_file = self.create_mg_library('macro', xsdata_names, xs_ids, + tabular_legendre, tabular_points) + + # Now move on the creating the geometry and assigning materials + if self.domain_type == 'mesh': root = openmc.Universe(name='root', universe_id=0) # Add cells representative of the mesh with reflective BC @@ -1205,29 +1182,17 @@ class Library(object): root.add_cell(root_cell) geometry = openmc.Geometry() geometry.root_universe = root + materials = openmc.Materials() for i, subdomain in enumerate(self.domains[0].cell_generator()): - # Build & add metadata to XSdata object - if xsdata_names is None: - xsdata_name = 'set' + str(i + 1) - else: - xsdata_name = xsdata_names[i] - - # Create XSdata and Macroscopic for this domain - xsdata = self.get_xsdata(self.domains[0], xsdata_name, - nuclide='total', - xs_type=xs_type, - xs_id=all_xs_ids[i], - tabular_legendre=tabular_legendre, - tabular_points=tabular_points, - subdomain=subdomain) - mgxs_file.add_xsdata(xsdata) - macroscopic = openmc.Macroscopic(name=xsdata_name, - xs=all_xs_ids[i]) + xsdata = mgxs_file.xsdatas[i] + [name, id] = xsdata.name.split('.') + # Build the macroscopic and assign it to the cell of + # interest + macroscopic = openmc.Macroscopic(name=name, xs=id) # Create Material and add to collection - material = openmc.Material(name=xsdata_name + '.' + - all_xs_ids[i]) + material = openmc.Material(name=xsdata.name) material.add_macroscopic(macroscopic) materials.append(material) @@ -1244,25 +1209,13 @@ class Library(object): # Create the xsdata object and add it to the mgxs_file for i, domain in enumerate(self.domains): + xsdata = mgxs_file.xsdatas[i] + [name, id] = xsdata.name.split('.') - # Build & add metadata to XSdata object - if xsdata_names is None: - xsdata_name = 'set' + str(i + 1) - else: - xsdata_name = xsdata_names[i] - - # Create XSdata and Macroscopic for this domain - xsdata = self.get_xsdata(domain, xsdata_name, nuclide='total', - xs_type=xs_type, xs_id=all_xs_ids[i], - tabular_legendre=tabular_legendre, - tabular_points=tabular_points) - mgxs_file.add_xsdata(xsdata) - macroscopic = openmc.Macroscopic(name=xsdata_name, - xs=all_xs_ids[i]) + macroscopic = openmc.Macroscopic(name=name, xs=id) # Create Material and add to collection - material = openmc.Material(name=xsdata_name + '.' + - all_xs_ids[i]) + material = openmc.Material(name=xsdata.name) material.add_macroscopic(macroscopic) materials.append(material) From 6c29c394434e2f5acfb78d7080aca73b9c62c66a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 15 Aug 2016 17:50:03 -0500 Subject: [PATCH 05/17] Add check on user-specified bounding boxes for volume calculations --- openmc/volume.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/openmc/volume.py b/openmc/volume.py index e9b1dac1d..2a2a92f61 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -1,6 +1,7 @@ from collections import Iterable, Mapping from numbers import Real, Integral from xml.etree import ElementTree as ET +from warnings import warn import numpy as np import pandas as pd @@ -68,10 +69,26 @@ class VolumeCalculation(object): self.samples = samples if lower_left is not None: - self.lower_left = lower_left if upper_right is None: raise ValueError('Both lower-left and upper-right coordinates ' 'should be specified') + + # For cell domains, try to compute bounding box and make sure + # user-specified one is valid + if self.domain_type == 'cell': + for c in domains: + if c.region is None: + continue + ll, ur = c.region.bounding_box + if np.any(np.isinf(ll)) or np.any(np.isinf(ur)): + continue + if (np.any(np.asarray(lower_left) > ll) or + np.any(np.asarray(upper_right) < ur)): + warn("Specified bounding box is smaller than computed " + "bounding box for cell {}. Volume calculation may " + "be incorrect!".format(c.id)) + + self.lower_left = lower_left self.upper_right = upper_right else: if self.domain_type == 'cell': From 1cfa392bb0580b584643927fb3e57f43f28b9f12 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 15 Aug 2016 18:04:22 -0500 Subject: [PATCH 06/17] Reject external source only if 95% of sites are rejected --- src/constants.F90 | 3 ++- src/source.F90 | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/constants.F90 b/src/constants.F90 index 0a6000553..fca45d145 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -54,7 +54,8 @@ module constants ! Maximum number of external source spatial resamples to encounter before an ! error is thrown. - integer, parameter :: MAX_EXTSRC_RESAMPLES = 10000 + integer, parameter :: EXTSRC_REJECT_THRESHOLD = 10000 + real(8), parameter :: EXTSRC_REJECT_FRACTION = 0.05 ! ============================================================================ ! PHYSICAL CONSTANTS diff --git a/src/source.F90 b/src/source.F90 index 194c8c6ad..fad9ae46a 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -107,7 +107,8 @@ contains real(8) :: r(3) ! sampled coordinates logical :: found ! Does the source particle exist within geometry? type(Particle) :: p ! Temporary particle for using find_cell - integer, save :: num_resamples = 0 ! Number of resamples encountered + integer, save :: n_sample = 0 ! Number of samples + integer, save :: n_reject = 0 ! Number of samples rejected ! Set weight to one by default site % wgt = ONE @@ -143,13 +144,6 @@ contains ! Now search to see if location exists in geometry call find_cell(p, found) - if (.not. found) then - num_resamples = num_resamples + 1 - if (num_resamples == MAX_EXTSRC_RESAMPLES) then - call fatal_error("Maximum number of external source spatial & - &resamples reached!") - end if - end if ! Check if spatial site is in fissionable material select type (space => external_source(i) % space) @@ -162,8 +156,21 @@ contains end if end if end select + + ! Check for rejection + if (.not. found) then + n_reject = n_reject + 1 + if (n_reject >= EXTSRC_REJECT_THRESHOLD .and. & + real(n_sample, 8)/n_reject <= EXTSRC_REJECT_FRACTION) then + call fatal_error("More than 95% of external source sites sampled & + &were rejected. Please check your external source definition.") + end if + end if end do + ! Increment number of samples + n_sample = n_sample + 1 + call p % clear() ! Sample angle From 8474a9c71b909a599f3e9e9f3fbb4f6fa2f521f8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 15 Aug 2016 18:12:55 -0500 Subject: [PATCH 07/17] Update documentation regarding CC environment variable --- docs/source/usersguide/install.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 1a0569148..457c5efd8 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -204,20 +204,22 @@ should be used: Compiling with MPI ++++++++++++++++++ -To compile with MPI, set the :envvar:`FC` environment variable to the path to -the MPI Fortran wrapper. For example, in a bash shell: +To compile with MPI, set the :envvar:`FC` and :envvar:`CC` environment variables +to the path to the MPI Fortran and C wrappers, respectively. For example, in a +bash shell: .. code-block:: sh export FC=mpif90 + export CC=mpicc cmake /path/to/openmc -Note that in many shells, an environment variable can be set for a single -command, i.e. +Note that in many shells, environment variables can be set for a single command, +i.e. .. code-block:: sh - FC=mpif90 cmake /path/to/openmc + FC=mpif90 CC=mpicc cmake /path/to/openmc Selecting HDF5 Installation +++++++++++++++++++++++++++ @@ -343,7 +345,7 @@ compiler, it is necessary to specify that all objects be compiled with the .. code-block:: sh mkdir build && cd build - FC=ifort FFLAGS=-mmic cmake -Dopenmp=on .. + FC=ifort CC=icc FFLAGS=-mmic cmake -Dopenmp=on .. make Note that unless an HDF5 build for the Intel Xeon Phi is already on your target From 6cd569fdead72a3fb1f9acf61256eec22ceccaf8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 15 Aug 2016 21:15:40 -0500 Subject: [PATCH 08/17] Add SiO2 to list of recognized S(a,b) tables --- openmc/data/thermal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py index cd44f21f9..be35da517 100644 --- a/openmc/data/thermal.py +++ b/openmc/data/thermal.py @@ -33,6 +33,7 @@ _THERMAL_NAMES = {'al': 'c_Al27', 'al27': 'c_Al27', 'orthod': 'c_ortho_D', 'dortho': 'c_ortho_D', 'orthoh': 'c_ortho_H', 'hortho': 'c_ortho_H', 'ouo2': 'c_O_in_UO2', 'o2-u': 'c_O_in_UO2', 'o2/u': 'c_O_in_UO2', + 'sio2': 'c_SiO2', 'parad': 'c_para_D', 'dpara': 'c_para_D', 'parah': 'c_para_H', 'hpara': 'c_para_H', 'sch4': 'c_solid_CH4', 'smeth': 'c_solid_CH4', From fcd24cc219b85120c211b8ab4cbb80adaca8f515 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 16 Aug 2016 21:19:01 -0500 Subject: [PATCH 09/17] Return 0.0 from MGXS.get_nuclide_density if nuclide not in list --- openmc/mgxs/mgxs.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 7aa12d041..137ab62f0 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -542,12 +542,6 @@ class MGXS(object): float The atomic number density (atom/b-cm) for the nuclide of interest - Raises - ------- - ValueError - When the density is requested for a nuclide which is not found in - the spatial domain. - """ cv.check_type('nuclide', nuclide, basestring) @@ -555,13 +549,7 @@ class MGXS(object): # Get list of all nuclides in the spatial domain nuclides = self.domain.get_nuclide_densities() - if nuclide not in nuclides: - msg = 'Unable to get density for nuclide "{0}" which is not in ' \ - '{1} "{2}"'.format(nuclide, self.domain_type, self.domain.id) - ValueError(msg) - - density = nuclides[nuclide][1] - return density + return nuclides[nuclide][1] if nuclide in nuclides else 0.0 def get_nuclide_densities(self, nuclides='all'): """Get an array of atomic number densities in units of atom/b-cm for all @@ -816,6 +804,7 @@ class MGXS(object): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] + xs[np.isnan(xs)] = 0.0 # Reverse data if user requested increasing energy groups since # tally data is stored in order of increasing energies @@ -1561,6 +1550,10 @@ class MGXS(object): df['mean'] /= np.tile(densities, tile_factor) df['std. dev.'] /= np.tile(densities, tile_factor) + # Replace NaNs by zeros (happens if nuclide density is zero) + df['mean'].replace(np.nan, 0.0, inplace=True) + df['std. dev.'].replace(np.nan, 0.0, inplace=True) + # Sort the dataframe by domain type id (e.g., distribcell id) and # energy groups such that data is from fast to thermal if self.domain_type == 'mesh': @@ -1813,6 +1806,7 @@ class MatrixMGXS(MGXS): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] + xs[np.isnan(xs)] = 0.0 # Reverse data if user requested increasing energy groups since # tally data is stored in order of increasing energies @@ -3645,6 +3639,7 @@ class ScatterMatrixXS(MatrixMGXS): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] + xs[np.isnan(xs)] = 0.0 # Reverse data if user requested increasing energy groups since # tally data is stored in order of increasing energies From f00461d9550bb1d68f81c162fcc0243936ce2f51 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 17 Aug 2016 06:09:03 -0500 Subject: [PATCH 10/17] Fix RELAX NG schemata for settings.xml --- src/relaxng/settings.rnc | 2 +- src/relaxng/settings.rng | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/relaxng/settings.rnc b/src/relaxng/settings.rnc index e23cbdd6c..742e13773 100644 --- a/src/relaxng/settings.rnc +++ b/src/relaxng/settings.rnc @@ -153,7 +153,7 @@ element settings { attribute lower_left { list { xsd:double+ } }) & (element upper_right { list { xsd:double+ } } | attribute upper_right { list { xsd:double+ } }) - }+ & + }* & element uniform_fs{ (element dimension { list { xsd:positiveInteger+ } } | diff --git a/src/relaxng/settings.rng b/src/relaxng/settings.rng index 38acea598..39bed4a62 100644 --- a/src/relaxng/settings.rng +++ b/src/relaxng/settings.rng @@ -625,7 +625,7 @@ - + @@ -694,7 +694,7 @@ - + From 079f61cd1c8e5cb3da7632b0bfa6ac876d42b72d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 17 Aug 2016 10:50:33 -0500 Subject: [PATCH 11/17] No need for redundant NaN -> zero (@samuelshaner beat me to it) --- openmc/mgxs/mgxs.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 4b465a19d..e77685088 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -815,7 +815,6 @@ class MGXS(object): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] - xs[np.isnan(xs)] = 0.0 # Eliminate the trivial score dimension xs = np.squeeze(xs, axis=len(xs.shape) - 1) @@ -1818,7 +1817,6 @@ class MatrixMGXS(MGXS): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] - xs[np.isnan(xs)] = 0.0 # Eliminate the trivial score dimension xs = np.squeeze(xs, axis=len(xs.shape) - 1) @@ -3655,7 +3653,6 @@ class ScatterMatrixXS(MatrixMGXS): densities = self.get_nuclide_densities('sum') if value == 'mean' or value == 'std_dev': xs /= densities[np.newaxis, :, np.newaxis] - xs[np.isnan(xs)] = 0.0 # Convert and nans to zero xs = np.nan_to_num(xs) From 4acfa570629bdf64d959f5f1a5ebaf969cfbc687 Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Thu, 18 Aug 2016 10:51:22 -0400 Subject: [PATCH 12/17] Added optimization option for OpenCG compatibility module --- openmc/opencg_compatible.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py index 58ce0d0c2..bca735a81 100644 --- a/openmc/opencg_compatible.py +++ b/openmc/opencg_compatible.py @@ -997,13 +997,17 @@ def get_opencg_geometry(openmc_geometry): return opencg_geometry -def get_openmc_geometry(opencg_geometry): +def get_openmc_geometry(opencg_geometry, compatible=True): """Return an OpenMC geometry corresponding to an OpenCG geometry. Parameters ---------- opencg_geometry : opencg.Geometry OpenCG geometry + compatible : bool + Whether the OpenCG geometry is compatible with OpenMOC's geometric + primitives. This should be set to False if the OpenCG geometry + uses SquarePrism surfaces. True by default as an optimization. Returns ------- @@ -1019,9 +1023,6 @@ def get_openmc_geometry(opencg_geometry): opencg_geometry.assign_auto_ids() opencg_geometry = copy.deepcopy(opencg_geometry) - # Update Cell bounding boxes in Geometry - opencg_geometry.update_bounding_boxes() - # Clear dictionaries and auto-generated ID OPENMC_SURFACES.clear() OPENCG_SURFACES.clear() @@ -1033,12 +1034,13 @@ def get_openmc_geometry(opencg_geometry): OPENCG_LATTICES.clear() # Make the entire geometry "compatible" before assigning auto IDs - universes = opencg_geometry.get_all_universes() - for universe in universes.values(): - if not isinstance(universe, opencg.Lattice): - make_opencg_cells_compatible(universe) + if not compatible: + universes = opencg_geometry.get_all_universes() + for universe in universes.values(): + if not isinstance(universe, opencg.Lattice): + make_opencg_cells_compatible(universe) - opencg_geometry.assign_auto_ids() + opencg_geometry.assign_auto_ids() opencg_root_universe = opencg_geometry.root_universe openmc_root_universe = get_openmc_universe(opencg_root_universe) From 3fb36ea9ec5736781d902f09a1b660c2a4f0a4da Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 18 Aug 2016 10:53:23 -0500 Subject: [PATCH 13/17] Hotfix for ScatterMatrixXS.get_pandas_dataframe (parent method doesn't account for multiple scores). --- openmc/mgxs/mgxs.py | 3 +- .../results_true.dat | 144 +++++++++--------- .../results_true.dat | 2 +- 3 files changed, 75 insertions(+), 74 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index e77685088..c0bc9c266 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -1523,7 +1523,8 @@ class MGXS(object): df.rename(columns={'energyout low [MeV]': 'group out'}, inplace=True) - out_groups = np.tile(all_groups, int(df.shape[0] / all_groups.size)) + out_groups = np.repeat(all_groups, self.xs_tally.num_scores) + out_groups = np.tile(out_groups, int(df.shape[0] / out_groups.size)) df['group out'] = out_groups del df['energyout high [MeV]'] columns = ['group in', 'group out'] diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat index 3563f141b..edd99b44c 100644 --- a/tests/test_mgxs_library_no_nuclides/results_true.dat +++ b/tests/test_mgxs_library_no_nuclides/results_true.dat @@ -29,39 +29,39 @@ 1 10000 1 total 0.385188 0.026946 0 10000 2 total 0.412389 0.015425 material group in group out nuclide moment mean std. dev. -9 10000 1 1 total P0 -0.000207 0.000149 -11 10000 1 1 total P1 0.000234 0.000128 -13 10000 1 1 total P2 0.051870 0.006983 +12 10000 1 1 total P0 0.384199 0.027001 +13 10000 1 1 total P1 0.051870 0.006983 +14 10000 1 1 total P2 0.020069 0.002846 15 10000 1 1 total P3 0.009478 0.002234 8 10000 1 2 total P0 0.000989 0.000482 -10 10000 1 2 total P1 -0.000103 0.000184 -12 10000 1 2 total P2 0.384199 0.027001 -14 10000 1 2 total P3 0.020069 0.002846 -1 10000 2 1 total P0 0.016482 0.004502 -3 10000 2 1 total P1 -0.010499 0.010438 -5 10000 2 1 total P2 -0.000768 0.000768 +9 10000 1 2 total P1 -0.000207 0.000149 +10 10000 1 2 total P2 -0.000103 0.000184 +11 10000 1 2 total P3 0.000234 0.000128 +4 10000 2 1 total P0 0.000925 0.000925 +5 10000 2 1 total P1 -0.000768 0.000768 +6 10000 2 1 total P2 0.000494 0.000494 7 10000 2 1 total P3 -0.000171 0.000172 0 10000 2 2 total P0 0.411465 0.015245 -2 10000 2 2 total P1 0.006371 0.010551 -4 10000 2 2 total P2 0.000925 0.000925 -6 10000 2 2 total P3 0.000494 0.000494 +1 10000 2 2 total P1 0.016482 0.004502 +2 10000 2 2 total P2 0.006371 0.010551 +3 10000 2 2 total P3 -0.010499 0.010438 material group in group out nuclide moment mean std. dev. -9 10000 1 1 total P0 -0.000207 0.000149 -11 10000 1 1 total P1 0.000234 0.000128 -13 10000 1 1 total P2 0.051870 0.006983 +12 10000 1 1 total P0 0.384199 0.027001 +13 10000 1 1 total P1 0.051870 0.006983 +14 10000 1 1 total P2 0.020069 0.002846 15 10000 1 1 total P3 0.009478 0.002234 8 10000 1 2 total P0 0.000989 0.000482 -10 10000 1 2 total P1 -0.000103 0.000184 -12 10000 1 2 total P2 0.384199 0.027001 -14 10000 1 2 total P3 0.020069 0.002846 -1 10000 2 1 total P0 0.016482 0.004502 -3 10000 2 1 total P1 -0.010499 0.010438 -5 10000 2 1 total P2 -0.000768 0.000768 +9 10000 1 2 total P1 -0.000207 0.000149 +10 10000 1 2 total P2 -0.000103 0.000184 +11 10000 1 2 total P3 0.000234 0.000128 +4 10000 2 1 total P0 0.000925 0.000925 +5 10000 2 1 total P1 -0.000768 0.000768 +6 10000 2 1 total P2 0.000494 0.000494 7 10000 2 1 total P3 -0.000171 0.000172 0 10000 2 2 total P0 0.411465 0.015245 -2 10000 2 2 total P1 0.006371 0.010551 -4 10000 2 2 total P2 0.000925 0.000925 -6 10000 2 2 total P3 0.000494 0.000494 +1 10000 2 2 total P1 0.016482 0.004502 +2 10000 2 2 total P2 0.006371 0.010551 +3 10000 2 2 total P3 -0.010499 0.010438 material group in group out nuclide mean std. dev. 3 10000 1 1 total 1.0 0.078516 2 10000 1 2 total 1.0 0.687184 @@ -154,39 +154,39 @@ 1 10001 1 total 0.310121 0.033788 0 10001 2 total 0.296264 0.043792 material group in group out nuclide moment mean std. dev. -9 10001 1 1 total P0 0.000000 0.000000 -11 10001 1 1 total P1 0.000000 0.000000 -13 10001 1 1 total P2 0.038230 0.008484 +12 10001 1 1 total P0 0.310121 0.033788 +13 10001 1 1 total P1 0.038230 0.008484 +14 10001 1 1 total P2 0.020745 0.004696 15 10001 1 1 total P3 0.007964 0.003732 8 10001 1 2 total P0 0.000000 0.000000 -10 10001 1 2 total P1 0.000000 0.000000 -12 10001 1 2 total P2 0.310121 0.033788 -14 10001 1 2 total P3 0.020745 0.004696 -1 10001 2 1 total P0 -0.011214 0.016180 -3 10001 2 1 total P1 -0.003270 0.007329 -5 10001 2 1 total P2 0.000000 0.000000 +9 10001 1 2 total P1 0.000000 0.000000 +10 10001 1 2 total P2 0.000000 0.000000 +11 10001 1 2 total P3 0.000000 0.000000 +4 10001 2 1 total P0 0.000000 0.000000 +5 10001 2 1 total P1 0.000000 0.000000 +6 10001 2 1 total P2 0.000000 0.000000 7 10001 2 1 total P3 0.000000 0.000000 0 10001 2 2 total P0 0.296264 0.043792 -2 10001 2 2 total P1 0.008837 0.011504 -4 10001 2 2 total P2 0.000000 0.000000 -6 10001 2 2 total P3 0.000000 0.000000 +1 10001 2 2 total P1 -0.011214 0.016180 +2 10001 2 2 total P2 0.008837 0.011504 +3 10001 2 2 total P3 -0.003270 0.007329 material group in group out nuclide moment mean std. dev. -9 10001 1 1 total P0 0.000000 0.000000 -11 10001 1 1 total P1 0.000000 0.000000 -13 10001 1 1 total P2 0.038230 0.008484 +12 10001 1 1 total P0 0.310121 0.033788 +13 10001 1 1 total P1 0.038230 0.008484 +14 10001 1 1 total P2 0.020745 0.004696 15 10001 1 1 total P3 0.007964 0.003732 8 10001 1 2 total P0 0.000000 0.000000 -10 10001 1 2 total P1 0.000000 0.000000 -12 10001 1 2 total P2 0.310121 0.033788 -14 10001 1 2 total P3 0.020745 0.004696 -1 10001 2 1 total P0 -0.011214 0.016180 -3 10001 2 1 total P1 -0.003270 0.007329 -5 10001 2 1 total P2 0.000000 0.000000 +9 10001 1 2 total P1 0.000000 0.000000 +10 10001 1 2 total P2 0.000000 0.000000 +11 10001 1 2 total P3 0.000000 0.000000 +4 10001 2 1 total P0 0.000000 0.000000 +5 10001 2 1 total P1 0.000000 0.000000 +6 10001 2 1 total P2 0.000000 0.000000 7 10001 2 1 total P3 0.000000 0.000000 0 10001 2 2 total P0 0.296264 0.043792 -2 10001 2 2 total P1 0.008837 0.011504 -4 10001 2 2 total P2 0.000000 0.000000 -6 10001 2 2 total P3 0.000000 0.000000 +1 10001 2 2 total P1 -0.011214 0.016180 +2 10001 2 2 total P2 0.008837 0.011504 +3 10001 2 2 total P3 -0.003270 0.007329 material group in group out nuclide mean std. dev. 3 10001 1 1 total 1.0 0.108779 2 10001 1 2 total 0.0 0.000000 @@ -279,39 +279,39 @@ 1 10002 1 total 0.671269 0.026186 0 10002 2 total 2.035388 0.258060 material group in group out nuclide moment mean std. dev. -9 10002 1 1 total P0 0.008758 0.000926 -11 10002 1 1 total P1 -0.003785 0.000817 -13 10002 1 1 total P2 0.381167 0.016243 +12 10002 1 1 total P0 0.639901 0.024709 +13 10002 1 1 total P1 0.381167 0.016243 +14 10002 1 1 total P2 0.152392 0.008156 15 10002 1 1 total P3 0.009148 0.003889 8 10002 1 2 total P0 0.031368 0.001728 -10 10002 1 2 total P1 -0.002568 0.001014 -12 10002 1 2 total P2 0.639901 0.024709 -14 10002 1 2 total P3 0.152392 0.008156 -1 10002 2 1 total P0 0.509941 0.051236 -3 10002 2 1 total P1 0.024988 0.008312 -5 10002 2 1 total P2 0.000400 0.000401 +9 10002 1 2 total P1 0.008758 0.000926 +10 10002 1 2 total P2 -0.002568 0.001014 +11 10002 1 2 total P3 -0.003785 0.000817 +4 10002 2 1 total P0 0.000443 0.000445 +5 10002 2 1 total P1 0.000400 0.000401 +6 10002 2 1 total P2 0.000320 0.000321 7 10002 2 1 total P3 0.000214 0.000215 0 10002 2 2 total P0 2.034945 0.257800 -2 10002 2 2 total P1 0.111175 0.013020 -4 10002 2 2 total P2 0.000443 0.000445 -6 10002 2 2 total P3 0.000320 0.000321 +1 10002 2 2 total P1 0.509941 0.051236 +2 10002 2 2 total P2 0.111175 0.013020 +3 10002 2 2 total P3 0.024988 0.008312 material group in group out nuclide moment mean std. dev. -9 10002 1 1 total P0 0.008758 0.000926 -11 10002 1 1 total P1 -0.003785 0.000817 -13 10002 1 1 total P2 0.381167 0.016243 +12 10002 1 1 total P0 0.639901 0.024709 +13 10002 1 1 total P1 0.381167 0.016243 +14 10002 1 1 total P2 0.152392 0.008156 15 10002 1 1 total P3 0.009148 0.003889 8 10002 1 2 total P0 0.031368 0.001728 -10 10002 1 2 total P1 -0.002568 0.001014 -12 10002 1 2 total P2 0.639901 0.024709 -14 10002 1 2 total P3 0.152392 0.008156 -1 10002 2 1 total P0 0.509941 0.051236 -3 10002 2 1 total P1 0.024988 0.008312 -5 10002 2 1 total P2 0.000400 0.000401 +9 10002 1 2 total P1 0.008758 0.000926 +10 10002 1 2 total P2 -0.002568 0.001014 +11 10002 1 2 total P3 -0.003785 0.000817 +4 10002 2 1 total P0 0.000443 0.000445 +5 10002 2 1 total P1 0.000400 0.000401 +6 10002 2 1 total P2 0.000320 0.000321 7 10002 2 1 total P3 0.000214 0.000215 0 10002 2 2 total P0 2.034945 0.257800 -2 10002 2 2 total P1 0.111175 0.013020 -4 10002 2 2 total P2 0.000443 0.000445 -6 10002 2 2 total P3 0.000320 0.000321 +1 10002 2 2 total P1 0.509941 0.051236 +2 10002 2 2 total P2 0.111175 0.013020 +3 10002 2 2 total P3 0.024988 0.008312 material group in group out nuclide mean std. dev. 3 10002 1 1 total 1.0 0.038609 2 10002 1 2 total 1.0 0.067667 diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/test_mgxs_library_nuclides/results_true.dat index d3e3235cc..3da814604 100644 --- a/tests/test_mgxs_library_nuclides/results_true.dat +++ b/tests/test_mgxs_library_nuclides/results_true.dat @@ -1 +1 @@ -8142ae4e107002a835999e4ace85c17376f262a7059fc224f3756a2de19aba6ca4c4fa14ca2085c87d7729aa8d6d6f78fdae21ac6dfe33ca303449c769076074 \ No newline at end of file +e494320a213b5704a2ac915a2ba504857be91961ceb6735b6ad05d81eb31c44c9584d5bd9d40baececf1dcb5b030e6ecec63cfbd20639baf69bcb596c5c46591 \ No newline at end of file From a265770e7b8221f06afa595c085bd1e8422d7a1c Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Thu, 18 Aug 2016 12:38:30 -0400 Subject: [PATCH 14/17] Fixed comment OpenMOC -> OpenMC --- openmc/opencg_compatible.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py index bca735a81..501e570a7 100644 --- a/openmc/opencg_compatible.py +++ b/openmc/opencg_compatible.py @@ -1005,7 +1005,7 @@ def get_openmc_geometry(opencg_geometry, compatible=True): opencg_geometry : opencg.Geometry OpenCG geometry compatible : bool - Whether the OpenCG geometry is compatible with OpenMOC's geometric + Whether the OpenCG geometry is compatible with OpenMC's geometric primitives. This should be set to False if the OpenCG geometry uses SquarePrism surfaces. True by default as an optimization. From 9e1da7a5bfa9e5cb0d66b66213cb48dd448c7f0a Mon Sep 17 00:00:00 2001 From: Will Boyd Date: Thu, 18 Aug 2016 14:20:33 -0400 Subject: [PATCH 15/17] Changed compatibility parameter to default to False for OpenCG-to-OpenMC conversion --- openmc/opencg_compatible.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py index bca735a81..e81538fcf 100644 --- a/openmc/opencg_compatible.py +++ b/openmc/opencg_compatible.py @@ -997,7 +997,7 @@ def get_opencg_geometry(openmc_geometry): return opencg_geometry -def get_openmc_geometry(opencg_geometry, compatible=True): +def get_openmc_geometry(opencg_geometry, compatible=False): """Return an OpenMC geometry corresponding to an OpenCG geometry. Parameters @@ -1007,7 +1007,7 @@ def get_openmc_geometry(opencg_geometry, compatible=True): compatible : bool Whether the OpenCG geometry is compatible with OpenMOC's geometric primitives. This should be set to False if the OpenCG geometry - uses SquarePrism surfaces. True by default as an optimization. + uses SquarePrism surfaces. False by default. Returns ------- From 59d474c1758d84d7e71b7f83276f51f6b62fa7b9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 18 Aug 2016 17:24:30 -0500 Subject: [PATCH 16/17] Respond to comments on #705 --- openmc/mgxs/mdgxs.py | 3 ++- src/source.F90 | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index 0a2f898c0..5e5d840b6 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -793,7 +793,8 @@ class MDGXS(MGXS): df.rename(columns={'energyout low [MeV]': 'group out'}, inplace=True) - out_groups = np.tile(all_groups, int(df.shape[0] / all_groups.size)) + out_groups = np.repeat(all_groups, self.xs_tally.num_scores) + out_groups = np.tile(out_groups, int(df.shape[0] / out_groups.size)) df['group out'] = out_groups del df['energyout high [MeV]'] columns = ['group in', 'group out'] diff --git a/src/source.F90 b/src/source.F90 index fad9ae46a..452d8ddfc 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -107,7 +107,7 @@ contains real(8) :: r(3) ! sampled coordinates logical :: found ! Does the source particle exist within geometry? type(Particle) :: p ! Temporary particle for using find_cell - integer, save :: n_sample = 0 ! Number of samples + integer, save :: n_accept = 0 ! Number of samples accepted integer, save :: n_reject = 0 ! Number of samples rejected ! Set weight to one by default @@ -161,15 +161,15 @@ contains if (.not. found) then n_reject = n_reject + 1 if (n_reject >= EXTSRC_REJECT_THRESHOLD .and. & - real(n_sample, 8)/n_reject <= EXTSRC_REJECT_FRACTION) then + real(n_accept, 8)/n_reject <= EXTSRC_REJECT_FRACTION) then call fatal_error("More than 95% of external source sites sampled & &were rejected. Please check your external source definition.") end if end if end do - ! Increment number of samples - n_sample = n_sample + 1 + ! Increment number of accepted samples + n_accept = n_accept + 1 call p % clear() From 256f0b93eb411430475255d783301b1adef32d71 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Thu, 18 Aug 2016 19:27:32 -0400 Subject: [PATCH 17/17] Resolving comments from @samuelshaner and @wbinventor --- openmc/mesh.py | 6 +++--- openmc/mgxs/library.py | 8 +++----- openmc/mgxs_library.py | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/openmc/mesh.py b/openmc/mesh.py index c2b23bf1f..58b9c7c0e 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -6,8 +6,7 @@ import sys import numpy as np import openmc.checkvalue as cv -import openmc.surface -import openmc.cell +import openmc if sys.version_info[0] >= 3: @@ -199,6 +198,7 @@ class Mesh(object): ... """ + if len(self.dimension) == 2: for x in range(self.dimension[0]): for y in range(self.dimension[1]): @@ -241,7 +241,7 @@ class Mesh(object): def build_cells(self, bc=['reflective'] * 6): """Generates a lattice of universes with the same dimensionality - as the mesh object in self. The individual cells/universes produced + as the mesh object. The individual cells/universes produced will not have material definitions applied and so downstream code will have to apply that information. diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index d3d32ee59..9e5dba310 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -899,7 +899,7 @@ class Library(object): cv.check_greater_than('tabular_points', tabular_points, 1) if subdomain is not None: cv.check_iterable_type('subdomain', subdomain, Integral, - max_depth=2) + max_depth=3) # Make sure statepoint has been loaded if self._sp_filename is None: @@ -1123,8 +1123,6 @@ class Library(object): # Create XSdata and Macroscopic for this domain xsdata = self.get_xsdata(domain, xsdata_name, - nuclide='total', - xs_type=xs_type, xs_id=all_xs_ids[i], tabular_legendre=tabular_legendre, tabular_points=tabular_points, @@ -1192,7 +1190,7 @@ class Library(object): in building the tabular distribution. Default is `33`. bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'} Boundary conditions for each of the four faces of a rectangle - (if aplying to a 2D mesh) or six faces of a parallelepiped + (if applying to a 2D mesh) or six faces of a parallelepiped (if applying to a 3D mesh) provided in the following order: [x min, x max, y min, y max, z min, z max]. 2-D cells do not contain the z min and z max entries. @@ -1227,7 +1225,7 @@ class Library(object): self.check_library_for_openmc_mgxs() # If the domain type is a mesh, then there can only be one domain for - # this method. Thi is because we can build a model automatically if + # this method. This is because we can build a model automatically if # the user provided multiple mesh domains for library generation since # the multiple meshes could be overlapping or in disparate regions # of the continuous energy model. The next step makes sure there is diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index c9a7debdc..a3a2187b7 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -622,7 +622,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -662,7 +662,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -703,7 +703,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -744,7 +744,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -795,7 +795,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -835,7 +835,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -885,7 +885,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also -------- @@ -958,7 +958,7 @@ class XSdata(object): barns. Defaults to 'macro'. subdomain : iterable of int If the MGXS contains a mesh domain type, the subdomain parameter - specifies which mesh cell ([i, j, k]) to use. + specifies which mesh cell (i.e., [i, j, k] index) to use. See also --------