Track multiple reaction_domains with openmc.deplete.MicroXS.from_model

When using the openmc.deplete.MicroXS.from_model method to generate one_group cross sections is there a way to track multiple reaction_domains for one transport calculations. Specifically I would like to generate cross sections for multiple materials in a reactor so it would be great to only need one instance of the openmc.deplete.MicroXS.from_model for multiple reaction_domains in this case multiple fuel materials?

I’m not sure I’m understanding your question correctly, but if you want to take mgxs tallies on multiple materials across multiple reaction types I have the code for that. Small problem, the nuclides it is tallying have to be in the original compositions defined in the code, so it gets a little complicated during a depletion sim. Below is a small snippet that some of the setup. Essentially you provide a list of cells (any number of cells) and it will take tallies on the materials used to fill those cells according to the reactions you include in the for loop. You can choose energy groups (1 for you), macro or micro, ect. The data processed output is a folder of excel spreadsheets, one for each material for each reaction type which is sorted internally by nuclide (again, only the nuclides present in the original material definition) and by energy group. If this is what you are looking for, let me know.

cell_set_list = [fuel_cell_56_9.id,fuel_cell_57_9.id,borod_46.id] # insert name of cell with ‘.id’

openmc_cells = assembly.get_all_material_cells().values()
xs_library = {}
for cell in openmc_cells:
xs_library[cell.id] = {}
xs_library[cell.id][‘total’] = mgxs.TotalXS(energy_groups=en_groups)
xs_library[cell.id][‘transport’] = mgxs.TransportXS(energy_groups=en_groups)
xs_library[cell.id][‘absorption’] = mgxs.AbsorptionXS(energy_groups=en_groups)
xs_library[cell.id][‘fission’] = mgxs.FissionXS(energy_groups=en_groups)
xs_library[cell.id][‘nu-fission’] = mgxs.FissionXS(energy_groups=en_groups, nu=True)
xs_library[cell.id][‘scatter’] = mgxs.ScatterXS(energy_groups=en_groups)
xs_library[cell.id][‘nu-scatter’] = mgxs.ScatterMatrixXS(energy_groups=en_groups, nu=True)
xs_library[cell.id][‘chi’] = mgxs.Chi(energy_groups=en_groups)

I think this should work, will just need to add a method to add atom of all the nuclides that I need cross sections for. Basically what I want is one group cross sections for multiple materials that I can then give back to the transport independent depletion solver to carry out the Burnup calculations.

List of energy group options, create one that you want to use

“each energy group is 10x” group

magnitude_group = mgxs.EnergyGroups([0., 0.0000000001e6, 0.000000001e6, 0.00000001e6, 0.0000001e6, 0.000001e6,
0.00001e6, 0.0001e6, 0.001e6, 0.01e6, 0.1e6, 1e6, 10e6, 100e6])

generic 8 group

eight_group = mgxs.EnergyGroups([0., 0.058, 0.14, 0.28,0.625, 4.0, 5.53e3, 821.0e3, 20.0e6])

This is the 4 group used in HAMMER

four_group_hammer = mgxs.EnergyGroups([0.004742,0.6552,5531,820900,14920000])

This is the 2 group used in HAMMER

two_group_hammer = mgxs.EnergyGroups([0.004742,0.6552,14920000])

Inputs

en_groups = four_group_hammer # Set this variable to the energy group you want to run.
outputxs_type = ‘micro’ # choose micro or macro
target_folder = ‘/home/rmclem/openmc/NURAM/MCFNRv2.5/MG_Working_Outs’ # make sure this is correct for your system, MG_Working_Outs is output folder
nuclide_specific = True # turning this to false significantly increases computation time, tracks all nuclides in material for each cell specified

list of cells to record data, tallies will only be recorded for these cells

cell_set_list = [fuel_cell_56_9.id,reg_water_56.id,clad_cell_56_9.id,L_borod_26.id] # insert name of cell with ‘.id’ at the end

STOP (delicate, handle with care)

openmc_cells = assembly.get_all_material_cells().values()
xs_library = {}
for cell in openmc_cells:
xs_library[cell.id] = {}
xs_library[cell.id][‘total’] = mgxs.TotalXS(energy_groups=en_groups)
xs_library[cell.id][‘transport’] = mgxs.TransportXS(energy_groups=en_groups)
xs_library[cell.id][‘absorption’] = mgxs.AbsorptionXS(energy_groups=en_groups)
xs_library[cell.id][‘fission’] = mgxs.FissionXS(energy_groups=en_groups)
xs_library[cell.id][‘nu-fission’] = mgxs.FissionXS(energy_groups=en_groups, nu=True)
xs_library[cell.id][‘scatter’] = mgxs.ScatterXS(energy_groups=en_groups)
xs_library[cell.id][‘nu-scatter’] = mgxs.ScatterMatrixXS(energy_groups=en_groups, nu=True)
xs_library[cell.id][‘chi’] = mgxs.Chi(energy_groups=en_groups)

tally_trigger = openmc.Trigger(‘std_dev’, 1e-4) # sensitivity, change if needed

