Strong trapping regime#
This verification case consists of a slab of depth \(l = 1 \ \mathrm{m}\) with one trap under the strong trapping regime.
A trapping parameter \(\zeta\) is defined by
where
\(\lambda \ \mathrm{(m)}\) is the lattice parameter,
\(\nu \ (\mathrm{s}^{-1})\), the Debye frequency
\(\rho\) is the trapping site fraction,
\(c_\mathrm{m}\) is the mobile atom fraction.
In the strong trapping regime, \(\zeta \approx c_\mathrm{m} / \rho\), and no permeation occurs until essentially all the traps have been filled.
The breakthrough time is given by
where \(c_{\mathrm{m},0}\) is the steady concentration of mobile atoms at \(x=0\). This analytical solution was obtained from TMAP7’s V&V report [3], case Val-1db.
For this case, \(\lambda=\sqrt{10^{-15}} \ \mathrm{m}\), \(\nu=10^{13} \ \mathrm{s}^{-1}\), \(D=1 \ \mathrm{m}^2 \mathrm{s}^{-1}\), and \(E_p/k_\mathrm{B}=10000 \ \mathrm{K}\) are used to obtain \(\zeta \approx 1.00454 c_\mathrm{m} / \rho\).
FESTIM Code#
import festim as F
import numpy as np
# Define input parameters
n = 3.162e22
rho = 1e-1 * n
D_0 = 1
E_D = 0.0
k_0 = 1e15 / n
p_0 = 1e13
E_p = 10000 * F.k_B
T = 1000
sample_depth = 1
c_m = 1e-4 * n
# Create the FESTIM model
my_model = F.HydrogenTransportProblem()
vertices = np.linspace(0, sample_depth, num=100)
my_model.mesh = F.Mesh1D(vertices)
material = F.Material(D_0=D_0, E_D=E_D)
volume = F.VolumeSubdomain1D(id=1, material=material, borders=[0, sample_depth])
left_boundary = F.SurfaceSubdomain1D(id=1, x=0)
right_boundary = F.SurfaceSubdomain1D(id=2, x=sample_depth)
my_model.subdomains = [left_boundary, volume, right_boundary]
mobile_H = F.Species("H")
trapped_H = F.Species("trapped_H", mobile=False)
empty_trap = F.ImplicitSpecies(n=rho, others=[trapped_H])
my_model.species = [mobile_H, trapped_H]
trapping_reaction = F.Reaction(
reactant=[mobile_H, empty_trap],
product=[trapped_H],
k_0=k_0,
E_k=E_D,
p_0=p_0,
E_p=E_p,
volume=volume,
)
my_model.reactions = [trapping_reaction]
my_model.temperature = T
my_model.boundary_conditions = [
F.DirichletBC(subdomain=left_boundary, value=c_m, species=mobile_H),
F.DirichletBC(subdomain=right_boundary, value=0, species=mobile_H),
]
my_model.settings = F.Settings(atol=2e15, rtol=5e-8, max_iterations=30, final_time=1000)
my_model.settings.stepsize = F.Stepsize(
initial_value=1e-6,
growth_factor=1.1,
cutback_factor=0.9,
target_nb_iterations=30,
max_stepsize=2,
)
right_flux = F.SurfaceFlux(field=mobile_H, surface=right_boundary)
my_model.exports = [right_flux]
/home/docs/checkouts/readthedocs.org/user_builds/festim-vv-report/conda/festim-2/lib/python3.11/site-packages/festim/coupled_heat_hydrogen_problem.py:1: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)
import tqdm.autonotebook
from petsc4py import PETSc
import dolfinx
# taken from https://github.com/FEniCS/dolfinx/blob/5fcb988c5b0f46b8f9183bc844d8f533a2130d6a/python/demo/demo_cahn-hilliard.py#L279C1-L286C28
use_superlu = (
PETSc.IntType == np.int64
) # or PETSc.ScalarType == np.complex64
sys = PETSc.Sys() # type: ignore
if sys.hasExternalPackage("mumps") and not use_superlu:
linear_solver = "mumps"
elif sys.hasExternalPackage("superlu_dist"):
linear_solver = "superlu_dist"
else:
linear_solver = "petsc"
petsc_options = {
"snes_type": "newtonls",
"snes_linesearch_type": "none",
"snes_stol": np.sqrt(np.finfo(dolfinx.default_real_type).eps)
* 1e-2,
"snes_atol": my_model.settings.atol,
"snes_rtol": my_model.settings.rtol,
"snes_divergence_tolerance": "PETSC_UNLIMITED",
"snes_max_it": my_model.settings.max_iterations,
"ksp_type": "preonly",
"pc_type": "lu",
"pc_factor_mat_solver_type": linear_solver,
# "snes_monitor": None,
}
my_model.petsc_options = petsc_options
my_model.initialise()
my_model.run()