Skip to content

Implementation of migration area score#3810

Open
GuySten wants to merge 11 commits intoopenmc-dev:developfrom
GuySten:migration
Open

Implementation of migration area score#3810
GuySten wants to merge 11 commits intoopenmc-dev:developfrom
GuySten:migration

Conversation

@GuySten
Copy link
Contributor

@GuySten GuySten commented Feb 16, 2026

Description

This PR implement 'migration-area' score to calculate diffusion coefficients and transport cross sections for multigroup.

Fixes #1734

Theory

https://www.researchgate.net/publication/324831861_Group-wise_Tally_Scheme_of_Incremental_Migration_Area_for_Cumulative_Migration_Method

Example

import openmc
import matplotlib.pyplot as plt

model = openmc.Model()

# Material
material = openmc.Material(name="Hydrogen")
material.add_nuclide("H1", 1.0)
material.set_density('g/cm3', 1.0)
material.add_s_alpha_beta('c_H_in_H2O')

# Geometry
radius = 10.0
sphere = openmc.Sphere(r=radius, boundary_type="reflective")
cell = openmc.Cell(region=-sphere, fill=material)
model.geometry = openmc.Geometry([cell])

# Settings
model.settings.particles = 100000
model.settings.batches = 20
model.settings.run_mode = 'fixed source'
model.settings.source = openmc.IndependentSource()
    

# Tally 
groups = openmc.mgxs.EnergyGroups('CASMO-70')
energy_filter = openmc.EnergyFilter(groups.group_edges)
tally = openmc.Tally()
tally.scores = ["migration-area", "flux", "total"]
tally.filters = [energy_filter]
model.tallies = [tally]

model.run()


with openmc.StatePoint('statepoint.20.h5') as sp:
    tally = sp.get_tally(id=1)
    
energies = 0.5*(groups.group_edges[1:]+groups.group_edges[:-1])
flux =  tally.get_values(value='mean', scores=['flux']).squeeze()
total =  tally.get_values(value='mean', scores=['total']).squeeze()
migration_area = tally.get_values(value='mean', scores=['migration-area']).squeeze()

migration_area /= flux
total /= flux

plt.semilogx(energies,1/(3*migration_area*total))
plt.title(r'$\Sigma_{tr}/\Sigma_t$')
plt.show()
Figure_1

Reference results:

Untitled

Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 15) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

@GuySten GuySten marked this pull request as ready for review February 16, 2026 19:20
@GuySten GuySten requested a review from paulromano as a code owner February 16, 2026 19:20
@GuySten GuySten requested review from jtramm and pshriwise March 2, 2026 12:36
Copy link
Contributor

@GiudGiud GiudGiud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

k_abs_tra; //!< sum over batches of k_absorption * k_tracklength
k_abs_tra; //!< sum over batches of k_absorption * k_tracklength
extern bool
migration_present; //! Does an active tally contains a migration score
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this global variable is justifiable because we need it during the simulation at every BC

extern double total_weight; //!< Total source weight in a batch
extern int64_t work_per_rank; //!< number of particles per MPI rank
extern bool
nonvacuum_boundary_present; //!< Does the geometry contain non-vacuum b.c.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is not, it's a setup item it should be handled with a check over all surfaces not the setting of a global boolean

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is set when reading surfaces and used when setting tallies.
So removing it will involve alot of function signature change.
I think this way is better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you would just need to not set it when reading surfaces, then when setting tallies you can loop over the geometry/surfaces if migration tallies are used to check their type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general it is not recommended to iterate over cells or surfaces twice because there are models with alot of cells and surfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulromano, what do you think?

This issue can affect performance.

tally.filters = [energy_filter]
model.tallies = [tally]

return model
Copy link
Contributor

@GiudGiud GiudGiud Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this test case the one used for the figures? If so let's keep it, we somewhat know what the result looks like

But we also need coverage on all the other types of supported boundary conditions. So let's make either:

  • a dummy test featuring all these
    or better:
  • a test featuring these BCs but that gives the exact same result due to the symmetries of the geometry

Copy link
Contributor Author

@GuySten GuySten Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current regression test is the same one from the example.

I've added a test that a large water sphere gives the same results as a small one with reflective boundary conditions.

I think I know how to extend this PR to white boundary conditions but I will leave that as a potential future PR.

Copy link
Contributor

@GiudGiud GiudGiud Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I know how to extend this PR to white boundary conditions but I will leave that as a potential future PR.

Yes for sure.
If OpenMC testing involves exception testing we'll just want a test that shows the error.
@paulromano might give guidance on whether it's needed here

GuySten and others added 5 commits March 10, 2026 21:28
Co-authored-by: Guillaume Giudicelli <guillaume.giudicelli@gmail.com>
Co-authored-by: Guillaume Giudicelli <guillaume.giudicelli@gmail.com>
Co-authored-by: Guillaume Giudicelli <guillaume.giudicelli@gmail.com>
Co-authored-by: Guillaume Giudicelli <guillaume.giudicelli@gmail.com>
@GiudGiud
Copy link
Contributor

GiudGiud commented Mar 10, 2026

@GuySten you should be able to lump the suggestions from the files tab (cant do it from the conversation tab) to limit the test suite runs (for next time)

@GuySten GuySten requested a review from GiudGiud March 10, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discussion about adding a new tally for CMM

2 participants