def test_from_atom_frac_func(): h2o = {10010: 2.0, 80160: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_mol, 3.0) assert_equal(mat.comp[10010], 0.11191487328808077) assert_equal(mat.comp[80160], 0.8880851267119192) assert_equal(mat.mass, 18.01056468403) assert_equal(mat.molecular_weight(), 18.01056468403) h2 = Material({10010: 1.0}, atoms_per_mol=2.0) h2o = {'O16': 1.0, h2: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_mol, 3.0) assert_equal(mat.comp[10010], 0.11191487328808077) assert_equal(mat.comp[80160], 0.8880851267119192) assert_equal(mat.molecular_weight(), 18.01056468403) ihm = from_atom_frac({922350: 0.5, 922380: 0.5}) uox = {ihm: 1.0, 'O16': 2.0} mat = from_atom_frac(uox) assert_equal(mat.atoms_per_mol, 3.0) assert_almost_equal(mat.comp[80160], 0.11912625316479536, 16) assert_almost_equal(mat.comp[922350], 0.43763757948940346, 15) assert_almost_equal(mat.comp[922380], 0.44323616734580107, 15) assert_almost_equal(mat.molecular_weight() / 268.53718965614, 1.0, 15)
def test_from_atom_frac_func(): h2o = {10010: 2.0, 80160: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_mol, 3.0) assert_equal(mat.comp[10010], 0.11191487328808077) assert_equal(mat.comp[80160], 0.8880851267119192) assert_equal(mat.mass, 18.01056468403) assert_equal(mat.molecular_weight(), 18.01056468403) h2 = Material({10010: 1.0}, atoms_per_mol=2.0) h2o = {'O16': 1.0, h2: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_mol, 3.0) assert_equal(mat.comp[10010], 0.11191487328808077) assert_equal(mat.comp[80160], 0.8880851267119192) assert_equal(mat.molecular_weight(), 18.01056468403) ihm = from_atom_frac({922350: 0.5, 922380: 0.5}) uox = {ihm: 1.0, 'O16': 2.0} mat = from_atom_frac(uox) assert_equal(mat.atoms_per_mol, 3.0) assert_almost_equal(mat.comp[80160], 0.11912625316479536, 16) assert_almost_equal(mat.comp[922350], 0.43763757948940346, 15) assert_almost_equal(mat.comp[922380], 0.44323616734580107, 15) assert_almost_equal(mat.molecular_weight()/268.53718965614, 1.0, 15)
def test_from_atom_frac_func(): h2o = {10010000: 2.0, 80160000: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_molecule, 3.0) assert_equal(mat.comp[10010000], 0.11191487328808077) assert_equal(mat.comp[80160000], 0.8880851267119192) assert_equal(mat.mass, 18.01056468403) assert_equal(mat.molecular_mass(), 18.01056468403) h2 = Material({10010000: 1.0}, atoms_per_molecule=2.0) h2o = {'O16': 1.0, h2: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_molecule, 3.0) assert_equal(mat.comp[10010000], 0.11191487328808077) assert_equal(mat.comp[80160000], 0.8880851267119192) assert_equal(mat.molecular_mass(), 18.01056468403) ihm = from_atom_frac({922350000: 0.5, 922380000: 0.5}) uox = {ihm: 1.0, 'O16': 2.0} mat = from_atom_frac(uox) assert_equal(mat.atoms_per_molecule, 3.0) assert_almost_equal(mat.comp[80160000], 0.11912625367051276, 16) assert_almost_equal(mat.comp[922350000], 0.43763757904405304, 15) assert_almost_equal(mat.comp[922380000], 0.44323616728543414, 15) assert_almost_equal(mat.molecular_mass()/268.53718851614, 1.0, 15)
def test_from_atom_frac_func(): h2o = {10010000: 2.0, 80160000: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_molecule, 3.0) assert_equal(mat.comp[10010000], 0.11191487328808077) assert_equal(mat.comp[80160000], 0.8880851267119192) assert_equal(mat.mass, 18.01056468403) assert_equal(mat.molecular_mass(), 18.01056468403) h2 = Material({10010000: 1.0}, atoms_per_molecule=2.0) h2o = {'O16': 1.0, h2: 1.0} mat = from_atom_frac(h2o) assert_equal(mat.atoms_per_molecule, 3.0) assert_equal(mat.comp[10010000], 0.11191487328808077) assert_equal(mat.comp[80160000], 0.8880851267119192) assert_equal(mat.molecular_mass(), 18.01056468403) ihm = from_atom_frac({922350000: 0.5, 922380000: 0.5}) uox = {ihm: 1.0, 'O16': 2.0} mat = from_atom_frac(uox) assert_equal(mat.atoms_per_molecule, 3.0) assert_almost_equal(mat.comp[80160000], 0.11912625367051276, 16) assert_almost_equal(mat.comp[922350000], 0.43763757904405304, 15) assert_almost_equal(mat.comp[922380000], 0.44323616728543414, 15) assert_almost_equal(mat.molecular_mass() / 268.53718851614, 1.0, 15)
def execute_origen(xs_tape9, time, nuclide, phi, origen, decay_tape9): xs_tape9 = xs_tape9 if not os.path.isabs(xs_tape9): xs_tape9 = os.path.join(LIBS_DIR, xs_tape9) parsed_xs_tape9 = parse_tape9(xs_tape9) parsed_decay_tape9 = parse_tape9(decay_tape9) merged_tape9 = merge_tape9([parsed_decay_tape9, parsed_xs_tape9]) # Can set outfile to change directory, but the file name needs to be # TAPE9.INP. write_tape9(merged_tape9) decay_nlb, xsfpy_nlb = nlbs(parsed_xs_tape9) # Can set outfile, but the file name should be called TAPE5.INP. write_tape5_irradiation("IRF", time/(60*60*24), phi, xsfpy_nlb=xsfpy_nlb, cut_off=0, out_table_num=[4, 5], out_table_nes=[True, False, False]) M = from_atom_frac({nuclide: 1}, mass=1, atoms_per_molecule=1) write_tape4(M) # Make pyne use naive atomic mass numbers to match ORIGEN for i in pyne.data.atomic_mass_map: pyne.data.atomic_mass_map[i] = float(pyne.nucname.anum(i)) origen_time, data = time_func(run_origen, origen) logger.info("ORIGEN runtime: %s", origen_time) return origen_time, data
def transmute(self, x, t=None, phi=None, tol=None, log=None, *args, **kwargs): """Transmutes a material into its daughters. Parameters ---------- x : Material or similar Input material for transmutation. t : float Transmutations time [sec]. phi : float or array of floats Neutron flux vector [n/cm^2/sec]. Currently this must either be a scalar or match the group structure of EAF. tol : float Tolerance level for chain truncation. log : file-like or None The log file object should be written. A None imples the log is not desired. Returns ------- y : Material The output material post-transmutation. """ if not isinstance(x, Material): x = Material(x) if t is not None: self.t = t if phi is not None: self.phi = phi if log is not None: self.log = log if tol is not None: self.tol = tol x_atoms = x.to_atom_frac() y_atoms = {} for nuc, adens in x_atoms.items(): # Find output for root of unit density and scale all output by # actual nuclide density and add to final output. partial = self._transmute_partial(nuc) for part_nuc, part_adens in partial.items(): y_atoms[part_nuc] = part_adens * adens + y_atoms.get( part_nuc, 0.0) mw_x = x.molecular_mass() y = from_atom_frac(y_atoms, atoms_per_molecule=x.atoms_per_molecule) # even though it doesn't look like it, the following line is actually # mass_y = MW_y * mass_x / MW_x y.mass *= x.mass / mw_x return y
def transmute(self, x, t=None, phi=None, tol=None, log=None, *args, **kwargs): """Transmutes a material into its daughters. Parameters ---------- x : Material or similar Input material for transmutation. t : float Transmutations time [sec]. phi : float or array of floats Neutron flux vector [n/cm^2/sec]. Currently this must either be a scalar or match the group structure of EAF. tol : float Tolerance level for chain truncation. log : file-like or None The log file object should be written. A None imples the log is not desired. Returns ------- y : Material The output material post-transmutation. """ if not isinstance(x, Material): x = Material(x) if t is not None: self.t = t if phi is not None: self.phi = phi if log is not None: self.log = log if tol is not None: self.tol = tol x_atoms = x.to_atom_frac() y_atoms = {} for nuc, adens in x_atoms.items(): # Find output for root of unit density and scale all output by # actual nuclide density and add to final output. partial = self._transmute_partial(nuc) for part_nuc, part_adens in partial.items(): y_atoms[part_nuc] = part_adens * adens + y_atoms.get(part_nuc, 0.0) mw_x = x.molecular_mass() y = from_atom_frac(y_atoms, atoms_per_molecule=x.atoms_per_molecule) # even though it doesn't look likt it, the following line is actually # mass_y = MW_y * mass_x / MW_x y.mass *= x.mass / mw_x return y
def num_density_to_mesh(lines, time, m): """num_density_to_mesh(lines, time, m) This function reads ALARA output containing number density information and creates material objects which are then added to a supplied PyNE Mesh object. The volumes within ALARA are assummed to appear in the same order as the idx on the Mesh object. Parameters ---------- lines : list or str ALARA output from ALARA run with 'number_density' in the 'output' block of the input file. Lines can either be a filename or the equivalent to calling readlines() on an ALARA output file. If reading in ALARA output from stdout, call split('\n') before passing it in as the lines parameter. time : str The decay time for which number densities are requested (e.g. '1 h', 'shutdown', etc.) m : PyNE Mesh Mesh object for which mats will be applied to. """ if isinstance(lines, basestring): with open(lines) as f: lines = f.readlines() elif not isinstance(lines, collections.Sequence): raise TypeError("Lines argument not a file or sequence.") # Advance file to number density portion. header = 'Number Density [atoms/cm3]' line = "" while line.rstrip() != header: line = lines.pop(0) # Get decay time index from next line (the column the decay time answers # appear in. line_strs = lines.pop(0).replace('\t', ' ') time_index = [s.strip() for s in line_strs.split(' ') if s.strip()].index(time) # Create a dict of mats for the mesh. mats = {} count = 0 # Read through file until enough material objects are create to fill mesh. while count != len(m): # Pop lines to the start of the next material. while (lines.pop(0) + " ")[0] != '=': pass # Create a new material object and add to mats dict. line = lines.pop(0) nucvec = {} density = 0.0 # Read lines until '=' delimiter at the end of a material. while line[0] != '=': nuc = line.split()[0] n = float(line.split()[time_index]) if n != 0.0: nucvec[nuc] = n density += n * anum(nuc) / N_A line = lines.pop(0) mat = from_atom_frac(nucvec, density=density, mass=0) mats[count] = mat count += 1 m.mats = mats
def test_number_density(): ethanol = from_atom_frac({'C':2, 'H':6, 'O':1}, density=0.78900) obs = ethanol.number_density() exp = 9.2825E22 assert_almost_equal(obs / exp, 1.0, 4)
def test_mass_density(): ethanol = from_atom_frac({'C':2, 'H':6, 'O':1}) atom_density_ethanol = 9.282542841E22 # atom density not molecule density mass_density = ethanol.mass_density(atom_density_ethanol) expected_mass_density = 0.78900 assert_almost_equal(mass_density, expected_mass_density, 4)
def num_density_to_mesh(lines, time, m): """num_density_to_mesh(lines, time, m) This function reads ALARA output containing number density information and creates material objects which are then added to a supplied PyNE Mesh object. The volumes within ALARA are assummed to appear in the same order as the idx on the Mesh object. Parameters ---------- lines : list or str ALARA output from ALARA run with 'number_density' in the 'output' block of the input file. Lines can either be a filename or the equivalent to calling readlines() on an ALARA output file. If reading in ALARA output from stdout, call split('\n') before passing it in as the lines parameter. time : str The decay time for which number densities are requested (e.g. '1 h', 'shutdown', etc.) m : PyNE Mesh Mesh object for which mats will be applied to. """ if isinstance(lines, basestring): with open(lines) as f: lines = f.readlines() elif not isinstance(lines, collections.Sequence): raise TypeError("Lines argument not a file or sequence.") # Advance file to number density portion. header = 'Number Density [atoms/cm3]' line = "" while line.rstrip() != header: line = lines.pop(0) # Get decay time index from next line (the column the decay time answers # appear in. line_strs = lines.pop(0).replace('\t', ' ') time_index = [s.strip() for s in line_strs.split(' ') if s.strip()].index(time) # Create a dict of mats for the mesh. mats = {} count = 0 # Read through file until enough material objects are create to fill mesh. while count != len(m): # Pop lines to the start of the next material. while (lines.pop(0) + " " )[0] != '=': pass # Create a new material object and add to mats dict. line = lines.pop(0) nucvec = {} density = 0.0 # Read lines until '=' delimiter at the end of a material. while line[0] != '=': nuc = line.split()[0] n = float(line.split()[time_index]) if n != 0.0: nucvec[nuc] = n density += n * anum(nuc)/N_A line = lines.pop(0) mat = from_atom_frac(nucvec, density=density, mass=0) mats[count] = mat count += 1 m.mats = mats
def _ensure_mats(self, rc): "Ensure we have a fuel material, clad material, and cooling material." if 'fuel_material'in rc: rc.fuel_material = ensure_mat(rc.fuel_material) elif 'fuel_chemical_form' in rc and 'initial_heavy_metal' in rc: ihm_mat = Material(rc.initial_heavy_metal) atom_frac = {nucname.id(k): v for k, v in rc.fuel_chemical_form.items() if k != "IHM"} atom_frac[ihm_mat] = rc.fuel_chemical_form.get("IHM", 0.0) rc.fuel_material = from_atom_frac(atom_frac) else: raise ValueError("Please specify a fuel.") if 'clad_material' in rc: rc.clad_material = ensure_mat(rc.clad_material) else: rc.clad_material = Material({ # Natural Zirconium 400900: 0.98135 * 0.5145, 400910: 0.98135 * 0.1122, 400920: 0.98135 * 0.1715, 400940: 0.98135 * 0.1738, 400960: 0.98135 * 0.0280, # The plastic is all melted and the natural Chromium too.. 240500: 0.00100 * 0.04345, 240520: 0.00100 * 0.83789, 240530: 0.00100 * 0.09501, 240540: 0.00100 * 0.02365, # Natural Iron 260540: 0.00135 * 0.05845, 260560: 0.00135 * 0.91754, 260570: 0.00135 * 0.02119, 260580: 0.00135 * 0.00282, # Natural Nickel 280580: 0.00055 * 0.68077, 280600: 0.00055 * 0.26223, 280610: 0.00055 * 0.01140, 280620: 0.00055 * 0.03634, 280640: 0.00055 * 0.00926, # Natural Tin 501120: 0.01450 * 0.0097, 501140: 0.01450 * 0.0065, 501150: 0.01450 * 0.0034, 501160: 0.01450 * 0.1454, 501170: 0.01450 * 0.0768, 501180: 0.01450 * 0.2422, 501190: 0.01450 * 0.0858, 501200: 0.01450 * 0.3259, 501220: 0.01450 * 0.0463, 501240: 0.01450 * 0.0579, # We Need Oxygen! 80160: 0.00125, }) if 'cool_material' in rc: rc.cool_material = ensure_mat(rc.cool_material) else: MW = (2 * 1.0) + (1 * 16.0) + (0.199 * 550 * 10.0**-6 * 10.0) + \ (0.801 * 550 * 10.0**-6 * 11.0) rc.cool_material = Material({ 10010: (2 * 1.0) / MW, 80160: (1 * 16.0) / MW, 50100: (0.199 * 550 * 10.0**-6 * 10.0) / MW, 50110: (0.801 * 550 * 10.0**-6 * 11.0) / MW, })
def test_number_density(): ethanol = from_atom_frac({'C': 2, 'H': 6, 'O': 1}, density=0.78900) obs = ethanol.number_density() exp = 9.2825E22 assert_almost_equal(obs / exp, 1.0, 4)
def test_mass_density(): ethanol = from_atom_frac({'C': 2, 'H': 6, 'O': 1}) atom_density_ethanol = 9.282542841E22 # atom density not molecule density mass_density = ethanol.mass_density(atom_density_ethanol) expected_mass_density = 0.78900 assert_almost_equal(mass_density, expected_mass_density, 4)
def __init__(self): ## Define the system: materials, surfaces, regions, cells. self.sys = definition.SystemDefinition(verbose=False) ## Materials. # Must provide a name as a keyword argument for material cards. See the # documentation for :py:mod:`pyne.material` for more information. uo2 = material.from_atom_frac({'U235': 0.05, 'U238': 0.95, 'O16' : 2.00}) self.uo2 = cards.Material(uo2, name='UO2') h2o = material.from_atom_frac({'H1' : 2.0, 'O16': 1.0}, attrs={'name': 'H2O'}) self.h2o = cards.Material(h2o) ## Surfaces. # There are two surfaces: one for the pin and one for the unit cell # boundary. radius = 0.40 # This creates an axis-aligned and axis-centered cylinder along the z # axis, with radius 0.40 cm. self.pin = cards.AxisCylinder('pin', 'Z', radius) # The Parallelepiped is a macrobody. The surface is reflecting, # creating an infinte geometry. The surface is infinite in the z # direction. pitch = 1.2 self.cellbound = cards.Parallelepiped('bound', -pitch / 2, pitch / 2, -pitch / 2, pitch / 2, 0, 0, reflecting=True) ## Cells. # We combine the materials and surfaces above into cells. We use MCNP # cells in order to specify particle importances and volumes directly # on the cell card. We could alternatively use the # :py:class:`Importance` and :py:class:`Volume` cards. # fuel cell. # The fuel is the region of space inside the pin, pin.neg. self.fuelregion = self.pin.neg # The neutron importance is 1, and the user-provided volume is 1 cm^3. self.fuel = cards.CellMCNP('fuel', self.fuelregion, self.uo2, 11.0, 'g/cm^3', importance=('neutron', 1), volume=1) # coolant cell. # The region is between the pin and the unit cell boundary. self.coolantregion = self.pin.pos | self.cellbound.neg self.coolant = cards.CellMCNP('coolant', self.coolantregion, self.h2o, 1.0, 'g/cm^3', importance=('neutron', 1), volume=1) # graveyard cell: where particles go to die. # The region is everything beyond the unit cell boundary. self.graveyardregion = self.cellbound.pos # This is a void cell, meaning it does not have a material. self.graveyard = cards.CellMCNP('graveyard', self.graveyardregion, importance=('neutron', 0)) # We add the cells to the system. The order we add them is the order # they are printed in the input file. self.sys.add_cell(self.fuel) # We can add multiple cells at once. self.sys.add_cell(self.coolant, self.graveyard) ## Define the simulation: sources, tallies, misc. Don't clutter the # command window. self.sim = definition.MCNPSimulation(self.sys, verbose=False) # Specify a thermal scattering law for the H2O material. This is a # unique card per material. self.sim.add_misc(cards.ScatteringLaw('H2O', {'H1': 'lwtr'})) # Add a criticality source, use default values. This is a unique card, # so we do not provide a card name. self.sim.add_source(cards.Criticality()) # Add points at which to start neutrons; use default point (0, 0, 0). self.sim.add_source(cards.CriticalityPoints()) # Tally neutron flux in both the fuel and coolant cells. self.sim.add_tally(cards.CellFlux('flux', 'neutron', ['fuel', 'coolant'])) # The energy grid on which to tally neutrons, applied to all tallies. self.sim.add_misc(cards.EnergyGrid('egrid0', None, 10**np.arange(-9.9, 1.1, 0.1)))