FESTIM: empowering tritium transport modelling
Remi Delaporte-Mathurin
Application: ITER PFCs
We need a numerical tool
W
Cu
CuCrZr
Particle and heat fluxes
Convection
14 mm
Problem: predict T retention and permeation
- Multi-dimensional
- Multi-material
- non homogeneous temperature
What is FESTIM
User inputs
- Material properties
- Trap properties
- Geometry
- Boundary conditions
- Initial conditions
- ...
Heat transfer model
Hydrogen transport model
- McNabb & Foster
- Multi-level trapping
- Multi-isotopes
- ...
FESTIM
Outputs
- H concentration fields \(c(x,t)\)
- Temperature field \(T(x,t)\)
- surface fluxes
- inventories
- average concentration
- ...
2022
2019
Start of development
- 1D/2D/3D
- Finite elements
- Python
- multi-material
- Heat transfer
History of FESTIM
open-source
- development continuing at MIT
Oct 2023
v1.0 release
2024
Meet the development team
Jonathan Dufour
CEA, France
+ other contributors
FESTIM is open-source
✅ More transparency
✅ More collaborations
✅ More flexibility
The code is missing a feature?
Just add it!
Found a bug?
Report it and we'll fix it!
FESTIM's development workflow
- Anyone can create their own copy (fork) of the FESTIM repository and make changes
- PRs are a place where FESTIM's maintainers review the proposed changes
- ~500 tests are automatically run
- The PR is only merged when all the tests pass ✅
fork
fork
pull request
FESTIM
Jane Doe
FESTIM
John Doe
FESTIM
festim-dev
pull request
How to use FESTIM
Documentation
and installation instructions
FESTIM is user-friendly
- Very easy to learn
- Plenty of libraries (numpy, scipy, matplotlib, HTM...)
- Inuitive interface
conda install -c conda-forge fenics
pip install festim
Two lines to install!
import festim as F
import numpy as np
my_model = F.Simulation()
my_model.mesh = F.MeshFromVertices(
vertices=np.linspace(0, 1e-6, num=1001)
)
my_model.materials = F.Material(id=1, D_0=1.9e-7, E_D=0.2)
my_model.T = 500 # K
my_model.boundary_conditions = [
F.DirichletBC(
surfaces=[1, 2],
value=1e15, # H/m3/s
field=0
)
]
my_model.settings = F.Settings(
absolute_tolerance=1e10,
relative_tolerance=1e-10,
final_time=100 # s
)
my_model.dt = F.Stepsize(0.1) # s
my_model.initialise()
my_model.run()
FESTIM workshop
The FESTIM workshop is a series of tutorials
from basic problems to more advanced cases
FESTIM is user-friendly
FESTIM is fully documented
Check out the complete documentation at
Installation instructions
User guide
- Development guide
- Tutorials
- Theory background
- API reference
FESTIM is verified & validated
- Validated against TDS, permeation experiments...
- Verified against analytical solutions in many different problems
- New V&V online book
festim-vv-report.readthedocs.io
14 verification cases (4 in progress)
6 validation cases (5 in progress)
V&V
Effective-diffusion through a slab
2D multi-material
Exact
Computed concentration
Method of Exact Solution
governing equations
exact solutions
parameters (sources, BCs, ICs)
FESTIM
computed solutions
solve
run
compare
⚠️sometimes very complex!
Method of Manufactured Solutions
governing equations
manufactured solutions
source terms, BCs and ICs
FESTIM
computed solutions
compare
FESTIM is used worldwide
8 private companies
13 universities
18 research organisations
IPP soon?
📈5 years of development
📑13+ publications
🗣️110+ citations
🧑💻20+ contributors
🏛️26+ institutions using the code
🧑💻70+ Slack members
⭐88+ stars on GitHub
FESTIM in numbers
Evolution of GitHub stars
Open source
SOFE
New reference paper
Kyoto Fusioneering
UKAEA
Retention studies
- Delaporte-Mathurin et al 2024 International Journal of Hydrogen Energy 63 786–802
- Delaporte-Mathurin et al 2024 Nucl. Fusion 64 026003
- ITER plasma facing components
- Transient estimation of tritium retention
Detritiation studies
Influence of ELMs on retention
- 1D model of a ITER monoblock
- Transient heat transfer simulation
- Varying surface heat flux
Breeding Blanket modelling
- DEMO WCLL
- Complex 3D geometry
- Coupled to fluid dynamics
- Tritium generation in the LiPb volume (computed from OpenMC)
James Dark et al 2021 Nucl. Fusion 61 116076
Tritium extraction system
courtesy of K. Dunnell (MIT)
- Permeation Against Vacuum
- Complex 3D geometry
- Coupled with fluid dynamics
- Tritium extraction from permeable membranes
Tritium extraction system
courtesy of K. Dunnell (MIT)
① neutrons are generated
② tritium is created from nuclear reactions
③ tritium is transported in the salt
④ tritium is released into the gas phase
⑤ tritium is collected and counted
BABY breeding experiment
👀 Presentation tomorrow...
BABY breeding experiment
Velocity
Temperature
Tritium concentration
Metal Foil Pumps for DIR
- H is implanted in the first \( 10 \ \mathrm{nm} \)
- Super-permeation regime is attained at high recombination energy (upstream surface)
- Source code
Benedikt & Day, (2017) Fusion Engineering and Design
Neutron-induced trap model
- Custom trapping model
- Dynamic evolution of trap densities including annealing
- Parametrised on IPP TDS data!
Permeation experiment
No barrier
with barrier
Permeation barrier
Substrate
High H pressure
Low H pressure
Conservation of chemical potential
Permeation flux
FESTIM can inform fuel cycle models
Text
Kinetic surface model
to be submitted
New in v1.3!
FESTIM development plans
FESTIM limitations
Parallel scaling issues
Technical debt
Legacy FEniCS deprecated
Current interface condition does not scale well
Many hard coded foudations
More complex implementationof new features
Bugs not being fixed
Can't take advantage of new features
FEniCSx
FESTIM 2.0
Next steps...
New computational engine
Community-driven
New Features
New computational engine
FEniCS deprecated in 2019
FEniCSx
- Designed from the ground up for parallelisation
- Better performance
- More cell types and control over the domain
Community-driven
Mailing list
New Features
Multi-isotope transport
New mesh types
Validation on PFCs
Chemical reactions
External physics integration
Anisotropic diffusion
Multilevel trapping
Massively parallel
Towards the future: FESTIM 2
Chemical reactions
- More suitable for molten salts
- Even more flexibility
Multi-species transport
- Isotopic exchange
- Multi-level trapping
- Transport of impurities, He, interstitials...
- Validation on WEST PFCs
Finite element engine upgrade
- Better performances (including in parallel)
- Bigger models
- Mixed topology meshes
Graphical user interface?
Follow the development roadmap
New examples
Isotope swapping
same underlying equations!
Can be represented by festim.Reaction
Isotope swapping
my_model.species = [
mobile_H,
mobile_D,
trapped_H,
trapped_D,
]
my_model.reactions = [
F.Reaction(
k_0=k_0,
E_k=0.39,
p_0=1e13,
E_p=1.2,
reactant1=mobile_H,
reactant2=empty_trap,
product=trapped_H,
volume=my_subdomain,
),
F.Reaction(
k_0=k_0,
E_k=0.39,
p_0=1e13,
E_p=1.2,
reactant1=mobile_D,
reactant2=empty_trap,
product=trapped_D,
volume=my_subdomain,
),
F.Reaction(
k_0=k_0,
E_k=0.1,
p_0=k_0,
E_p=0.1,
reactant1=mobile_H,
reactant2=trapped_D,
product=[mobile_D, trapped_H],
volume=my_subdomain,
),
]
Usual trapping reactions
Swapping reaction
4 species are defined
Multi-isotope, multi-level trapping
- 7 different species
- 6 reactions
- \( c_H = 10^{20} \ \mathrm{m^{-3}} \) on the left
- \( c_D = 10^{19} \ \mathrm{m^{-3}} \) on the right
- Source code available here
1 trap, 2 levels, 2 isotopes
\( \mathrm{H} \) = mobile H
\( \mathrm{D} \) = mobile D
\( [\mathrm{H}_x\mathrm{D}_y] \) = \(x\) H and \(y\) D in trap
Spherical cavity trapping
see Zibrov and Schmid, NME, 2024
for complete description
- Implementation in FESTIM of the spherical cavity trapping model developed by Zibrov and Schmid
- Custom trapping equations
- Smooth implementation in FESTIM
Anisotropy
- Anisotropic materials can be simulated with very few modifications
- Composites
- Anisotropic microstructures
Interface discontinuity
- 2 materials
- 1 mobile + 1 trap
Example dolfinx code available in issue #719
But this changes a lot of things!
FESTIM 1
with dolfinx
1 mesh for the whole domain
1 mesh for the whole domain
Submesh 1
Submesh 2
VectorFunctionSpace \(V\) (eg. 3 components)
Function \(u\) (eg. 3 components)
VectorFunctionSpace \(V_1\)
\(V_2\)
Function \(u_1\) (eg. 2 comps.)
\(u_2\) (eg. 3 comps.)
1 function for the whole domain
1 function per subdomain
Workshop time
The workshop
📖Tasks
Basic
- Simple model
- Simulating a TDS
- Permeation experiment
-
Post-processing
Advanced
- Fitting a TDS
- Kinetic Surface model
- HTM integration
- Neutron induced traps
Bonus
- Permeation barrier
- Non cartesian meshes
- Multi-dimension
💪Challenges
- A: Evaluate a PRF
- B: Fit a TDS spectrum
- C: Permeation flux through a pipe
🚀Contribution/Hackathon
You'll need a GitHub account for this
What is a contribution?
- Bug fixes
- New functionality
- Enhancements
- Documentation updates/fixes
- Testing
- Architecture (CI, CD...)
We curated a list of easy issues for this workshop:
- Documentation
- Quality of Life
- Bug fixes
- Anyone can make a copy of the repository and make changes there
- Changes are reviewed by official maintainers via pull-requests
- ~500 tests are run automatically
- Changes are only merged when all the tests pass ✅
fork
fork
pull request
FESTIM
Jane
FESTIM
John
FESTIM
festim-dev
pull request
The contribution workflow
✅
❌
How to contribute to the documentation (easy)
How to contribute to the documentation
- Make changes to the
docs
folder locally - Compile the documentation locally
- Inspect the HTML files
- Push changes
- Documentation is automatically built with PR
cd docs/source
make html
We need to test our code
def add_two(x):
return x + 2
def test_add_two():
assert add_two(2) == 4
assert add_two(3) == 5
assert add_two(4) == 6
assert add_two(5) == 7
test_add_two()
test_example.py
$ python test_example.py
We want to test this function
We write a test function
We can test more functions
def add_two(x):
return x + 2
def add_three(x):
return x + 3
def test_add_two():
assert add_two(2) == 4
assert add_two(3) == 5
assert add_two(4) == 6
assert add_two(5) == 7
def test_add_three():
assert add_three(2) == 5
assert add_three(3) == 6
assert add_three(4) == 7
assert add_three(5) == 8
test_add_two()
test_add_three()
test_example.py
$ python test_example.py
We use pytest
instead
def add_two(x):
return x + 2
def add_three(x):
return x + 3
def test_add_two():
assert add_two(2) == 4
assert add_two(3) == 5
assert add_two(4) == 6
assert add_two(5) == 7
def test_add_three():
assert add_three(2) == 5
assert add_three(3) == 6
assert add_three(4) == 7
assert add_three(5) == 8
test_example.py
$ python -m pytest test_example.py
================================================================ test session starts ================================================================
platform linux -- Python 3.11.9, pytest-7.4.4, pluggy-1.0.0
rootdir: /home/remidm/FESTIM-workshop
collected 2 items
example_test.py .. [100%]
================================================================= 2 passed in 0.01s =================================================================
Let's split the scripts
from example import *
def test_add_two():
assert add_two(2) == 4
assert add_two(3) == 5
assert add_two(4) == 6
assert add_two(5) == 7
def test_add_three():
assert add_three(2) == 5
assert add_three(3) == 6
assert add_three(4) == 7
assert add_three(5) == 8
test_example.py
$ python -m pytest test_example.py
def add_two(x):
return x + 2
def add_three(x):
return x + 3
example.py
================================================================ test session starts ================================================================
platform linux -- Python 3.11.9, pytest-7.4.4, pluggy-1.0.0
rootdir: /home/remidm/FESTIM-workshop
collected 2 items
example_test.py .. [100%]
================================================================= 2 passed in 0.01s =================================================================
This is basically FESTIM
from example import *
def test_add_two():
assert add_two(2) == 4
assert add_two(3) == 5
assert add_two(4) == 6
assert add_two(5) == 7
def test_add_three():
assert add_three(2) == 5
assert add_three(3) == 6
assert add_three(4) == 7
assert add_three(5) == 8
test_example.py
def add_two(x):
return x + 2
def add_three(x):
return x + 3
example.py
festim/festim
festim/test
Testing is automated with GitHub Actions
name: CI
on: [pull_request, push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Conda
uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: myenv
channels: conda-forge, defaults
- name: Create Conda environment
shell: bash -l {0}
run: |
conda install -c conda-forge fenics numpy=1.24
- name: Install dependencies
shell: bash -l {0}
run: |
pip install pytest pytest-cov
- name: Run tests
shell: bash -l {0}
run: |
pytest test/ --cov festim --cov-report xml --cov-report term
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
Triggered by pushes and PRs
Runs-on cloud ubuntu machine
Clone FESTIM repository
Install dependencies
Run the tests
Upload code coverage
Workflow file stored in .github/workflows/
It shows up during PRs
Now you know
✅Continuous Integration
We also have automation for
- pip distribution
- building the documentation
- testing the documentation
- computing coverage
- ...
Code coverage tells you how much of the code is tested
FESTIM @ IPP
By Remi Delaporte-Mathurin
FESTIM @ IPP
Slides for the FESTIM workshop held at IPP in September 2024
- 113