yonderdrake 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yonderdrake-0.1.0a1/LICENSE +28 -0
- yonderdrake-0.1.0a1/PKG-INFO +176 -0
- yonderdrake-0.1.0a1/README.md +131 -0
- yonderdrake-0.1.0a1/pyproject.toml +156 -0
- yonderdrake-0.1.0a1/setup.cfg +4 -0
- yonderdrake-0.1.0a1/src/yonderdrake/__init__.py +61 -0
- yonderdrake-0.1.0a1/src/yonderdrake/_external.py +80 -0
- yonderdrake-0.1.0a1/src/yonderdrake/_firedrake.py +160 -0
- yonderdrake-0.1.0a1/src/yonderdrake/_version.py +3 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/__init__.py +37 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/__init__.py +43 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/inverse.py +391 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/model.py +277 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/pml.py +125 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/propagation.py +1335 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/sources.py +63 -0
- yonderdrake-0.1.0a1/src/yonderdrake/applications/caputo_wismer/stepper.py +199 -0
- yonderdrake-0.1.0a1/src/yonderdrake/periodic/__init__.py +5 -0
- yonderdrake-0.1.0a1/src/yonderdrake/periodic/_external.py +100 -0
- yonderdrake-0.1.0a1/src/yonderdrake/periodic/grid.py +708 -0
- yonderdrake-0.1.0a1/src/yonderdrake/periodic/operator.py +66 -0
- yonderdrake-0.1.0a1/src/yonderdrake/py.typed +1 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/__init__.py +5 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/_external.py +360 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/dense.py +358 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/distributed_hmatrix.py +636 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/geometry.py +337 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/hmatrix.py +458 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/matfree.py +109 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/operator.py +145 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/outer_quadrature.py +267 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/tetrahedron_action.py +326 -0
- yonderdrake-0.1.0a1/src/yonderdrake/riesz/triangle_action.py +574 -0
- yonderdrake-0.1.0a1/src/yonderdrake/spectral/__init__.py +5 -0
- yonderdrake-0.1.0a1/src/yonderdrake/spectral/_external.py +68 -0
- yonderdrake-0.1.0a1/src/yonderdrake/spectral/operator.py +97 -0
- yonderdrake-0.1.0a1/src/yonderdrake/spectral/shifted_solves.py +246 -0
- yonderdrake-0.1.0a1/src/yonderdrake/spectral/sinc.py +102 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/__init__.py +55 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/_stepper_lifecycle.py +36 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/_ufl_marker.py +186 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/auxiliary_ode.py +564 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/checkpointing.py +169 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/coefficients.py +271 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/fast_cq.py +735 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/formulations.py +43 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/full_history.py +949 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/marker.py +52 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/representations/__init__.py +47 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/representations/core.py +732 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/representations/specialized.py +909 -0
- yonderdrake-0.1.0a1/src/yonderdrake/time/stepper.py +1369 -0
- yonderdrake-0.1.0a1/src/yonderdrake.egg-info/PKG-INFO +176 -0
- yonderdrake-0.1.0a1/src/yonderdrake.egg-info/SOURCES.txt +55 -0
- yonderdrake-0.1.0a1/src/yonderdrake.egg-info/dependency_links.txt +1 -0
- yonderdrake-0.1.0a1/src/yonderdrake.egg-info/requires.txt +23 -0
- yonderdrake-0.1.0a1/src/yonderdrake.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Timon S. Gutleb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Third-party components
|
|
24
|
+
|
|
25
|
+
The Fira Sans and Fira Mono fonts bundled under docs/source/_static/fonts/
|
|
26
|
+
are not covered by the MIT License above. They are licensed under the SIL
|
|
27
|
+
Open Font License 1.1. The full text and copyright notice are in
|
|
28
|
+
docs/source/_static/fonts/LICENSE-Fira.txt.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yonderdrake
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: A library for nonlocal time and space operators in Firedrake
|
|
5
|
+
Author: Timon S. Gutleb
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Documentation, https://timon.gutleb.com/yonderdrake/
|
|
8
|
+
Project-URL: Homepage, https://github.com/TSGut/yonderdrake
|
|
9
|
+
Project-URL: Issues, https://github.com/TSGut/yonderdrake/issues
|
|
10
|
+
Project-URL: Source, https://github.com/TSGut/yonderdrake
|
|
11
|
+
Keywords: caputo,finite-element-method,firedrake,fractional-calculus,fractional-laplacian
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.24
|
|
26
|
+
Requires-Dist: scipy>=1.10
|
|
27
|
+
Provides-Extra: test
|
|
28
|
+
Requires-Dist: mpmath>=1.3; extra == "test"
|
|
29
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
30
|
+
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
35
|
+
Requires-Dist: yonderdrake[test]; extra == "dev"
|
|
36
|
+
Provides-Extra: visual
|
|
37
|
+
Requires-Dist: matplotlib>=3.9; extra == "visual"
|
|
38
|
+
Requires-Dist: pillow>=10; extra == "visual"
|
|
39
|
+
Provides-Extra: docs
|
|
40
|
+
Requires-Dist: furo>=2024.8.6; extra == "docs"
|
|
41
|
+
Requires-Dist: myst-parser>=4; extra == "docs"
|
|
42
|
+
Requires-Dist: sphinx<9,>=8; extra == "docs"
|
|
43
|
+
Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="https://timon.gutleb.com/yonderdrake/_static/yonderdrake-logo.png"
|
|
48
|
+
alt="Yonderdrake"
|
|
49
|
+
width="560">
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<h1 align="center">Yonderdrake</h1>
|
|
53
|
+
|
|
54
|
+
<p align="center">
|
|
55
|
+
Fractional in time, space and other nonlocal operators for
|
|
56
|
+
<a href="https://www.firedrakeproject.org/">Firedrake</a>
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<p align="center">
|
|
60
|
+
<a href="https://github.com/TSGut/yonderdrake/actions/workflows/ci.yml"><img src="https://github.com/TSGut/yonderdrake/actions/workflows/ci.yml/badge.svg" alt="Tests"></a>
|
|
61
|
+
<a href="https://timon.gutleb.com/yonderdrake/"><img src="https://github.com/TSGut/yonderdrake/actions/workflows/docs.yml/badge.svg" alt="Documentation"></a>
|
|
62
|
+
<a href="https://github.com/TSGut/yonderdrake/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
> **Alpha software:** Yonderdrake has been broadly tested, but bugs and missing
|
|
66
|
+
> features may remain. Please [report them as issues](https://github.com/TSGut/yonderdrake/issues).
|
|
67
|
+
|
|
68
|
+
Yonderdrake adds various fractional time derivatives, fading-memory operators,
|
|
69
|
+
and spatial fractional Laplacians directly to
|
|
70
|
+
[UFL](https://docs.fenicsproject.org/ufl/main/) forms solved with
|
|
71
|
+
[Firedrake](https://www.firedrakeproject.org/). Time- and space-nonlocal
|
|
72
|
+
operators can also be combined in the same equation.
|
|
73
|
+
|
|
74
|
+
The eventual goal is to gather all FEM-compatible methods for fractional differential
|
|
75
|
+
equations in one place, so that comparing or switching between them does not
|
|
76
|
+
mean rebuilding the problem each time.
|
|
77
|
+
|
|
78
|
+
## Features
|
|
79
|
+
|
|
80
|
+
- Caputo and initialized Riemann-Liouville fractional-in-time derivatives with various methods including static memory diffusive representations, full-history stepping along with additional implementations from the literature for easy comparisons.
|
|
81
|
+
- General single-timescale exponential memory operators, including a convenience wrapper for the Caputo-Fabrizio operator.
|
|
82
|
+
- Homogeneous-Dirichlet spectral, zero-exterior Riesz, and periodic Fourier
|
|
83
|
+
fractional Laplacians.
|
|
84
|
+
- 2D and 3D Caputo-Wismer waves with heterogeneous density, driven sources,
|
|
85
|
+
impedance boundaries, PML, configurable sensor arrays, exact adjoints, time
|
|
86
|
+
reversal, and regularized reconstruction.
|
|
87
|
+
- Variable timesteps, PETSc solver configuration, MPI execution, and checkpoint/restart.
|
|
88
|
+
- Compatibility with [Irksome](https://www.firedrakeproject.org/Irksome/index.html) for classical time stepping alongside Yonderdrake operators.
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
### Fractional time
|
|
93
|
+
|
|
94
|
+
Three sources in a BrainWeb anatomical head with material-dependent
|
|
95
|
+
Caputo-Wismer damping:
|
|
96
|
+
|
|
97
|
+
<p align="center">
|
|
98
|
+
<img src="./demos/demo-output/caputo-wismer-brainweb-sources-readme.gif"
|
|
99
|
+
alt="Three sources in a BrainWeb anatomical head with fractional damping"
|
|
100
|
+
width="900">
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
Recovering a vessel-shaped initial pressure from measurements around a
|
|
104
|
+
realistic head. The first two panels compare the true source with its
|
|
105
|
+
reconstruction. The third shows the pressure recorded by the sensor
|
|
106
|
+
array:
|
|
107
|
+
|
|
108
|
+
<p align="center">
|
|
109
|
+
<img src="./demos/demo-output/caputo-wismer-brainweb-imaging-readme.png"
|
|
110
|
+
alt="Vessel-shaped source, reconstructed pressure, and exterior sensor measurements in a BrainWeb head"
|
|
111
|
+
width="900">
|
|
112
|
+
</p>
|
|
113
|
+
|
|
114
|
+
### Fractional space
|
|
115
|
+
|
|
116
|
+
Classical, spectral-fractional, and Riesz heat flow on a Koch snowflake:
|
|
117
|
+
|
|
118
|
+
<p align="center">
|
|
119
|
+
<img src="./demos/demo-output/fractional-heat-koch-snowflake.gif"
|
|
120
|
+
alt="Classical, spectral-fractional, and Riesz heat flow on a Koch snowflake"
|
|
121
|
+
width="900">
|
|
122
|
+
</p>
|
|
123
|
+
|
|
124
|
+
See the [guides and examples](https://timon.gutleb.com/yonderdrake/#guides-and-examples)
|
|
125
|
+
for small, reproducible problems and the
|
|
126
|
+
[demo gallery](https://timon.gutleb.com/yonderdrake/gallery/index.html) for the
|
|
127
|
+
full applications.
|
|
128
|
+
|
|
129
|
+
## Installation
|
|
130
|
+
|
|
131
|
+
Create a [Firedrake environment](https://www.firedrakeproject.org/install.html):
|
|
132
|
+
|
|
133
|
+
```console
|
|
134
|
+
git clone https://github.com/TSGut/yonderdrake.git
|
|
135
|
+
cd yonderdrake
|
|
136
|
+
python -m pip install .
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Add the plotting dependencies to run the gallery demos or regenerate their
|
|
140
|
+
media:
|
|
141
|
+
|
|
142
|
+
```console
|
|
143
|
+
python -m pip install '.[visual]'
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
For development:
|
|
147
|
+
|
|
148
|
+
```console
|
|
149
|
+
python -m pip install -e '.[dev,docs]'
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Firedrake supplies MPI and PETSc. See
|
|
153
|
+
[supported platforms](https://timon.gutleb.com/yonderdrake/support.html).
|
|
154
|
+
|
|
155
|
+
## Documentation
|
|
156
|
+
|
|
157
|
+
Start with the [quickstart](https://timon.gutleb.com/yonderdrake/quickstart.html),
|
|
158
|
+
then the [guides and examples](https://timon.gutleb.com/yonderdrake/#guides-and-examples).
|
|
159
|
+
The [mathematics and methods](https://timon.gutleb.com/yonderdrake/#mathematics-and-methods)
|
|
160
|
+
summarize the supported algorithms and the papers behind them. The
|
|
161
|
+
[API reference](https://timon.gutleb.com/yonderdrake/api.html) gives exact
|
|
162
|
+
signatures and restrictions.
|
|
163
|
+
|
|
164
|
+
## Contributing
|
|
165
|
+
|
|
166
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for what a numerical change should
|
|
167
|
+
include. LLM-assisted contributions are welcome in principle and are held to
|
|
168
|
+
the same standards as all others. The human author remains responsible for the
|
|
169
|
+
code they submit.
|
|
170
|
+
|
|
171
|
+
## Logo
|
|
172
|
+
|
|
173
|
+
The logo nods to the *long memory* of time-fractional operators: a fractional
|
|
174
|
+
derivative still feels the entire history that preceded it. The
|
|
175
|
+
logo dragon is inspired by the
|
|
176
|
+
[Lindwurmbrunnen](https://www.atlasobscura.com/places/lindwurmbrunnen) in Klagenfurt, Austria, drawn in a viridis-like colour scheme.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://timon.gutleb.com/yonderdrake/_static/yonderdrake-logo.png"
|
|
3
|
+
alt="Yonderdrake"
|
|
4
|
+
width="560">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">Yonderdrake</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Fractional in time, space and other nonlocal operators for
|
|
11
|
+
<a href="https://www.firedrakeproject.org/">Firedrake</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://github.com/TSGut/yonderdrake/actions/workflows/ci.yml"><img src="https://github.com/TSGut/yonderdrake/actions/workflows/ci.yml/badge.svg" alt="Tests"></a>
|
|
16
|
+
<a href="https://timon.gutleb.com/yonderdrake/"><img src="https://github.com/TSGut/yonderdrake/actions/workflows/docs.yml/badge.svg" alt="Documentation"></a>
|
|
17
|
+
<a href="https://github.com/TSGut/yonderdrake/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
> **Alpha software:** Yonderdrake has been broadly tested, but bugs and missing
|
|
21
|
+
> features may remain. Please [report them as issues](https://github.com/TSGut/yonderdrake/issues).
|
|
22
|
+
|
|
23
|
+
Yonderdrake adds various fractional time derivatives, fading-memory operators,
|
|
24
|
+
and spatial fractional Laplacians directly to
|
|
25
|
+
[UFL](https://docs.fenicsproject.org/ufl/main/) forms solved with
|
|
26
|
+
[Firedrake](https://www.firedrakeproject.org/). Time- and space-nonlocal
|
|
27
|
+
operators can also be combined in the same equation.
|
|
28
|
+
|
|
29
|
+
The eventual goal is to gather all FEM-compatible methods for fractional differential
|
|
30
|
+
equations in one place, so that comparing or switching between them does not
|
|
31
|
+
mean rebuilding the problem each time.
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- Caputo and initialized Riemann-Liouville fractional-in-time derivatives with various methods including static memory diffusive representations, full-history stepping along with additional implementations from the literature for easy comparisons.
|
|
36
|
+
- General single-timescale exponential memory operators, including a convenience wrapper for the Caputo-Fabrizio operator.
|
|
37
|
+
- Homogeneous-Dirichlet spectral, zero-exterior Riesz, and periodic Fourier
|
|
38
|
+
fractional Laplacians.
|
|
39
|
+
- 2D and 3D Caputo-Wismer waves with heterogeneous density, driven sources,
|
|
40
|
+
impedance boundaries, PML, configurable sensor arrays, exact adjoints, time
|
|
41
|
+
reversal, and regularized reconstruction.
|
|
42
|
+
- Variable timesteps, PETSc solver configuration, MPI execution, and checkpoint/restart.
|
|
43
|
+
- Compatibility with [Irksome](https://www.firedrakeproject.org/Irksome/index.html) for classical time stepping alongside Yonderdrake operators.
|
|
44
|
+
|
|
45
|
+
## Examples
|
|
46
|
+
|
|
47
|
+
### Fractional time
|
|
48
|
+
|
|
49
|
+
Three sources in a BrainWeb anatomical head with material-dependent
|
|
50
|
+
Caputo-Wismer damping:
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<img src="./demos/demo-output/caputo-wismer-brainweb-sources-readme.gif"
|
|
54
|
+
alt="Three sources in a BrainWeb anatomical head with fractional damping"
|
|
55
|
+
width="900">
|
|
56
|
+
</p>
|
|
57
|
+
|
|
58
|
+
Recovering a vessel-shaped initial pressure from measurements around a
|
|
59
|
+
realistic head. The first two panels compare the true source with its
|
|
60
|
+
reconstruction. The third shows the pressure recorded by the sensor
|
|
61
|
+
array:
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<img src="./demos/demo-output/caputo-wismer-brainweb-imaging-readme.png"
|
|
65
|
+
alt="Vessel-shaped source, reconstructed pressure, and exterior sensor measurements in a BrainWeb head"
|
|
66
|
+
width="900">
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
### Fractional space
|
|
70
|
+
|
|
71
|
+
Classical, spectral-fractional, and Riesz heat flow on a Koch snowflake:
|
|
72
|
+
|
|
73
|
+
<p align="center">
|
|
74
|
+
<img src="./demos/demo-output/fractional-heat-koch-snowflake.gif"
|
|
75
|
+
alt="Classical, spectral-fractional, and Riesz heat flow on a Koch snowflake"
|
|
76
|
+
width="900">
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
See the [guides and examples](https://timon.gutleb.com/yonderdrake/#guides-and-examples)
|
|
80
|
+
for small, reproducible problems and the
|
|
81
|
+
[demo gallery](https://timon.gutleb.com/yonderdrake/gallery/index.html) for the
|
|
82
|
+
full applications.
|
|
83
|
+
|
|
84
|
+
## Installation
|
|
85
|
+
|
|
86
|
+
Create a [Firedrake environment](https://www.firedrakeproject.org/install.html):
|
|
87
|
+
|
|
88
|
+
```console
|
|
89
|
+
git clone https://github.com/TSGut/yonderdrake.git
|
|
90
|
+
cd yonderdrake
|
|
91
|
+
python -m pip install .
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Add the plotting dependencies to run the gallery demos or regenerate their
|
|
95
|
+
media:
|
|
96
|
+
|
|
97
|
+
```console
|
|
98
|
+
python -m pip install '.[visual]'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For development:
|
|
102
|
+
|
|
103
|
+
```console
|
|
104
|
+
python -m pip install -e '.[dev,docs]'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Firedrake supplies MPI and PETSc. See
|
|
108
|
+
[supported platforms](https://timon.gutleb.com/yonderdrake/support.html).
|
|
109
|
+
|
|
110
|
+
## Documentation
|
|
111
|
+
|
|
112
|
+
Start with the [quickstart](https://timon.gutleb.com/yonderdrake/quickstart.html),
|
|
113
|
+
then the [guides and examples](https://timon.gutleb.com/yonderdrake/#guides-and-examples).
|
|
114
|
+
The [mathematics and methods](https://timon.gutleb.com/yonderdrake/#mathematics-and-methods)
|
|
115
|
+
summarize the supported algorithms and the papers behind them. The
|
|
116
|
+
[API reference](https://timon.gutleb.com/yonderdrake/api.html) gives exact
|
|
117
|
+
signatures and restrictions.
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for what a numerical change should
|
|
122
|
+
include. LLM-assisted contributions are welcome in principle and are held to
|
|
123
|
+
the same standards as all others. The human author remains responsible for the
|
|
124
|
+
code they submit.
|
|
125
|
+
|
|
126
|
+
## Logo
|
|
127
|
+
|
|
128
|
+
The logo nods to the *long memory* of time-fractional operators: a fractional
|
|
129
|
+
derivative still feels the entire history that preceded it. The
|
|
130
|
+
logo dragon is inspired by the
|
|
131
|
+
[Lindwurmbrunnen](https://www.atlasobscura.com/places/lindwurmbrunnen) in Klagenfurt, Austria, drawn in a viridis-like colour scheme.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yonderdrake"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A library for nonlocal time and space operators in Firedrake"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Timon S. Gutleb" },
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"caputo",
|
|
18
|
+
"finite-element-method",
|
|
19
|
+
"firedrake",
|
|
20
|
+
"fractional-calculus",
|
|
21
|
+
"fractional-laplacian",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 3 - Alpha",
|
|
25
|
+
"Intended Audience :: Science/Research",
|
|
26
|
+
"Operating System :: MacOS",
|
|
27
|
+
"Operating System :: POSIX :: Linux",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.10",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
34
|
+
]
|
|
35
|
+
dependencies = [
|
|
36
|
+
"numpy>=1.24",
|
|
37
|
+
"scipy>=1.10",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
test = [
|
|
42
|
+
"mpmath>=1.3",
|
|
43
|
+
"pytest>=8",
|
|
44
|
+
"pytest-cov>=5",
|
|
45
|
+
]
|
|
46
|
+
dev = [
|
|
47
|
+
"build>=1.2",
|
|
48
|
+
"mypy>=1.11",
|
|
49
|
+
"ruff>=0.6",
|
|
50
|
+
"yonderdrake[test]",
|
|
51
|
+
]
|
|
52
|
+
visual = [
|
|
53
|
+
"matplotlib>=3.9",
|
|
54
|
+
"pillow>=10",
|
|
55
|
+
]
|
|
56
|
+
docs = [
|
|
57
|
+
"furo>=2024.8.6",
|
|
58
|
+
"myst-parser>=4",
|
|
59
|
+
"sphinx>=8,<9",
|
|
60
|
+
"sphinx-copybutton>=0.5",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[project.urls]
|
|
64
|
+
Documentation = "https://timon.gutleb.com/yonderdrake/"
|
|
65
|
+
Homepage = "https://github.com/TSGut/yonderdrake"
|
|
66
|
+
Issues = "https://github.com/TSGut/yonderdrake/issues"
|
|
67
|
+
Source = "https://github.com/TSGut/yonderdrake"
|
|
68
|
+
|
|
69
|
+
[tool.setuptools]
|
|
70
|
+
package-dir = { "" = "src" }
|
|
71
|
+
|
|
72
|
+
[tool.setuptools.packages.find]
|
|
73
|
+
where = ["src"]
|
|
74
|
+
|
|
75
|
+
[tool.setuptools.package-data]
|
|
76
|
+
yonderdrake = ["py.typed"]
|
|
77
|
+
|
|
78
|
+
[tool.setuptools.dynamic]
|
|
79
|
+
version = { attr = "yonderdrake._version.__version__" }
|
|
80
|
+
|
|
81
|
+
[tool.pytest.ini_options]
|
|
82
|
+
addopts = "--strict-config --strict-markers -ra"
|
|
83
|
+
testpaths = ["tests"]
|
|
84
|
+
pythonpath = ["."]
|
|
85
|
+
filterwarnings = [
|
|
86
|
+
"ignore:Setting the shape on a NumPy array has been deprecated.*:DeprecationWarning:pyop2.utils",
|
|
87
|
+
]
|
|
88
|
+
markers = [
|
|
89
|
+
"unit: fast tests of isolated numerical or API components",
|
|
90
|
+
"verification: numerical verification against an independent reference",
|
|
91
|
+
"slow: computationally expensive tests",
|
|
92
|
+
"parallel: tests requiring more than one MPI rank",
|
|
93
|
+
"performance: non-functional performance measurements",
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
[tool.coverage.run]
|
|
97
|
+
branch = true
|
|
98
|
+
parallel = true
|
|
99
|
+
relative_files = true
|
|
100
|
+
source = ["yonderdrake"]
|
|
101
|
+
|
|
102
|
+
[tool.coverage.report]
|
|
103
|
+
fail_under = 97.0
|
|
104
|
+
precision = 1
|
|
105
|
+
show_missing = true
|
|
106
|
+
skip_covered = true
|
|
107
|
+
|
|
108
|
+
[tool.ruff]
|
|
109
|
+
target-version = "py310"
|
|
110
|
+
line-length = 88
|
|
111
|
+
src = ["src", "tests"]
|
|
112
|
+
|
|
113
|
+
[tool.ruff.lint]
|
|
114
|
+
select = ["B", "E", "F", "I", "UP"]
|
|
115
|
+
|
|
116
|
+
[tool.mypy]
|
|
117
|
+
python_version = "3.10"
|
|
118
|
+
files = ["src/yonderdrake"]
|
|
119
|
+
strict = true
|
|
120
|
+
no_site_packages = true
|
|
121
|
+
|
|
122
|
+
[[tool.mypy.overrides]]
|
|
123
|
+
module = ["numpy", "numpy.*"]
|
|
124
|
+
ignore_missing_imports = true
|
|
125
|
+
|
|
126
|
+
[[tool.mypy.overrides]]
|
|
127
|
+
module = [
|
|
128
|
+
"firedrake",
|
|
129
|
+
"firedrake.*",
|
|
130
|
+
"mpi4py",
|
|
131
|
+
"mpi4py.*",
|
|
132
|
+
"petsc4py",
|
|
133
|
+
"petsc4py.*",
|
|
134
|
+
]
|
|
135
|
+
ignore_missing_imports = true
|
|
136
|
+
|
|
137
|
+
[[tool.mypy.overrides]]
|
|
138
|
+
module = ["ufl", "ufl.*"]
|
|
139
|
+
ignore_missing_imports = true
|
|
140
|
+
|
|
141
|
+
[[tool.mypy.overrides]]
|
|
142
|
+
module = ["scipy", "scipy.*"]
|
|
143
|
+
ignore_missing_imports = true
|
|
144
|
+
|
|
145
|
+
[[tool.mypy.overrides]]
|
|
146
|
+
module = "yonderdrake.time._ufl_marker"
|
|
147
|
+
ignore_errors = true
|
|
148
|
+
|
|
149
|
+
[[tool.mypy.overrides]]
|
|
150
|
+
module = [
|
|
151
|
+
"yonderdrake._external",
|
|
152
|
+
"yonderdrake.periodic._external",
|
|
153
|
+
"yonderdrake.riesz._external",
|
|
154
|
+
"yonderdrake.spectral._external",
|
|
155
|
+
]
|
|
156
|
+
ignore_errors = true
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Yonderdrake public interface."""
|
|
2
|
+
|
|
3
|
+
from yonderdrake._version import __version__
|
|
4
|
+
from yonderdrake.periodic import PeriodicFractionalLaplacian
|
|
5
|
+
from yonderdrake.riesz import RieszFractionalLaplacian
|
|
6
|
+
from yonderdrake.spectral import SpectralFractionalLaplacian
|
|
7
|
+
from yonderdrake.time import (
|
|
8
|
+
AlikhanovL21Sigma,
|
|
9
|
+
AuxiliaryODE,
|
|
10
|
+
BirkSong,
|
|
11
|
+
CaputoDerivative,
|
|
12
|
+
CaputoFabrizioOperator,
|
|
13
|
+
Cayley,
|
|
14
|
+
Diethelm2008,
|
|
15
|
+
Diethelm2022,
|
|
16
|
+
ExponentialMemory,
|
|
17
|
+
ExponentialMemoryCompatibilityWarning,
|
|
18
|
+
FastObliviousCQ,
|
|
19
|
+
FractionalTimeStepper,
|
|
20
|
+
FullHistory,
|
|
21
|
+
LubichCQ,
|
|
22
|
+
ModeCountAdvisoryWarning,
|
|
23
|
+
Oscillator,
|
|
24
|
+
Recurrence,
|
|
25
|
+
RiemannLiouvilleDerivative,
|
|
26
|
+
SineDiffusive,
|
|
27
|
+
StartingCorrectionAdvisoryWarning,
|
|
28
|
+
SumOfExponentials,
|
|
29
|
+
TimeMemoryStepper,
|
|
30
|
+
YuanAgrawal,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"AlikhanovL21Sigma",
|
|
35
|
+
"AuxiliaryODE",
|
|
36
|
+
"BirkSong",
|
|
37
|
+
"CaputoDerivative",
|
|
38
|
+
"CaputoFabrizioOperator",
|
|
39
|
+
"Cayley",
|
|
40
|
+
"Diethelm2008",
|
|
41
|
+
"Diethelm2022",
|
|
42
|
+
"FastObliviousCQ",
|
|
43
|
+
"ExponentialMemory",
|
|
44
|
+
"ExponentialMemoryCompatibilityWarning",
|
|
45
|
+
"FractionalTimeStepper",
|
|
46
|
+
"FullHistory",
|
|
47
|
+
"LubichCQ",
|
|
48
|
+
"ModeCountAdvisoryWarning",
|
|
49
|
+
"Oscillator",
|
|
50
|
+
"StartingCorrectionAdvisoryWarning",
|
|
51
|
+
"PeriodicFractionalLaplacian",
|
|
52
|
+
"Recurrence",
|
|
53
|
+
"RiemannLiouvilleDerivative",
|
|
54
|
+
"RieszFractionalLaplacian",
|
|
55
|
+
"SineDiffusive",
|
|
56
|
+
"SpectralFractionalLaplacian",
|
|
57
|
+
"SumOfExponentials",
|
|
58
|
+
"TimeMemoryStepper",
|
|
59
|
+
"YuanAgrawal",
|
|
60
|
+
"__version__",
|
|
61
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Common Firedrake registration for linear external operators."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from firedrake import (
|
|
8
|
+
AbstractExternalOperator,
|
|
9
|
+
Cofunction,
|
|
10
|
+
Function,
|
|
11
|
+
assemble_method,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from yonderdrake._firedrake import (
|
|
15
|
+
assemble_linear_action_adjoint,
|
|
16
|
+
assemble_linear_action_matrix,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class LinearExternalOperator(AbstractExternalOperator):
|
|
21
|
+
"""Shared registrations for a cached linear primal action."""
|
|
22
|
+
|
|
23
|
+
basis_name = "external_operator"
|
|
24
|
+
|
|
25
|
+
def _build_manager(self) -> Any:
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
|
|
28
|
+
def _manager(self) -> Any:
|
|
29
|
+
current = self.operator_data.get("manager")
|
|
30
|
+
if current is None:
|
|
31
|
+
current = self._build_manager()
|
|
32
|
+
self.operator_data["manager"] = current
|
|
33
|
+
if float(self.operator_data["order_operand"]) != self.operator_data["order"]:
|
|
34
|
+
raise RuntimeError(
|
|
35
|
+
"changing s after construction is unsupported; rebuild the operator"
|
|
36
|
+
)
|
|
37
|
+
return current
|
|
38
|
+
|
|
39
|
+
def invalidate_cache(self) -> None:
|
|
40
|
+
self.operator_data["manager"] = None
|
|
41
|
+
|
|
42
|
+
@assemble_method(0, (0,))
|
|
43
|
+
def assemble_forward(self, *, assembly_opts: Any = None) -> Function:
|
|
44
|
+
del assembly_opts
|
|
45
|
+
return self._manager().apply(self.ufl_operands[0])
|
|
46
|
+
|
|
47
|
+
@assemble_method(1, (0, None))
|
|
48
|
+
def assemble_jacobian_action(
|
|
49
|
+
self,
|
|
50
|
+
*,
|
|
51
|
+
assembly_opts: Any = None,
|
|
52
|
+
) -> Function:
|
|
53
|
+
del assembly_opts
|
|
54
|
+
return self._manager().apply(self.argument_slots()[-1])
|
|
55
|
+
|
|
56
|
+
@assemble_method(1, (None, 0))
|
|
57
|
+
def assemble_jacobian_adjoint_action(
|
|
58
|
+
self,
|
|
59
|
+
*,
|
|
60
|
+
assembly_opts: Any = None,
|
|
61
|
+
) -> Cofunction:
|
|
62
|
+
del assembly_opts
|
|
63
|
+
manager = self._manager()
|
|
64
|
+
return assemble_linear_action_adjoint(
|
|
65
|
+
self.function_space(),
|
|
66
|
+
manager.apply,
|
|
67
|
+
self.argument_slots()[0],
|
|
68
|
+
basis_name=f"{self.basis_name}_adjoint_basis",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@assemble_method(1, (0, 1))
|
|
72
|
+
@assemble_method(1, (1, 0))
|
|
73
|
+
def assemble_jacobian(self, *, assembly_opts: Any = None) -> Any:
|
|
74
|
+
manager = self._manager()
|
|
75
|
+
return assemble_linear_action_matrix(
|
|
76
|
+
self,
|
|
77
|
+
manager.apply,
|
|
78
|
+
assembly_opts=assembly_opts,
|
|
79
|
+
basis_name=f"{self.basis_name}_basis",
|
|
80
|
+
)
|