Esempio n. 1
0
    def __init__(self, filename):
        # A user may not have h5py, but they can still use the rest of the
        # Python API so we'll only try to import h5py if the user actually inits
        # a Summary object.
        import h5py
        if h5py.__version__ == '2.6.0':
            raise ImportError("h5py 2.6.0 has a known bug which makes it "
                              "incompatible with OpenMC's HDF5 files. "
                              "Please switch to a different version.")

        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        self._openmc_geometry = None
        self._opencg_geometry = None

        self._read_metadata()
        self._read_nuclides()
        self._read_geometry()
        self._read_tallies()
        self._f.close()
Esempio n. 2
0
def pincell_model():
    """Set up a model to test with and delete files when done"""
    openmc.reset_auto_ids()
    pincell = openmc.examples.pwr_pin_cell()
    pincell.settings.verbosity = 1

    # Add a tally
    filter1 = openmc.MaterialFilter(pincell.materials)
    filter2 = openmc.EnergyFilter([0.0, 1.0, 1.0e3, 20.0e6])
    mat_tally = openmc.Tally()
    mat_tally.filters = [filter1, filter2]
    mat_tally.nuclides = ['U235', 'U238']
    mat_tally.scores = ['total', 'elastic', '(n,gamma)']
    pincell.tallies.append(mat_tally)

    # Add an expansion tally
    zernike_tally = openmc.Tally()
    filter3 = openmc.ZernikeFilter(5, r=.63)
    cells = pincell.geometry.root_universe.cells
    filter4 = openmc.CellFilter(list(cells.values()))
    zernike_tally.filters = [filter3, filter4]
    zernike_tally.scores = ['fission']
    pincell.tallies.append(zernike_tally)

    # Add an energy function tally
    energyfunc_tally = openmc.Tally()
    energyfunc_filter = openmc.EnergyFunctionFilter([0.0, 20e6], [0.0, 20e6])
    energyfunc_tally.scores = ['fission']
    energyfunc_tally.filters = [energyfunc_filter]
    pincell.tallies.append(energyfunc_tally)

    # Write XML files in tmpdir
    with cdtemp():
        pincell.export_to_xml()
        yield
Esempio n. 3
0
def test_init(run_in_tmpdir, pin_model_attributes, mpi_intracomm):
    mats, geom, settings, tals, plots, _, _ = \
        pin_model_attributes

    openmc.reset_auto_ids()
    # Check blank initialization of a model
    test_model = openmc.Model()
    assert test_model.geometry.root_universe is None
    assert len(test_model.materials) == 0
    ref_settings = openmc.Settings()
    assert sorted(test_model.settings.__dict__.keys()) == \
        sorted(ref_settings.__dict__.keys())
    for ref_k, ref_v in ref_settings.__dict__.items():
        assert test_model.settings.__dict__[ref_k] == ref_v
    assert len(test_model.tallies) == 0
    assert len(test_model.plots) == 0
    assert test_model._materials_by_id == {}
    assert test_model._materials_by_name == {}
    assert test_model._cells_by_id == {}
    assert test_model._cells_by_name == {}
    assert test_model.is_initialized is False

    # Now check proper init of an actual model. Assume no interference between
    # parameters and so we can apply them all at once instead of testing one
    # parameter initialization at a time
    test_model = openmc.Model(geom, mats, settings, tals, plots)
    assert test_model.geometry is geom
    assert test_model.materials is mats
    assert test_model.settings is settings
    assert test_model.tallies is tals
    assert test_model.plots is plots
    assert test_model._materials_by_id == {1: mats[0], 2: mats[1], 3: mats[2]}
    assert test_model._materials_by_name == {
        'UO2': {mats[0]},
        'Zirc': {mats[1]},
        'Borated water': {mats[2]}
    }
    # The last cell is the one that contains the infinite fuel
    assert test_model._cells_by_id == \
        {2: geom.root_universe.cells[2], 3: geom.root_universe.cells[3],
         4: geom.root_universe.cells[4],
         1: geom.root_universe.cells[2].fill.cells[1]}
    # No cell name for 2 and 3, so we expect a blank name to be assigned to
    # cell 3 due to overwriting
    assert test_model._cells_by_name == {
        'fuel': {geom.root_universe.cells[2]},
        '': {geom.root_universe.cells[3], geom.root_universe.cells[4]},
        'inf fuel': {geom.root_universe.cells[2].fill.cells[1]}
    }
    assert test_model.is_initialized is False

    # Finally test the parameter type checking by passing bad types and
    # obtaining the right exception types
    def_params = [geom, mats, settings, tals, plots]
    for i in range(len(def_params)):
        args = def_params.copy()
        # Try an integer, as that is a bad type for all arguments
        args[i] = i
        with pytest.raises(TypeError):
            test_model = openmc.Model(*args)
Esempio n. 4
0
    def __init__(self, filename):
        # A user may not have h5py, but they can still use the rest of the
        # Python API so we'll only try to import h5py if the user actually inits
        # a Summary object.
        import h5py
        if h5py.__version__ == '2.6.0':
            raise ImportError("h5py 2.6.0 has a known bug which makes it "
                              "incompatible with OpenMC's HDF5 files. "
                              "Please switch to a different version.")

        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        self._openmc_geometry = None
        self._opencg_geometry = None

        self._read_metadata()
        self._read_nuclides()
        self._read_geometry()
        self._read_tallies()
        self._f.close()
