# Firefly Reading Circle — "Build a Nuclear Reactor in 1 Hour"
### Hands-on OpenMC session guide

Goal: by the end of the hour, everyone has run a real Monte-Carlo neutron
transport simulation of a simplified reactor, seen the geometry, watched the
flux/power distribution, and understands what k-effective means.

Repo for this session: `~/work/openmc-reactor-demo/`
  - `build_model.py`   — defines materials + geometry + settings + tallies + plots
  - `download_xs.py`   — fetches the nuclear data (cross sections) needed to run
  - `visualize.py`     — turns the raw output into readable PNGs
  - `xs_data/`         — downloaded cross section library (ENDF/B-VII.1, NNDC)

---

## 0. Before the session (facilitator, ~15 min prep)
1. Install OpenMC (conda is easiest, no sudo needed):
   ```
   curl -fsSL -o miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
   bash miniconda.sh -b -p $HOME/miniconda3
   source ~/miniconda3/etc/profile.d/conda.sh
   conda config --add channels conda-forge
   conda config --set channel_priority strict
   conda create -y --name openmc-env openmc matplotlib
   conda activate openmc-env
   ```
2. Get nuclear data (cross sections) — only needs to happen once per machine:
   ```
   pip install openmc_data_downloader
   python download_xs.py        # ~5-10 min, downloads ~200MB for our isotopes
   ```
2b. Install Jupyter (for the notebook version of this session):
   ```
   pip install notebook
   ```
3. Copy the repo folder to everyone's laptop (or have them each run steps 1-2
   on their own machine ahead of time — the data download is the slow part).
4. From then on, just `source env.sh` in the repo folder to activate the
   conda env and point OpenMC at the downloaded cross-section data in one go.

## 1. The big idea (5 min, no laptops)
A nuclear reactor is just:
  - **Fuel** that releases neutrons when it fissions (we use UO2, uranium
    enriched to 4% U-235)
  - **Moderator** that slows fast neutrons down so they're more likely to
    cause another fission (we use ordinary water)
  - **Control rods** (boron carbide, B4C) that eat up neutrons on purpose,
    to control the chain reaction — push them in to slow down, pull them out
    to speed up
  - A **chain reaction** balance measured by **k-effective (keff)**:
      - keff = 1.000 → critical, steady power, this is what a running plant
        targets
      - keff > 1.000 → supercritical, power rising
      - keff < 1.000 → subcritical, power falling / reaction dying out

OpenMC is an open-source Monte Carlo particle transport code: it literally
simulates thousands of individual neutrons bouncing around the geometry,
tracks when they fission, scatter, or get absorbed, and from that statistics
estimates keff and where the power is produced.

## 2. Look at the model file together (10 min)
Open `build_model.py` and walk through section by section:
  - **Materials**: fuel/clad/water/B4C/air — notice `enrichment=4.0` for the
    fuel, that's the fissile U-235 fraction
  - **Geometry**: a single fuel pin cell (concentric cylinders: fuel → gas
    gap → clad → water), then a `RectLattice` arranging a 7×7 grid of pins
    into a mini "assembly" with a cross of control rods down the middle, then
    a water reflector around the outside with a vacuum boundary (neutrons
    that leak out are gone for good — a real finite reactor, not an infinite
    idealization)
  - **Settings**: eigenvalue run, few thousand particles — small on purpose
    so it runs in seconds for a live demo
  - **Tallies**: a mesh to record flux and fission-rate spatially

## 3. Run it (10 min)

**Option A — notebook (recommended for the group):**
```
cd ~/work/openmc-reactor-demo
source env.sh
jupyter notebook Reactor_Reading_Circle.ipynb
```
Run each cell with Shift+Enter, reading the markdown commentary between
them. The notebook already has a full explanation of every step baked in,
plus the experiment instructions from Section 4 below built into its
Section 8.

**Option B — plain scripts:**
```
cd ~/work/openmc-reactor-demo
source ~/miniconda3/etc/profile.d/conda.sh
conda activate openmc-env
python build_model.py      # writes geometry.xml, materials.xml, etc.
openmc                     # runs the Monte Carlo transport + makes plots
python visualize.py        # produces PNGs
```
Look at:
  - `reactor_geometry_overview.png` — the geometry you just defined, colored
    by material (red=fuel, grey=clad, blue=water, black=B4C control rods)
  - `reactor_flux_fission.png` — where neutrons are (flux) vs. where fissions
    (power) actually happen — ask the group: why isn't the power map
    perfectly uniform? (hint: control rods absorb neutrons locally, and
    neutrons leak out near the edge)
  - The printed k-effective value and its uncertainty — is this reactor
    critical, sub-, or supercritical as modeled?

## 4. Everyone experiments (20 min) — pick one or two
Have each small group make ONE change, rerun `openmc`, and report what
happened to keff and the power map:
  a. **Pull a control rod**: change one `C` in the `pattern` grid in
     `build_model.py` to `F` (fuel) — does keff go up or down? By how much?
  b. **Change enrichment**: edit `fuel.add_element('U', 1.0, enrichment=4.0)`
     to `enrichment=2.0` or `enrichment=5.0` — more fissile material = more
     reactivity?
  c. **Remove the boron from the coolant**: delete the
     `water.add_element('B', 500e-6)` line — boron is a neutron poison
     deliberately added to control reactivity; what happens without it?
  d. **Make the core bigger**: change `N = 7` to `N = 9` or `11` — does a
     bigger core (more fuel, less relative leakage) push keff up?
  e. **Swap water for something else**: try `set_density('g/cm3', 1.0)`
     cold/unborated water vs the hot 0.74 g/cm3 used by default — density
     changes moderation efficiency.

## 5. Wrap-up discussion (10 min)
  - Why do real reactors need *active* control (not just "critical and done")?
  - What's the difference between what we modeled (k-eigenvalue, steady
    state) and a real reactor transient (time-dependent, feedback from fuel
    temperature, xenon poisoning, etc.)? OpenMC can do time-dependent/depletion
    too — that's a "part 2" topic.
  - This model is a teaching toy: pin dimensions and pattern are realistic
    PWR-ish numbers, but it is NOT a licensed, validated reactor design. Real
    reactor physics calculations (what Samarth's CERT-In-adjacent engineering
    colleagues or an actual utility would use) require validated nuclear data,
    full 3D geometry, depletion, thermal-hydraulic feedback, and QA.

---

## Troubleshooting
- `ModuleNotFoundError: No module named 'openmc'` → you forgot
  `conda activate openmc-env`
- OpenMC run errors mentioning missing cross sections → re-run
  `python download_xs.py`, or check `echo $OPENMC_CROSS_SECTIONS` points at
  `xs_data/cross_sections.xml`
- Everything is red/one color in the plot → check `color_by` and the
  `colors` dict in `build_model.py` match the materials you defined
