Release candidate 2 for 2.2
Pre-releaseFESTIM v2.2-rc.2
Second release candidate for 2.2. The headline of this one is codimensional (manifold) subdomains — transport along a grain boundary, a crack or a thin surface layer, coupled to the bulk — and drift terms, which bring back Soret from FESTIM 1 and add electromigration. Alongside those, reactions have been reworked into a proper class hierarchy, field exports gained new formats (including single-file vtkhdf), and a series of fixes to the discontinuous/Nitsche interface machinery.
Please try it out and report anything that breaks before 2.2 final.
pip install festim==2.2rc2
What's Changed
Major
Codimensional (manifold) subdomains 🎉
A VolumeSubdomain can now be a manifold embedded in the mesh — a line in a 2D mesh, a surface in a 3D mesh — carrying its own transport equation and exchanging with every bulk subdomain it touches. This is how you model a grain boundary, a crack, or a thin surface layer without resolving it with cells. See the new Subdomains user guide.
gamma = F.VolumeSubdomain(
id=2, material=mat, dim=1, locator=lambda x: np.isclose(x[1], 0.5)
)- Codim: base functionality by @RemDelaporteMathurin in #1216
- Simplify
compute_ordered_interior_facet_databy @RemDelaporteMathurin in #1219 - Codim: Backwards compatibility by @RemDelaporteMathurin in #1221
- Codim: fix for the flux conservation bug across internal interfaces by @RemDelaporteMathurin in #1228
- Codim: support for derived quantities by @RemDelaporteMathurin in #1229
- Codim: Fix multiple codim subdomains erroring on a single bulk subdomain by @ee-nn in #1233
- Codim: allow manifolds to be linked to more than 2 volumes by @RemDelaporteMathurin in #1250
Derived quantities (SurfaceFlux, TotalSurface, AverageSurface, TotalVolume, AverageVolume) now work on a manifold, on its own boundary, and for a bulk species across an interior manifold — the last of which used to silently report 0.0. And a manifold may now be linked to any number of adjacent volumes, not just two, so a grain-boundary network can thread a polycrystal where each grain is its own subdomain.
Drift terms
Transport driven by a gradient other than the species' own, all sharing one conservative div(c v) assembly:
| term | drift velocity | driving field |
|---|---|---|
F.AdvectionTerm (existing) |
given directly | a moving fluid |
F.SoretTerm |
-D Q*/(k_B T²) grad(T) |
temperature |
F.ElectromigrationTerm |
-z D/(k_B T) grad(phi) |
electric potential |
model.drift_terms = [
F.SoretTerm(species=H, Q_star=0.2, subdomain=vol),
F.ElectromigrationTerm(species=OD, charge=1, potential=phi, subdomain=membrane),
]
model.boundary_conditions = [F.OutflowBC(subdomain=outlet, species=H)]Soret was documented in the theory guide but had no implementation in FESTIM 2 — this closes that v1 → v2 regression. Also here: the new F.OutflowBC, and SurfaceFlux now reports the total flux -D grad(c)·n + c v·n (the "advection terms are not accounted for" warning is gone).
- Drift terms by @RemDelaporteMathurin in #1231
Reaction re-work
Reaction becomes a small hierarchy so FESTIM can express reactions beyond Arrhenius trapping/detrapping, and reactions are now expanded into ParticleSource objects rather than written into the formulation by each problem class.
| class | net rate |
|---|---|
ReactionBase |
arbitrary R = f(c_i, x, T, t) |
GenericReaction |
mass action |
ArrheniusReaction |
k_0/E_k, p_0/E_p (the old Reaction) |
DecayReaction |
first-order radioactive decay |
Rate coefficients are now festim.Value objects, so they accept floats, UFL expressions, fem.Constant/fem.Function, or callables of T, t, x and other species.
New export formats
Field exports are no longer VTX-only. The format is now an argument, backed by a FieldWriter strategy, and adding a format is one small class.
format |
extension | ParaView |
|---|---|---|
"vtx" |
.bp |
yes (default, unchanged) |
"vtkhdf" |
.vtkhdf |
yes — new, one HDF5 file instead of a directory tree |
"xdmf" |
.xdmf |
yes |
"checkpoint" |
.bp / .h5 |
no — now available for all field types |
F.SpeciesExport("results.vtkhdf", field=[H], subdomain=vol, format="vtkhdf")Exports pointing at the same .vtkhdf filename become named blocks of a single MultiBlockDataSet, so a multi-material model no longer scatters one .bp directory per subdomain.
- Io4dolfinx export formats by @RemDelaporteMathurin in #1242
Fixes
- Fix:
CustomQuantitywith immobileSpeciesby @RemDelaporteMathurin in #1212 - Discontinuous initial condition fix by @jhdark in #1234
- Fix for sign on the penalty term by @ee-nn in #1237
- 1026 fix nitsche interface by @RemDelaporteMathurin in #1238
- Fixes for parallel runs by @RemDelaporteMathurin in #1239
Worth calling out #1238: interface.method was dead — every interface's method was overwritten with the class default on every run, so only the deprecated problem-level route worked. On top of that, nitsche_method left D out of its consistency term, ignored the solubility-law branching that penalty_method has, and applied penalty_term to a quantity in potential rather than flux units. With realistic data that last one put Nitsche out by 4× at penalty_term = 10 and 280× at 1e3. The constraint is now built once in Interface.equality() and shared by both methods. penalty_method is behaviourally unchanged.
#1239 fixes meshtags definitions to include ghost cells, plus a logger bug — both needed for correct parallel runs.
Docs
- added Chris' thesis by @RemDelaporteMathurin in #1215
- Fellowship updates by @jhdark in #1189
New pages: Drift terms, a rewritten Subdomains page covering manifolds, and an expanded Exports & post-processing page.
Misc / CI
- Normalise version tags in conda nightly build by @RemDelaporteMathurin in #1213
- Fix conda based actions by @RemDelaporteMathurin in #1240
- Bump pypa/gh-action-pypi-publish from 1.14.1 to 1.14.2 by @dependabot[bot] in #1218
- Bump pyvista/setup-headless-display-action from 4 to 5 by @dependabot[bot] in #1244
Deprecations and breaking changes
| old | new |
|---|---|
F.Reaction |
F.ArrheniusReaction (alias kept, warns) |
F.VTXSpeciesExport / F.VTXTemperatureExport |
F.SpeciesExport / F.TemperatureExport with format="vtx" (aliases kept, warn) |
F.XDMFExport |
F.SpeciesExport(..., format="xdmf") (alias kept, warns) |
VTXSpeciesExport(..., checkpoint=True) |
format="checkpoint" (mapped, warns) |
model.advection_terms |
model.drift_terms (appended, warns) |
problem.method_interface |
interface.method |
Removed outright:
F.ExportBaseClass→F.FieldExportBase.- The
festim.exports.vtxmodule →festim.exports.field.
Behaviour changes to be aware of:
SurfaceFluxnow includes the drift/advection contribution, so reported values change for any model with an advection term.interface.methodis now actually honoured — a discontinuous model that set it and silently got the class default will now solve with the method it asked for.
Full Changelog: v2.2-rc.1...v2.2-rc.2