@@ -6,42 +6,189 @@ Decay Sources
66
77Through the :ref: `depletion <usersguide_depletion >` capabilities in OpenMC, it
88is possible to simulate radiation emitted from the decay of activated materials.
9- For fusion energy systems, this is commonly done using what is known as the
10- `rigorous 2-step <https://doi.org/10.1016/S0920-3796(02)00144-8 >`_ (R2S) method.
11- In this method, a neutron transport calculation is used to determine the neutron
12- flux and reaction rates over a cell- or mesh-based spatial discretization of the
13- model. Then, the neutron flux in each discrete region is used to predict the
14- activated material composition using a depletion solver. Finally, a photon
15- transport calculation with a source based on the activity and energy spectrum of
16- the activated materials is used to determine a desired physical response (e.g.,
17- a dose rate) at one or more locations of interest.
18-
19- Once a depletion simulation has been completed in OpenMC, the intrinsic decay
20- source can be determined as follows. First the activated material composition
21- can be determined using the :class: `openmc.deplete.Results ` object. Indexing an
22- instance of this class with the timestep index returns a
23- :class: `~openmc.deplete.StepResult ` object, which itself has a
24- :meth: `~openmc.deplete.StepResult.get_material ` method. Once the activated
25- :class: `~openmc.Material ` has been obtained, the
26- :meth: `~openmc.Material.get_decay_photon_energy ` method will give the energy
27- spectrum of the decay photon source. The integral of the spectrum also indicates
28- the intensity of the source in units of [Bq]. Altogether, the workflow looks as
29- follows::
30-
9+ For fusion energy systems, this is commonly done using either the `rigorous
10+ 2-step <https://doi.org/10.1016/S0920-3796(02)00144-8> `_ (R2S) method or the
11+ `direct 1-step <https://doi.org/10.1016/S0920-3796(01)00188-0 >`_ (D1S) method.
12+ In the R2S method, a neutron transport calculation is used to determine the
13+ neutron flux and reaction rates over a cell- or mesh-based spatial
14+ discretization of the model. Then, the neutron flux in each discrete region is
15+ used to predict the activated material composition using a depletion solver.
16+ Finally, a photon transport calculation with a source based on the activity and
17+ energy spectrum of the activated materials is used to determine a desired
18+ physical response (e.g., a dose rate) at one or more locations of interest.
19+ OpenMC includes automation for both the R2S and D1S methods as described in the
20+ following sections.
21+
22+ Rigorous 2-Step (R2S) Calculations
23+ ==================================
24+
25+ OpenMC includes an :class: `openmc.deplete.R2SManager ` class that fully automates
26+ cell- and mesh-based R2S calculations. Before we describe this class, it is
27+ useful to understand the basic mechanics of how an R2S calculation works.
28+ Generally, it involves the following steps:
29+
30+ 1. The :meth: `openmc.deplete.get_microxs_and_flux ` function is called to run a
31+ neutron transport calculation that determines fluxes and microscopic cross
32+ sections in each activation region.
33+ 2. The :class: `openmc.deplete.IndependentOperator ` and
34+ :class: `openmc.deplete.PredictorIntegrator ` classes are used to carry out a
35+ depletion (activation) calculation in order to determine predicted material
36+ compositions based on a set of timesteps and source rates.
37+ 3. The activated material composition is determined using the
38+ :class: `openmc.deplete.Results ` class. Indexing an instance of this class
39+ with the timestep index returns a :class: `~openmc.deplete.StepResult ` object,
40+ which itself has a :meth: `~openmc.deplete.StepResult.get_material ` method
41+ returning an activated material.
42+ 4. The :meth: `openmc.Material.get_decay_photon_energy ` method is used to obtain
43+ the energy spectrum of the decay photon source. The integral of the spectrum
44+ also indicates the intensity of the source in units of [Bq].
45+ 5. A new photon source is defined using one of OpenMC's source classes with the
46+ energy distribution set equal to the object returned by the
47+ :meth: `openmc.Material.get_decay_photon_energy ` method. The source is then
48+ assigned to a photon :class: `~openmc.Model `.
49+ 6. A photon transport calculation is run with ``model.run() ``.
50+
51+ Altogether, the workflow looks as follows::
52+
53+ # Run neutron transport calculation
54+ fluxes, micros = openmc.deplete.get_microxs_and_flux(model, domains)
55+
56+ # Run activation calculation
57+ op = openmc.deplete.IndependentOperator(mats, fluxes, micros)
58+ timesteps = ...
59+ source_rates = ...
60+ integrator = openmc.deplete.Integrator(op, timesteps, source_rates)
61+ integrator.integrate()
62+
63+ # Get decay photon source at last timestep
3164 results = openmc.deplete.Results("depletion_results.h5")
32-
33- # Get results at last timestep
3465 step = results[-1]
35-
36- # Get activated material composition for ID=1
3766 activated_mat = step.get_material('1')
38-
39- # Determine photon source
4067 photon_energy = activated_mat.get_decay_photon_energy()
41-
42- By default, the :meth: `~openmc.Material.get_decay_photon_energy ` method will
43- eliminate spectral lines with very low intensity, but this behavior can be
44- configured with the ``clip_tolerance `` argument.
68+ photon_source = openmc.IndependentSource(
69+ space=...,
70+ energy=photon_energy,
71+ particle='photon',
72+ strength=photon_energy.integral()
73+ )
74+
75+ # Run photon transport calculation
76+ model.settings.source = photon_source
77+ model.run()
78+
79+ Note that by default, the :meth: `~openmc.Material.get_decay_photon_energy `
80+ method will eliminate spectral lines with very low intensity, but this behavior
81+ can be configured with the ``clip_tolerance `` argument.
82+
83+ Cell-based R2S
84+ --------------
85+
86+ In practice, users do not need to manually go through each of the steps in an R2S
87+ calculation described above. The :class: `~openmc.deplete.R2SManager ` fully
88+ automates the execution of neutron transport, depletion, decay source
89+ generation, and photon transport. For a cell-based R2S calculation, once you
90+ have a :class: `~openmc.Model ` that has been defined, simply create an instance
91+ of :class: `~openmc.deplete.R2SManager ` by passing the model and a list of cells
92+ to activate::
93+
94+ r2s = openmc.deplete.R2SManager(model, [cell1, cell2, cell3])
95+
96+ Note that the ``volume `` attribute must be set for any cell that is to be
97+ activated. The :class: `~openmc.deplete.R2SManager ` class allows you to
98+ optionally specify a separate photon model; if not given as an argument, it will
99+ create a shallow copy of the original neutron model (available as the
100+ ``neutron_model `` attribute) and store it in the ``photon_model `` attribute. We
101+ can use this to define tallies specific to the photon model::
102+
103+ dose_tally = openmc.Tally()
104+ ...
105+ r2s.photon_model.tallies = [dose_tally]
106+
107+ Next, define the timesteps and source rates for the activation calculation::
108+
109+ timesteps = [(3.0, 'd'), (5.0, 'h')]
110+ source_rates = [1e12, 0.0]
111+
112+ In this case, the model is irradiated for 3 days with a source rate of
113+ :math: `10 ^{12 }` neutron/sec and then the source is turned off and the activated
114+ materials are allowed to decay for 5 hours. These parameters should be passed to
115+ the :meth: `~openmc.deplete.R2SManager.run ` method to execute the full R2S
116+ calculation. Before we can do that though, for a cell-based calculation, the one
117+ other piece of information that is needed is bounding boxes of the activated
118+ cells::
119+
120+ bounding_boxes = {
121+ cell1.id: cell1.bounding_box,
122+ cell2.id: cell2.bounding_box,
123+ cell3.id: cell3.bounding_box
124+ }
125+
126+ Note that calling the ``bounding_box `` attribute may not work for all
127+ constructive solid geometry regions (for example, a cell that uses a
128+ non-axis-aligned plane). In these cases, the bounding box will need to be
129+ specified manually. Once you have a set of bounding boxes, the R2S calculation
130+ can be run::
131+
132+ r2s.run(timesteps, source_rates, bounding_boxes=bounding_boxes)
133+
134+ If not specified otherwise, a photon transport calculation is run at each time
135+ in the depletion schedule. That means in the case above, we would see three
136+ photon transport calculations. To specify specific times at which photon
137+ transport calculations should be run, pass the ``photon_time_indices `` argument.
138+ For example, if we wanted to run a photon transport calculation only on the last
139+ time (after the 5 hour decay), we would run::
140+
141+ r2s.run(timesteps, source_rates, bounding_boxes=bounding_boxes,
142+ photon_time_indices=[2])
143+
144+ After an R2S calculation has been run, the :class: `~openmc.deplete.R2SManager `
145+ instance will have a ``results `` dictionary that allows you to directly access
146+ results from each of the steps. It will also write out all the output files into
147+ a directory that is named "r2s_<timestamp>/". The ``output_dir `` argument to the
148+ :meth: `~openmc.deplete.R2SManager.run ` method enables you to override the
149+ default output directory name if desired.
150+
151+ The :meth: `~openmc.deplete.R2SManager.run ` method actually runs three
152+ lower-level methods under the hood::
153+
154+ r2s.step1_neutron_transport(...)
155+ r2s.step2_activation(...)
156+ r2s.step3_photon_transport(...)
157+
158+ For users looking for more control over the calculation, these lower-level
159+ methods can be used in lieu of the :meth: `openmc.deplete.R2SManager.run ` method.
160+
161+ Mesh-based R2S
162+ --------------
163+
164+ Executing a mesh-based R2S calculation looks nearly identical to the cell-based
165+ R2S workflow described above. The only difference is that instead of passing a
166+ list of cells to the ``domains `` argument of
167+ :class: `~openmc.deplete.R2SManager `, you need to define a mesh object and pass
168+ that instead. This might look like the following::
169+
170+ # Define a regular Cartesian mesh
171+ mesh = openmc.RegularMesh()
172+ mesh.lower_left = (-50., -50., 0.)
173+ mesh.upper_right = (50., 50., 75.)
174+ mesh.dimension = (10, 10, 5)
175+
176+ r2s = openmc.deplete.R2SManager(model, mesh)
177+
178+ Executing the R2S calculation is then performed by adding photon tallies and
179+ calling the :meth: `~openmc.deplete.R2SManager.run ` method with the appropriate
180+ timesteps and source rates. Note that in this case we do not need to define cell
181+ volumes or bounding boxes as is required for a cell-based R2S calculation.
182+ Instead, during the neutron transport step, OpenMC will run a raytracing
183+ calculation to determine material volume fractions within each mesh element
184+ using the :meth: `openmc.MeshBase.material_volumes ` method. Arguments to this
185+ method can be customized via the ``mat_vol_kwargs `` argument to the
186+ :meth: `~openmc.deplete.R2SManager.run ` method. Most often, this would involve
187+ customizing the number of rays traced to obtain better estimates of volumes. As
188+ an example, if we wanted to run the raytracing calculation with 10 million rays,
189+ we would run::
190+
191+ r2s.run(timesteps, source_rates, mat_vol_kwargs={'n_samples': 10_000_000})
45192
46193Direct 1-Step (D1S) Calculations
47194================================
0 commit comments