Esempio n. 5
0
def setup_regression_test(request):
    # Reset autogenerated IDs assigned to OpenMC objects
    openmc.reset_auto_ids()

    # Change to test directory
    olddir = request.fspath.dirpath().chdir()
    try:
        yield
    finally:
        olddir.chdir()
Esempio n. 6
0
def model(request):
    openmc.reset_auto_ids()
    marker = request.node.get_closest_marker("surf_source_op")
    surf_source_op = marker.args[0]

    openmc_model = openmc.model.Model()

    # Materials
    # None

    # Geometry
    # Concentric void spheres
    # - Innermost sphere to bank surface sources
    # - Second shell to tally cell flux
    # - Outermost sphere as vacuum boundary
    sph_1 = openmc.Sphere(r=1.0)  # Surface to bank/write sources.
    sph_2 = openmc.Sphere(r=2.0)
    sph_3 = openmc.Sphere(r=2.5)
    sph_4 = openmc.Sphere(r=4.0, boundary_type='vacuum')
    cell_1 = openmc.Cell(region=-sph_1)
    cell_2 = openmc.Cell(region=+sph_1 & -sph_2)
    cell_3 = openmc.Cell(region=+sph_2 & -sph_3)  # Cell to tally flux.
    cell_4 = openmc.Cell(region=+sph_3 & -sph_4)
    root = openmc.Universe(cells=[cell_1, cell_2, cell_3, cell_4])
    openmc_model.geometry = openmc.Geometry(root)

    # Settings
    openmc_model.settings.run_mode = 'fixed source'
    openmc_model.settings.particles = 1000
    openmc_model.settings.batches = 10
    openmc_model.settings.seed = 1

    if surf_source_op == 'write':
        point = openmc.stats.Point((0, 0, 0))
        pt_src = openmc.Source(space=point)
        openmc_model.settings.source = pt_src

        openmc_model.settings.surf_source_write = {
            'surface_ids': [1],
            'max_particles': 1000
        }
    elif surf_source_op == 'read':
        openmc_model.settings.surf_source_read = {
            'path': 'surface_source_true.h5'
        }

    # Tallies
    tal = openmc.Tally()
    cell_filter = openmc.CellFilter(cell_3)
    tal.filters = [cell_filter]
    tal.scores = ['flux']
    openmc_model.tallies.append(tal)

    return openmc_model
Esempio n. 7
0
def pincell_model_w_univ():
    """Set up a model to test with and delete files when done"""
    openmc.reset_auto_ids()
    pincell = openmc.examples.pwr_pin_cell()
    clad_univ = openmc.Universe(cells=[openmc.Cell(fill=pincell.materials[1])])
    pincell.geometry.root_universe.cells[2].fill = clad_univ
    pincell.settings.verbosity = 1

    # Write XML files in tmpdir
    with cdtemp():
        pincell.export_to_xml()
        yield
Esempio n. 8
0
    def __call__(self, vec, power):
        """Runs a simulation.

        Simulation will abort under the following circumstances:

            1) No energy is computed using OpenMC tallies.

        Parameters
        ----------
        vec : list of numpy.ndarray
            Total atoms to be used in function.
        power : float
            Power of the reactor in [W]

        Returns
        -------
        openmc.deplete.OperatorResult
            Eigenvalue and reaction rates resulting from transport operator

        """
        # Reset results in OpenMC
        openmc.lib.reset()

        # If the source rate is zero, return zero reaction rates without running
        # a transport solve
        if power == 0.0:
            rates = self.reaction_rates.copy()
            rates.fill(0.0)
            return OperatorResult(ufloat(0.0, 0.0), rates)

        # Prevent OpenMC from complaining about re-creating tallies
        openmc.reset_auto_ids()

        # Update status
        self.number.set_density(vec)

        # Update material compositions and tally nuclides
        self._update_materials()
        nuclides = self._get_tally_nuclides()
        self._rate_helper.nuclides = nuclides
        self._energy_helper.nuclides = nuclides
        self._yield_helper.update_tally_nuclides(nuclides)

        # Run OpenMC
        openmc.lib.run()
        openmc.lib.reset_timers()

        # Extract results
        op_result = self._unpack_tallies_and_normalize(power)

        return copy.deepcopy(op_result)
Esempio n. 9
0
    def __init__(self, filename):
        # A user may not have h5py, but they can still use the rest of the
        # Python API so we'll only try to import h5py if the user actually inits
        # a Summary object.
        import h5py

        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        self.openmc_geometry = None
        self.opencg_geometry = None

        self._read_metadata()
        self._read_geometry()
        self._read_tallies()
Esempio n. 10
0
    def __init__(self, filename):
        # A user may not have h5py, but they can still use the rest of the
        # Python API so we'll only try to import h5py if the user actually inits
        # a Summary object.
        import h5py

        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        self._openmc_geometry = None
        self._opencg_geometry = None

        self._read_metadata()
        self._read_geometry()
        self._read_tallies()
Esempio n. 11
0
def test_import_properties(run_in_tmpdir, mpi_intracomm):
    """Test importing properties on the Model class """

    # Create PWR pin cell model and write XML files
    openmc.reset_auto_ids()
    model = openmc.examples.pwr_pin_cell()
    model.init_lib(output=False, intracomm=mpi_intracomm)

    # Change fuel temperature and density and export properties
    cell = openmc.lib.cells[1]
    cell.set_temperature(600.0)
    cell.fill.set_density(5.0, 'g/cm3')
    openmc.lib.export_properties(output=False)

    # Import properties to existing model
    model.import_properties("properties.h5")

    # Check to see that values are assigned to the C and python representations
    # First python
    cell = model.geometry.get_all_cells()[1]
    assert cell.temperature == [600.0]
    assert cell.fill.get_mass_density() == pytest.approx(5.0)
    # Now C
    assert openmc.lib.cells[1].get_temperature() == 600.
    assert openmc.lib.materials[1].get_density('g/cm3') == pytest.approx(5.0)

    # Clear the C API
    openmc.lib.finalize()

    # Verify the attributes survived by exporting to XML and re-creating
    model.export_to_xml("with_properties")

    # Load model with properties and confirm temperature/density changed
    model_with_properties = openmc.Model.from_xml(
        'with_properties/geometry.xml', 'with_properties/materials.xml',
        'with_properties/settings.xml')
    cell = model_with_properties.geometry.get_all_cells()[1]
    assert cell.temperature == [600.0]
    assert cell.fill.get_mass_density() == pytest.approx(5.0)
Esempio n. 12
0
    def __init__(self, filename):
        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        cv.check_filetype_version(self._f, 'summary', _VERSION_SUMMARY)

        self._geometry = openmc.Geometry()

        self._fast_materials = {}
        self._fast_surfaces = {}
        self._fast_cells = {}
        self._fast_universes = {}
        self._fast_lattices = {}

        self._materials = openmc.Materials()
        self._nuclides = {}

        self._read_nuclides()
        self._read_geometry()
Esempio n. 13
0
    def __init__(self, filename):
        openmc.reset_auto_ids()

        if not filename.endswith(('.h5', '.hdf5')):
            msg = 'Unable to open "{0}" which is not an HDF5 summary file'
            raise ValueError(msg)

        self._f = h5py.File(filename, 'r')
        cv.check_filetype_version(self._f, 'summary', _VERSION_SUMMARY)

        self._geometry = openmc.Geometry()

        self._fast_materials = {}
        self._fast_surfaces = {}
        self._fast_cells = {}
        self._fast_universes  = {}
        self._fast_lattices = {}

        self._materials = openmc.Materials()
        self._nuclides = {}

        self._read_nuclides()
        self._read_geometry()
