def step1(): config = ConfigParser.ConfigParser() config.read(config_filename) structured = config.getboolean("general", "structured") sub_voxel = config.getboolean("general", "sub_voxel") meshtal = config.get("step1", "meshtal") tally_num = config.getint("step1", "tally_num") flux_tag = config.get("step1", "flux_tag") decay_times = config.get("step2", "decay_times").split(",") geom = config.get("step1", "geom") reverse = config.getboolean("step1", "reverse") num_rays = config.getint("step1", "num_rays") grid = config.getboolean("step1", "grid") load(geom) # get meshtal info from meshtal file flux_mesh = resolve_mesh(meshtal, tally_num, flux_tag) # create the cell_fracs array before irradiation_steup if flux_mesh.structured: cell_fracs = discretize_geom(flux_mesh, num_rays=num_rays, grid=grid) # tag cell fracs for both default and subvoxel r2s modes flux_mesh.tag_cell_fracs(cell_fracs) else: cell_fracs = discretize_geom(flux_mesh) cell_mats = cell_materials(geom) irradiation_setup( flux_mesh, cell_mats, cell_fracs, alara_params_filename, tally_num, num_rays=num_rays, grid=grid, reverse=reverse, flux_tag=flux_tag, decay_times=decay_times, sub_voxel=sub_voxel, ) # create a blank mesh for step 2: ves = list(flux_mesh.iter_ve()) tags_keep = ( "cell_number", "cell_fracs", "cell_largest_frac_number", "cell_largest_frac", ) for tag in flux_mesh.get_all_tags(): if tag.name not in tags_keep and isinstance(tag, NativeMeshTag): tag.delete() flux_mesh.write_hdf5("blank_mesh.h5m") print("The file blank_mesh.h5m has been saved to disk.") print("Do not delete this file; it is needed by r2s.py step2.\n") print("R2S step1 complete, run ALARA with the command:") print(">> alara alara_inp > output.txt")
def step1(): config = ConfigParser.ConfigParser() config.read(config_filename) structured = config.getboolean("general", "structured") meshtal = config.get("step1", "meshtal") tally_num = config.getint("step1", "tally_num") flux_tag = config.get("step1", "flux_tag") decay_times = config.get("step2", "decay_times").split(",") geom = config.get("step1", "geom") reverse = config.getboolean("step1", "reverse") num_rays = config.getint("step1", "num_rays") grid = config.getboolean("step1", "grid") responses = config.get("general", "responses").split(",") wdr_file = config.get("general", "wdr_file") load(geom) # get meshtal info from meshtal file flux_mesh = resolve_mesh(meshtal, tally_num, flux_tag) # create the cell_fracs array before irradiation_steup if flux_mesh.structured: cell_fracs = discretize_geom(flux_mesh, num_rays=num_rays, grid=grid) else: cell_fracs = discretize_geom(flux_mesh) cell_mats = cell_materials(geom) irradiation_setup( flux_mesh, cell_mats, cell_fracs, alara_params_filename, tally_num, num_rays=num_rays, grid=grid, reverse=reverse, output_mesh="activation_responses_step1.h5m", flux_tag=flux_tag, decay_times=decay_times, sub_voxel=False, responses=responses, wdr_file=wdr_file, ) # create a blank mesh for step 2: ves = list(flux_mesh.iter_ve()) for tag in flux_mesh.get_all_tags(): tag.delete() flux_mesh.write_hdf5("blank_mesh.h5m") print("The file blank_mesh.h5m has been saved to disk.") print( "Do not delete this file; it is needed by activation_responses.py step2.\n" ) print("Decay_heat step1 complete, run ALARA with the command:") print(">> alara alara_inp > output.txt")
def step1(): config = ConfigParser.ConfigParser() config.read(config_filename) structured = config.getboolean('general', 'structured') meshtal = config.get('step1', 'meshtal') tally_num = config.getint('step1', 'tally_num') flux_tag = config.get('step1', 'flux_tag') decay_times = config.get('step2', 'decay_times').split(',') geom = config.get('step1', 'geom') reverse = config.getboolean('step1', 'reverse') num_rays = config.getint('step1', 'num_rays') grid = config.getboolean('step1', 'grid') responses = config.get('general', 'responses').split(',') wdr_file = config.get('general', 'wdr_file') load(geom) # get meshtal info from meshtal file flux_mesh = resolve_mesh(meshtal, tally_num, flux_tag) # create the cell_fracs array before irradiation_steup if flux_mesh.structured: cell_fracs = discretize_geom(flux_mesh, num_rays=num_rays, grid=grid) else: cell_fracs = discretize_geom(flux_mesh) cell_mats = cell_materials(geom) irradiation_setup(flux_mesh, cell_mats, cell_fracs, alara_params_filename, tally_num, num_rays=num_rays, grid=grid, reverse=reverse, output_mesh="activation_responses_step1.h5m", flux_tag=flux_tag, decay_times=decay_times, sub_voxel=False, responses=responses, wdr_file=wdr_file) # create a blank mesh for step 2: ves = list(flux_mesh.iter_ve()) for tag in flux_mesh.get_all_tags(): tag.delete() flux_mesh.write_hdf5('blank_mesh.h5m') print('The file blank_mesh.h5m has been saved to disk.') print( 'Do not delete this file; it is needed by activation_responses.py step2.\n' ) print('Decay_heat step1 complete, run ALARA with the command:') print('>> alara alara_inp > output.txt')
def step1(): config = ConfigParser.ConfigParser() config.read(config_filename) structured = config.getboolean('general', 'structured') sub_voxel = config.getboolean('general', 'sub_voxel') meshtal = config.get('step1', 'meshtal') tally_num = config.getint('step1', 'tally_num') flux_tag = config.get('step1', 'flux_tag') decay_times = config.get('step2', 'decay_times').split(',') geom = config.get('step1', 'geom') reverse = config.getboolean('step1', 'reverse') num_rays = config.getint('step1', 'num_rays') grid = config.getboolean('step1', 'grid') load(geom) # get meshtal info from meshtal file flux_mesh = resolve_mesh(meshtal, tally_num, flux_tag) # create the cell_fracs array before irradiation_steup if flux_mesh.structured: cell_fracs = discretize_geom(flux_mesh, num_rays=num_rays, grid=grid) # tag cell fracs for both default and subvoxel r2s modes flux_mesh.tag_cell_fracs(cell_fracs) else: cell_fracs = discretize_geom(flux_mesh) cell_mats = cell_materials(geom) irradiation_setup(flux_mesh, cell_mats, cell_fracs, alara_params_filename, tally_num, num_rays=num_rays, grid=grid, reverse=reverse, flux_tag=flux_tag, decay_times=decay_times, sub_voxel=sub_voxel) # create a blank mesh for step 2: ves = list(flux_mesh.iter_ve()) tags_keep = ("cell_number", "cell_fracs", "cell_largest_frac_number", "cell_largest_frac") for tag in flux_mesh.get_all_tags(): if tag.name not in tags_keep and isinstance(tag, NativeMeshTag): tag.delete() flux_mesh.write_hdf5('blank_mesh.h5m') print('The file blank_mesh.h5m has been saved to disk.') print('Do not delete this file; it is needed by r2s.py step2.\n') print('R2S step1 complete, run ALARA with the command:') print('>> alara alara_inp > output.txt')
def discretize_geom_mix(): from pyne import dagmc dagmc.load(path) coords = [0, 1] coords2 = [0, 2] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) results1 = dagmc.discretize_geom(mesh, num_rays=100, grid=True) # To to make sure standard error decreases with increasing rays results2 = dagmc.discretize_geom(mesh, num_rays=625, grid=True) return [results1, results2]
def discretize_geom_grid(): from pyne import dagmc dagmc.load(path) coords = [-4, -1, 1, 4] mesh = Mesh(structured=True, structured_coords=[coords, coords, coords]) results = dagmc.discretize_geom(mesh, num_rays=49, grid=True) return [results, coords]
def discretize_geom_mix(): from pyne import dagmc dagmc.load(path) coords = [0, 1] coords2 = [0, 2] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) results1 = dagmc.discretize_geom(mesh, num_rays=100, grid=True) assert_equal(results1[0]['cell'], 2) assert_almost_equal(results1[0]['vol_frac'], 0.5) assert_equal(results1[1]['cell'], 3) assert_almost_equal(results1[1]['vol_frac'], 0.5) # To to make sure standard error decreases with increasing rays results2 = dagmc.discretize_geom(mesh, num_rays=625, grid=True) assert (results2[0]['rel_error'] < results1[0]['rel_error']) assert (results2[1]['rel_error'] < results1[1]['rel_error'])
def discretize_geom_mix(): from pyne import dagmc dagmc.load(path) coords = [0, 1] coords2 = [0, 2] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) results1 = dagmc.discretize_geom(mesh, num_rays=100, grid=True) assert_equal(results1[0]['cell'], 2) assert_almost_equal(results1[0]['vol_frac'], 0.5) assert_equal(results1[1]['cell'], 3) assert_almost_equal(results1[1]['vol_frac'], 0.5) # To to make sure standard error decreases with increasing rays results2 = dagmc.discretize_geom(mesh, num_rays=625, grid=True) assert(results2[0]['rel_error'] < results1[0]['rel_error']) assert(results2[1]['rel_error'] < results1[1]['rel_error'])
def test_discretize_geom_mix(self): """Single mesh volume element that is a 50:50 split of geometry volumes 2 and 3. """ if not HAVE_IMESH: raise SkipTest coords = [0, 1] coords2 = [0, 2] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) results1 = dagmc.discretize_geom(mesh, num_rays=100, grid=True) assert_equal(results1[0]['cell'], 2) assert_almost_equal(results1[0]['vol_frac'], 0.5) assert_equal(results1[1]['cell'], 3) assert_almost_equal(results1[1]['vol_frac'], 0.5) # To to make sure standard error decreases with increasing rays results2 = dagmc.discretize_geom(mesh, num_rays=625, grid=True) assert (results2[0]['rel_error'] < results1[0]['rel_error']) assert (results2[1]['rel_error'] < results1[1]['rel_error'])
def test_discretize_geom_mix(self): """Single mesh volume element that is a 50:50 split of geometry volumes 2 and 3. """ if not HAVE_IMESH: raise SkipTest coords = [0, 1] coords2 = [0, 2] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) results1 = dagmc.discretize_geom(mesh, num_rays=100, grid=True) assert_equal(results1[0]['cell'], 2) assert_almost_equal(results1[0]['vol_frac'], 0.5) assert_equal(results1[1]['cell'], 3) assert_almost_equal(results1[1]['vol_frac'], 0.5) # To to make sure standard error decreases with increasing rays results2 = dagmc.discretize_geom(mesh, num_rays=625, grid=True) assert(results2[0]['rel_error'] < results1[0]['rel_error']) assert(results2[1]['rel_error'] < results1[1]['rel_error'])
def discretize_geom_grid(): from pyne import dagmc dagmc.load(path) coords = [-4, -1, 1, 4] mesh = Mesh(structured=True, structured_coords=[coords, coords, coords]) results = dagmc.discretize_geom(mesh, num_rays=49, grid=True) assert_equal(len(results), (len(coords) - 1)**3) for res in results: if res['idx'] != 13: assert_equal(res['cell'], 3) else: assert_equal(res['cell'], 2) assert_almost_equal(res['vol_frac'], 1.0)
def test_discretize_geom_grid(self): """The 14th (index 13) mesh volume element fully contains volume 2. Use grid sampling. """ if not HAVE_IMESH: raise SkipTest coords = [-4, -1, 1, 4] mesh = Mesh(structured=True, structured_coords=[coords, coords, coords]) results = dagmc.discretize_geom(mesh, num_rays=49, grid=True) assert_equal(len(results), (len(coords) - 1)**3) for res in results: if res['idx'] != 13: assert_equal(res['cell'], 3) else: assert_equal(res['cell'], 2) assert_almost_equal(res['vol_frac'], 1.0)
def discretize_geom_centers(): from pyne import dagmc dagmc.load(path) coords = [0, 1] coords2 = [0, 2, 4] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) # explicitly set to unstructured to trigger the ve centers sampling # method mesh.structured = False res = dagmc.discretize_geom(mesh) assert_array_equal(res["idx"], [0, 1]) assert_array_equal(res["cell"], [2, 3]) assert_array_equal(res["vol_frac"], [1.0, 1.0]) assert_array_equal(res["rel_error"], [1.0, 1.0]) # ensure kwargs are not accepted for unstructured mesh assert_raises(ValueError, dagmc.discretize_geom, mesh, num_rays=3, grid=True)
def test_discretize_geom_centers(self): """Test that unstructured mesh is sampled by mesh ve centers. """ if not HAVE_IMESH: raise SkipTest coords = [0, 1] coords2 = [0, 2, 4] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) # explicitly set to unstructured to trigger the ve centers sampling # method mesh.structured = False res = dagmc.discretize_geom(mesh) assert_array_equal(res["idx"], [0, 1]) assert_array_equal(res["cell"], [2, 3]) assert_array_equal(res["vol_frac"], [1.0, 1.0]) assert_array_equal(res["rel_error"], [1.0, 1.0]) # ensure kwargs are not accepted for unstructured mesh assert_raises(ValueError, dagmc.discretize_geom, mesh, num_rays=3, grid=True)
def discretize_geom_centers(): from pyne import dagmc dagmc.load(path) coords = [0, 1] coords2 = [0, 2, 4] mesh = Mesh(structured=True, structured_coords=[coords2, coords, coords]) # explicitly set to unstructured to trigger the ve centers sampling # method mesh.structured = False res = dagmc.discretize_geom(mesh) # ensure kwargs are not accepted for unstructured mesh # if assert_raises is True, then k will be None, else a fail will occur k = assert_raises(ValueError, dagmc.discretize_geom, mesh, num_rays=3, grid=True) return [res, k]
def _get_zones(mesh, hdf5, bounds, num_rays, grid): """Get the minimum zone definitions for the geometry. """ # load the geometry from pyne import dagmc dagmc.load(hdf5) # Descretize the geometry and get cell fractions dg = dagmc.discretize_geom(mesh, num_rays=num_rays, grid=grid) # Reorganize dictionary of each voxel's info with the key the voxel number # and values of cell and volume fraction voxel = {} for i in dg: idx = i[0] # voxel number if idx not in voxel: voxel[idx] = {} voxel[idx]['cell'] = [] voxel[idx]['vol_frac'] = [] voxel[idx]['cell'].append(i[1]) voxel[idx]['vol_frac'].append(i[2]) # get material to cell assignments mat_assigns = dagmc.cell_material_assignments(hdf5) # Replace cell numbers with materials, eliminating duplicate materials # within single zone definition zones = {} for z in voxel: zones[z] = {} zones[z]['vol_frac'] = [] zones[z]['mat'] = [] for i, cell in enumerate(voxel[z]['cell']): if mat_assigns[cell] not in zones[z]['mat']: # create new entry zones[z]['mat'].append(mat_assigns[cell]) zones[z]['vol_frac'].append(voxel[z]['vol_frac'][i]) else: # update value that already exists with new volume fraction for j, val in enumerate(zones[z]['mat']): if mat_assigns[cell] == val: vol_frac = zones[z]['vol_frac'][j] + voxel[z]['vol_frac'][i] zones[z]['vol_frac'][j] = vol_frac # Remove vacuum or graveyard from material definition if not vol_frac of 1.0 skip_array = [['mat:Vacuum'], ['mat:vacuum'], ['mat:Graveyard'], ['mat:graveyard']] skip_list = ['mat:Vacuum', 'mat:vacuum', 'mat:Graveyard', 'mat:graveyard'] zones_compressed = {} for z, info in zones.iteritems(): # check first if the definition is 100% void, keep same if is if zones[z]['mat'] in skip_array and zones[z]['vol_frac'] == [1.0]: zones_compressed[z] = info else: # check for partial void zones_compressed[z] = {'mat':[], 'vol_frac':[]} for i, mat in enumerate(zones[z]['mat']): if mat not in skip_list: zones_compressed[z]['mat'].append(mat) zones_compressed[z]['vol_frac'].append(zones[z]['vol_frac'][i]) # Eliminate duplicate zones and assign each voxel a zone number. # Assign zone = 0 if vacuum or graveyard and eliminate material definition. voxel_zone = {} zones_mats = {} z = 0 match = False first = True for i, vals in zones_compressed.iteritems(): # Find if the zone already exists for zone, info in zones_mats.iteritems(): # Iterate through both sets to disregard order match_all = np.empty(len(vals['mat']), dtype=bool) match_all.fill(False) for ii, mat in enumerate(vals['mat']): for jj, mat_info in enumerate(info['mat']): if mat == mat_info and np.allclose(np.array(vals['vol_frac'][ii]), \ np.array(info['vol_frac'][jj]), rtol=1e-5): match_all[ii] = True break if match_all.all() == True: match = True y = zone break else: match = False # Create a new zone if first zone or does not match other zones if first or not match: # Check that the material is not 100% void (assign zone 0 otherwise) if vals['mat'] in skip_array: voxel_zone[i] = 0 else: z += 1 zones_mats[z] = zones_compressed[i] voxel_zone[i] = z first = False else: if vals['mat'] in skip_array: voxel_zone[i] = 0 else: voxel_zone[i] = y # Remove any instances of graveyard or vacuum in zone definitions zones_novoid = {} for z in zones_mats: zones_novoid[z] = {'mat':[], 'vol_frac':[]} for i, mat in enumerate(zones_mats[z]['mat']): if mat not in skip_list: name = strip_mat_name(mat) zones_novoid[z]['mat'].append(name) zones_novoid[z]['vol_frac'].append(zones_mats[z]['vol_frac'][i]) # Put zones into format for PARTISN input if 'x' in bounds: im = len(bounds['x']) - 1 else: im = 1 if 'y' in bounds: jm = len(bounds['y']) - 1 else: jm = 1 if 'z' in bounds: km = len(bounds['z']) - 1 else: km = 1 n = 0 zones_formatted = np.zeros(shape=(jm*km, im), dtype=int) for i in range(im): for jk in range(jm*km): zones_formatted[jk, i] = voxel_zone[n] n += 1 return zones_formatted, zones_novoid
speed.append(float(split_str[6])) return xyz,direction,speed (xyz,direction,speed) = load_input_file("input.txt") mesh = Mesh(mesh="../geom/conv_pipe_mesh.h5m") # load dag geometry load("../geom/conv_pipe_geom.h5m") # discretise geom onto mesh cell_fracs = discretize_geom(mesh) mesh.vol_id = IMeshTag(1,int) mesh.source_strength = IMeshTag(1,float) id_list = [] for element in cell_fracs: id_list.append(element["cell"]) mesh.vol_id[:]=id_list # loop along path, use point in volume to determine the vol id volumes = get_all_cells(xyz,direction,speed) # loop along path, use point in volume to determine the vol id # but tag each tet in the range with right source strength
def isotropic_vol_source(geom, mesh, cells, spectra, intensities, **kwargs): """This function creates an isotropic volumetric source within each requested geometry cell of a DAGMC CAD geometry. This is done by Monte Carlo ray tracing to determine volume fractions of each source cell within each mesh volume element. The PARTISN SOURCF card is returned, as well as the ray-traced volume fractions (dagmc.discretize_geom output), so that ray tracing does not have to be done twice when using this function with write_partisn_input. The supplied mesh is also tagged with the calculated source distribution using this function. Parameters: ----------- geom : str The DAGMC geometry (.h5m) file containing the geometry of interest. mesh : PyNE Mesh The superimposed Cartesian mesh that will be used to define the source for PARTISN transport. cells : list of ints The cell numbers of DAGMC geometry cells which have non-zero source intensity. spectra : list of list of floats The normalized energy spectrum for each of the cells. If spectra are not normalized, they will be normalized in this function. intensities : list of floats The volumetric intensity (i.e. s^-1 cm^-3) for each geometry cell. tag_name : str, optional, default = 'src' The name of the tag for which source data will be tagged on the mesh. num_rays : int, optional, default = 10 For discretize_geom. The number of rays to fire in each mesh row for each direction. grid : boolean, optional, default = False For discretize_geom. If false, rays starting points are chosen randomly (on the boundary) for each mesh row. If true, a linearly spaced grid of starting points is used, with dimension sqrt(num_rays) x sqrt(num_rays). In this case, "num_rays" must be a perfect square. Returns: -------- output : str PARTISN SOURF card representing the requested source dg : record array The output of dagmc.discretize_geom; stored in a one dimensional array, each entry containing the following fields: :idx: int The volume element index. :cell: int The geometry cell number. :vol_frac: float The volume fraction of the cell withing the mesh ve. :rel_error: float The relative error associated with the volume fraction. This array is returned in sorted order with respect to idx and cell, with cell changing fastest. """ # discretize_geom inputs tag_name = kwargs.get("tag_name", "src") num_rays = kwargs.get("num_rays", 10) grid = kwargs.get("grid", False) # Check lengths of input if len(cells) != len(spectra) or len(cells) != len(intensities): raise ValueError("Cells, spectra, intensities must be the same length") lengths = [len(x) for x in spectra] if not all(lengths[0] == length for length in lengths): raise ValueError("Spectra must all be the same length") # Normalize spectra norm_spectra = [] for spec in spectra: total = np.sum(spec) norm_spectra.append(np.array(spec) / total) norm_spectra = {cell: spec for cell, spec in zip(cells, norm_spectra)} intensities = {cell: inten for cell, inten in zip(cells, intensities)} # ray trace if not HAVE_DAGMC: raise RuntimeError("DAGMC is not available." "Cannot run isotropic_vol_source().") else: dagmc.load(geom) dg = dagmc.discretize_geom(mesh, num_rays=num_rays, grid=grid) # determine source intensities data = np.zeros(shape=(len(mesh), len(spectra[0]))) for row in dg: if row[1] in cells: data[row[0], :] += np.multiply(row[2] * intensities[row[1]], norm_spectra[row[1]]) mesh.tag = NativeMeshTag(len(spectra[0]), float, name=tag_name) mesh.tag[:] = data output = mesh_to_isotropic_source(mesh, tag_name) return output, dg
def _get_zones(mesh, hdf5, bounds, num_rays, grid, dg, mat_assigns, unique_names): """Get the minimum zone definitions for the geometry.""" # Discretize the geometry and get cell fractions if dg is None: if not HAVE_DAGMC: raise RuntimeError("DAGMC is not available." "Unable to discretize the geometry.") else: dagmc.load(hdf5) dg = dagmc.discretize_geom(mesh, num_rays=num_rays, grid=grid) # Reorganize dictionary of each voxel's info with the key the voxel number # and values of cell and volume fraction voxel = {} for i in dg: idx = i[0] # voxel number if idx not in voxel: voxel[idx] = {} voxel[idx]["cell"] = [] voxel[idx]["vol_frac"] = [] voxel[idx]["cell"].append(i[1]) voxel[idx]["vol_frac"].append(i[2]) # get material to cell assignments if mat_assigns is None: if not HAVE_DAGMC: raise RuntimeError("DAGMC is not available." "Unable to get cell material assignments.") else: mat_assigns = dagmc.cell_material_assignments(hdf5) # Replace the names in the material assignments with unique names temp = {} for i, name in mat_assigns.items(): if "vacuum" in name.lower() or "graveyard" in name.lower(): temp[i] = name else: temp[i] = unique_names[name] mat_assigns = temp # Replace cell numbers with materials, eliminating duplicate materials # within single zone definition zones = {} for z in voxel: zones[z] = {} zones[z]["vol_frac"] = [] zones[z]["mat"] = [] for i, cell in enumerate(voxel[z]["cell"]): if mat_assigns[cell] not in zones[z]["mat"]: # create new entry zones[z]["mat"].append(mat_assigns[cell]) zones[z]["vol_frac"].append(voxel[z]["vol_frac"][i]) else: # update value that already exists with new volume fraction for j, val in enumerate(zones[z]["mat"]): if mat_assigns[cell] == val: vol_frac = zones[z]["vol_frac"][j] + voxel[z][ "vol_frac"][i] zones[z]["vol_frac"][j] = vol_frac # Remove vacuum or graveyard from material definition if not vol_frac of 1.0 skip_array = [["mat:Vacuum"], ["mat:vacuum"], ["mat:Graveyard"], ["mat:graveyard"]] skip_list = ["mat:Vacuum", "mat:vacuum", "mat:Graveyard", "mat:graveyard"] zones_compressed = {} for z, info in zones.items(): # check first if the definition is 100% void, keep same if is if zones[z]["mat"] in skip_array and zones[z]["vol_frac"] == [1.0]: zones_compressed[z] = info else: # check for partial void zones_compressed[z] = {"mat": [], "vol_frac": []} for i, mat in enumerate(zones[z]["mat"]): if mat not in skip_list: zones_compressed[z]["mat"].append(mat) zones_compressed[z]["vol_frac"].append( zones[z]["vol_frac"][i]) # Eliminate duplicate zones and assign each voxel a zone number. # Assign zone = 0 if vacuum or graveyard and eliminate material definition. voxel_zone = {} zones_mats = {} z = 0 match = False first = True for i, vals in zones_compressed.items(): # Find if the zone already exists for zone, info in zones_mats.items(): # Iterate through both sets to disregard order match_all = np.empty(len(vals["mat"]), dtype=bool) match_all.fill(False) for ii, mat in enumerate(vals["mat"]): for jj, mat_info in enumerate(info["mat"]): if mat == mat_info and np.allclose( np.array(vals["vol_frac"][ii]), np.array(info["vol_frac"][jj]), rtol=1e-5, ): match_all[ii] = True break if match_all.all() == True: match = True y = zone break else: match = False # Create a new zone if first zone or does not match other zones if first or not match: # Check that the material is not 100% void (assign zone 0 otherwise) if vals["mat"] in skip_array: voxel_zone[i] = 0 else: z += 1 zones_mats[z] = zones_compressed[i] voxel_zone[i] = z first = False else: if vals["mat"] in skip_array: voxel_zone[i] = 0 else: voxel_zone[i] = y # Remove any instances of graveyard or vacuum in zone definitions zones_novoid = {} for z in zones_mats: zones_novoid[z] = {"mat": [], "vol_frac": []} for i, mat in enumerate(zones_mats[z]["mat"]): if mat not in skip_list: zones_novoid[z]["mat"].append(mat) zones_novoid[z]["vol_frac"].append( zones_mats[z]["vol_frac"][i]) # Put zones into format for PARTISN input if "x" in bounds: im = len(bounds["x"]) - 1 else: im = 1 if "y" in bounds: jm = len(bounds["y"]) - 1 else: jm = 1 if "z" in bounds: km = len(bounds["z"]) - 1 else: km = 1 n = 0 zones_formatted = np.zeros(shape=(jm * km, im), dtype=int) for i in range(im): temp = np.zeros(shape=(jm * km), dtype=int) for jk in range(jm * km): temp[jk] = voxel_zone[n] n += 1 temp = np.reshape(temp, (jm, km)) temp = np.transpose(temp) temp = np.reshape(temp, jm * km) zones_formatted[:, i] = temp return zones_formatted, zones_novoid
def irradiation_setup(flux_mesh, cell_mats, alara_params, tally_num=4, geom=None, num_rays=10, grid=False, flux_tag="n_flux", fluxin="alara_fluxin", reverse=False, alara_inp="alara_geom", alara_matlib="alara_matlib", output_mesh="r2s_step1.h5m", output_material=False): """This function is used to setup the irradiation inputs after the first R2S transport step. Parameters ---------- flux_mesh : PyNE Meshtal object, Mesh object, or str The source of the neutron flux information. This can be a PyNE Meshtal object, a pyne Mesh object, or the filename an MCNP meshtal file, or the filename of an unstructured mesh tagged with fluxes. tally_num : int The MCNP FMESH4 tally number of the neutron flux tally within the meshtal file. cell_mats : dict Maps geometry cell numbers to PyNE Material objects. alara_params : str The ALARA input blocks specifying everything except the geometry and materials. This can either be passed as string or as a file name. geom : str, optional The file name of a DAGMC-loadable faceted geometry. This is only necessary if the geometry is not already loaded into memory. num_rays : int, optional The number of rays to fire down a mesh row for geometry discretization. This number must be a perfect square if grid=True. grid : bool, optional The if False, geometry discretization will be done with randomly fired rays. If true, a grid of sqrt(num_rays) x sqrt(num_rays) rays is used for each mesh row. flux_tag : str, optional The iMesh tag for the neutron flux. fluxin : str, optional The name of the ALARA fluxin file to be created. reverse : bool, optional If True the fluxes in the fluxin file will be printed in the reverse order of how they appear within the flux vector tag. Since MCNP and the Meshtal class order fluxes from low energy to high energy, this option should only be true if the transmutation data being used is ordered from high energy to low energy. alara_inp : str, optional The name of the ALARA input file to be created. alara_matlib : str, optional The name of the alara_matlib file to be created. output_mesh : str, optional A mesh containing all the fluxes and materials used for irradiation setup. output_material : bool, optional If true, output mesh will have materials as determined by dagmc.discretize_geom() """ from pyne.dagmc import load, discretize_geom if geom is not None and isfile(geom): load(geom) # flux_mesh is Mesh object if isinstance(flux_mesh, Mesh): m = flux_mesh # flux_mesh is unstructured mesh file elif isinstance(flux_mesh, str) and isfile(flux_mesh) \ and flux_mesh.endswith(".h5m"): m = Mesh(structured=False, mesh=flux_mesh) # flux_mesh is Meshtal or meshtal file else: # flux_mesh is meshtal file if isinstance(flux_mesh, str) and isfile(flux_mesh): flux_mesh = Meshtal(flux_mesh, {tally_num: (flux_tag, flux_tag + "_err", flux_tag + "_total", flux_tag + "_err_total")}, meshes_have_mats=output_material) m = flux_mesh.tally[tally_num] # flux_mesh is Meshtal object elif isinstance(flux_mesh, Meshtal): m = flux_mesh.tally[tally_num] else: raise ValueError("meshtal argument not a Mesh object, Meshtal" " object, MCNP meshtal file or meshtal.h5m file.") if m.structured: cell_fracs = discretize_geom(m, num_rays=num_rays, grid=grid) else: cell_fracs = discretize_geom(m) if output_material: m.cell_fracs_to_mats(cell_fracs, cell_mats) mesh_to_fluxin(m, flux_tag, fluxin, reverse) record_to_geom(m, cell_fracs, cell_mats, alara_inp, alara_matlib) if isfile(alara_params): with open(alara_params, 'r') as f: alara_params = f.read() with open(alara_inp, 'a') as f: f.write("\n" + alara_params) m.write_hdf5(output_mesh)
def step5(cfg, cfg2, cfg5): """ This function creates the adjoint neutron source and writes the PARTISN input file for adjoint neutron transport. Parameters ---------- cfg : dictionary User input from 'general' section of config.yml file cfg2 : dictionary User input for step 2 from the config.yml file cfg5 : dictionary User input for step 3 from the config.yml file """ # Get user-input from config file num_n_groups = cfg['n_groups'] num_p_groups = cfg['p_groups'] n_geom = cfg2['n_geom_file'] decay_times = str(cfg2['decay_times']).split(' ') meshflux = cfg5['meshflux'] # Base of geometry file name basename = n_geom.split("/")[-1].split(".")[0] # The total number of photon and neutron energy groups total_num_groups = num_n_groups + num_p_groups # Read given flux file and tag to a mesh if meshflux: # Adjoint flux file is an hdf5 mesh file fw_n_err = meshflux m = Mesh(structured=True, mesh=fw_n_err, mats=None) else: raise RuntimeError("No neutron flux file given") # Size of flux tag is equal to the total number of energy groups m.ERROR_TAG = NativeMeshTag(num_n_groups, name="ERROR_TAG") fw_n_err = m.ERROR_TAG[:] # Load geometry and get material assignments load(n_geom) ml = MaterialLibrary(n_geom) mat_names = list(ml.keys()) cell_mats = cell_material_assignments(n_geom) # Load T matrix if not os.path.exists('step2_T.npy'): raise RuntimeError("T matrix from step 2 (step2_T.npy) not found") T = np.load('step2_T.npy') # Loop over mesh voxels and calculate the error in the photon source by multiplying neutron flux and T matrix dg = discretize_geom(m) for t, dt in enumerate(decay_times): temp = np.zeros(shape=(len(m), num_p_groups)) for i in range(len(m)): for row in np.atleast_1d(dg[dg["idx"] == i]): cell = row[1] if not cell_mats[cell] in mat_names: continue vol_frac = row[2] mat = mat_names.index(cell_mats[cell]) for h in range(num_p_groups): for g in range(num_n_groups): temp[i, h] += (fw_n_err[i, g]**2) * T[mat, t, g, h] * vol_frac print("err ", temp[i, h]) # Tag the mesh with the squared error in the photon source values tag_name = "sq_err_q_src_{0}".format(dt) m.err_q_src = NativeMeshTag(num_p_groups, name=tag_name) m.err_q_src[:] = temp # Save adjoint neutron source mesh file tagged with values for all decay times m.save("sq_err_q_src.h5m")
def irradiation_setup(flux_mesh, cell_mats, alara_params, tally_num=4, geom=None, num_rays=10, grid=False, flux_tag="n_flux", fluxin="alara_fluxin", reverse=False, alara_inp="alara_geom", alara_matlib="alara_matlib", output_mesh="r2s_step1.h5m"): """This function is used to setup the irradiation inputs after the first R2S transport step. Parameters ---------- flux_mesh : PyNE Meshtal object, Mesh object, or str The source of the neutron flux information. This can be a PyNE Meshtal object, a pyne Mesh object, or the filename an MCNP meshtal file, or the filename of an unstructured mesh tagged with fluxes. tally_num : int The MCNP FMESH4 tally number of the neutron flux tally within the meshtal file. cell_mats : dict Maps geometry cell numbers to PyNE Material objects. alara_params : str The ALARA input blocks specifying everything except the geometry and materials. This can either be passed as string or as a file name. geom : str, optional The file name of a DAGMC-loadable faceted geometry. This is only necessary if the geometry is not already loaded into memory. num_rays : int, optional The number of rays to fire down a mesh row for geometry discretization. This number must be a perfect square if grid=True. grid : bool, optional The if False, geometry discretization will be done with randomly fired rays. If true, a grid of sqrt(num_rays) x sqrt(num_rays) rays is used for each mesh row. flux_tag : str, optional The iMesh tag for the neutron flux. fluxin : str, optional The name of the ALARA fluxin file to be created. reverse : bool, optional If True the fluxes in the fluxin file will be printed in the reverse order of how they appear within the flux vector tag. Since MCNP and the Meshtal class order fluxes from low energy to high energy, this option should only be true if the transmutation data being used is ordered from high energy to low energy. alara_inp : str, optional The name of the ALARA input file to be created. alara_matlib : str, optional The name of the alara_matlib file to be created. output_mesh : str, optional A mesh containing all the fluxes and materials used for irradiation setup. """ if geom is not None and isfile(geom): load(geom) # flux_mesh is Mesh object if isinstance(flux_mesh, Mesh): m = flux_mesh # flux_mesh is unstructured mesh file elif isinstance(flux_mesh, str) and isfile(flux_mesh) \ and flux_mesh.endswith(".h5m"): m = Mesh(structured=False, mesh=flux_mesh) # flux_mesh is Meshtal or meshtal file else: # flux_mesh is meshtal file if isinstance(flux_mesh, str) and isfile(flux_mesh): flux_mesh = Meshtal(flux_mesh, { tally_num: (flux_tag, flux_tag + "_err", flux_tag + "_total", flux_tag + "_err_total") }, meshes_have_mats=True) m = flux_mesh.tally[tally_num] # flux_mesh is Meshtal object elif instance(flux_mesh, Meshtal): m = flux_mesh.tally[tally_num] else: raise ValueError("meshtal argument not a Mesh object, Meshtal" " object, MCNP meshtal file or meshtal.h5m file.") if m.structured: vol_fracs = discretize_geom(m, num_rays=num_rays, grid=grid) else: vol_fracs = discretize_geom(m) m.cell_fracs_to_mats(vol_fracs, cell_mats) mesh_to_fluxin(m, flux_tag, fluxin, reverse) mesh_to_geom(m, alara_inp, alara_matlib) if isfile(alara_params): with open(alara_params, 'r') as f: alara_params = f.read(alara_params) with open(alara_inp, 'a') as f: f.write("\n" + alara_params) m.write_hdf5(output_mesh)
def _get_zones(mesh, hdf5, bounds, num_rays, grid): """Get the minimum zone definitions for the geometry. """ # load the geometry from pyne import dagmc dagmc.load(hdf5) # Descretize the geometry and get cell fractions dg = dagmc.discretize_geom(mesh, num_rays=num_rays, grid=grid) # Reorganize dictionary of each voxel's info with the key the voxel number # and values of cell and volume fraction voxel = {} for i in dg: idx = i[0] # voxel number if idx not in voxel: voxel[idx] = {} voxel[idx]['cell'] = [] voxel[idx]['vol_frac'] = [] voxel[idx]['cell'].append(i[1]) voxel[idx]['vol_frac'].append(i[2]) # get material to cell assignments mat_assigns = dagmc.cell_material_assignments(hdf5) # Replace cell numbers with materials, eliminating duplicate materials # within single zone definition zones = {} for z in voxel: zones[z] = {} zones[z]['vol_frac'] = [] zones[z]['mat'] = [] for i, cell in enumerate(voxel[z]['cell']): if mat_assigns[cell] not in zones[z]['mat']: # create new entry zones[z]['mat'].append(mat_assigns[cell]) zones[z]['vol_frac'].append(voxel[z]['vol_frac'][i]) else: # update value that already exists with new volume fraction for j, val in enumerate(zones[z]['mat']): if mat_assigns[cell] == val: vol_frac = zones[z]['vol_frac'][j] + voxel[z][ 'vol_frac'][i] zones[z]['vol_frac'][j] = vol_frac # Remove vacuum or graveyard from material definition if not vol_frac of 1.0 skip_array = [['mat:Vacuum'], ['mat:vacuum'], ['mat:Graveyard'], ['mat:graveyard']] skip_list = ['mat:Vacuum', 'mat:vacuum', 'mat:Graveyard', 'mat:graveyard'] zones_compressed = {} for z, info in zones.iteritems(): # check first if the definition is 100% void, keep same if is if zones[z]['mat'] in skip_array and zones[z]['vol_frac'] == [1.0]: zones_compressed[z] = info else: # check for partial void zones_compressed[z] = {'mat': [], 'vol_frac': []} for i, mat in enumerate(zones[z]['mat']): if mat not in skip_list: zones_compressed[z]['mat'].append(mat) zones_compressed[z]['vol_frac'].append( zones[z]['vol_frac'][i]) # Eliminate duplicate zones and assign each voxel a zone number. # Assign zone = 0 if vacuum or graveyard and eliminate material definition. voxel_zone = {} zones_mats = {} z = 0 match = False first = True for i, vals in zones_compressed.iteritems(): # Find if the zone already exists for zone, info in zones_mats.iteritems(): # Iterate through both sets to disregard order match_all = np.empty(len(vals['mat']), dtype=bool) match_all.fill(False) for ii, mat in enumerate(vals['mat']): for jj, mat_info in enumerate(info['mat']): if mat == mat_info and np.allclose(np.array(vals['vol_frac'][ii]), \ np.array(info['vol_frac'][jj]), rtol=1e-5): match_all[ii] = True break if match_all.all() == True: match = True y = zone break else: match = False # Create a new zone if first zone or does not match other zones if first or not match: # Check that the material is not 100% void (assign zone 0 otherwise) if vals['mat'] in skip_array: voxel_zone[i] = 0 else: z += 1 zones_mats[z] = zones_compressed[i] voxel_zone[i] = z first = False else: if vals['mat'] in skip_array: voxel_zone[i] = 0 else: voxel_zone[i] = y # Remove any instances of graveyard or vacuum in zone definitions zones_novoid = {} for z in zones_mats: zones_novoid[z] = {'mat': [], 'vol_frac': []} for i, mat in enumerate(zones_mats[z]['mat']): if mat not in skip_list: name = strip_mat_name(mat) zones_novoid[z]['mat'].append(name) zones_novoid[z]['vol_frac'].append( zones_mats[z]['vol_frac'][i]) # Put zones into format for PARTISN input if 'x' in bounds: im = len(bounds['x']) - 1 else: im = 1 if 'y' in bounds: jm = len(bounds['y']) - 1 else: jm = 1 if 'z' in bounds: km = len(bounds['z']) - 1 else: km = 1 n = 0 zones_formatted = np.zeros(shape=(jm * km, im), dtype=int) for i in range(im): for jk in range(jm * km): zones_formatted[jk, i] = voxel_zone[n] n += 1 return zones_formatted, zones_novoid