dose calculation

Hi Amna,

At present, OpenMC cannot tally dose responses directly. To get dose, you’d have to come up with your own flux-to-dose conversion factor and then apply it to the tallied flux (possibly as a function of energy) as a post-processing step. Another thing to keep in mind is that OpenMC does not handle photon or electron transport yet, so you will only be able to determine dose due to neutrons.

In the future, please post questions directly to the user’s group email (openmc-users@googlegroups.com). I receive all the messages there as do many of our other developers/users, so if I can’t reply promptly, someone else may be able to assist you.

Best,
Paul

I noticed this old post and wanted to add an example as I think dose for neutrons and photons can now be calculated using inbuilt dose coefficients from this code addition by @paulromano https://github.com/openmc-dev/openmc/pull/1558

I think this is nearly there but I appear to be getting strange numbers so I shall check the model a bit more

energy_bins_n, dose_coeffs_n = openmc.data.dose_coefficients(particle=“neutron”, geometry=“ISO”)
energy_bins_p, dose_coeffs_p = openmc.data.dose_coefficients(particle=“photon”, geometry=“ISO”)

energy_function_filter_n = openmc.EnergyFunctionFilter(energy_bins_n, dose_coeffs_n)
energy_function_filter_p = openmc.EnergyFunctionFilter(energy_bins_p, dose_coeffs_p)

surface_filter = openmc.SurfaceFilter(outer_surface)
surface_filter = openmc.SurfaceFilter(outer_surface)

dose_tally_photon = openmc.Tally(name=“photon_energy_dose_surface”)
dose_tally_photon.scores = [“current”]

dose_tally_photon.filters = [surface_filter, photon_particle_filter, energy_function_filter_p]

dose_tally_neutron = openmc.Tally(name=“neutron_energy_dose_surface”)
dose_tally_neutron.scores = [“current”]

dose_tally_neutron.filters = [surface_filter, neutron_particle_filter, energy_function_filter_n]

tallies = openmc.Tallies()
tallies.append(dose_tally_neutron)
tallies.append(dose_tally_photon)

I am wondering if the negative numbers I am getting are due to the use of the surface filter. Does anyone know if particles crossing the surface in one direction count as negative while the other direction the are positive additions to the dose tally?

Yes, that’s correct – surfaces going one direction are positive and the other direction are negative. Here’s the relevant snippet of code:

If you want to get only one direction, the best thing to do is to use a CellFromFilter indicating the cell that the particle would be traveling from.

Thanks Paul, CellFromFilter sounds perfect

Just noticed that the EnergyFunctionFilter uses linear-linear interpolation. We might need log-log or linear-log to get the dose rate correct

Good point @Shimwell – this should be relatively simple to implement. Thanks for opening an issue for that so we can track it.

Just trying to create a effective dose tally for a cell instead of for a surface (see above). I just wanted to check if the score should be flux?

energy_bins_n, dose_coeffs_n = openmc.data.dose_coefficients(particle=“neutron”, geometry=“ISO”)
energy_bins_p, dose_coeffs_p = openmc.data.dose_coefficients(particle=“photon”, geometry=“ISO”)

energy_function_filter_n = openmc.EnergyFunctionFilter(energy_bins_n, dose_coeffs_n)
energy_function_filter_p = openmc.EnergyFunctionFilter(energy_bins_p, dose_coeffs_p)

cell_filter = openmc.CellFilter(outer_cell)

dose_tally_photon = openmc.Tally(name=“photon_energy_dose_cell”)
dose_tally_photon.scores = [“flux”]

dose_tally_photon.filters = [cell_filter , photon_particle_filter, energy_function_filter_p]

dose_tally_neutron = openmc.Tally(name=“neutron_energy_dose_cell”)
dose_tally_neutron.scores = [“flux”]

dose_tally_neutron.filters = [cell_filter , neutron_particle_filter, energy_function_filter_n]

tallies = openmc.Tallies()
tallies.append(dose_tally_neutron)
tallies.append(dose_tally_photon)

Yes, that’s right @Shimwell. The values that are given by dose_coefficients are flux to dose factors, so the score you want is indeed flux.

1 Like

Thanks Paul, good to know I am on the right track. Much appreciated.

for surface dose I’ve been dividing the tally result by the surface area to end up with pico Sieverts per source particle crossing the surface

for cell dose I’ve been dividing the tally result by the cell volume to end up with pico Sieverts per source particle in the cell

for regular mesh tallies I’ve been dividing the tally result by the mesh voxel volume to end up with pico Sieverts per source particle in the mesh voxel

I’m then multiplying the results by the number of neutrons in a pulse to get pico Sieverts per pulse

Hi all,
following up on this topic, I would need few clarifications on the units of the tally that is obtained. If I got it right, applying the dose_coefficients means multiplying the flux tally with units [particle*cm/source] by the dose conversion factor with units [pSv-cm2/source] and that will give us a tally value in [pSv-cm3 / source].
To obtain values in units per seconds I usually multiply by the number of source particles per second I estimate in my system, but it doesn’t seem quite right in here. Can anyone give me a insight on this? Thanks

Hi Lorenzo

I think applying the EnergyFunctionFilter with dose_coefficients converts the output units of a tally with a flux score into units of [pSv per source particle]

I believe to get [pSv per second] you would then multiply by the number of particles per second emitted by the source.

I’ve been trying to automated unit conversion like this and perhaps this package and example is handy

Hi @Shimwell, thank you for the clarification and the package link.

Hi @Shimwell and @lorenzo ,

Please correct me if I’m wrong, but my understanding is that using the EnergyFunctionFilter with dose_coefficients does give units of [pSv-cm^3/source_particle], since the flux tally is given in [particles-cm/source particle] and the dose_coefficients are in [pSv*cm^2].

So to get [pSv/second] you would need to multiply but the source strength in [particles/second] and also divide by the cell tally volume (or mesh voxel volume for mesh tallies) in [cm^3]. Is this correct?

1 Like

Hi @kevinm387,
Yes that’s correct, you also need to divide by the tally volume.

Hi All again,
I have another doubt about dose conversion factors and material definition of the cell tally.
Being these factors calculated for very specific human phantoms, should we define our cell tally having the same average material composition of those, and if so does someone has any reference?
I ask the question cause I’ve noticed that slightly varying the water material composition of the cell tally can cause different results, especially in the absorbed neutron dose. Thanks

Hi @lorenzo

I have been using a tissue material for the phantom.

Not sure if I have the ideal material but there are some tissue materials in the materials compendium. If you search for tissue in this file there are a few neutronics_material_maker/pnnl_materials.json at main · fusion-energy/neutronics_material_maker · GitHub

I have also added some examples to the neutronics workshop to include cell tallies with phantoms and comparison with hand calcs

All the best

1 Like

Hi there,
I’m not sure this is entirely correct. I’ve been doing some reading in the ICRP-report (of 1974) whence the dose-coefficients that are applied come. As far as I can understand the coefficients are computed using a (presumably detailed) phantom with organs and their respective material composition.

This would suggest that the flux should be tallied in a void, to avoid applying material effects twice - would it not? Or if that’s inconvenient that it should only be tallied on impinging flux.

I made a sphere model over here where I compare ICRP dose with openmc phantom dose and got quite similar numbers. Might be handy

Thanks @Shimwell. Upon taking another look through the ICRP-report I believe you are quite right. Sec 2.3.2 specifically says that dose should be measured in the ICRU 4-element tissue model.