Esempio n. 14
0
def test_unstructured_mesh(test_opts):

    openmc.reset_auto_ids()

    # skip the test if the library is not enabled
    if test_opts['library'] == 'moab' and not openmc.lib._dagmc_enabled():
        pytest.skip("DAGMC (and MOAB) mesh not enbaled in this build.")

    if test_opts['library'] == 'libmesh' and not openmc.lib._libmesh_enabled():
        pytest.skip("LibMesh is not enabled in this build.")

    # skip the tracklength test for libmesh
    if test_opts['library'] == 'libmesh' and \
       test_opts['estimator'] == 'tracklength':
        pytest.skip("Tracklength tallies are not supported using libmesh.")

    ### Materials ###
    materials = openmc.Materials()

    fuel_mat = openmc.Material(name="fuel")
    fuel_mat.add_nuclide("U235", 1.0)
    fuel_mat.set_density('g/cc', 4.5)
    materials.append(fuel_mat)

    zirc_mat = openmc.Material(name="zircaloy")
    zirc_mat.add_element("Zr", 1.0)
    zirc_mat.set_density("g/cc", 5.77)
    materials.append(zirc_mat)

    water_mat = openmc.Material(name="water")
    water_mat.add_nuclide("H1", 2.0)
    water_mat.add_nuclide("O16", 1.0)
    water_mat.set_density("atom/b-cm", 0.07416)
    materials.append(water_mat)

    materials.export_to_xml()

    ### Geometry ###
    fuel_min_x = openmc.XPlane(-5.0, name="minimum x")
    fuel_max_x = openmc.XPlane(5.0, name="maximum x")

    fuel_min_y = openmc.YPlane(-5.0, name="minimum y")
    fuel_max_y = openmc.YPlane(5.0, name="maximum y")

    fuel_min_z = openmc.ZPlane(-5.0, name="minimum z")
    fuel_max_z = openmc.ZPlane(5.0, name="maximum z")

    fuel_cell = openmc.Cell(name="fuel")
    fuel_cell.region = +fuel_min_x & -fuel_max_x & \
                       +fuel_min_y & -fuel_max_y & \
                       +fuel_min_z & -fuel_max_z
    fuel_cell.fill = fuel_mat

    clad_min_x = openmc.XPlane(-6.0, name="minimum x")
    clad_max_x = openmc.XPlane(6.0, name="maximum x")

    clad_min_y = openmc.YPlane(-6.0, name="minimum y")
    clad_max_y = openmc.YPlane(6.0, name="maximum y")

    clad_min_z = openmc.ZPlane(-6.0, name="minimum z")
    clad_max_z = openmc.ZPlane(6.0, name="maximum z")

    clad_cell = openmc.Cell(name="clad")
    clad_cell.region = (-fuel_min_x | +fuel_max_x |
                        -fuel_min_y | +fuel_max_y |
                        -fuel_min_z | +fuel_max_z) & \
                        (+clad_min_x & -clad_max_x &
                         +clad_min_y & -clad_max_y &
                         +clad_min_z & -clad_max_z)
    clad_cell.fill = zirc_mat

    if test_opts['external_geom']:
        bounds = (15, 15, 15)
    else:
        bounds = (10, 10, 10)

    water_min_x = openmc.XPlane(x0=-bounds[0],
                                name="minimum x",
                                boundary_type='vacuum')
    water_max_x = openmc.XPlane(x0=bounds[0],
                                name="maximum x",
                                boundary_type='vacuum')

    water_min_y = openmc.YPlane(y0=-bounds[1],
                                name="minimum y",
                                boundary_type='vacuum')
    water_max_y = openmc.YPlane(y0=bounds[1],
                                name="maximum y",
                                boundary_type='vacuum')

    water_min_z = openmc.ZPlane(z0=-bounds[2],
                                name="minimum z",
                                boundary_type='vacuum')
    water_max_z = openmc.ZPlane(z0=bounds[2],
                                name="maximum z",
                                boundary_type='vacuum')

    water_cell = openmc.Cell(name="water")
    water_cell.region = (-clad_min_x | +clad_max_x |
                         -clad_min_y | +clad_max_y |
                         -clad_min_z | +clad_max_z) & \
                         (+water_min_x & -water_max_x &
                          +water_min_y & -water_max_y &
                          +water_min_z & -water_max_z)
    water_cell.fill = water_mat

    # create a containing universe
    geometry = openmc.Geometry([fuel_cell, clad_cell, water_cell])

    ### Tallies ###

    # create meshes and mesh filters
    regular_mesh = openmc.RegularMesh()
    regular_mesh.dimension = (10, 10, 10)
    regular_mesh.lower_left = (-10.0, -10.0, -10.0)
    regular_mesh.upper_right = (10.0, 10.0, 10.0)

    regular_mesh_filter = openmc.MeshFilter(mesh=regular_mesh)

    if test_opts['holes']:
        mesh_filename = "test_mesh_tets_w_holes.e"
    else:
        mesh_filename = "test_mesh_tets.e"

    uscd_mesh = openmc.UnstructuredMesh(mesh_filename, test_opts['library'])
    uscd_filter = openmc.MeshFilter(mesh=uscd_mesh)

    # create tallies
    tallies = openmc.Tallies()

    regular_mesh_tally = openmc.Tally(name="regular mesh tally")
    regular_mesh_tally.filters = [regular_mesh_filter]
    regular_mesh_tally.scores = ['flux']
    regular_mesh_tally.estimator = test_opts['estimator']
    tallies.append(regular_mesh_tally)

    uscd_tally = openmc.Tally(name="unstructured mesh tally")
    uscd_tally.filters = [uscd_filter]
    uscd_tally.scores = ['flux']
    uscd_tally.estimator = test_opts['estimator']
    tallies.append(uscd_tally)

    ### Settings ###
    settings = openmc.Settings()
    settings.run_mode = 'fixed source'
    settings.particles = 1000
    settings.batches = 10

    # source setup
    r = openmc.stats.Uniform(a=0.0, b=0.0)
    theta = openmc.stats.Discrete(x=[0.0], p=[1.0])
    phi = openmc.stats.Discrete(x=[0.0], p=[1.0])

    space = openmc.stats.SphericalIndependent(r, theta, phi)
    energy = openmc.stats.Discrete(x=[15.e+06], p=[1.0])
    source = openmc.Source(space=space, energy=energy)
    settings.source = source

    model = openmc.model.Model(geometry=geometry,
                               materials=materials,
                               tallies=tallies,
                               settings=settings)

    harness = UnstructuredMeshTest('statepoint.10.h5', model,
                                   test_opts['inputs_true'],
                                   test_opts['holes'])
    harness.main()
