Irradiation of a slab of U-238

This notebook shows how ONIX can be used to run a standalone simulation of the irradiation of a slab of uranium 238 with user-defined nuclear data.

import onix
import numpy as np
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-5726ea1fceba> in <module>
----> 1 import onix

ModuleNotFoundError: No module named 'onix'

Defining a sequence

The first thing to define is the sequence of burnup points or time points that ONIX should follow when iterating between OpenMC simulations and depletion calculations.

We first define the macrostep vector in burnup units (MWd/kg) or time units (“s” for seconds, “m” for minutes, “d” for days, “y” for years). These points defines when OpenMC simulations update the neutron flux and reaction rates.

There is no need to define the initial point (which would be 0 in burnup or time units).

[ ]:
macrostep_vector = np.logspace(-1.0, 1.0)
macrostep_unit = 'd'

We then define a vector for power of flux normalization. This vector indicates what is the value or the flux or power density to use for each macrostep. The user choose between flux and power density by defining the unit of the vector, “flux” or “power”.

The flux should be in units of \(cm^{-2}\cdot s^{-1}\), the power should be in units of \(kW/l\).

[ ]:
norma_vector = [1e14]*len(macrostep_vector)
norma_unit = 'flux'

The last element of the sequence object that we need to define is the number of microsteps within each macrostep. Below, we indicate to ONIX that there should be 3 microsteps that divide each and every macrosteps.

[ ]:
microstep_vector = [3]*len(macrostep_vector)

We then instantiate a sequence object and fill it with the vectors we defined above.

Important to note: since ONIX enables the user to define multiple sequence objects within one input file, the user needs to associate each sequence object with a number id as below.

[ ]:
sequence1 = onix.Sequence(1)
sequence1.set_macrostep(macrostep_vector, macrostep_unit)
sequence1.set_norma(norma_vector, norma_unit)
sequence1.microstep_vector = microstep_vector

Finally, we need to define the way ONIX approximate the neutron flux for each microstep. In the current version, the only option is to take the initial value (‘iv’) of the flux for the microstep.

[ ]:
sequence1.flux_approximation ='iv'

Defining a BUCell

Now we can define the BUCell that corresponds to the burnup region we want to deplete, that is, the slab of uranium-238.

[ ]:
bucell = onix.Cell(1, 'slab')

We use the BUCell object to define the initial density of our slab in atm per \(cm^{3}\). In this example, we set the density to an arbitrary value.

[ ]:
bucell.set_initial_dens({'922380': 1.00E+12})

Building the depletion network with user-defined nuclear data

ONIX provides commands to design custom depletion network with user-defined nuclear data. This is very useful for relatively small and simple nuclides network.

We first instantiate a decay-lib object. This object will allow us to define and store the decay data of our depletion system.

[ ]:
decay1 = onix.utils.decay_lib(1)

We can add decay data for as many nuclides as we want. Once a nuclide exist in one of the object libraries defined by the user, it will be modelled in the nuclides network.

[ ]:
decay1.add_data('922380', half_life =1.4099935680E+17 )
decay1.add_data('922390', betaneg = 0.0004926419193745169)
decay1.add_data('932390', betaneg = 3.405151448232769e-06 )
decay1.add_data('942390', half_life = 7.60853735110E+11)
decay1.add_data('942400', half_life = 2.0704941360E+11)
decay1.add_data('531350', betaneg = 2.9306070546251702e-05)
decay1.add_data('541350', betaneg = 2.1065742176025568e-05 )
decay1.add_data('551350', half_life = 7.2582480E+13 )

Next we use a xs_lib object to define and store one-group cross section data.

[ ]:
xs1 = onix.utils.xs_lib(1)
xs1.add_data('922380', ngamma = 1e5, fission = 1e4 )
xs1.add_data('942390', ngamma = 1e5)

Finally we define a fy_lib object that will store fission yield data.

[ ]:
fy1 = onix.utils.fy_lib(1)
I135_fy_dict = {'922380':1.2}
Xe135_fy_dict = {'922380':0.2}
Cs135_fy_dict = {'922380':1.8E-5}
fy1.add_data('531350', I135_fy_dict)
fy1.add_data('541350', Xe135_fy_dict)
fy1.add_data('551350', Cs135_fy_dict)

Defining a Standalone object and launching the simulation

We instantiate a standalone object which will execute the simulation for us

[ ]:
SA = onix.Stand_alone()

We first need to add the BUCell we defined previously to our Standalone object.

[ ]:

Next we set the volumes of the BUCell as well as the total volume of the System. A Standalone object automatically instantiates a System object which is supposed to host all BUCell objects. In our case, the System and the BUCell are the same. So the total volume of the system is the same as the BUCell. We can set the volume of the BUCell to an arbitrary value of 1 in this example.

[ ]:
vol_dict = {'slab': 1 ,'total volume':1}

Now we should set the various nuclear libraries object we defined previously to our Standalone object.

[ ]:
SA.set_decay_from_object('slab', decay1)
SA.set_xs_from_object('slab', xs1)
SA.set_fy_from_object('slab', fy1)

We also need to indicate to the Standalone object what is the irridiation sequence.

[ ]:

Finally, we can launch the simulation

[ ]:

Output results are going to be located in two types of folder. Per step folders include densities, power, neutron flux, burnup, one-group cross sections and burnup matrices for each macrostep, separately. The output summary folder contains aggregated output results for the whole simulation and for every macrostep.