04 — Divertor Heat Flux & Blanket Neutronics¶

This tutorial demonstrates two nuclear engineering modules:

  1. Divertor Thermal Simulation — heat-flux spreading on the divertor target
  2. Blanket Neutronics — tritium breeding ratio (TBR) calculation

Both are critical for DEMO-class reactor feasibility.

License: © 1998–2026 Miroslav Šotek. GNU AGPL v3.

Open In Colab Binder


In [ ]:
import numpy as np
import matplotlib.pyplot as plt

Part A: Divertor Thermal Simulation¶

The divertor receives the exhaust heat from the plasma scrape-off layer. ITER's divertor must handle ~10 MW/m² steady-state, with transients up to 20 MW/m².

In [ ]:
from scpn_fusion.core.divertor_thermal_sim import DivertorThermalSim

# ITER-like divertor parameters
sim = DivertorThermalSim(
    target_length_m=1.2,
    target_width_m=0.3,
    n_points=100,
    coolant_temp_K=423.0,  # 150°C water
)

# Sweep over power levels
powers = np.linspace(5.0, 25.0, 20)  # MW/m²
peak_temps = []
for q in powers:
    result = sim.compute_steady_state(heat_flux_mw_m2=q)
    peak_temps.append(result["peak_temp_K"])

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(powers, np.array(peak_temps) - 273.15, "b-o", markersize=4)
ax.axhline(y=1800, color="r", linestyle="--", label="Tungsten recrystallization (1800°C)")
ax.axhline(y=3422, color="darkred", linestyle="--", label="Tungsten melting (3422°C)")
ax.set_xlabel("Heat Flux [MW/m²]")
ax.set_ylabel("Peak Surface Temperature [°C]")
ax.set_title("Divertor Target Temperature vs Heat Flux")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

print(f"At 10 MW/m²: {peak_temps[5] - 273.15:.0f}°C")
print(f"At 20 MW/m²: {peak_temps[15] - 273.15:.0f}°C")

Part B: Blanket Neutronics (Tritium Breeding)¶

A D-T fusion reactor must breed its own tritium. The Tritium Breeding Ratio (TBR) must exceed 1.0 for fuel self-sufficiency. ITER targets TBR ≈ 1.10.

In [ ]:
from scpn_fusion.nuclear.blanket_neutronics import BlanketNeutronics

neutronics = BlanketNeutronics()

# Compare blanket concepts
concepts = {
    "HCLL (Li-Pb)": {"li6_enrichment": 0.30, "blanket_thickness_m": 0.8},
    "HCPB (Li-ceramic)": {"li6_enrichment": 0.60, "blanket_thickness_m": 0.7},
    "WCLL (Water-cooled)": {"li6_enrichment": 0.40, "blanket_thickness_m": 0.75},
}

results = {}
for name, params in concepts.items():
    tbr = neutronics.compute_tbr(**params)
    results[name] = tbr
    print(f"{name:25s}: TBR = {tbr:.3f} {'✓' if tbr > 1.0 else '✗'}")

# Plot
fig, ax = plt.subplots(figsize=(8, 4))
bars = ax.barh(
    list(results.keys()), list(results.values()), color=["#2196F3", "#4CAF50", "#FF9800"]
)
ax.axvline(x=1.0, color="r", linestyle="--", linewidth=2, label="TBR = 1.0 (self-sufficiency)")
ax.set_xlabel("Tritium Breeding Ratio")
ax.set_title("Blanket Concept TBR Comparison")
ax.legend()
plt.tight_layout()
plt.show()

Benchmark¶

In [ ]:
%%timeit -n1 -r3
for _name, _params in concepts.items():
    neutronics.compute_tbr(**_params)

Part C: Li-6 Enrichment Sensitivity¶

TBR depends strongly on Li-6 enrichment. Natural lithium is only 7.5% Li-6.

In [ ]:
enrichments = np.linspace(0.075, 0.90, 50)
tbr_values = [
    neutronics.compute_tbr(li6_enrichment=e, blanket_thickness_m=0.8) for e in enrichments
]

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(enrichments * 100, tbr_values, "g-", linewidth=2)
ax.axhline(y=1.0, color="r", linestyle="--", label="TBR = 1.0")
ax.axhline(y=1.1, color="orange", linestyle="--", alpha=0.7, label="TBR = 1.1 (target)")
ax.axvline(x=7.5, color="gray", linestyle=":", label="Natural Li-6 (7.5%)")
ax.set_xlabel("Li-6 Enrichment [%]")
ax.set_ylabel("Tritium Breeding Ratio")
ax.set_title("TBR vs Li-6 Enrichment (0.8m blanket)")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Performance Benchmarks¶

Timing the key computations in this notebook:

  1. Single divertor steady-state solve (compute_steady_state)
  2. Heat flux sweep (20-point parameter scan)
  3. Single TBR calculation (compute_tbr)
  4. Li-6 enrichment sweep (50-point parameter scan)
In [ ]:
import timeit


# 1. Single divertor steady-state solve
def bench_divertor_single():
    sim.compute_steady_state(heat_flux_mw_m2=10.0)


t_div = timeit.repeat(bench_divertor_single, number=100, repeat=5)
print("compute_steady_state single call (100 calls):")
print(f"  Mean: {np.mean(t_div) * 1000:.1f} ms +/- {np.std(t_div) * 1000:.1f} ms")
print(f"  Per call: {np.mean(t_div) / 100 * 1000:.2f} ms")


# 2. Heat flux sweep (20-point parameter scan)
def bench_divertor_sweep():
    for q in np.linspace(5.0, 25.0, 20):
        sim.compute_steady_state(heat_flux_mw_m2=q)


t_sweep = timeit.repeat(bench_divertor_sweep, number=10, repeat=3)
print("\nDivertor 20-point heat flux sweep (10 runs):")
print(f"  Mean: {np.mean(t_sweep) * 1000:.1f} ms +/- {np.std(t_sweep) * 1000:.1f} ms")
print(f"  Per run: {np.mean(t_sweep) / 10 * 1000:.2f} ms")


# 3. Single TBR calculation
def bench_tbr_single():
    neutronics.compute_tbr(li6_enrichment=0.30, blanket_thickness_m=0.8)


t_tbr = timeit.repeat(bench_tbr_single, number=1000, repeat=5)
print("\ncompute_tbr single call (1000 calls):")
print(f"  Mean: {np.mean(t_tbr) * 1000:.1f} ms +/- {np.std(t_tbr) * 1000:.1f} ms")
print(f"  Per call: {np.mean(t_tbr) / 1000 * 1e6:.2f} us")


# 4. Li-6 enrichment sweep (50-point parameter scan)
def bench_tbr_sweep():
    for e in np.linspace(0.075, 0.90, 50):
        neutronics.compute_tbr(li6_enrichment=e, blanket_thickness_m=0.8)


t_tbr_sweep = timeit.repeat(bench_tbr_sweep, number=10, repeat=3)
print("\nTBR 50-point enrichment sweep (10 runs):")
print(f"  Mean: {np.mean(t_tbr_sweep) * 1000:.1f} ms +/- {np.std(t_tbr_sweep) * 1000:.1f} ms")
print(f"  Per run: {np.mean(t_tbr_sweep) / 10 * 1000:.2f} ms")

Summary¶

  • The divertor model computes 1D/2D temperature profiles under steady-state and transient heat loads
  • The neutronics model estimates TBR from Li-6 enrichment, blanket geometry, and neutron multiplication
  • Both modules feed into the compact reactor optimizer (see notebook 01) for integrated design
  • With Rust acceleration, these calculations can be embedded in real-time digital twin scenarios