def test_matlib(): mats = { 0: Material({ 'H1': 1.0, 'K39': 1.0 }, density=1.1), 1: Material({ 'H1': 0.1, 'O16': 1.0 }, density=2.2), 2: Material({'He4': 42.0}, density=3.3), 3: Material({'Tm171': 171.0}, density=4.4), } m = gen_mesh(mats=mats) for i, ve in enumerate(mesh_iterate(m.mesh)): assert_is(m.mats[i], mats[i]) assert_equal( m.mesh.tag_get_data(m.mesh.tag_get_handle('idx'), ve, flat=True)[0], i) m.write_hdf5('test_matlib.h5m') shutil.copy('test_matlib.h5m', 'test_matlib2.h5m') m2 = Mesh(mesh='test_matlib2.h5m') # MOAB fails to flush for i, mat, ve in m2: assert_equal(len(mat.comp), len(mats[i].comp)) for key in mats[i].iterkeys(): assert_equal(mat.comp[key], mats[i].comp[key]) assert_equal(mat.density, mats[i].density) assert_equal(m2.idx[i], i)
def cadis(adj_flux_mesh, adj_flux_tag, q_mesh, q_tag, ww_mesh, ww_tag, q_bias_mesh, q_bias_tag, beta=5): """This function reads PyNE Mesh objects tagged with adjoint fluxes and unbiased source densities and outputs PyNE Meshes of weight window lower bounds and biased source densities as computed by the Consistant Adjoint-Driven Importance Sampling (CADIS) method [1]. Note that values can be stored on the same Mesh object, all different Mesh objects, or any combination in between. Meshes can be structured or unstructured. Note that this function is suitable for Forward Weighted (FW) CADIS as well, the only difference being the adjoint source used for the estimation of the adjoint flux. [1] Haghighat, A. and Wagner, J. C., "Monte Carlo Variance Reduction with Deterministic Importance Functions," Progress in Nuclear Energy, Vol. 42, No. 1, pp. 25-53, 2003. Parameters ---------- adj_flux_mesh : PyNE Mesh object The mesh containing the adjoint fluxes. adj_flux_tag : string The name of the adjoint flux tag on adj_mesh. q_mesh : PyNE Mesh object The mesh containing the unbiased source density. q_tag : string The name of the source density tag on q_mesh. ww_mesh : PyNE Mesh object The mesh to store the output weight window mesh. ww_tag : string Name of the tag to store output weight window values on ww_mesh. q_bias_mesh : PyNE Mesh object The mesh to store the output biased source density mesh. q_bias_tag : PyNE Mesh object Name of the tag to store output weight window values on q_bias_mesh. beta : float The ratio of the weight window upper bound to the weight window lower bound. The default value is 5: the value used in MCNP. """ # find number of energy groups e_groups = adj_flux_mesh.get_tag(adj_flux_tag)[list( mesh_iterate(adj_flux_mesh.mesh))[0]] e_groups = np.atleast_1d(e_groups) num_e_groups = len(e_groups) # verify source (q) mesh has the same number of energy groups q_e_groups = q_mesh.get_tag(q_tag)[list(mesh_iterate(q_mesh.mesh))[0]] q_e_groups = np.atleast_1d(q_e_groups) num_q_e_groups = len(q_e_groups) if num_q_e_groups != num_e_groups: raise TypeError("{0} on {1} and {2} on {3} " "must be of the same dimension".format( adj_flux_mesh, adj_flux_tag, q_mesh, q_tag)) # create volume element (ve) iterators adj_ves = mesh_iterate(adj_flux_mesh.mesh) q_ves = mesh_iterate(q_mesh.mesh) # calculate total source strength q_tot = 0 for q_ve in q_ves: q_tot += np.sum(q_mesh.get_tag(q_tag)[q_ve]) \ * q_mesh.elem_volume(q_ve) q_ves.reset() # calculate the total response per source particle (R) R = 0 for adj_ve, q_ve in zip(adj_ves, q_ves): adj_flux = adj_flux_mesh.get_tag(adj_flux_tag)[adj_ve] adj_flux = np.atleast_1d(adj_flux) q = q_mesh.get_tag(q_tag)[q_ve] q = np.atleast_1d(q) vol = adj_flux_mesh.elem_volume(adj_ve) for i in range(0, num_e_groups): R += adj_flux[i] * q[i] * vol / q_tot # generate weight windows and biased source densities using R ww_mesh.tag(ww_tag, np.zeros(num_e_groups, dtype=float), 'nat_mesh', size=num_e_groups, dtype=float) tag_ww = ww_mesh.get_tag(ww_tag) ww_ves = mesh_iterate(ww_mesh.mesh) q_bias_mesh.tag(q_bias_tag, np.zeros(num_e_groups, dtype=float), 'nat_mesh', size=num_e_groups, dtype=float) tag_q_bias = q_bias_mesh.get_tag(q_bias_tag) q_bias_ves = mesh_iterate(q_bias_mesh.mesh) # reset previously created iterators q_ves.reset() adj_ves.reset() for adj_ve, q_ve, ww_ve, q_bias_ve in zip(adj_ves, q_ves, ww_ves, q_bias_ves): adj_flux = adj_flux_mesh.get_tag(adj_flux_tag)[adj_ve] adj_flux = np.atleast_1d(adj_flux) q = q_mesh.get_tag(q_tag)[q_ve] q = np.atleast_1d(q) tag_q_bias[q_bias_ve] = [ adj_flux[i] * q[i] / q_tot / R for i in range(num_e_groups) ] tag_ww[ww_ve] = [ R / (adj_flux[i] * (beta + 1.) / 2.) if adj_flux[i] != 0.0 else 0.0 for i in range(num_e_groups) ]
def mesh_to_fluxin( flux_mesh, flux_tag, fluxin="fluxin.out", reverse=False, sub_voxel=False, cell_fracs=None, cell_mats=None, print_progress=True, ): """This function creates an ALARA fluxin file from fluxes tagged on a PyNE Mesh object. Fluxes are printed in the order of the flux_mesh.__iter__(). Parameters ---------- flux_mesh : PyNE Mesh object Contains the mesh with fluxes tagged on each volume element. flux_tag : string The name of the tag of the flux mesh. Flux values for different energy groups are assumed to be represented as vector tags. fluxin : string The name of the ALARA fluxin file to be output. reverse : bool If true, fluxes will be printed in the reverse order as they appear in the flux vector tagged on the mesh. sub_voxel: bool, optional If true, sub-voxel r2s work flow will be sued. Flux of a voxel will be duplicated c times. Where c is the cell numbers of that voxel. cell_fracs : structured array, optional The output from dagmc.discretize_geom(). A sorted, 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. The array must be sorted with respect to both idx and cell, with cell changing fastest. cell_mats : dict, optional Maps geometry cell numbers to PyNE Material objects. The cell_fracs and cell_mats are used only when sub_voxel=True. If sub_voxel=False, neither cell_fracs nor cell_mats will be used. print_progress : bool Print the progress with progress bar. Set to False to turn off progress. """ tag_flux = flux_mesh.get_tag(flux_tag) # find number of e_groups e_groups = tag_flux[list(mesh_iterate(flux_mesh.mesh))[0]] e_groups = np.atleast_1d(e_groups) num_e_groups = len(e_groups) # write flux data block by block with open(fluxin, "w") as f: if not sub_voxel: bar = IfBar( "Writing alara fluxin", max=len(flux_mesh), suffix="%(percent).1f%% - %(eta)ds", show=print_progress, ) for i, mat, ve in flux_mesh: f.write(_output_flux_block(ve, tag_flux, reverse)) bar.next() bar.finish() else: ves = list(flux_mesh.iter_ve()) bar = IfBar( "Writing alara fluxin", max=len(cell_fracs), suffix="%(percent).1f%% - %(eta)ds", show=print_progress, ) for i, row in enumerate(cell_fracs): if len(cell_mats[row["cell"]].comp) != 0: f.write( _output_flux_block(ves[row["idx"]], tag_flux, reverse)) bar.next() bar.finish()
def mesh_to_fluxin(flux_mesh, flux_tag, fluxin="fluxin.out", reverse=False, sub_voxel=False, cell_fracs=None, cell_mats=None): """This function creates an ALARA fluxin file from fluxes tagged on a PyNE Mesh object. Fluxes are printed in the order of the flux_mesh.__iter__(). Parameters ---------- flux_mesh : PyNE Mesh object Contains the mesh with fluxes tagged on each volume element. flux_tag : string The name of the tag of the flux mesh. Flux values for different energy groups are assumed to be represented as vector tags. fluxin : string The name of the ALARA fluxin file to be output. reverse : bool If true, fluxes will be printed in the reverse order as they appear in the flux vector tagged on the mesh. sub_voxel: bool, optional If true, sub-voxel r2s work flow will be sued. Flux of a voxel will be duplicated c times. Where c is the cell numbers of that voxel. cell_fracs : structured array, optional The output from dagmc.discretize_geom(). A sorted, 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. The array must be sorted with respect to both idx and cell, with cell changing fastest. cell_mats : dict, optional Maps geometry cell numbers to PyNE Material objects. The cell_fracs and cell_mats are used only when sub_voxel=True. If sub_voxel=False, neither cell_fracs nor cell_mats will be used. """ tag_flux = flux_mesh.get_tag(flux_tag) # find number of e_groups e_groups = tag_flux[list(mesh_iterate(flux_mesh.mesh))[0]] e_groups = np.atleast_1d(e_groups) num_e_groups = len(e_groups) # Establish for loop bounds based on if forward or backward printing # is requested if not reverse: start = 0 stop = num_e_groups direction = 1 else: start = num_e_groups - 1 stop = -1 direction = -1 output = u"" if not sub_voxel: for i, mat, ve in flux_mesh: # print flux data to file output = _output_flux(ve, tag_flux, output, start, stop, direction) else: ves = list(flux_mesh.iter_ve()) for row in cell_fracs: if len(cell_mats[row['cell']].comp) != 0: output = _output_flux(ves[row['idx']], tag_flux, output, start, stop, direction) with open(fluxin, "w") as f: f.write(output)