Skip to content

Allow calculations without neutrons to skip neutron data entirely - #63

Draft
GuySten wants to merge 12 commits into
claude/assert-xs-particle-typefrom
claude/sharp-tesla-00fexy
Draft

GuySten wants to merge 12 commits into
claude/assert-xs-particle-typefrom
claude/sharp-tesla-00fexy

Conversation

@GuySten

@GuySten GuySten commented Sep 14, 2026 •

Copy link
Copy Markdown
Owner

Description

Stacked on #64, a cross section cache fix for pre-existing bugs this work exposed, which is going upstream on its own. Review #64 first; the diff here is only the feature.

Photon and electron transport are driven entirely by per-element data, so a calculation in which no neutrons appear does not need neutron cross sections. OpenMC nevertheless requires a type="neutron" entry in cross_sections.xml for every nuclide in every material and then reads the corresponding HDF5 file, whether or not a neutron is ever transported.

That is not only wasteful. ENDF/B-VII.1 carries photoatomic data for every element through Z=100, but its neutron sublibrary has no evaluation for neon, ytterbium, osmium or platinum — so none of those four can appear in a photon calculation at all, even though every cross section such a calculation needs is sitting in the library. It fails in Python, at Material.add_element, before OpenMC starts:

ValueError: Unable to expand element Pt because the cross section library
provided does not contain any of the natural isotopes for that element.

Platinum is the one most likely to be missed: it is the encapsulation and the radiopaque marker of brachytherapy sources, and Yb-169 is itself a brachytherapy source isotope.

The photon transport step of an R2S calculation is the other motivating case: its source comes from the decay of activated materials, so it transports no neutrons of its own.

settings.run_mode = 'fixed source'
settings.photon_transport = True
settings.neutron_transport = False          # new
settings.source = openmc.IndependentSource(particle='photon')

With that, cross_sections.xml only has to list the photon data for the elements in the model.

How nuclide properties are obtained without a library

A new Nuclide constructor builds a nuclide from its name alone. Z, A and the metastable state are parsed from the name; the atomic weight ratio comes from the AME2020 masses already in the tree (added in openmc-dev#4129) rather than from a data file.

Elemental evaluations such as C0, which some libraries provide in place of the individual isotopes, are supported through a new ATOMIC_WEIGHT table of natural-abundance-weighted atomic masses. ENDF/B-VII.1 is one such library — it carries C0 rather than C12 and C13 — so a material carried over from a calculation that used it may well contain one. openmc.data.atomic_mass previously knew elemental masses for only six hardcoded elements; it now computes them for every element with naturally occurring isotopes, so the Python API can read back what the C++ side accepts.

Only canonical GNDS spellings are accepted. ParticleType also parses aliases like alpha, h1 and bare PDG numbers, and accepting those would make a model run only while neutron data was being skipped.

Densities may differ in the last few digits from a run that reads neutron data, since AME2020 and a library's tabulated atomic weight ratios are not bit-identical. For elemental evaluations the difference can reach a part in a thousand. The statepoint records neutron_transport so post-processing can tell which of the two a run's masses came from.

Expanding an element with no neutron data

Element.expand() decides which isotopes exist by reading cross_sections.xml, and refused outright when the library listed none for the element — the error above. But photon data is tabulated per element, so a library with no neutron data for an element is simply silent about its isotopes, and natural abundance is the whole of what it knows.

It now falls back to natural abundance in exactly two cases: a library with no neutron data at all, as a photon-only calculation uses, and one whose photon data covers an element its neutron data skips, which is the ENDF/B-VII.1 case above. An element with neither kind of data is still an error, as are the partial cases the surrounding code already handled — C0 standing in for C12 and C13, O18 folded into O16.

A neutron calculation naming one of those four elements now fails when the data is actually wanted, reporting the missing nuclide, rather than at expansion — the same error one step later, and the price of the model being usable at all when neutrons are not transported.

Which particles get transported

A photon source turns photon transport on, because that setting is off by default and a source saying it emits photons settles something never specified.

Neutron transport has no counterpart. It is only ever off because it was asked for, so turning it back on would override an explicit choice, silently change which particles a calculation transports, and surface later as missing data rather than as the source that caused it. It also cannot be applied uniformly — a compiled source cannot be inspected before the data decision is made. So a source that emits neutrons is an error instead:

ERROR: A source emits neutrons, but neutron transport is turned off. Either
       turn it back on or give a source that does not emit neutrons.

A model specifying no source at all falls back to OpenMC's default source, which emits neutrons, and is reported the same way rather than as missing nuclide data further along.

Sources whose particles are not knowable up front are checked when the particle appears: a compiled source emitting a neutron, and a particle restart file holding one, both report it rather than transporting with no data.

Run modes

Only eigenvalue and fixed source calculations sample the external source, so sources are not checked elsewhere. A stochastic volume calculation samples no source and transports nothing, so it reports nuclide inventories without reading any neutron data — and with no data at all if the model carries no photon source. Plotting reads none either.

What is skipped for want of neutron data

  • The logarithmic neutron energy grid, whose spacing would otherwise be derived from the unbounded defaults left behind when no nuclide has an energy grid.
  • The minimum/maximum neutron data temperature message.
  • Cell::set_temperature's interpolation bounds check, which has no temperature-dependent data to bound against.

Rejected combinations

Each of these would otherwise do nothing silently:

Combination Reason
Eigenvalue mode needs neutrons
Multi-group mode multi-group data is neutron data; also covers the random ray solver, which requires it
Thermal scattering <sab> affects neutron scattering only
NCrystal <cfg> likewise
Resonance scattering acts on neutron data
Multipole data likewise
use_decay_photons (D1S) replaces photons produced in neutron reactions, so with no neutron reactions it produces nothing. R2S, whose source is a decay source, is unaffected

Fixes found in review

Two independent reviews of this branch found problems it had made reachable:

  • A nuclide-filtered tally with multiply_density off called the neutron cross section routine for whatever particle was being scored — a segfault with no neutron data. Fixed in Keep the micro cross section caches addressed correctly #64, where it belongs; the regression test stays here, since this branch is what makes the crash reachable.
  • Sources OpenMC cannot inspect up front reached transport with no data, segfaulting. Now reported, with the error serialized so threads do not race through std::exit.
  • Nuclide::reaction_index_ is only filled by create_derived(), which neither the new constructor nor the volume-mode early return reaches, leaving 902 garbage entries that pass the >= 0 test callers use before indexing an empty reactions_. Filled in both constructors, which also fixes the pre-existing volume mode case.
  • A bad nuclide name reached the C API as std::exit rather than an error code, killing the host interpreter. openmc_load_nuclide now reports it through set_errmsg and OPENMC_E_DATA. (The same pattern in Tally::set_nuclides and read_ce_cross_sections is independent of this branch and is fixed separately in Report unresolvable nuclide names instead of terminating, and fix the tally docs #66.)

Testing

tests/unit_tests/test_neutron_transport_off.py runs against a library built by stripping everything but the photon entries out of the configured one, so a run that touched neutron data in any way could not succeed. It covers the photon-only run itself (including that densities are normalized from the tabulated masses), that the same library is still rejected without opting in, rejection of neutron sources and of each combination above, elemental evaluations, volume mode, the particle restart path, and the tally case that used to crash.

tests/unit_tests/test_element.py covers expansion against a synthetic cross_sections.xml: a photon-only library expands by natural abundance, so does a library whose neutron data skips the element while its photon data covers it (parametrized over Pt, Os, Yb and Ne), an element with neither kind of data is still refused, and non-neutron entries never count as isotope availability. Those build their own XML rather than needing a data library.

tests/cpp_unit_tests/test_nuclide.cpp covers the data-free constructor: identity and mass from the name, metastables, H1 taking the atomic rather than the bare proton mass, elemental evaluations, reaction_index_, and rejected names. Atomic weight ratios are asserted against values from a neutron data library rather than re-derived from the table under test.

Verified against the real ENDF/B-VII.1 HDF5 library: the four gap elements were confirmed by enumerating its 443 neutron and 100 photoatomic files against NATURAL_ABUNDANCE, Element('Pt').expand() reproduces the error above without this change, and a platinum photon model runs to completion with it, reading Pt photoatomic data and no neutron data at all.

Not covered: comparing a physics result with and without neutron data. That needs both runs to be possible for the same model, which they are not for these four elements.

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)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

🤖 Generated with Claude Code

https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c

@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 3c20c4f to 895c455 Compare September 14, 2026 13:28
@GuySten
GuySten changed the base branch from develop to claude/assert-xs-particle-type September 14, 2026 13:28
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 895c455 to 0167f97 Compare September 14, 2026 14:00
@GuySten GuySten changed the title Add support for running without neutron transport data Allow calculations without neutrons to skip neutron data entirely Sep 14, 2026
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 0167f97 to 38e98f2 Compare September 14, 2026 14:16
@GuySten
GuySten changed the base branch from claude/assert-xs-particle-type to claude/report-data-errors September 14, 2026 14:16
@GuySten
GuySten force-pushed the claude/report-data-errors branch from 93cb39e to e873494 Compare September 14, 2026 14:21
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 38e98f2 to 0f1b967 Compare September 14, 2026 14:21
@GuySten
GuySten force-pushed the claude/report-data-errors branch from e873494 to 3a09103 Compare September 14, 2026 14:26
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 0f1b967 to 4e72bdb Compare September 14, 2026 14:27
@GuySten
GuySten force-pushed the claude/report-data-errors branch from 3a09103 to 49a86af Compare September 14, 2026 14:28
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 4e72bdb to 6364fdb Compare September 14, 2026 14:28
@GuySten
GuySten force-pushed the claude/report-data-errors branch from 49a86af to 9471cd4 Compare September 14, 2026 14:32
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 6364fdb to f12ae89 Compare September 14, 2026 14:32
@GuySten
GuySten changed the base branch from claude/report-data-errors to claude/assert-xs-particle-type September 14, 2026 14:33
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from cfff90e to 84896c1 Compare September 14, 2026 14:39
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from f12ae89 to 396b346 Compare September 14, 2026 14:39
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from 84896c1 to 36872ed Compare September 14, 2026 16:33
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 396b346 to 7e7250f Compare September 14, 2026 16:33
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from 36872ed to c507e5f Compare September 14, 2026 16:47
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 7e7250f to 7a43a73 Compare September 14, 2026 16:47
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from c507e5f to bdc0fb4 Compare September 14, 2026 16:51
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from 7a43a73 to f854342 Compare September 14, 2026 16:51
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from bdc0fb4 to 4b24cf1 Compare September 14, 2026 16:56
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from f854342 to a34d085 Compare September 14, 2026 16:56
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from 4b24cf1 to 047ad5c Compare September 14, 2026 17:01
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from a34d085 to f77afaf Compare September 14, 2026 17:02
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from 047ad5c to e83a7ec Compare September 14, 2026 17:08
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from f77afaf to 9e0e18c Compare September 14, 2026 17:08
Photon and electron transport are driven entirely by per-element data, but
OpenMC required a type="neutron" entry in cross_sections.xml for every nuclide
in every material and then read the corresponding HDF5 file, whether or not
neutrons were ever transported. A photon-only calculation therefore needed a
neutron data library it never used, and Element.expand() could not expand an
element against a library holding only photon data.

Add a neutron_transport setting (default true) that turns this off:

* Material::init_nuclide_index no longer requires a neutron library entry, and
  openmc_load_nuclide creates the nuclide without opening an HDF5 file.
* A new Nuclide constructor builds a nuclide from its name alone, taking Z, A
  and the metastable state from the name and the atomic weight ratio from the
  tabulated AME2020 atomic masses rather than from the data library. Nuclide
  names that cannot be resolved this way, such as elemental data like C0, are
  reported as errors.
* The neutron energy grid setup, the neutron temperature bounds and the
  temperature interpolation check are skipped, since no neutron data exists to
  define them.
* Element.expand() ignores non-neutron library entries and falls back to
  natural abundances when a library has no neutron data at all, so
  Material.add_element works against a photon-only library.

Mirroring the way a photon source turns photon transport on, a source that
emits neutrons turns neutron transport back on, so a model is never left
transporting particles for which no data was read. Combinations that would
otherwise silently do nothing are rejected: eigenvalue mode, multigroup mode,
thermal scattering data, resonance scattering, decay photon sources, and
turning neutron transport off without photon transport on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
Test the feature against a cross section library built by stripping everything
but the photon data out of the configured one, so a run that touched neutron
data in any way could not succeed. The tests cover the photon-only run itself
(including that densities are normalized from the tabulated atomic masses), that
the same library is still rejected without opting in, that a neutron source
turns neutron transport back on, and that thermal scattering data and eigenvalue
mode are rejected.

Also complete the source-driven enabling: the default source used when a model
specifies none is built through the programmatic IndependentSource constructor
rather than the XML one, so it was not turning neutron transport back on and
would have left neutrons being sampled with no data to transport them with.
Moving the call into that constructor covers every IndependentSource, which in
turn makes the "no particles would be transported" check unreachable -- a source
always enables transport of its own particle type -- so drop it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
The default source created when a model specifies none is built through the
programmatic IndependentSource constructor, which takes no particle type, so
enabling transport there was a hard-coded neutron_transport = true expressed as
a call on a value that is always the default. Set it where the default source is
created instead, so the reason is visible at the point it applies and the
constructor carries no global side effect. Behavior is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
…idden

A fixed source calculation with neutron transport turned off and no source
specified fell back to the default neutron source, turned neutron transport back
on, and then failed with "Could not find nuclide ... in the nuclear data
library" -- which points at the data rather than at the real mistake. Report the
missing source instead. Other run modes keep the existing fallback, since they
do not sample the external source.

Sources turning transport back on is deliberate, but doing so silently leaves no
sign that the setting was overridden, so warn when a source has turned neutron
transport back on after the user asked for it to be off. Plotting is excluded
because it reads no data, so the setting has no bearing on it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
Only eigenvalue and fixed source calculations sample the external source, so the
default source that stands in when a model specifies none has no bearing on the
others. Turning neutron transport back on for all of them meant a stochastic
volume calculation still demanded neutron data it never used; it samples no
source and transports nothing, needing only the names and densities of the
nuclides present, so let it run with no data at all. Plotting reads no data
either way.

A particle restart does transport, but takes its particle from the restart file
rather than from a source, and its type is only known once that file has been
read -- long after the decision of which data to load. A restarted neutron
therefore reached transport with no energy grid to look up and segfaulted;
report it instead.

The random ray solver needs no separate handling: it requires multi-group mode,
which already rejects turning neutron transport off. A test covers that path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
Testing the restart guard meant writing a restart file by hand, since OpenMC
only produces them for particles that get lost. A fabricated data file is not
worth having in the suite. The guard itself stays.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
Restarting was the one behavior left without a test after the hand-written
restart file was dropped. Losing a particle is what makes OpenMC write these
files, so let it: the material does not reach the outer boundary, leaving a gap
that every photon leaving it is lost in. Restarting from the resulting file
exercises the restart path against a run that read no neutron data.

How many files get written depends on the thread count, since the write limit is
checked before the lost particle count is incremented, so the test takes any one
of them rather than asserting on the number. Verified with 1, 2 and 4 threads.

This covers a photon restart, which needs no neutron data. The guard that
reports a restarted neutron when neutron transport is off remains covered only
by manual testing, since producing a neutron restart file would require the
neutron data the test is built to do without.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
"Decay photon sources are produced by neutron activation" was misleading: R2S
also drives photon transport from a decay source, and its photon step is one of
the clearest uses of running without neutron data. What cannot work is D1S,
where a single coupled neutron-photon calculation replaces the photons produced
in neutron reactions with decay photons, so with no neutron reactions it would
produce no photons at all. Name that method in the error and point R2S users
elsewhere, and document the distinction.

Also add the missing underscore to the decay sources label, which made it a
comment rather than a target. Nothing referenced it until now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
An independent review turned up two segfaults and an uninitialized member that
this branch had made reachable.

A nuclide-filtered tally with multiply_density off takes a branch that fills the
neutron micro cross section cache whenever the tallied nuclide is absent from
the scoring region, with no check on the particle type. For a photon that was
already wasted work computing a neutron cross section at a photon energy; with
no neutron data it dereferences an empty energy grid. A cell filter over a void
region is enough to reach it. Guard both estimators on the particle type.

Sources OpenMC cannot inspect up front do not go through enable_transport, so a
compiled source emitting neutrons reached transport with no data. Check the
particle type in Particle::from_source. Every thread arrives at once, so the
error is serialized; racing through std::exit turned a reported error into a
segfault.

Nuclide::reaction_index_ is only filled by create_derived(), which neither the
data-free constructor nor the volume calculation early return reaches, leaving
902 garbage entries that pass the >= 0 test callers use before indexing an empty
reactions_. openmc.lib.nuclides[...].collapse_rate() aborted on it. Fill it in
both constructors, which also fixes the pre-existing volume mode case.

Also: validate the nuclide name before registering anything globally and report
failures through the C API rather than calling std::exit, so a bad nuclide no
longer kills the host interpreter; reject multipole data, which became reachable
once photon transport stopped being required; move the neutron_transport reset
next to photon_transport's; and say in the docs that elemental evaluations such
as C0 cannot be used, which materials carried over from a neutron calculation
may well contain.

Tests: assert atomic weight ratios against literals from a neutron data library
rather than re-deriving them from the table under test, cover reaction_index_
and rejected names, and add a regression test for the tally crash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
Turning neutron transport back on when a source emits neutrons mirrored the way
a photon source turns photon transport on, but the two are not the same
operation. Photon transport is off by default, so a photon source settles
something the user never specified; neutron transport is only ever off because
it was asked for, so doing the same there overrides an explicit choice. It also
could not be applied uniformly -- a compiled source cannot be inspected before
the data decision is made -- which left three different outcomes depending on
where the neutrons came from. Reject such a source instead, so every path
reports the same thing, and at the source rather than as missing data further
along. The override warning goes with it.

Elemental evaluations such as C0, which several libraries provide in place of
the individual isotopes, are now supported rather than rejected: their mass is
the natural-abundance-weighted atomic weight, which is what such an evaluation
reports as its atomic weight ratio. The table is computed from the AME2020
masses and natural abundances already in the repository. A material carried over
from a calculation that used a neutron library may well hold one of these, so
rejecting them would have blocked the R2S photon step this setting exists for.

Also reject an NCrystal configuration, which configures neutron scattering in
the same way S(a,b) data does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
A second independent review found that ParticleType parses all-digit names with
std::stoi, which throws out_of_range rather than invalid_argument on overflow.
That is a logic_error either way, but only invalid_argument was caught, so a
material naming something like 99999999999 terminated on an uncaught exception
with no message, and killed the host interpreter through the C API. Catch the
common base.

The same parser also accepts aliases such as "alpha", "h1" and "proton", and
bare PDG numbers, none of which a data library would name a nuclide. Accepting
them here meant a model would run only while neutron data was being skipped, and
would write names into summary.h5 and the volume files that the Python API
cannot parse back. Require the canonical spelling, reporting what it should be.

Also: record neutron_transport in the statepoint, so post-processing can tell
whether the atomic weight ratios came from a library or from AME2020; correct
the claim that an elemental evaluation's atomic weight ratio is the abundance-
weighted mass, which can differ by a part in a thousand; and note that a volume
calculation still reads photon data if the model carries a photon source.

openmc.data.atomic_mass now computes elemental masses for every element with
naturally occurring isotopes rather than a fixed list of six, so the Python API
can read back materials the C++ side accepts. Values for those six are
unchanged; the C++ table agrees with Python across all 84 elements to 4e-9.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
@GuySten
GuySten force-pushed the claude/assert-xs-particle-type branch from e83a7ec to e94fcbd Compare September 14, 2026 17:57
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch 2 times, most recently from 5208518 to 051d7f3 Compare September 15, 2026 11:04
Element.expand() decides which isotopes exist by reading cross_sections.xml,
and refuses outright when the library lists none for the element. The fallback
added earlier on this branch only covered a library holding no neutron data at
all, which is the photon-only case but not the one users actually hit.

ENDF/B-VII.1 carries photoatomic data for every element through Z=100, but its
neutron sublibrary has no evaluation for neon, ytterbium, osmium or platinum.
None of those four can appear in a photon calculation at all -- not as a bulk
material, and not as the platinum encapsulation or marker band of a
brachytherapy source, which is where a photon model is most likely to meet it.
It fails at Material.add_element, before OpenMC starts:

  ValueError: Unable to expand element Pt because the cross section library
  provided does not contain any of the natural isotopes for that element.

Decide per element as well as per library. A library with no neutron data at
all still says nothing about any element, as before; now neither does one whose
neutron data skips this element while its photon data covers it. Either way
natural abundance is the whole of what the library knows, so expand by it. An
element with neither kind of data is still an error, unchanged, as are the
partial cases the surrounding code already handles -- an elemental evaluation
such as C0 standing in for C12 and C13, and O18 folded into O16.

A neutron calculation naming one of these four now fails when the data is
actually wanted, reporting the missing nuclide, rather than at expansion. That
is the same error one step later, and it is the price of the model being usable
at all when neutrons are not transported.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxR1sQWWnALXj39rX12v7c
@GuySten
GuySten force-pushed the claude/sharp-tesla-00fexy branch from f17f294 to 6bad8f0 Compare September 15, 2026 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants