Skip to content

Random Ray Forward Flux Save in Adjoint Mode#3962

Open
jtramm wants to merge 9 commits into
openmc-dev:developfrom
jtramm:rrm_forward_flux_save
Open

Random Ray Forward Flux Save in Adjoint Mode#3962
jtramm wants to merge 9 commits into
openmc-dev:developfrom
jtramm:rrm_forward_flux_save

Conversation

@jtramm
Copy link
Copy Markdown
Contributor

@jtramm jtramm commented Jun 5, 2026

Problem

This PR addresses Issue #3379. In random ray adjoint mode (e.g. FW-CADIS), OpenMC runs a forward flux solve, uses it to build the adjoint source, then runs the adjoint solve. The forward solve writes the usual output files, but the adjoint solve overwrites them, so the forward solution is lost. The forward solve also writes a weight_windows.h5 that is meaningless (only the final adjoint-derived weight windows matter).

Change

When a forward solve precedes an adjoint solve, its output is tagged with a forward infix so it is no longer clobbered:

Forward solve Adjoint solve (unchanged)
statepoint.forward.N.h5 statepoint.N.h5
tallies.forward.out tallies.out
<plot>.forward.vtk <plot>.vtk
(no weight window file) weight_windows.h5

To allow the file i/o regions of the code to know when this sort of labeling is appropriate, I ended up refactoring some of the logic that determines when and if forward and/or adjoint solves are used. Previously this involved a combination of several local and global variables and with this addition was starting to get fairly onerous. If I had left the old logic intact we would have needed yet another global variable stapled on, so I figured it was worthwhile to reorganize this area.

The new forward/adjoint orchestration tracks the current pass with a FlatSourceDomain::solve_ enum (FORWARD, FORWARD_FOR_ADJOINT, or ADJOINT). This also folds the forward/adjoint mode tracking into a single enum and simplifies the openmc_run_random_ray() control flow.

Note that I didn't add any new regression test given that we're just renaming some files and not really introducing a new feature.

Docs

Updated the Adjoint Flux Mode section of the random ray user guide (the prior text incorrectly stated the forward solution is not saved).

Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 18) 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)

Closes #3379.

jtramm and others added 9 commits June 4, 2026 21:13
When a random ray adjoint (FW-CADIS) run performs an initial forward solve, its output files were overwritten by the subsequent adjoint solve. Tag the forward solve's statepoint, tallies, and voxel plots with a "forward" infix (statepoint.forward.N.h5, tallies.forward.out, *.forward.vtk) and skip the meaningless forward weight-window export. Adjoint and all other output names are unchanged. Local FW-CADIS (user-supplied adjoint source, so no forward solve) is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collapse the overloaded FlatSourceDomain::adjoint_ flag and the temporary simulation::adjoint_forward_pass flag into single-purpose state: FlatSourceDomain::adjoint_requested_ (run-level config) and a RandomRaySolve solve_ enum (FORWARD / FORWARD_FOR_ADJOINT / ADJOINT) for the current pass, exposed via adjoint() (physics) and outputs_are_intermediate() (output naming / weight-window suppression). openmc_run_random_ray() now derives the run shape (run_forward, run_adjoint) once and runs two guarded solve blocks instead of repeated conditionals and an early return. No behavior change for pure-forward, global FW-CADIS, or local (user adjoint source) runs. Removes the random-ray flag from the core simulation.h.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
run_adjoint was always identical to want_adjoint: an adjoint solve runs exactly when requested. Keep a single variable and state that invariant in the comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Explain why a forward solve precedes the adjoint solve (the adjoint source is constructed from the forward flux when the user has not defined one), rather than restating the boolean logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the original wording for the adjoint request flag comment, merge the weight window export comment into a single coherent note, simplify the solve orchestration comments, and make output tagging comments uniform. Comment-only change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shared_site_bank.h and dagmc.patch are local untracked files that were swept up by an overly broad git add; remove them from tracking (files remain on disk).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Random ray mode enums (RandomRayVolumeEstimator, RandomRaySourceShape, RandomRaySampleMethod) are all defined in constants.h alongside SolverType, so RandomRaySolve belongs there too rather than locally in flat_source_domain.h.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /*from_forward=*/ annotation has no precedent in the codebase, and the user guide consistently writes "e.g.," with a comma.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
adjoint() and outputs_are_intermediate() each had only a few call sites, and the direct comparisons against RandomRaySolve enumerators are clearer than the function names they were hidden behind.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jtramm jtramm requested a review from paulromano June 5, 2026 21:25
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.

FW-CADIS StatePoint output

1 participant