for cell in openmc_cells:
for mgxs_type in xs_library[cell.id]:
xs_library[cell.id][mgxs_type].tally_trigger = tally_trigger

Instantiate an empty Tallies object

tallies_file = openmc.Tallies()

Iterate over all cells and cross section types

for cell in openmc_cells:
for rxn_type in xs_library[cell.id]:
xs_library[cell.id][rxn_type].domain = cell # not sure what happens if this is changed
xs_library[cell.id][rxn_type].by_nuclide = nuclide_specific # turning this to false significantly increases computation time
for tally in xs_library[cell.id][rxn_type].tallies.values():
tallies_file.append(tally, merge=True)

Export to “tallies.xml”

tallies_file.export_to_xml()

#####################################################################################################################
###---------------------------------MGXS Advanced Tallies Post Processing (Section 8)------------------------------
#####################################################################################################################

This generates the output files for the advanced tallies. Make sure you have the correct settings before running.

‘’’

Make sure this is turned off during tally taking

sp = openmc.StatePoint(‘statepoint_100.h5’) # make sure this matches the statepoint output with your tallies

Iterate over all cells and cross section types (creates our cross sections), doesn’t need editing

for cell in openmc_cells:
for rxn_type in xs_library[cell.id]:
xs_library[cell.id][rxn_type].load_from_statepoint(sp)

for i in range(len(cell_set_list)): # careful adjusting order of cross sections, they have to be in a specific order or they won’t work
cell_set = cell_set_list[i]

total = xs_library[cell_set]['total']
df1 = total.get_pandas_dataframe(xs_type=outputxs_type)

transport = xs_library[cell_set]['transport']
df2 = transport.get_pandas_dataframe(xs_type=outputxs_type)

absorbtion = xs_library[cell_set]['absorption']
df3 = absorbtion.get_pandas_dataframe(xs_type=outputxs_type)

fission = xs_library[cell_set]['fission']
df4 = fission.get_pandas_dataframe(xs_type=outputxs_type)

nufission = xs_library[cell_set]['nu-fission']
df5 = nufission.get_pandas_dataframe(xs_type=outputxs_type)

scatter = xs_library[cell_set]['scatter']
df6 = scatter.get_pandas_dataframe(xs_type=outputxs_type)   

nuscatter = xs_library[cell_set]['nu-scatter']
df7 = nuscatter.get_pandas_dataframe(xs_type=outputxs_type)

chi = xs_library[cell_set]['chi']
df8 = chi.get_pandas_dataframe(xs_type=outputxs_type)

# These name and output our data into the target folder by cell ID and xs type

file_path_tot = f'{target_folder}/{cell_set}-total-xs.xlsx'
dftot = pd.DataFrame(df1)
writer = pd.ExcelWriter(file_path_tot)
dftot.to_excel(writer, index=False)
writer.save()

file_path_trans = f'{target_folder}/{cell_set}-transport-xs.xlsx'
dftrans = pd.DataFrame(df2)
writer = pd.ExcelWriter(file_path_trans)
dftrans.to_excel(writer, index=False)
writer.save()

file_path_abs = f'{target_folder}/{cell_set}-absorption-xs.xlsx'
dfabs = pd.DataFrame(df3)
writer = pd.ExcelWriter(file_path_abs)
dfabs.to_excel(writer, index=False)
writer.save()

file_path_fiss = f'{target_folder}/{cell_set}-fission-xs.xlsx'
dffiss = pd.DataFrame(df4)
writer = pd.ExcelWriter(file_path_fiss)
dffiss.to_excel(writer, index=False)
writer.save()

file_path_nufiss = f'{target_folder}/{cell_set}-nufission-xs.xlsx'
dfnufiss = pd.DataFrame(df5)
writer = pd.ExcelWriter(file_path_nufiss)
dfnufiss.to_excel(writer, index=False)
writer.save()

file_path_scat = f'{target_folder}/{cell_set}-scatter-xs.xlsx'
dfscat = pd.DataFrame(df6)
writer = pd.ExcelWriter(file_path_scat)
dfscat.to_excel(writer, index=False)
writer.save()

file_path_nuscat = f'{target_folder}/{cell_set}-nuscatter-xs.xlsx'
dfnuscat = pd.DataFrame(df7)
writer = pd.ExcelWriter(file_path_nuscat)
dfnuscat.to_excel(writer, index=False)
writer.save()

file_path_chi = f'{target_folder}/{cell_set}-chi.xlsx'
dfchi = pd.DataFrame(df8)
writer = pd.ExcelWriter(file_path_chi)
dfchi.to_excel(writer, index=False)
writer.save()

‘’’

Not sure why things are getting bolded, but this is the full code copy pasted. You don’t want the post-processing code active while you are taking tallies, so it is commented out. When the tallies are done, simply rerun the code with the post-processing active and the tallies section active (run the python script, not openmc simulation). The variables are setup for my stuff so you may need to change things like the target folder and path. This has nuclide_specific = True, so it will track every nuclide that is present in the material definition. Let me know if you have trouble adapting it to your code. Also, the code at the bottom of the post-processing is sequestered into its own scroll for some reason, that is all part of the above for loop.