Metadata-Version: 2.4
Name: dolfinx-external-operator
Version: 0.11.0
Summary: An implementation of ufl.ExternalOperator for DOLFINx
Author-email: Andrey Latyshev <andrey.latyshev@uni.lu>, "Jack S. Hale" <jack.hale@uni.lu>
Description-Content-Type: text/markdown
License-File: COPYING
License-File: COPYING.LESSER
Requires-Dist: fenics-dolfinx<0.12.0,>=0.11.0
Requires-Dist: fenics-ufl>=2026.1.0
Provides-Extra: doc
Requires-Dist: jupyter-book<2.0; extra == "doc"
Requires-Dist: jupytext; extra == "doc"
Provides-Extra: demo
Requires-Dist: gmsh; extra == "demo"
Requires-Dist: numba; extra == "demo"
Requires-Dist: jax[cpu]; extra == "demo"
Requires-Dist: pyvista; extra == "demo"
Requires-Dist: mpltools; extra == "demo"
Requires-Dist: torch>=2.0; extra == "demo"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Provides-Extra: lint
Requires-Dist: ruff; extra == "lint"
Provides-Extra: ci
Requires-Dist: dolfinx-external-operator[doc]; extra == "ci"
Requires-Dist: dolfinx-external-operator[demo]; extra == "ci"
Requires-Dist: dolfinx-external-operator[test]; extra == "ci"
Requires-Dist: dolfinx-external-operator[lint]; extra == "ci"
Dynamic: license-file

![License: LGPLv3](https://img.shields.io/badge/License-LGPL%20v3.0-lightgrey.svg)

# dolfinx-external-operator

`dolfinx-external-operator` is a implementation of the [external
operator](https://doi.org/10.48550/arXiv.2111.00945) concept in
[DOLFINx](https://github.com/FEniCS/dolfinx).

It allows for the expression of operators/functions in FEniCS that cannot be
easily written in the [Unified Form Language](https://github.com/fenics/ufl).

Potential application areas include complex constitutive models in solid and
fluid mechanics, neural network constitutive models, multiscale modelling and
inverse problems. 

Implementations of external operators can be written in any library that
supports the [array interface
protocol](https://numpy.org/doc/stable/reference/arrays.interface.html), e.g.
[NumPy](https://numpy.org/), [Numba](http://numba.pydata.org),
[JAX](https://github.com/google/jax) and [PyTorch](https://pytorch.org/).

When using a library that supports program level automatic differentiation (AD),
such as JAX or PyTorch, it is possible to automatically derive derivatives for
use in local first and second-order solvers. Just-in-time compilation, batching
and accelerators (GPUs, TPUs) are also supported.

![diagram](./img/diagram.png)

## Installation

`dolfinx-external-operator` is a pure Python package that depends on the
DOLFINx Python interface and UFL. Version numbers match with compatible
releases of DOLFINx.

The latest release version can be installed with:

```Shell
pip install dolfinx-external-operator
```

The latest development version can be installed for development with:

```Shell
git clone https://github.com/a-latyshev/dolfinx-external-operator.git
cd dolfinx-external-operator
pip install -e .
```

## AI Copilot Assistant / Agent Skill

We bundle a customized coding assistant skill (`dolfinx-external-operator-assistant`) directly within the python package. This skill provides your LLM-based coding copilot (such as Gemini, Claude, GitHub Copilot, or Codex) with package workflows, mathematical Gâteaux derivative conventions, mixed-space rules, and local examples.

After installing the package via `pip`, you can install the skill locally to your current workspace:

* **For Gemini / Antigravity / GitHub Copilot / Codex** (installs to `.agents/skills/`):
  ```Shell
  dolfinx-external-operator install-skill
  ```

* **For Claude Code** (installs to `.claude/skills/`):
  ```Shell
  dolfinx-external-operator install-skill --claude
  ```

* **Upgrading / Overwriting** an existing installation:
  ```Shell
  dolfinx-external-operator install-skill --force
  ```

### Manual Installation
You can copy the skill directory from a local clone of the repository. To resolve the internal symbolic links into real, self-contained files, use the `-L` (dereference) flag:

* **For Gemini / Copilot / Codex** (copies to `.agents/skills/`):
  ```Shell
  mkdir -p .agents/skills/ && cp -rL src/dolfinx_external_operator/skills/dolfinx-external-operator-assistant .agents/skills/
  ```

* **For Claude Code** (copies to `.claude/skills/`):
  ```Shell
  mkdir -p .claude/skills/ && cp -rL src/dolfinx_external_operator/skills/dolfinx-external-operator-assistant .claude/skills/
  ```

### How to Use the Skill

Once the skill is installed in your workspace, your AI coding assistant (like Gemini, Claude, or GitHub Copilot) will automatically register it. You can start by asking it how to formulate your physical problem.

**Example Prompt:**
> "How to apply external operators to my problem?"

The assistant will guide you through the process, check for linear/nonlinear suitability, outline the variational formulation (it may generate a Markdown file in the workspace root with the mathematical derivation), and generate Python code modeled after the packaged demos and tests.

```{important}
Please note that using this skill does not guarantee the generated code will be the most computationally efficient implementation. Its primary purpose is to restrict the agent's scope to focus on the curated APIs, workflows, and templates of the `dolfinx-external-operator` library, and to provide practical prompting examples internally. 

Alternatively, if your agent has internet access and can retrieve website contents directly, simply providing it with the link to the [online documentation](https://a-latyshev.github.io/dolfinx-external-operator/) will often provide sufficient context on its own.
```

## Documentation

### Tutorials 

The [tutorials](https://a-latyshev.github.io/dolfinx-external-operator/)
contains various examples focusing on complex constitutive behaviour in solid
mechanics, including:

* nonlinear heat equation using [NumPy](https://numpy.org/doc/stable/index.html),
* von Mises plasticity using [Numba](https://numba.pydata.org/),
* Mohr-Coulomb plasticity using [JAX](https://jax.readthedocs.io/en/latest),
* Isihara hyperelasticity using [PyTorch](https://pytorch.org/).

### Supplementary materials

* Introduction to External Operators — FEniCS 2024 Conference:

<iframe width="700" height="400" src="https://www.youtube.com/embed/y8goeapqfsw?si=BQwDcdwqS3EF5rwW" frameborder="0" allowfullscreen></iframe>

* Poster - CSMA 2026 and FEniCS 2026 conferences: [Download PDF](https://hdl.handle.net/10993/68619).
```{image} ../img/poster_CSMA26_FEniCS26_A0.png
:align: center
:width: 250px
```

## Citations 

If you use `dolfinx-external-operator` in your research we ask that you cite
the following references:

```bibtex
@article{jtcam:14449,
  title      = {Expressing general constitutive models in FEniCSx using external operators and algorithmic automatic differentiation},
  author     = {Andrey Latyshev and Jérémy Bleyer and Corrado Maurini and Jack Hale},
  doi        = {10.46298/jtcam.14449},
  journal    = {Journal of Theoretical, Computational and Applied Mechanics},
  issn       = {2726-6141},
  year       = {2025},
  month      = {Sep},
  keywords   = {automated finite element solvers, Numba, JAX, FEniCSx, external operators, algorithmic automatic differentiation, constitutive models}
}

@software{latyshev_2024_external_code,
  title = {a-latyshev/dolfinx-external-operator},
  author = {Latyshev, Andrey and Hale, Jack},
  date = {2025},
  doi = {10.5281/zenodo.10907417},
  organization = {Zenodo}
}
```

## Contributors

* Andrey Latyshev (University of Luxembourg, Sorbonne Université,
  andrey.latyshev@uni.lu)
* Jérémy Bleyer (École des Ponts ParisTech, Université Gustave Eiffel, jeremy.bleyer@enpc.fr)
* Jack S. Hale (University of Luxembourg, jack.hale@uni.lu)
* Corrado Maurini (Sorbonne Université, corrado.maurini@sorbonne-universite.fr)
* Jørgen S. Dokken (Simula Research Laboratory, dokken@simula.no)

If you wish to be added as a contributor after an accepted PR please ask via
email.

## License

dolfinx-external-operator is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

dolfinx-external-operator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
for more details.

You should have received a copy of the GNU Lesser General Public License along
with dolfinx-external-operator. If not, see https://www.gnu.org/licenses/.

## Acknowledgments

This research was funded in whole, or in part, by the Luxembourg National
Research Fund (FNR), grant reference PRIDE/21/16747448/MATHCODA.

## Developer notes

### Docker container

```Shell
docker run -ti -v $(pwd):/shared --entrypoint /bin/bash -w /shared docker.io/dolfinx/lab:nightly
pip install .
```

### Building Documentation

Note: If you plan to run the demos during the documentation build, you will need the optional `demo` dependencies (which includes PyTorch). To avoid downloading the large CUDA-enabled version of PyTorch, you can optionally install the CPU-only version first:

```Shell
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install '.[doc,demo]'
```

Otherwise, standard build:

```Shell
pip install '.[doc]'
cd doc/
jupyter-book build .
```

and follow the instructions printed.

To continuously build and view the documentation in a web browser

```Shell
pip install sphinx-autobuild
cd build/
jupyter-book config sphinx .
sphinx-autobuild . _build/html -b html
```

### Linting

To lint and format

```Shell
pip install '.[lint]'
ruff check .
ruff format .
```

### Running tests

```Shell
pip install '.[test]'
py.test -v test/
```

### Releases

```Shell
git pull
git checkout release
git merge --no-commit origin/main
git checkout --theirs . # files deleted on `main` must be manually git `rm`ed
vim pyproject.toml # Update version numbers
git diff origin/main # Check for mistakes
git tag v0.9.0 # for example
git push --tags origin
```

Then make a release using GitHub Releases.
