# Fix "No fission sites banked" and run-mode/source mistakes in OpenMC

Use this when OpenMC aborts with `ERROR: No fission sites banked on MPI rank
0` (often followed by an `MPI_Abort`), or when a fixed-source shielding /
detector problem produces no usable result. The error has two distinct
causes — wrong run mode vs genuinely missing fissile material — and the fix
is different for each. Classify before changing anything.

## 1. Read the error and classify

The full signature looks like this:

```
ERROR: No fission sites banked on MPI rank 0
Abort(-1) on node 0 (rank 0 in comm 0): application called MPI_Abort(MPI_COMM_WORLD, -1) - process 0
```

In the Python API the same failure surfaces as `RuntimeError: No fission
sites banked on MPI rank 0`. Now ask one question: **does your model contain
fissile material that should sustain a chain reaction?**

- **Case A — it does not.** You defined a source (`settings.source`) and
  non-fissile materials (graphite stack, water shield, detector geometry),
  i.e. a fixed-source shielding or flux problem — but `run_mode` defaults to
  `'eigenvalue'`. OpenMC tried to bank fission sites from a first generation
  that can never produce them. Fix: the run mode (step 2). This is the most
  common cause on the forum.
- **Case B — it should.** You intended an eigenvalue calculation on fuel.
  Then the material composition is wrong: a typo in a nuclide name, an
  element added where a nuclide was needed, or a natural element with no
  fissile isotope at the density you set. Fix: the material (step 3).

Do not "fix" case A by adding fake fissile material, and do not "fix" case
B by switching to fixed source — each hides the real mistake.

## 2. Case A: switch genuinely fixed-source problems to fixed source

Set the run mode explicitly; the default `'eigenvalue'` is not what you
want when there is no fission chain to iterate:

```python
settings = openmc.Settings()
settings.run_mode = 'fixed source'
settings.batches = 20
settings.particles = 10000

source = openmc.IndependentSource()
source.space = openmc.stats.Point((0, 0, 10))
source.angle = openmc.stats.Isotropic()
source.energy = openmc.stats.Discrete([4.2e6], [1])
settings.source = source
```

Notes that bite people:

- Valid `run_mode` values are `'eigenvalue'` (default), `'fixed source'`,
  `'plot'`, `'volume'`, and `'particle restart'` — the space in `'fixed
  source'` is required; `'fixed_source'` is not accepted.
- In fixed-source mode there is no fission source to converge, so **all
  batches are active** — do not set `settings.inactive`; it has no meaning
  here.
- Fission is still simulated by default in fixed-source runs (fission
  neutrons are created and multiply). If you want a pure non-multiplying
  transport solve, set `settings.create_fission_neutrons = False`.
- A common tell of case A: `settings.source` is set *and* the run dies on
  the first batch. Eigenvalue runs ignore `settings.source` for the fission
  bank, so a defined source plus this error is near-certain case A.

## 3. Case B: verify the material actually contains fissile nuclides

Check what is really in the model before assuming the solver is at fault:

```python
for mat in materials:
    print(mat.name, mat.get_nuclides())
```

Frequent culprits:

- **Typo or wrong naming.** Nuclide names are case-sensitive strings like
  `'U235'` / `'Pu239'`. Adding element `'U'` gives natural uranium (mostly
  U238); adding `'U235'` as an element is not the same as adding the
  nuclide. Confirm the fissile nuclide appears in `get_nuclides()`.
- **Zero-density or unset density.** A material whose density was never set
  (or set to 0) contributes no atoms; fission sites cannot be banked in it.
- **Source or cell mismatch (rarer).** If the source samples points outside
  all fissile cells — e.g. an `IndependentSource` with
  `constraints={'domains': [cell], 'rejection_strategy': 'kill'}` pointed at
  the wrong cell — fewer particles than requested are simulated and the
  fission bank can come up empty. Check that the sampled positions land
  inside fissile material.

## 4. Related: tally scores that silently give nothing

A sibling symptom of the same confusion: the run completes but a tally is
empty or zero. Two checks before blaming physics:

- In case-A-style problems, `tally.scores = ['flux']` needs a fixed-source
  run; an eigenvalue run of a non-multiplying model will not even get that
  far (see step 1).
- Verify the tally was actually exported: the Python snippet
  `tallies = openmc.Tallies([tally]); tallies.export_to_xml()` must run, and
  `tally.scores` (plural) is the attribute — assigning `tally.score`
  (singular) silently does nothing in older API usage seen on the forum.

## 5. Checklist for the failing command

1. Capture the exact error: `No fission sites banked on MPI rank 0`.
2. Classify: no fissile material + a defined source → case A (run mode);
   intended eigenvalue on fuel → case B (material composition).
3. Case A: `settings.run_mode = 'fixed source'`, keep all batches active,
   do not set `inactive`.
4. Case B: print `mat.get_nuclides()` for every material; fix the nuclide
   name, element-vs-nuclide choice, or density.
5. Never paper over the error by adding fissile material to a shielding
   problem or by flipping an eigenvalue problem to fixed source.
