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)
def test_transfer_volumes(run_in_tmpdir): """Unit test of volume transfer in restart calculations.""" op = dummy_operator.DummyOperator() op.output_dir = "test_transfer_volumes" # Perform simulation using the predictor algorithm dt = [0.75] power = 1.0 PredictorIntegrator(op, dt, power).integrate() # Load the files res = openmc.deplete.ResultsList.from_hdf5(op.output_dir / "depletion_results.h5") # Create a dictionary of volumes to transfer res[0].volume['1'] = 1.5 res[0].volume['2'] = 2.5 # Create dummy geometry mat1 = openmc.Material(material_id=1) mat1.depletable = True mat2 = openmc.Material(material_id=2) cell = openmc.Cell() cell.fill = [mat1, mat2] root = openmc.Universe() root.add_cell(cell) geometry = openmc.Geometry(root) # Transfer volumes res[0].transfer_volumes(openmc.Model(geometry)) assert mat1.volume == 1.5 assert mat2.volume is None
def model(): model = openmc.Model() fuel = openmc.Material() fuel.set_density('g/cm3', 12.0) fuel.add_nuclide('U235', 1.0) al = openmc.Material() al.set_density('g/cm3', 1.0) al.add_nuclide('H1', 1.0) model.materials.extend([fuel, al]) # 🍩🍩🍩 zt = openmc.ZTorus(a=3, b=1.5, c=1) xt = openmc.XTorus(x0=6, a=3, b=1.5, c=1) yt = openmc.YTorus(x0=6, a=6, b=1, c=0.75) box = openmc.model.RectangularParallelepiped(-5, 14, -5, 5, -8, 8, boundary_type='vacuum') xt_cell = openmc.Cell(fill=fuel, region=-xt) yt_cell = openmc.Cell(fill=fuel, region=-yt) zt_cell = openmc.Cell(fill=fuel, region=-zt) outer_cell = openmc.Cell(fill=al, region=-box & +xt & +yt & +zt) model.geometry = openmc.Geometry([xt_cell, yt_cell, zt_cell, outer_cell]) model.settings.particles = 1000 model.settings.batches = 10 model.settings.inactive = 5 return model
def inf_medium_model(cutoff_energy, source_energy): """Infinite medium problem with a monoenergetic photon source""" model = openmc.Model() m = openmc.Material() m.add_nuclide('Zr90', 1.0) m.set_density('g/cm3', 1.0) sph = openmc.Sphere(r=100.0, boundary_type='reflective') cell = openmc.Cell(fill=m, region=-sph) model.geometry = openmc.Geometry([cell]) model.settings.run_mode = 'fixed source' model.settings.source = openmc.Source( particle='photon', energy=openmc.stats.Discrete([source_energy], [1.0]), ) model.settings.particles = 100 model.settings.batches = 10 model.settings.cutoff = {'energy_photon': cutoff_energy} tally_flux = openmc.Tally(name='flux') tally_flux.filters = [ openmc.EnergyFilter([0.0, cutoff_energy, source_energy]), openmc.ParticleFilter(['photon']) ] tally_flux.scores = ['flux'] tally_heating = openmc.Tally(name='heating') tally_heating.scores = ['heating'] model.tallies = openmc.Tallies([tally_flux, tally_heating]) return model
def test_deplete(run_in_tmpdir, pin_model_attributes, mpi_intracomm): mats, geom, settings, tals, plots, op_kwargs, chain_file_xml = \ pin_model_attributes with open('test_chain.xml', 'w') as f: f.write(chain_file_xml) test_model = openmc.Model(geom, mats, settings, tals, plots) initial_mat = mats[0].clone() initial_u = initial_mat.get_nuclide_atom_densities()['U235'][1] # Note that the chain file includes only U-235 fission to a stable Xe136 w/ # a yield of 100%. Thus all the U235 we lose becomes Xe136 # In this test we first run without pre-initializing the shared library # data and then compare. Then we repeat with the C API already initialized # and make sure we get the same answer test_model.deplete([1e6], 'predictor', final_step=False, operator_kwargs=op_kwargs, power=1., output=False) # Get the new Xe136 and U235 atom densities after_xe = mats[0].get_nuclide_atom_densities()['Xe136'][1] after_u = mats[0].get_nuclide_atom_densities()['U235'][1] assert after_xe + after_u == pytest.approx(initial_u, abs=1e-15) assert test_model.is_initialized is False # Reset the initial material densities mats[0].nuclides.clear() densities = initial_mat.get_nuclide_atom_densities() tot_density = 0. for nuc, density in densities.values(): mats[0].add_nuclide(nuc, density) tot_density += density mats[0].set_density('atom/b-cm', tot_density) # Now we can re-run with the pre-initialized API test_model.init_lib(output=False, intracomm=mpi_intracomm) test_model.deplete([1e6], 'predictor', final_step=False, operator_kwargs=op_kwargs, power=1., output=False) # Get the new Xe136 and U235 atom densities after_lib_xe = mats[0].get_nuclide_atom_densities()['Xe136'][1] after_lib_u = mats[0].get_nuclide_atom_densities()['U235'][1] assert after_lib_xe + after_lib_u == pytest.approx(initial_u, abs=1e-15) assert test_model.is_initialized is True # And end by comparing to the previous case assert after_xe == pytest.approx(after_lib_xe, abs=1e-15) assert after_u == pytest.approx(after_lib_u, abs=1e-15) test_model.finalize_lib()
def test_calc_volumes(run_in_tmpdir, pin_model_attributes, mpi_intracomm): mats, geom, settings, tals, plots, _, _ = pin_model_attributes test_model = openmc.Model(geom, mats, settings, tals, plots) # With no vol calcs, it should fail with pytest.raises(ValueError): test_model.calculate_volumes(output=False) # Add a cell and mat volume calc material_vol_calc = openmc.VolumeCalculation([mats[2]], samples=1000, lower_left=(-.63, -.63, -100.), upper_right=(.63, .63, 100.)) cell_vol_calc = openmc.VolumeCalculation([geom.root_universe.cells[3]], samples=1000, lower_left=(-.63, -.63, -100.), upper_right=(.63, .63, 100.)) test_model.settings.volume_calculations = \ [material_vol_calc, cell_vol_calc] # Now lets compute the volumes and check to see if it was applied # First lets do without using the C-API # Make sure the volumes are unassigned first assert mats[2].volume is None assert geom.root_universe.cells[3].volume is None test_model.calculate_volumes(output=False, apply_volumes=True) # Now let's test that we have volumes assigned; we arent checking the # value, just that the value was changed assert mats[2].volume > 0. assert geom.root_universe.cells[3].volume > 0. # Now reset the values mats[2].volume = None geom.root_universe.cells[3].volume = None # And do again with an initialized library for file in ['volume_1.h5', 'volume_2.h5']: file = Path(file) file.unlink() test_model.init_lib(output=False, intracomm=mpi_intracomm) test_model.calculate_volumes(output=False, apply_volumes=True) assert mats[2].volume > 0. assert geom.root_universe.cells[3].volume > 0. assert openmc.lib.materials[3].volume == mats[2].volume test_model.finalize_lib()
def test_decay(run_in_tmpdir): """Test decay-only timesteps where no transport solve is performed""" # Create a model with a single nuclide, Sr89 mat = openmc.Material() mat.add_nuclide('Sr89', 1.0) mat.set_density('g/cm3', 1.0) mat.depletable = True r = 5.0 mat.volume = 4 / 3 * pi * r**3 surf = openmc.Sphere(r=r, boundary_type='vacuum') cell = openmc.Cell(fill=mat, region=-surf) geometry = openmc.Geometry([cell]) settings = openmc.Settings() settings.batches = 10 settings.particles = 1000 settings.run_mode = 'fixed source' # Create depletion chain with only Sr89 and sample its half-life. Note that # currently at least one reaction has to exist in the depletion chain chain = openmc.deplete.Chain() sr89 = openmc.deplete.Nuclide('Sr89') sr89.half_life = normalvariate(4365792.0, 6048.0) sr89.add_decay_mode('beta-', None, 1.0) sr89.add_reaction('(n,gamma)', None, 0.0, 1.0) chain.add_nuclide(sr89) chain.export_to_xml('test_chain.xml') model = openmc.Model(geometry=geometry, settings=settings) # Create transport operator op = openmc.deplete.Operator(model, 'test_chain.xml', normalization_mode="source-rate") # Deplete with two decay steps integrator = openmc.deplete.PredictorIntegrator( op, [sr89.half_life, 2 * sr89.half_life], source_rates=[0.0, 0.0]) integrator.integrate() # Get resulting number of atoms results = openmc.deplete.ResultsList.from_hdf5('depletion_results.h5') _, atoms = results.get_atoms(str(mat.id), "Sr89") # Ensure density goes down by a factor of 2 after each half-life assert atoms[1] / atoms[0] == pytest.approx(0.5) assert atoms[2] / atoms[1] == pytest.approx(0.25)
def test_plots(run_in_tmpdir, pin_model_attributes, mpi_intracomm): mats, geom, settings, tals, plots, _, _ = pin_model_attributes test_model = openmc.Model(geom, mats, settings, tals, plots) # This test cannot check the correctness of the plot, but it can # check that a plot was made and that the expected png files are there # We will run the test twice, the first time without C API, the second with for i in range(2): if i == 1: test_model.init_lib(output=False, intracomm=mpi_intracomm) test_model.plot_geometry(output=False) # Now look for the files for fname in ('test.png', 'plot_2.png'): test_file = Path(fname) assert test_file.exists() test_file.unlink() test_model.finalize_lib()
def test_init_finalize_lib(run_in_tmpdir, pin_model_attributes, mpi_intracomm): # We are going to init and then make sure data is loaded mats, geom, settings, tals, plots, _, _ = pin_model_attributes test_model = openmc.Model(geom, mats, settings, tals, plots) test_model.init_lib(output=False, intracomm=mpi_intracomm) # First check that the API is advertised as initialized assert openmc.lib.is_initialized is True assert test_model.is_initialized is True # Now make sure it actually is initialized by making a call to the lib c_mat = openmc.lib.find_material((0.6, 0., 0.)) # This should be Borated water assert c_mat.name == 'Borated water' assert c_mat.id == 3 # Ok, now lets test that we can clear the data and check that it is cleared test_model.finalize_lib() # First check that the API is advertised as initialized assert openmc.lib.is_initialized is False assert test_model.is_initialized is False
def model_surf(request): # Select random distance and source energy x = uniform(50., 100.) E = uniform(0., 20.0e6) # Create model model = openmc.Model() mat = openmc.Material() mat.add_nuclide('Zr90', 1.0) mat.set_density('g/cm3', 1.0) model.materials.append(mat) left = openmc.XPlane(-1., boundary_type='vacuum') black_surface = openmc.XPlane(x, boundary_type='vacuum') right = openmc.XPlane(x + 1) void_cell = openmc.Cell(region=+left & -black_surface) black_cell = openmc.Cell(region=+black_surface & -right) model.geometry = openmc.Geometry([void_cell, black_cell]) model.settings = openmc.Settings() model.settings.run_mode = 'fixed source' model.settings.particles = 1000 model.settings.batches = 20 particle = request.param model.settings.source = openmc.Source( space=openmc.stats.Point((0., 0., 0.)), angle=openmc.stats.Monodirectional([1., 0., 0.]), energy=openmc.stats.Discrete([E], [1.0]), particle=particle) # Calculate time it will take neutrons to reach purely-absorbing surface t0 = time(particle, x, E) # Create tally with surface and time filters tally = openmc.Tally() tally.filters = [ openmc.SurfaceFilter([black_surface]), openmc.TimeFilter([0.0, t0 * 0.999, t0 * 1.001, 100.0]) ] tally.scores = ['current'] model.tallies.append(tally) return model
def model(request): # Select random sphere radius, source position, and source energy r = uniform(0., 2.) x = uniform(2., 10.) E = uniform(0., 20.0e6) # Create model model = openmc.Model() mat = openmc.Material() mat.add_nuclide('Zr90', 1.0) mat.set_density('g/cm3', 1.0) model.materials.append(mat) inner_sphere = openmc.Sphere(r=r) outer_sphere = openmc.Sphere(r=10.0, boundary_type='vacuum') center_cell = openmc.Cell(fill=mat, region=-inner_sphere) outer_void = openmc.Cell(region=+inner_sphere & -outer_sphere) model.geometry = openmc.Geometry([center_cell, outer_void]) model.settings = openmc.Settings() model.settings.run_mode = 'fixed source' model.settings.particles = 1000 model.settings.batches = 20 particle = request.param model.settings.source = openmc.Source( space=openmc.stats.Point((x, 0., 0.)), angle=openmc.stats.Monodirectional([-1., 0., 0.]), energy=openmc.stats.Discrete([E], [1.0]), particle=particle) # Calculate time it will take neutrons to reach sphere t0 = time(particle, x - r, E) # Create tally with time filter tally = openmc.Tally() tally.filters = [openmc.TimeFilter([0.0, t0, 2 * t0])] tally.scores = ['total'] model.tallies.append(tally) return model
def test_run(run_in_tmpdir, pin_model_attributes, mpi_intracomm): mats, geom, settings, tals, plots, _, _ = pin_model_attributes test_model = openmc.Model(geom, mats, settings, tals, plots) # This case will run by getting the k-eff and tallies for command-line and # C API execution modes and ensuring they give the same result. sp_path = test_model.run(output=False) with openmc.StatePoint(sp_path) as sp: cli_keff = sp.k_combined cli_flux = sp.get_tally(id=1).get_values(scores=['flux'])[0, 0, 0] cli_fiss = sp.get_tally(id=1).get_values(scores=['fission'])[0, 0, 0] test_model.init_lib(output=False, intracomm=mpi_intracomm) sp_path = test_model.run(output=False) with openmc.StatePoint(sp_path) as sp: lib_keff = sp.k_combined lib_flux = sp.get_tally(id=1).get_values(scores=['flux'])[0, 0, 0] lib_fiss = sp.get_tally(id=1).get_values(scores=['fission'])[0, 0, 0] # and lets compare results assert lib_keff.n == pytest.approx(cli_keff.n, abs=1e-13) assert lib_flux == pytest.approx(cli_flux, abs=1e-13) assert lib_fiss == pytest.approx(cli_fiss, abs=1e-13) # Now we should make sure that the flags for items which should be handled # by init are properly set with pytest.raises(ValueError): test_model.run(threads=1) with pytest.raises(ValueError): test_model.run(geometry_debug=True) with pytest.raises(ValueError): test_model.run(restart_file='1.h5') with pytest.raises(ValueError): test_model.run(tracks=True) test_model.finalize_lib()
def model(): 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 = 200 settings.batches = 2 settings.max_splits = 200 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 = (5, 10, 15) 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) # weight windows # load pre-generated weight windows # (created using the same tally as above) ww_n_lower_bnds = np.loadtxt('ww_n.txt') ww_p_lower_bnds = np.loadtxt('ww_p.txt') # create a mesh matching the one used # to generate the weight windows ww_mesh = openmc.RegularMesh() ww_mesh.lower_left = (-240, -240, -240) ww_mesh.upper_right = (240, 240, 240) ww_mesh.dimension = (5, 6, 7) ww_n = openmc.WeightWindows(ww_mesh, ww_n_lower_bnds, None, 10.0, e_bnds, max_lower_bound_ratio=1.5) ww_p = openmc.WeightWindows(ww_mesh, ww_p_lower_bnds, None, 10.0, e_bnds, max_lower_bound_ratio=1.5) model.settings.weight_windows = [ww_n, ww_p] return model
def test_py_lib_attributes(run_in_tmpdir, pin_model_attributes, mpi_intracomm): mats, geom, settings, tals, plots, _, _ = pin_model_attributes test_model = openmc.Model(geom, mats, settings, tals, plots) test_model.init_lib(output=False, intracomm=mpi_intracomm) # Now we can call rotate_cells, translate_cells, update_densities, # and update_cell_temperatures and make sure the changes have taken hold. # For each we will first try bad inputs to make sure we get the right # errors and then we do a good one which calls the material by name and # then id to make sure it worked # The rotate_cells and translate_cells will work on the cell named fill, as # it is filled with a universe and thus the operation will be valid # First rotate_cells with pytest.raises(TypeError): # Make sure it tells us we have a bad names_or_ids type test_model.rotate_cells(None, (0, 0, 90)) with pytest.raises(TypeError): test_model.rotate_cells([None], (0, 0, 90)) with pytest.raises(openmc.exceptions.InvalidIDError): # Make sure it tells us we had a bad id test_model.rotate_cells([7200], (0, 0, 90)) with pytest.raises(openmc.exceptions.InvalidIDError): # Make sure it tells us we had a bad id test_model.rotate_cells(['bad_name'], (0, 0, 90)) # Now a good one assert np.all(openmc.lib.cells[2].rotation == (0., 0., 0.)) test_model.rotate_cells([2], (0, 0, 90)) assert np.all(openmc.lib.cells[2].rotation == (0., 0., 90.)) # And same thing by name test_model.rotate_cells(['fuel'], (0, 0, 180)) # Now translate_cells. We dont need to re-check the TypeErrors/bad ids, # because the other functions use the same hidden method as rotate_cells assert np.all(openmc.lib.cells[2].translation == (0., 0., 0.)) test_model.translate_cells([2], (0, 0, 10)) assert np.all(openmc.lib.cells[2].translation == (0., 0., 10.)) # Now lets do the density updates. # Check initial conditions assert openmc.lib.materials[1].get_density('atom/b-cm') == \ pytest.approx(0.06891296988603757, abs=1e-13) mat_a_dens = np.sum([ v[1] for v in test_model.materials[0].get_nuclide_atom_densities().values() ]) assert mat_a_dens == pytest.approx(0.06891296988603757, abs=1e-8) # Change the density test_model.update_densities(['UO2'], 2.) assert openmc.lib.materials[1].get_density('atom/b-cm') == \ pytest.approx(2., abs=1e-13) mat_a_dens = np.sum([ v[1] for v in test_model.materials[0].get_nuclide_atom_densities().values() ]) assert mat_a_dens == pytest.approx(2., abs=1e-8) # Now lets do the cell temperature updates. # Check initial conditions 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]} assert openmc.lib.cells[3].get_temperature() == \ pytest.approx(293.6, abs=1e-13) assert test_model.geometry.root_universe.cells[3].temperature is None # Change the temperature test_model.update_cell_temperatures([3], 600.) assert openmc.lib.cells[3].get_temperature() == \ pytest.approx(600., abs=1e-13) assert test_model.geometry.root_universe.cells[3].temperature == \ pytest.approx(600., abs=1e-13) # And finally material volume assert openmc.lib.materials[1].volume == \ pytest.approx(0.4831931368640985, abs=1e-13) # The temperature on the material will be None because its just the default assert test_model.materials[0].volume == \ pytest.approx(0.4831931368640985, abs=1e-13) # Change the temperature test_model.update_material_volumes(['UO2'], 2.) assert openmc.lib.materials[1].volume == pytest.approx(2., abs=1e-13) assert test_model.materials[0].volume == pytest.approx(2., abs=1e-13) test_model.finalize_lib()
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 test_full(run_in_tmpdir, problem, multiproc): """Full system test suite. Runs an entire OpenMC simulation with depletion coupling and verifies that the outputs match a reference file. Sensitive to changes in OpenMC. This test runs a complete OpenMC simulation and tests the outputs. It will take a while. """ geometry, lower_left, upper_right = problem # OpenMC-specific settings settings = openmc.Settings() settings.particles = 100 settings.batches = 10 settings.inactive = 0 space = openmc.stats.Box(lower_left, upper_right) settings.source = openmc.Source(space=space) settings.seed = 1 settings.verbosity = 1 model = openmc.Model(geometry=geometry, settings=settings) # Create operator chain_file = Path(__file__).parents[2] / 'chain_simple.xml' op = openmc.deplete.Operator(model, chain_file) op.round_number = True # Power and timesteps dt1 = 15. * 24 * 60 * 60 # 15 days dt2 = 1.5 * 30 * 24 * 60 * 60 # 1.5 months N = floor(dt2 / dt1) dt = np.full(N, dt1) power = 2.337e15 * 4 * JOULE_PER_EV * 1e6 # MeV/second cm from CASMO # Perform simulation using the predictor algorithm openmc.deplete.pool.USE_MULTIPROCESSING = multiproc openmc.deplete.PredictorIntegrator(op, dt, power).integrate() # Get path to test and reference results path_test = op.output_dir / 'depletion_results.h5' path_reference = Path(__file__).with_name('test_reference.h5') # If updating results, do so and return if config['update']: shutil.copyfile(str(path_test), str(path_reference)) return # Load the reference/test results res_test = openmc.deplete.ResultsList.from_hdf5(path_test) res_ref = openmc.deplete.ResultsList.from_hdf5(path_reference) # Assert same mats for mat in res_ref[0].mat_to_ind: assert mat in res_test[0].mat_to_ind, \ "Material {} not in new results.".format(mat) for nuc in res_ref[0].nuc_to_ind: assert nuc in res_test[0].nuc_to_ind, \ "Nuclide {} not in new results.".format(nuc) for mat in res_test[0].mat_to_ind: assert mat in res_ref[0].mat_to_ind, \ "Material {} not in old results.".format(mat) for nuc in res_test[0].nuc_to_ind: assert nuc in res_ref[0].nuc_to_ind, \ "Nuclide {} not in old results.".format(nuc) tol = 1.0e-6 for mat in res_test[0].mat_to_ind: for nuc in res_test[0].nuc_to_ind: _, y_test = res_test.get_atoms(mat, nuc) _, y_old = res_ref.get_atoms(mat, nuc) # Test each point correct = True for i, ref in enumerate(y_old): if ref != y_test[i]: if ref != 0.0: correct = np.abs(y_test[i] - ref) / ref <= tol else: correct = False assert correct, "Discrepancy in mat {} and nuc {}\n{}\n{}".format( mat, nuc, y_old, y_test) # Compare statepoint files with depletion results t_test, k_test = res_test.get_eigenvalue() t_ref, k_ref = res_ref.get_eigenvalue() k_state = np.empty_like(k_ref) n_tallies = np.empty(N + 1, dtype=int) # Get statepoint files for all BOS points and EOL for n in range(N + 1): statepoint = openmc.StatePoint("openmc_simulation_n{}.h5".format(n)) k_n = statepoint.k_combined k_state[n] = [k_n.nominal_value, k_n.std_dev] n_tallies[n] = len(statepoint.tallies) # Look for exact match pulling from statepoint and depletion_results assert np.all(k_state == k_test) assert np.allclose(k_test, k_ref) # Check that no additional tallies are loaded from the files assert np.all(n_tallies == 0)
# Create an initial uniform spatial source distribution over fissionable zones bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1] uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True) settings.source = openmc.source.Source(space=uniform_dist) entropy_mesh = openmc.RegularMesh() entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50] entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50] entropy_mesh.dimension = [10, 10, 1] settings.entropy_mesh = entropy_mesh ############################################################################### # Initialize and run depletion calculation ############################################################################### model = openmc.Model(geometry=geometry, settings=settings) # Create depletion "operator" chain_file = 'chain_simple.xml' op = openmc.deplete.Operator(model, chain_file) # Perform simulation using the predictor algorithm time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days power = 174 # W/cm, for 2D simulations only (use W for 3D) integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power, timestep_units='d') integrator.integrate() ############################################################################### # Read depletion calculation results ###############################################################################