pytrip5 is a Python high-level interface for Tripoli-5 enabling full-core PWR (Pressurized Water Reactor) modelling and simulations.
- Fluent, Pythonic API for building reactor core models
- Type-annotated domain models (Material, Pin, Assembly, Core)
- Adapter pattern for clean separation from Tripoli-5 API
- Mock adapter for testing and development without Tripoli-5 installation
- Comprehensive scoring (k-eff, pin powers, flux distributions, reaction rates)
- I/O utilities for JSON, HDF5, and CSV data exchange
- Parameter sweeps for sensitivity studies
- Full test coverage with pytest
- Example notebooks for quick start
pip install -e .For development with testing dependencies:
pip install -e ".[dev]"from pytrip5 import Core, MockTripoliAdapter, SimulationConfig, Runner
from pytrip5.score import KeffectiveScore, PinPowerScore
# Create a simple 3x3 core
core = Core.simple_demo_3x3()
# Configure simulation
config = SimulationConfig.quick_criticality(
scores=[KeffectiveScore(), PinPowerScore('pin_powers')],
seed=42
)
# Run with mock adapter (for testing/development)
adapter = MockTripoliAdapter()
result = Runner.run(adapter, core, config)
print(f"k-effective: {result.k_eff_with_uncertainty}")
print(f"Pin powers shape: {result.pin_powers.shape}")For production runs with real Tripoli-5:
from pytrip5 import TripoliAdapter
# Requires tripoli5 package installed
adapter = TripoliAdapter()
result = Runner.run(adapter, core, config)pytrip5/
├── core.py # Domain model: Material, Pin, Assembly, Core
├── adapter.py # Tripoli-5 API adapter (real + mock)
├── simulation.py # Runner, SimulationConfig, RunResult
├── score.py # Score abstractions (k-eff, flux, power, etc.)
├── io.py # Import/export utilities
└── tests/ # Comprehensive unit tests
from pytrip5 import Material
fuel = Material(
name='UO2_4.5%',
density=10.4, # g/cm³
compositions={
'U235': 0.045,
'U238': 0.955,
'O16': 2.0
},
temperature=900.0 # Kelvin
)from pytrip5 import Pin, Assembly, Core
# Create fuel pin
pin = Pin(id='fuel_std', radius=0.475, material=fuel, pitch=1.26)
# Create 17x17 pin lattice
pins = [[pin for _ in range(17)] for _ in range(17)]
assembly = Assembly(id='ASM_4.5', pitch=21.5, pins=pins, enrichment=4.5)
# Create core layout
layout = [
['ASM_4.5', 'ASM_4.5', 'ASM_4.5'],
['ASM_4.5', 'ASM_4.5', 'ASM_4.5'],
['ASM_4.5', 'ASM_4.5', 'ASM_4.5']
]
core = Core(
assemblies={'ASM_4.5': assembly},
layout=layout,
boron_concentration=500.0 # ppm
)config = SimulationConfig.quick_criticality(
scores=[KeffectiveScore(), PinPowerScore('pin_powers')],
seed=42
)config = SimulationConfig.production_criticality(
scores=[
KeffectiveScore(),
PinPowerScore('pin_powers'),
FluxScore('thermal_flux', energy_bounds=[0, 0.625e-6]),
FluxScore('fast_flux', energy_bounds=[0.1, 20.0])
],
seed=12345
)config = SimulationConfig(
criticality=True,
particles_per_batch=100000,
active_batches=200,
inactive_batches=50,
scores=[...],
seed=42,
parallel_tasks=8 # For HPC runs
)from pytrip5 import Runner
# Sweep boron concentration
boron_values = [0, 500, 1000, 1500]
results = Runner.parameter_sweep(
adapter,
core,
'boron_concentration',
boron_values,
config
)
# Analyze results
for boron, result in results.items():
print(f"Boron {boron} ppm: k-eff = {result.k_eff:.5f}")from pytrip5 import io
# Save
io.save_core_json(core, 'core_config.json')
# Load
core = io.load_core_json('core_config.json')# Save to JSON
io.save_results_json(result, 'results.json')
# Save to HDF5 (requires h5py)
io.save_results_hdf5(result, 'results.h5')
# Export pin powers to CSV
io.export_pin_powers_csv(result.pin_powers, 'pin_powers.csv')
# Export summary
io.export_summary_txt(result, 'summary.txt')See examples/notebooks/quickstart.py for a comprehensive tutorial covering:
- Building core models
- Running simulations
- Analyzing results
- Visualizing pin powers
- Parameter sweeps
- Data I/O
To run the notebook:
# Convert to Jupyter notebook (requires jupytext)
jupytext --to notebook examples/notebooks/quickstart.py
# Or run as Python script
python examples/notebooks/quickstart.pyRun the test suite:
pytest pytrip5/tests/ -vRun with coverage:
pytest pytrip5/tests/ --cov=pytrip5 --cov-report=htmlAll tests use MockTripoliAdapter by default and don't require Tripoli-5 installation. For integration tests with real Tripoli-5, set:
export TRIPOLI_PRESENT=1
pytest pytrip5/tests/ -v -m integration- Python ≥ 3.9
- numpy
- (Optional) h5py for HDF5 I/O
- pytest
- pytest-cov
- black (formatting)
- ruff (linting)
- Tripoli-5 Python API (for real simulations)
pytrip5 requires the Tripoli-5 Python API for production runs. Tripoli-5 is developed by CEA/ASNR/EDF and may have licensing restrictions.
See Tripoli-5 documentation for installation instructions.
Note: Development and testing can be done entirely with MockTripoliAdapter without Tripoli-5.
- API Ergonomics — Inspired by PyDrag, pytrip5 provides a fluent, composable API
- Type Safety — Full PEP 484 type annotations for IDE support and type checking
- Testability — Mock adapter enables testing without Tripoli-5
- Separation of Concerns — Adapter pattern isolates Tripoli-5 API details
- Production Ready — Comprehensive tests, documentation, and CI/CD
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License. See LICENSE file for details.
If you use pytrip5 in your research, please cite:
@software{pytrip5,
title = {pytrip5: Python Interface for Tripoli-5 Monte Carlo Code},
author = {IRSN},
year = {2024},
url = {https://github.com/IRSN/reacT5}
}For issues, questions, or feature requests, please open an issue on GitHub.
- CEA/ASNR/EDF for Tripoli-5 development
- IRSN for PyDrag API design inspiration