Skip to content

Export reaction rate#1127

Open
RemDelaporteMathurin wants to merge 32 commits intomainfrom
reaction-rate-export
Open

Export reaction rate#1127
RemDelaporteMathurin wants to merge 32 commits intomainfrom
reaction-rate-export

Conversation

@RemDelaporteMathurin
Copy link
Copy Markdown
Collaborator

@RemDelaporteMathurin RemDelaporteMathurin commented Apr 28, 2026

Description

Summary

This PR leverages #1126 and provides an easy way for users to export reaction rates as a VTX export.

Additionally, this also makes the CustomFieldExport class work with ImplicitSpecies.

Motivation and Context

It is sometime informative to know the reaction rate of a certain reaction.

Usage

Users can use the new ReactionRate export class and simply pass it a Reaction instance. Optionally, one can define forward, backward or both (default) directions.

Example 2D

from mpi4py import MPI

import numpy as np
from dolfinx.mesh import create_unit_square

import festim as F

my_model = F.HydrogenTransportProblem()

mat = F.Material(D_0=1, E_D=0, K_S_0=1, E_K_S=0)

vol = F.VolumeSubdomain(id=1, material=mat)

top = F.SurfaceSubdomain(id=1, locator=lambda x: np.isclose(x[1], 1))
bottom = F.SurfaceSubdomain(id=2, locator=lambda x: np.isclose(x[1], 0))
left = F.SurfaceSubdomain(id=3, locator=lambda x: np.isclose(x[0], 0))
right = F.SurfaceSubdomain(id=4, locator=lambda x: np.isclose(x[0], 1))

my_model.subdomains = [vol, top, bottom, left, right]

dolfinx_mesh = create_unit_square(MPI.COMM_WORLD, 10, 10)
my_model.mesh = F.Mesh(dolfinx_mesh)


A = F.Species("A")
B = F.Species("B")
C = F.Species("C")
D = F.Species("D")

my_model.species = [A, B, C, D]

my_model.boundary_conditions = (
    [
        F.FixedConcentrationBC(species=A, subdomain=top, value=1),
        F.FixedConcentrationBC(species=B, subdomain=bottom, value=1),
    ]
    + [
        F.FixedConcentrationBC(species=A, subdomain=bottom, value=0),
        F.FixedConcentrationBC(species=B, subdomain=top, value=0),
    ]
    + [
        F.FixedConcentrationBC(species=C, subdomain=surf, value=0)
        for surf in [top, bottom, left, right]
    ]
    + [
        F.FixedConcentrationBC(species=D, subdomain=surf, value=0)
        for surf in [top, bottom, left, right]
    ]
)

my_model.reactions = [
    F.Reaction(reactant=[A, B], product=[C], k_0=1, E_k=0, p_0=5, E_p=0, volume=vol),
    F.Reaction(reactant=[C], product=[D], k_0=0.1, E_k=0, p_0=0, E_p=0, volume=vol),
]


my_model.temperature = 300

my_model.settings = F.Settings(final_time=1, atol=1e-9, rtol=1e-9, stepsize=0.01)
# my_model.settings = F.Settings(transient=False, atol=1e-9, rtol=1e-9)

custom_field = F.CustomFieldExport(
    filename="results/custom_field.bp",
    expression=lambda c_A, c_B, x: c_A * c_B,
    species_dependent_value={"c_A": A, "c_B": B},
)

forward_reaction_rate = F.ReactionRate(
    filename="results/forward_reaction_rate.bp",
    reaction=my_model.reactions[0],
    direction="forward",
)
backward_reaction_rate = F.ReactionRate(
    filename="results/backward_reaction_rate.bp",
    reaction=my_model.reactions[0],
    direction="backward",
)
net_reaction_rate = F.ReactionRate(
    filename="results/net_reaction_rate.bp",
    reaction=my_model.reactions[0],
    direction="both",
)

my_model.exports = [
    F.VTXSpeciesExport(filename="results/out.bp", field=[A, B, C, D]),
    custom_field,
    forward_reaction_rate,
    backward_reaction_rate,
    net_reaction_rate,
]

my_model.initialise()

my_model.run()

Example: TDS

Simply adding the following to the TDS festim example:

reaction_rate1 = F.ReactionRate(
    reaction=trapping_reaction_1,
    filename="results/reaction_rate1.bp",
)
reaction_rate2 = F.ReactionRate(
    reaction=trapping_reaction_2,
    filename="results/reaction_rate2.bp",
)

my_model.exports += [reaction_rate1, reaction_rate2]
image image

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🔨 Code refactoring (no functional changes, no API changes)
  • 📝 Documentation update
  • ✅ Test update (adding missing tests or correcting existing tests)
  • 🔧 Build/CI configuration change

Testing

  • All existing tests pass locally (pytest)
  • I have added new tests that prove my fix is effective or that my feature works

Code Quality Checklist

  • My code follows the code style of this project (Ruff formatted: ruff format .)
  • My code passes linting checks (ruff check .)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas

Documentation

  • I have updated the documentation accordingly (if applicable)
  • I have added docstrings to new functions/classes following the project conventions

Breaking Changes

Screenshots/Examples

Additional Notes

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 95.58824% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.90%. Comparing base (35b86fe) to head (f44acd3).

Files with missing lines Patch % Lines
src/festim/exports/vtx.py 94.00% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1127   +/-   ##
=======================================
  Coverage   94.90%   94.90%           
=======================================
  Files          44       44           
  Lines        3376     3417   +41     
=======================================
+ Hits         3204     3243   +39     
- Misses        172      174    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@RemDelaporteMathurin RemDelaporteMathurin marked this pull request as ready for review April 28, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant