Fix performance regression in libMesh unstructured mesh tallies #3577
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
#3185 added support for adaptive libMesh tallies initialized by an external C++ driver application (e.g. Cardinal) to support a project investigating adaptive mesh refinement applied to unstructured mesh tallies in Monte Carlo particle transport. Unfortunately, this addition also introduced a bug which yielded a massive performance penalty during tallying for users of both OpenMC and Cardinal. The crux of the issue is the function
was changed to
Without getting too deep into the weeds of how libMesh is designed and the process behind adaptive mesh refinement, the return value of
n_elem()
is cached when the libMesh mesh is constructed, whilen_active_elem()
(required for AMR) is not. This necessitates what is essentially a loop over all elements every timen_active_elem()
is called, which in the case of transport is every time a libMesh element accumulates a hit due to this function:This Implementation
To fix this performance regression, I've reverted the
LibMesh
class back to it's previous state. All of the adaptivity code necessary for mesh tally AMR in Cardinal has been moved to a new class calledAdaptiveLibMesh
which inherits fromLibMesh
and overrides the few functions required to get adaptivity working.n_active_elem()
is cached on construction to avoid any performance hits in transport. This should insulate OpenMC users from any other changes made to support the AMR project in Cardinal, such as #3553.Simpler Implementation
If a simpler fix is desired, I can revert these changes and simply implement the cache for
n_active_elem()
inLibMesh
. I decided to go all the way in an attempt to guard against future performance regressions.FYI @pshriwise @aprilnovak
Checklist
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)