Esempio n. 15
0
def model():
    openmc.reset_auto_ids()
    model = openmc.Model()

    # materials (M4 steel alloy)
    m4 = openmc.Material()
    m4.set_density('g/cc', 2.3)
    m4.add_nuclide('H1', 0.168018676)
    m4.add_nuclide("H2", 1.93244e-05)
    m4.add_nuclide("O16", 0.561814465)
    m4.add_nuclide("O17", 0.00021401)
    m4.add_nuclide("Na23", 0.021365)
    m4.add_nuclide("Al27", 0.021343)
    m4.add_nuclide("Si28", 0.187439342)
    m4.add_nuclide("Si29", 0.009517714)
    m4.add_nuclide("Si30", 0.006273944)
    m4.add_nuclide("Ca40", 0.018026179)
    m4.add_nuclide("Ca42", 0.00012031)
    m4.add_nuclide("Ca43", 2.51033e-05)
    m4.add_nuclide("Ca44", 0.000387892)
    m4.add_nuclide("Ca46", 7.438e-07)
    m4.add_nuclide("Ca48", 3.47727e-05)
    m4.add_nuclide("Fe54", 0.000248179)
    m4.add_nuclide("Fe56", 0.003895875)
    m4.add_nuclide("Fe57", 8.99727e-05)
    m4.add_nuclide("Fe58", 1.19737e-05)

    s0 = openmc.Sphere(r=240)
    s1 = openmc.Sphere(r=250, boundary_type='vacuum')

    c0 = openmc.Cell(fill=m4, region=-s0)
    c1 = openmc.Cell(region=+s0 & -s1)

    model.geometry = openmc.Geometry([c0, c1])

    # settings
    settings = model.settings
    settings.run_mode = 'fixed source'
    settings.particles = 500
    settings.batches = 2
    settings.max_splits = 100
    settings.photon_transport = True
    space = Point((0.001, 0.001, 0.001))
    energy = Discrete([14E6], [1.0])

    settings.source = openmc.Source(space=space, energy=energy)

    # tally
    mesh = openmc.RegularMesh()
    mesh.lower_left = (-240, -240, -240)
    mesh.upper_right = (240, 240, 240)
    mesh.dimension = (3, 5, 7)

    mesh_filter = openmc.MeshFilter(mesh)

    e_bnds = [0.0, 0.5, 2E7]
    energy_filter = openmc.EnergyFilter(e_bnds)

    particle_filter = openmc.ParticleFilter(['neutron', 'photon'])

    tally = openmc.Tally()
    tally.filters = [mesh_filter, energy_filter, particle_filter]
    tally.scores = ['flux']

    model.tallies.append(tally)

    return model
    def __init__(self,
                 geometry,
                 settings,
                 chain_file=None,
                 prev_results=None,
                 diff_burnable_mats=False,
                 energy_mode="fission-q",
                 fission_q=None,
                 dilute_initial=1.0e3,
                 fission_yield_mode="constant",
                 fission_yield_opts=None):
        if fission_yield_mode not in self._fission_helpers:
            raise KeyError(
                "fission_yield_mode must be one of {}, not {}".format(
                    ", ".join(self._fission_helpers), fission_yield_mode))
        if energy_mode == "energy-deposition":
            if fission_q is not None:
                warn("Fission Q dictionary not used if energy deposition "
                     "is used")
                fission_q = None
        elif energy_mode != "fission-q":
            raise ValueError(
                "energy_mode {} not supported. Must be energy-deposition "
                "or fission-q".format(energy_mode))
        super().__init__(chain_file, fission_q, dilute_initial, prev_results)
        self.round_number = False
        self.prev_res = None
        self.settings = settings
        self.geometry = geometry
        self.diff_burnable_mats = diff_burnable_mats

        # Differentiate burnable materials with multiple instances
        if self.diff_burnable_mats:
            self._differentiate_burnable_mats()

        # Clear out OpenMC, create task lists, distribute
        openmc.reset_auto_ids()
        self.burnable_mats, volume, nuclides = self._get_burnable_mats()
        self.local_mats = _distribute(self.burnable_mats)

        # Generate map from local materials => material index
        self._mat_index_map = {
            lm: self.burnable_mats.index(lm)
            for lm in self.local_mats
        }

        if self.prev_res is not None:
            # Reload volumes into geometry
            prev_results[-1].transfer_volumes(geometry)

            # Store previous results in operator
            # Distribute reaction rates according to those tracked
            # on this process
            if comm.size == 1:
                self.prev_res = prev_results
            else:
                self.prev_res = ResultsList()
                mat_indexes = _distribute(range(len(self.burnable_mats)))
                for res_obj in prev_results:
                    new_res = res_obj.distribute(self.local_mats, mat_indexes)
                    self.prev_res.append(new_res)

        # Determine which nuclides have incident neutron data
        self.nuclides_with_data = self._get_nuclides_with_data()

        # Select nuclides with data that are also in the chain
        self._burnable_nucs = [
            nuc.name for nuc in self.chain.nuclides
            if nuc.name in self.nuclides_with_data
        ]

        # Extract number densities from the geometry / previous depletion run
        self._extract_number(self.local_mats, volume, nuclides, self.prev_res)

        # Create reaction rates array
        self.reaction_rates = ReactionRates(self.local_mats,
                                            self._burnable_nucs,
                                            self.chain.reactions)

        # Get classes to assist working with tallies
        self._rate_helper = DirectReactionRateHelper(
            self.reaction_rates.n_nuc, self.reaction_rates.n_react)
        if energy_mode == "fission-q":
            self._energy_helper = ChainFissionHelper()
        else:
            score = "heating" if settings.photon_transport else "heating-local"
            self._energy_helper = EnergyScoreHelper(score)

        # Select and create fission yield helper
        fission_helper = self._fission_helpers[fission_yield_mode]
        fission_yield_opts = ({} if fission_yield_opts is None else
                              fission_yield_opts)
        self._yield_helper = fission_helper.from_operator(
            self, **fission_yield_opts)
Esempio n. 17
0
def clean_up_openmc():
    """ Resets all automatic indexing in OpenMC, as these get in the way. """
    openmc.reset_auto_ids()
Esempio n. 18
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-l', '--benchmarks', type=pathlib.Path,
                        default=pathlib.Path('benchmarks/lists/pst-short'),
                        help='List of benchmarks to run.')
    parser.add_argument('-c', '--code', choices=['openmc', 'mcnp'],
                        default='openmc',
                        help='Code used to run benchmarks.')
    parser.add_argument('-x', '--cross-sections', type=str,
                        default=os.getenv('OPENMC_CROSS_SECTIONS'),
                        help='OpenMC cross sections XML file.')
    parser.add_argument('-s', '--suffix', type=str, default='70c',
                        help='MCNP cross section suffix')
    parser.add_argument('-p', '--particles', type=int, default=10000,
                        help='Number of source particles.')
    parser.add_argument('-b', '--batches', type=int, default=150,
                        help='Number of batches.')
    parser.add_argument('-i', '--inactive', type=int, default=50,
                        help='Number of inactive batches.')
    parser.add_argument('-m', '--max-batches', type=int, default=10000,
                        help='Maximum number of batches.')
    parser.add_argument('-t', '--threshold', type=float, default=0.0001,
                        help='Value of the standard deviation trigger on '
                        'eigenvalue.')
    parser.add_argument('-o', '--output-name', type=str,
                        help='Base filename for plot.')
    parser.add_argument('-f', '--output-format', type=str, default='png',
                        help='File format for plot.')
    args = parser.parse_args()

    # Create timestamp
    current_time = time.localtime()
    timestamp = time.strftime("%Y-%m-%d-%H%M%S", current_time)

    # Check that executable exists
    executable = 'mcnp6' if args.code == 'mcnp' else 'openmc'
    if not shutil.which(executable, os.X_OK):
        msg = f'Unable to locate executable {executable} in path.'
        raise IOError(msg)

    # Create directory and set filename for results
    os.makedirs('results', exist_ok=True)
    outfile = f'results/{timestamp}.csv'

    # Get a copy of the benchmarks repository
    if not pathlib.Path('benchmarks').is_dir():
        repo = 'https://github.com/mit-crpg/benchmarks.git'
        subprocess.run(['git', 'clone', repo], check=True)

    # Get the list of benchmarks to run
    if not args.benchmarks.is_file():
        msg = f'Unable to locate benchmark list {args.benchmarks}.'
        raise IOError(msg)
    with open(args.benchmarks) as f:
        benchmarks = f.read().split()

    # Prepare and run benchmarks
    for benchmark in benchmarks:
        path = pathlib.Path('benchmarks') / benchmark

        if args.code == 'openmc':
            openmc.reset_auto_ids()

            # Remove old statepoint files
            for f in path.glob('statepoint.*.h5'):
                os.remove(f)

            # Modify settings
            settings = openmc.Settings.from_xml(path / 'settings.xml')
            settings.particles = args.particles
            settings.inactive = args.inactive
            settings.batches = args.batches
            settings.keff_trigger = {'type': 'std_dev',
                                     'threshold': args.threshold}
            settings.trigger_active = True
            settings.trigger_max_batches = args.max_batches
            settings.output = {'tallies': False}
            settings.export_to_xml(path)

            # Set path to cross sections XML
            materials = openmc.Materials.from_xml(path / 'materials.xml')
            materials.cross_sections = args.cross_sections
            materials.export_to_xml(path / 'materials.xml')

            # Run benchmark
            openmc.run(cwd=path)

            # Read k-effective mean and standard deviation from statepoint
            filename = list(path.glob('statepoint.*.h5'))[0]
            with openmc.StatePoint(filename) as sp:
                mean = sp.k_combined.nominal_value
                stdev = sp.k_combined.std_dev

        elif args.code == 'mcnp':
            # Read input file
            with open(path / 'input', 'r') as f:
                lines = f.readlines()

            # Update criticality source card
            line = f'kcode {args.particles} 1 {args.inactive} {args.batches}\n'
            for i in range(len(lines)):
                if lines[i].strip().startswith('kcode'):
                    lines[i] = line
                    break

            # Update cross section suffix
            match = '(7[0-4]c)|(8[0-6]c)'
            if not re.match(match, args.suffix):
                msg = f'Unsupported cross section suffix {args.suffix}.'
                raise ValueError(msg)
            lines = [re.sub(match, args.suffix, x) for x in lines]

            # Write new input file
            with open(path / 'input', 'w') as f:
                f.write(''.join(lines))

            # Remove old MCNP output files
            for f in ('outp', 'runtpe', 'srctp'):
                try:
                    os.remove(path / f)
                except OSError:
                    pass

            # Run benchmark and capture and print output
            arg_list = [executable, 'inp=input']
            p = subprocess.Popen(
                args=arg_list, cwd=path, stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT, universal_newlines=True
            )
            while True:
                line = p.stdout.readline()
                if not line and p.poll() is not None:
                    break
                print(line, end='')

            # Read k-effective mean and standard deviation from output
            with open(path / 'outp', 'r') as f:
                line = f.readline()
                while not line.strip().startswith('col/abs/trk len'):
                    line = f.readline()
                words = line.split()
                mean = float(words[2])
                stdev = float(words[3])

        # Write results
        words = benchmark.split('/')
        name = words[1]
        case = words[3] if len(words) > 3 else ''
        line = '{}, {}, {}, {}'.format(name, case, mean, stdev)
        if benchmark != benchmarks[-1]:
            line += '\n'
        with open(outfile, 'a') as f:
            f.write(line)

    plot(outfile, output_name=args.output_name,
         output_format=args.output_format)
Esempio n. 19
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-l',
                        '--benchmarks',
                        type=Path,
                        default=Path('benchmarks/lists/pst-short'),
                        help='List of benchmarks to run.')
    parser.add_argument('-c',
                        '--code',
                        choices=['openmc', 'mcnp'],
                        default='openmc',
                        help='Code used to run benchmarks.')
    parser.add_argument('-x',
                        '--cross-sections',
                        type=str,
                        default=os.getenv('OPENMC_CROSS_SECTIONS'),
                        help='OpenMC cross sections XML file.')
    parser.add_argument('-s',
                        '--suffix',
                        type=str,
                        default='70c',
                        help='MCNP cross section suffix')
    parser.add_argument('-p',
                        '--particles',
                        type=int,
                        default=10000,
                        help='Number of source particles.')
    parser.add_argument('-b',
                        '--batches',
                        type=int,
                        default=150,
                        help='Number of batches.')
    parser.add_argument('-i',
                        '--inactive',
                        type=int,
                        default=50,
                        help='Number of inactive batches.')
    parser.add_argument('-m',
                        '--max-batches',
                        type=int,
                        default=10000,
                        help='Maximum number of batches.')
    parser.add_argument(
        '-t',
        '--threshold',
        type=float,
        default=0.0001,
        help='Value of the standard deviation trigger on eigenvalue.')
    parser.add_argument(
        '--mpi-args',
        default="",
        help="MPI execute command and any additional MPI arguments")
    args = parser.parse_args()

    # Create timestamp
    timestamp = time.strftime("%Y-%m-%d-%H%M%S")

    # Check that executable exists
    executable = 'mcnp6' if args.code == 'mcnp' else 'openmc'
    if not shutil.which(executable, os.X_OK):
        msg = f'Unable to locate executable {executable} in path.'
        raise IOError(msg)
    mpi_args = args.mpi_args.split()

    # Create directory and set filename for results
    results_dir = Path('results')
    results_dir.mkdir(exist_ok=True)
    outfile = results_dir / f'{timestamp}.csv'

    # Get a copy of the benchmarks repository
    if not Path('benchmarks').is_dir():
        repo = 'https://github.com/mit-crpg/benchmarks.git'
        subprocess.run(['git', 'clone', repo], check=True)

    # Get the list of benchmarks to run
    if not args.benchmarks.is_file():
        msg = f'Unable to locate benchmark list {args.benchmarks}.'
        raise IOError(msg)
    with open(args.benchmarks) as f:
        benchmarks = [Path(line) for line in f.read().split()]

    # Set cross sections
    if args.cross_sections is not None:
        os.environ["OPENMC_CROSS_SECTIONS"] = args.cross_sections

    # Prepare and run benchmarks
    for i, benchmark in enumerate(benchmarks):
        print(f"{i + 1} {benchmark} ", end="", flush=True)

        path = 'benchmarks' / benchmark

        if args.code == 'openmc':
            openmc.reset_auto_ids()

            # Remove old statepoint files
            for f in path.glob('statepoint.*.h5'):
                os.remove(f)

            # Modify settings
            settings = openmc.Settings.from_xml(path / 'settings.xml')
            settings.particles = args.particles
            settings.inactive = args.inactive
            settings.batches = args.batches
            settings.keff_trigger = {
                'type': 'std_dev',
                'threshold': args.threshold
            }
            settings.trigger_active = True
            settings.trigger_max_batches = args.max_batches
            settings.output = {'tallies': False}
            settings.export_to_xml(path)

            # Re-generate materials if Python script is present
            genmat_script = path / "generate_materials.py"
            if genmat_script.is_file():
                subprocess.run(["python", "generate_materials.py"], cwd=path)

            # Run benchmark
            proc = subprocess.run(
                mpi_args + ["openmc"],
                cwd=path,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                universal_newlines=True,
            )

            # Determine last statepoint
            t_last = 0
            last_statepoint = None
            for sp in path.glob('statepoint.*.h5'):
                mtime = sp.stat().st_mtime
                if mtime >= t_last:
                    t_last = mtime
                    last_statepoint = sp

            # Read k-effective mean and standard deviation from statepoint
            if last_statepoint is not None:
                with openmc.StatePoint(last_statepoint) as sp:
                    mean = sp.k_combined.nominal_value
                    stdev = sp.k_combined.std_dev

        else:
            # Read input file
            with open(path / 'input', 'r') as f:
                lines = f.readlines()

            # Update criticality source card
            line = f'kcode {args.particles} 1 {args.inactive} {args.batches}\n'
            for i in range(len(lines)):
                if lines[i].strip().startswith('kcode'):
                    lines[i] = line
                    break

            # Update cross section suffix
            match = '(7[0-4]c)|(8[0-6]c)'
            if not re.match(match, args.suffix):
                msg = f'Unsupported cross section suffix {args.suffix}.'
                raise ValueError(msg)
            lines = [re.sub(match, args.suffix, x) for x in lines]

            # Write new input file
            with open(path / 'input', 'w') as f:
                f.write(''.join(lines))

            # Remove old MCNP output files
            for f in ('outp', 'runtpe', 'srctp'):
                try:
                    os.remove(path / f)
                except OSError:
                    pass

            # Run benchmark and capture and print output
            arg_list = mpi_args + [executable, 'inp=input']
            proc = subprocess.run(arg_list,
                                  cwd=path,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT,
                                  universal_newlines=True)

            # Read k-effective mean and standard deviation from output
            with open(path / 'outp', 'r') as f:
                line = f.readline()
                while not line.strip().startswith('col/abs/trk len'):
                    line = f.readline()
                words = line.split()
                mean = float(words[2])
                stdev = float(words[3])

        # Write output to file
        with open(path / f"output_{timestamp}", "w") as fh:
            fh.write(proc.stdout)

        if proc.returncode != 0:
            mean = stdev = ""
            print()
        else:
            # Display k-effective
            print(f"{mean:.5f} ± {stdev:.5f}")

        # Write results
        words = str(benchmark).split('/')
        name = words[1]
        case = '/' + words[3] if len(words) > 3 else ''
        line = f'{name}{case},{mean},{stdev}\n'
        with open(outfile, 'a') as f:
            f.write(line)
Esempio n. 20
0
def reset():
    openmc.reset_auto_ids()
Esempio n. 21
0
    def __init__(self,
                 geometry,
                 settings,
                 chain_file=None,
                 prev_results=None,
                 diff_burnable_mats=False,
                 normalization_mode="fission-q",
                 fission_q=None,
                 dilute_initial=1.0e3,
                 fission_yield_mode="constant",
                 fission_yield_opts=None,
                 reaction_rate_mode="direct",
                 reaction_rate_opts=None,
                 reduce_chain=False,
                 reduce_chain_level=None):
        check_value('fission yield mode', fission_yield_mode,
                    self._fission_helpers.keys())
        check_value('normalization mode', normalization_mode,
                    ('energy-deposition', 'fission-q', 'source-rate'))
        if normalization_mode != "fission-q":
            if fission_q is not None:
                warn("Fission Q dictionary will not be used")
                fission_q = None
        super().__init__(chain_file, fission_q, dilute_initial, prev_results)
        self.round_number = False
        self.settings = settings
        self.geometry = geometry
        self.diff_burnable_mats = diff_burnable_mats

        # Reduce the chain before we create more materials
        if reduce_chain:
            all_isotopes = set()
            for material in geometry.get_all_materials().values():
                if not material.depletable:
                    continue
                for name, _dens_percent, _dens_type in material.nuclides:
                    all_isotopes.add(name)
            self.chain = self.chain.reduce(all_isotopes, reduce_chain_level)

        # Differentiate burnable materials with multiple instances
        if self.diff_burnable_mats:
            self._differentiate_burnable_mats()

        # Clear out OpenMC, create task lists, distribute
        openmc.reset_auto_ids()
        self.burnable_mats, volume, nuclides = self._get_burnable_mats()
        self.local_mats = _distribute(self.burnable_mats)

        # Generate map from local materials => material index
        self._mat_index_map = {
            lm: self.burnable_mats.index(lm)
            for lm in self.local_mats
        }

        if self.prev_res is not None:
            # Reload volumes into geometry
            prev_results[-1].transfer_volumes(geometry)

            # Store previous results in operator
            # Distribute reaction rates according to those tracked
            # on this process
            if comm.size == 1:
                self.prev_res = prev_results
            else:
                self.prev_res = ResultsList()
                mat_indexes = _distribute(range(len(self.burnable_mats)))
                for res_obj in prev_results:
                    new_res = res_obj.distribute(self.local_mats, mat_indexes)
                    self.prev_res.append(new_res)

        # Determine which nuclides have incident neutron data
        self.nuclides_with_data = self._get_nuclides_with_data()

        # Select nuclides with data that are also in the chain
        self._burnable_nucs = [
            nuc.name for nuc in self.chain.nuclides
            if nuc.name in self.nuclides_with_data
        ]

        # Extract number densities from the geometry / previous depletion run
        self._extract_number(self.local_mats, volume, nuclides, self.prev_res)

        # Create reaction rates array
        self.reaction_rates = ReactionRates(self.local_mats,
                                            self._burnable_nucs,
                                            self.chain.reactions)

        # Get classes to assist working with tallies
        if reaction_rate_mode == "direct":
            self._rate_helper = DirectReactionRateHelper(
                self.reaction_rates.n_nuc, self.reaction_rates.n_react)
        elif reaction_rate_mode == "flux":
            if reaction_rate_opts is None:
                reaction_rate_opts = {}

            # Ensure energy group boundaries were specified
            if 'energies' not in reaction_rate_opts:
                raise ValueError(
                    "Energy group boundaries must be specified in the "
                    "reaction_rate_opts argument when reaction_rate_mode is"
                    "set to 'flux'.")

            self._rate_helper = FluxCollapseHelper(self.reaction_rates.n_nuc,
                                                   self.reaction_rates.n_react,
                                                   **reaction_rate_opts)
        else:
            raise ValueError("Invalid reaction rate mode.")

        if normalization_mode == "fission-q":
            self._normalization_helper = ChainFissionHelper()
        elif normalization_mode == "energy-deposition":
            score = "heating" if settings.photon_transport else "heating-local"
            self._normalization_helper = EnergyScoreHelper(score)
        else:
            self._normalization_helper = SourceRateHelper()

        # Select and create fission yield helper
        fission_helper = self._fission_helpers[fission_yield_mode]
        fission_yield_opts = ({} if fission_yield_opts is None else
                              fission_yield_opts)
        self._yield_helper = fission_helper.from_operator(
            self, **fission_yield_opts)