IRKsome 2026.0.0__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.
- irksome-2026.0.0/IRKsome.egg-info/PKG-INFO +54 -0
- irksome-2026.0.0/IRKsome.egg-info/SOURCES.txt +85 -0
- irksome-2026.0.0/IRKsome.egg-info/dependency_links.txt +1 -0
- irksome-2026.0.0/IRKsome.egg-info/requires.txt +13 -0
- irksome-2026.0.0/IRKsome.egg-info/top_level.txt +1 -0
- irksome-2026.0.0/LICENSE +13 -0
- irksome-2026.0.0/PKG-INFO +54 -0
- irksome-2026.0.0/README.md +17 -0
- irksome-2026.0.0/irksome/__init__.py +122 -0
- irksome-2026.0.0/irksome/backend.py +129 -0
- irksome-2026.0.0/irksome/backends/__init__.py +0 -0
- irksome-2026.0.0/irksome/backends/dolfinx.py +184 -0
- irksome-2026.0.0/irksome/backends/firedrake.py +139 -0
- irksome-2026.0.0/irksome/base_time_stepper.py +252 -0
- irksome-2026.0.0/irksome/bcs.py +52 -0
- irksome-2026.0.0/irksome/constant.py +21 -0
- irksome-2026.0.0/irksome/dirk_stepper.py +224 -0
- irksome-2026.0.0/irksome/discontinuous_galerkin_stepper.py +309 -0
- irksome-2026.0.0/irksome/explicit_stepper.py +21 -0
- irksome-2026.0.0/irksome/galerkin_stepper.py +440 -0
- irksome-2026.0.0/irksome/imex.py +647 -0
- irksome-2026.0.0/irksome/integrated_lagrange.py +39 -0
- irksome-2026.0.0/irksome/labeling.py +174 -0
- irksome-2026.0.0/irksome/multistep.py +182 -0
- irksome-2026.0.0/irksome/nystrom_dirk_stepper.py +281 -0
- irksome-2026.0.0/irksome/nystrom_stepper.py +222 -0
- irksome-2026.0.0/irksome/pc.py +170 -0
- irksome-2026.0.0/irksome/scheme.py +186 -0
- irksome-2026.0.0/irksome/stage_derivative.py +433 -0
- irksome-2026.0.0/irksome/stage_value.py +344 -0
- irksome-2026.0.0/irksome/stepper.py +236 -0
- irksome-2026.0.0/irksome/tableaux/ButcherTableaux.py +261 -0
- irksome-2026.0.0/irksome/tableaux/ars_dirk_imex_tableaux.py +111 -0
- irksome-2026.0.0/irksome/tableaux/dirk_imex_tableaux.py +58 -0
- irksome-2026.0.0/irksome/tableaux/multistep_tableaux.py +126 -0
- irksome-2026.0.0/irksome/tableaux/pep_explicit_rk.py +70 -0
- irksome-2026.0.0/irksome/tableaux/sspk_tableau.py +85 -0
- irksome-2026.0.0/irksome/tableaux/wso_dirk_tableaux.py +183 -0
- irksome-2026.0.0/irksome/tools.py +171 -0
- irksome-2026.0.0/irksome/ufl/__init__.py +0 -0
- irksome-2026.0.0/irksome/ufl/deriv.py +176 -0
- irksome-2026.0.0/irksome/ufl/estimate_degrees.py +194 -0
- irksome-2026.0.0/irksome/ufl/lag.py +12 -0
- irksome-2026.0.0/irksome/ufl/manipulation.py +277 -0
- irksome-2026.0.0/pyproject.toml +37 -0
- irksome-2026.0.0/setup.cfg +10 -0
- irksome-2026.0.0/tests/test_accuracy.py +133 -0
- irksome-2026.0.0/tests/test_adaptive.py +225 -0
- irksome-2026.0.0/tests/test_adjoint.py +59 -0
- irksome-2026.0.0/tests/test_appctx.py +20 -0
- irksome-2026.0.0/tests/test_base_kwargs.py +45 -0
- irksome-2026.0.0/tests/test_bern.py +240 -0
- irksome-2026.0.0/tests/test_bounds.py +371 -0
- irksome-2026.0.0/tests/test_butcher.py +64 -0
- irksome-2026.0.0/tests/test_collocation_eval.py +224 -0
- irksome-2026.0.0/tests/test_curl.py +60 -0
- irksome-2026.0.0/tests/test_dae.py +151 -0
- irksome-2026.0.0/tests/test_degree_estimation.py +114 -0
- irksome-2026.0.0/tests/test_delta.py +135 -0
- irksome-2026.0.0/tests/test_differentiation.py +94 -0
- irksome-2026.0.0/tests/test_dirichletbc.py +65 -0
- irksome-2026.0.0/tests/test_dirk.py +289 -0
- irksome-2026.0.0/tests/test_disc_galerkin.py +153 -0
- irksome-2026.0.0/tests/test_equationbc.py +167 -0
- irksome-2026.0.0/tests/test_explicit.py +76 -0
- irksome-2026.0.0/tests/test_galerkin.py +371 -0
- irksome-2026.0.0/tests/test_has_nonlinear_time_derivative.py +80 -0
- irksome-2026.0.0/tests/test_imex.py +258 -0
- irksome-2026.0.0/tests/test_inhomogbc.py +55 -0
- irksome-2026.0.0/tests/test_lag.py +56 -0
- irksome-2026.0.0/tests/test_mass_conservation.py +163 -0
- irksome-2026.0.0/tests/test_multistep.py +325 -0
- irksome-2026.0.0/tests/test_multistep_tableau.py +48 -0
- irksome-2026.0.0/tests/test_nystrom.py +282 -0
- irksome-2026.0.0/tests/test_nystrom_pc.py +100 -0
- irksome-2026.0.0/tests/test_odevsdae.py +57 -0
- irksome-2026.0.0/tests/test_pc.py +414 -0
- irksome-2026.0.0/tests/test_rtcf.py +59 -0
- irksome-2026.0.0/tests/test_split.py +207 -0
- irksome-2026.0.0/tests/test_stage_value_init.py +53 -0
- irksome-2026.0.0/tests/test_stokes.py +212 -0
- irksome-2026.0.0/tests/test_subdomainbc.py +104 -0
- irksome-2026.0.0/tests/test_tensor_fs.py +28 -0
- irksome-2026.0.0/tests/test_time_form_splitting.py +154 -0
- irksome-2026.0.0/tests/test_vecbc.py +62 -0
- irksome-2026.0.0/tests/test_wave_energy.py +79 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: IRKsome
|
|
3
|
+
Version: 2026.0.0
|
|
4
|
+
Summary: A library for fully implicit Runge-Kutta methods in Firedrake
|
|
5
|
+
Author: Pablo Brubeck, Patrick E. Farrell, Scott P. MacLachlan
|
|
6
|
+
Author-email: "Robert C. Kirby" <Robert_Kirby@baylor.edu>
|
|
7
|
+
License: Irksome is free software: you can redistribute it and/or modify it under
|
|
8
|
+
the terms of the GNU Lesser General Public License as published by the
|
|
9
|
+
Free Software Foundation, either version 3 of the License, or (at your
|
|
10
|
+
option) any later version.
|
|
11
|
+
|
|
12
|
+
Irksome is distributed in the hope that it will be useful, but WITHOUT
|
|
13
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
15
|
+
License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU Lesser General Public
|
|
18
|
+
License along with Irksome. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Project-URL: Homepage, https://www.firedrakeproject.org/Irksome
|
|
22
|
+
Project-URL: Repository, https://github.com/firedrakeproject/Irksome.git
|
|
23
|
+
Classifier: Programming Language :: Python
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: ci
|
|
27
|
+
Requires-Dist: flake8; extra == "ci"
|
|
28
|
+
Requires-Dist: pytest; extra == "ci"
|
|
29
|
+
Requires-Dist: vtk; extra == "ci"
|
|
30
|
+
Provides-Extra: dolfinx
|
|
31
|
+
Requires-Dist: scifem; extra == "dolfinx"
|
|
32
|
+
Requires-Dist: firedrake-fiat; extra == "dolfinx"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# Irksome
|
|
39
|
+
|
|
40
|
+
This package works with Firedrake to generate Runge-Kutta methods from a semi-discrete UFL form. We have added a UFL symbol for time derivatives and can produce UFL for the fully discrete method from a semi-discrete form and a Butcher tableau. Several such tableaux are available, and some utility functions for time-stepping and adaptive time-stepping provided the tableau has an embedded lower-order method.
|
|
41
|
+
|
|
42
|
+
A long-standing critique of fully implicit RK methods, especially for PDE, is that they require a very large algebraic solve for all stages concurrently. However, we can use Firedrake's solver infrastructure to address this issue, and also recover most of the comparative efficiency of DIRK or explicit methods.
|
|
43
|
+
|
|
44
|
+
The core of Irksome is based on UFL manipulation and so should be adaptable to work with FEniCS or other UFL-based packages, but the current version works only with Firedrake. As such, it requires a working Irksome installation.
|
|
45
|
+
|
|
46
|
+
To install Irksome you need a working Firedrake installation (instructions can be found [here](https://www.firedrakeproject.org/install.html)) and then Irksome can be installed by running:
|
|
47
|
+
```
|
|
48
|
+
$ pip install --src . --editable git+https://github.com/firedrakeproject/Irksome.git#egg=Irksome
|
|
49
|
+
```
|
|
50
|
+
or, equivalently:
|
|
51
|
+
```
|
|
52
|
+
$ git clone https://github.com/firedrakeproject/Irksome.git
|
|
53
|
+
$ pip install --editable ./Irksome
|
|
54
|
+
```
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
5
|
+
IRKsome.egg-info/PKG-INFO
|
|
6
|
+
IRKsome.egg-info/SOURCES.txt
|
|
7
|
+
IRKsome.egg-info/dependency_links.txt
|
|
8
|
+
IRKsome.egg-info/requires.txt
|
|
9
|
+
IRKsome.egg-info/top_level.txt
|
|
10
|
+
irksome/__init__.py
|
|
11
|
+
irksome/backend.py
|
|
12
|
+
irksome/base_time_stepper.py
|
|
13
|
+
irksome/bcs.py
|
|
14
|
+
irksome/constant.py
|
|
15
|
+
irksome/dirk_stepper.py
|
|
16
|
+
irksome/discontinuous_galerkin_stepper.py
|
|
17
|
+
irksome/explicit_stepper.py
|
|
18
|
+
irksome/galerkin_stepper.py
|
|
19
|
+
irksome/imex.py
|
|
20
|
+
irksome/integrated_lagrange.py
|
|
21
|
+
irksome/labeling.py
|
|
22
|
+
irksome/multistep.py
|
|
23
|
+
irksome/nystrom_dirk_stepper.py
|
|
24
|
+
irksome/nystrom_stepper.py
|
|
25
|
+
irksome/pc.py
|
|
26
|
+
irksome/scheme.py
|
|
27
|
+
irksome/stage_derivative.py
|
|
28
|
+
irksome/stage_value.py
|
|
29
|
+
irksome/stepper.py
|
|
30
|
+
irksome/tools.py
|
|
31
|
+
irksome/backends/__init__.py
|
|
32
|
+
irksome/backends/dolfinx.py
|
|
33
|
+
irksome/backends/firedrake.py
|
|
34
|
+
irksome/tableaux/ButcherTableaux.py
|
|
35
|
+
irksome/tableaux/ars_dirk_imex_tableaux.py
|
|
36
|
+
irksome/tableaux/dirk_imex_tableaux.py
|
|
37
|
+
irksome/tableaux/multistep_tableaux.py
|
|
38
|
+
irksome/tableaux/pep_explicit_rk.py
|
|
39
|
+
irksome/tableaux/sspk_tableau.py
|
|
40
|
+
irksome/tableaux/wso_dirk_tableaux.py
|
|
41
|
+
irksome/ufl/__init__.py
|
|
42
|
+
irksome/ufl/deriv.py
|
|
43
|
+
irksome/ufl/estimate_degrees.py
|
|
44
|
+
irksome/ufl/lag.py
|
|
45
|
+
irksome/ufl/manipulation.py
|
|
46
|
+
tests/test_accuracy.py
|
|
47
|
+
tests/test_adaptive.py
|
|
48
|
+
tests/test_adjoint.py
|
|
49
|
+
tests/test_appctx.py
|
|
50
|
+
tests/test_base_kwargs.py
|
|
51
|
+
tests/test_bern.py
|
|
52
|
+
tests/test_bounds.py
|
|
53
|
+
tests/test_butcher.py
|
|
54
|
+
tests/test_collocation_eval.py
|
|
55
|
+
tests/test_curl.py
|
|
56
|
+
tests/test_dae.py
|
|
57
|
+
tests/test_degree_estimation.py
|
|
58
|
+
tests/test_delta.py
|
|
59
|
+
tests/test_differentiation.py
|
|
60
|
+
tests/test_dirichletbc.py
|
|
61
|
+
tests/test_dirk.py
|
|
62
|
+
tests/test_disc_galerkin.py
|
|
63
|
+
tests/test_equationbc.py
|
|
64
|
+
tests/test_explicit.py
|
|
65
|
+
tests/test_galerkin.py
|
|
66
|
+
tests/test_has_nonlinear_time_derivative.py
|
|
67
|
+
tests/test_imex.py
|
|
68
|
+
tests/test_inhomogbc.py
|
|
69
|
+
tests/test_lag.py
|
|
70
|
+
tests/test_mass_conservation.py
|
|
71
|
+
tests/test_multistep.py
|
|
72
|
+
tests/test_multistep_tableau.py
|
|
73
|
+
tests/test_nystrom.py
|
|
74
|
+
tests/test_nystrom_pc.py
|
|
75
|
+
tests/test_odevsdae.py
|
|
76
|
+
tests/test_pc.py
|
|
77
|
+
tests/test_rtcf.py
|
|
78
|
+
tests/test_split.py
|
|
79
|
+
tests/test_stage_value_init.py
|
|
80
|
+
tests/test_stokes.py
|
|
81
|
+
tests/test_subdomainbc.py
|
|
82
|
+
tests/test_tensor_fs.py
|
|
83
|
+
tests/test_time_form_splitting.py
|
|
84
|
+
tests/test_vecbc.py
|
|
85
|
+
tests/test_wave_energy.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
irksome
|
irksome-2026.0.0/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Irksome is free software: you can redistribute it and/or modify it under
|
|
2
|
+
the terms of the GNU Lesser General Public License as published by the
|
|
3
|
+
Free Software Foundation, either version 3 of the License, or (at your
|
|
4
|
+
option) any later version.
|
|
5
|
+
|
|
6
|
+
Irksome is distributed in the hope that it will be useful, but WITHOUT
|
|
7
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
8
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
9
|
+
License for more details.
|
|
10
|
+
|
|
11
|
+
You should have received a copy of the GNU Lesser General Public
|
|
12
|
+
License along with Irksome. If not, see <http://www.gnu.org/licenses/>.
|
|
13
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: IRKsome
|
|
3
|
+
Version: 2026.0.0
|
|
4
|
+
Summary: A library for fully implicit Runge-Kutta methods in Firedrake
|
|
5
|
+
Author: Pablo Brubeck, Patrick E. Farrell, Scott P. MacLachlan
|
|
6
|
+
Author-email: "Robert C. Kirby" <Robert_Kirby@baylor.edu>
|
|
7
|
+
License: Irksome is free software: you can redistribute it and/or modify it under
|
|
8
|
+
the terms of the GNU Lesser General Public License as published by the
|
|
9
|
+
Free Software Foundation, either version 3 of the License, or (at your
|
|
10
|
+
option) any later version.
|
|
11
|
+
|
|
12
|
+
Irksome is distributed in the hope that it will be useful, but WITHOUT
|
|
13
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
15
|
+
License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU Lesser General Public
|
|
18
|
+
License along with Irksome. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Project-URL: Homepage, https://www.firedrakeproject.org/Irksome
|
|
22
|
+
Project-URL: Repository, https://github.com/firedrakeproject/Irksome.git
|
|
23
|
+
Classifier: Programming Language :: Python
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: ci
|
|
27
|
+
Requires-Dist: flake8; extra == "ci"
|
|
28
|
+
Requires-Dist: pytest; extra == "ci"
|
|
29
|
+
Requires-Dist: vtk; extra == "ci"
|
|
30
|
+
Provides-Extra: dolfinx
|
|
31
|
+
Requires-Dist: scifem; extra == "dolfinx"
|
|
32
|
+
Requires-Dist: firedrake-fiat; extra == "dolfinx"
|
|
33
|
+
Provides-Extra: docs
|
|
34
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == "docs"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# Irksome
|
|
39
|
+
|
|
40
|
+
This package works with Firedrake to generate Runge-Kutta methods from a semi-discrete UFL form. We have added a UFL symbol for time derivatives and can produce UFL for the fully discrete method from a semi-discrete form and a Butcher tableau. Several such tableaux are available, and some utility functions for time-stepping and adaptive time-stepping provided the tableau has an embedded lower-order method.
|
|
41
|
+
|
|
42
|
+
A long-standing critique of fully implicit RK methods, especially for PDE, is that they require a very large algebraic solve for all stages concurrently. However, we can use Firedrake's solver infrastructure to address this issue, and also recover most of the comparative efficiency of DIRK or explicit methods.
|
|
43
|
+
|
|
44
|
+
The core of Irksome is based on UFL manipulation and so should be adaptable to work with FEniCS or other UFL-based packages, but the current version works only with Firedrake. As such, it requires a working Irksome installation.
|
|
45
|
+
|
|
46
|
+
To install Irksome you need a working Firedrake installation (instructions can be found [here](https://www.firedrakeproject.org/install.html)) and then Irksome can be installed by running:
|
|
47
|
+
```
|
|
48
|
+
$ pip install --src . --editable git+https://github.com/firedrakeproject/Irksome.git#egg=Irksome
|
|
49
|
+
```
|
|
50
|
+
or, equivalently:
|
|
51
|
+
```
|
|
52
|
+
$ git clone https://github.com/firedrakeproject/Irksome.git
|
|
53
|
+
$ pip install --editable ./Irksome
|
|
54
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Irksome
|
|
2
|
+
|
|
3
|
+
This package works with Firedrake to generate Runge-Kutta methods from a semi-discrete UFL form. We have added a UFL symbol for time derivatives and can produce UFL for the fully discrete method from a semi-discrete form and a Butcher tableau. Several such tableaux are available, and some utility functions for time-stepping and adaptive time-stepping provided the tableau has an embedded lower-order method.
|
|
4
|
+
|
|
5
|
+
A long-standing critique of fully implicit RK methods, especially for PDE, is that they require a very large algebraic solve for all stages concurrently. However, we can use Firedrake's solver infrastructure to address this issue, and also recover most of the comparative efficiency of DIRK or explicit methods.
|
|
6
|
+
|
|
7
|
+
The core of Irksome is based on UFL manipulation and so should be adaptable to work with FEniCS or other UFL-based packages, but the current version works only with Firedrake. As such, it requires a working Irksome installation.
|
|
8
|
+
|
|
9
|
+
To install Irksome you need a working Firedrake installation (instructions can be found [here](https://www.firedrakeproject.org/install.html)) and then Irksome can be installed by running:
|
|
10
|
+
```
|
|
11
|
+
$ pip install --src . --editable git+https://github.com/firedrakeproject/Irksome.git#egg=Irksome
|
|
12
|
+
```
|
|
13
|
+
or, equivalently:
|
|
14
|
+
```
|
|
15
|
+
$ git clone https://github.com/firedrakeproject/Irksome.git
|
|
16
|
+
$ pip install --editable ./Irksome
|
|
17
|
+
```
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from .tableaux.ButcherTableaux import (
|
|
2
|
+
Alexander,
|
|
3
|
+
BackwardEuler,
|
|
4
|
+
GaussLegendre,
|
|
5
|
+
LobattoIIIA,
|
|
6
|
+
LobattoIIIC,
|
|
7
|
+
PareschiRusso,
|
|
8
|
+
QinZhang,
|
|
9
|
+
RadauIIA,
|
|
10
|
+
)
|
|
11
|
+
from .tableaux.multistep_tableaux import (
|
|
12
|
+
BDF,
|
|
13
|
+
AdamsBashforth,
|
|
14
|
+
AdamsMoulton,
|
|
15
|
+
)
|
|
16
|
+
from .tableaux.pep_explicit_rk import PEPRK
|
|
17
|
+
from .ufl.deriv import Dt, expand_time_derivatives, check_irksome_import_order
|
|
18
|
+
from .ufl.lag import lag
|
|
19
|
+
|
|
20
|
+
check_irksome_import_order()
|
|
21
|
+
|
|
22
|
+
from .tableaux.dirk_imex_tableaux import DIRK_IMEX
|
|
23
|
+
from .tableaux.ars_dirk_imex_tableaux import ARS_DIRK_IMEX
|
|
24
|
+
from .tableaux.sspk_tableau import SSPK_DIRK_IMEX, SSPButcherTableau
|
|
25
|
+
from .tableaux.multistep_tableaux import MultistepTableau
|
|
26
|
+
|
|
27
|
+
from .constant import MeshConstant
|
|
28
|
+
from .tableaux.wso_dirk_tableaux import WSODIRK
|
|
29
|
+
from .scheme import create_time_quadrature
|
|
30
|
+
from .scheme import ContinuousPetrovGalerkinScheme, DiscontinuousGalerkinScheme
|
|
31
|
+
from .scheme import GalerkinCollocationScheme, DiscontinuousGalerkinCollocationScheme
|
|
32
|
+
from .bcs import BoundsConstrainedDirichletBC
|
|
33
|
+
from .dirk_stepper import DIRKTimeStepper
|
|
34
|
+
from .imex import RadauIIAIMEXMethod, DIRKIMEXMethod
|
|
35
|
+
from .stage_derivative import getForm
|
|
36
|
+
from .nystrom_dirk_stepper import DIRKNystromTimeStepper, ExplicitNystromTimeStepper
|
|
37
|
+
from .nystrom_stepper import (
|
|
38
|
+
StageDerivativeNystromTimeStepper,
|
|
39
|
+
ClassicNystrom4Tableau,
|
|
40
|
+
)
|
|
41
|
+
from .stage_value import StageValueTimeStepper
|
|
42
|
+
|
|
43
|
+
from .multistep import MultistepTimeStepper
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
"AdamsBashforth",
|
|
48
|
+
"AdamsMoulton",
|
|
49
|
+
"Alexander",
|
|
50
|
+
"ARS_DIRK_IMEX",
|
|
51
|
+
"BackwardEuler",
|
|
52
|
+
"BDF",
|
|
53
|
+
"create_time_quadrature",
|
|
54
|
+
"DIRK_IMEX",
|
|
55
|
+
"DiscontinuousGalerkinCollocationScheme",
|
|
56
|
+
"Dt",
|
|
57
|
+
"expand_time_derivatives",
|
|
58
|
+
"GalerkinCollocationScheme",
|
|
59
|
+
"GaussLegendre",
|
|
60
|
+
"lag",
|
|
61
|
+
"LobattoIIIA",
|
|
62
|
+
"LobattoIIIC",
|
|
63
|
+
"MeshConstant",
|
|
64
|
+
"MultistepTableau",
|
|
65
|
+
"PareschiRusso",
|
|
66
|
+
"PEPRK",
|
|
67
|
+
"QinZhang",
|
|
68
|
+
"RadauIIA",
|
|
69
|
+
"SSPButcherTableau",
|
|
70
|
+
"SSPK_DIRK_IMEX",
|
|
71
|
+
"WSODIRK",
|
|
72
|
+
"DIRKTimeStepper",
|
|
73
|
+
"BoundsConstrainedDirichletBC",
|
|
74
|
+
"getForm",
|
|
75
|
+
"RadauIIAIMEXMethod",
|
|
76
|
+
"DIRKIMEXMethod",
|
|
77
|
+
"DIRKNystromTimeStepper",
|
|
78
|
+
"ExplicitNystromTimeStepper",
|
|
79
|
+
"StageDerivativeNystromTimeStepper",
|
|
80
|
+
"ClassicNystrom4Tableau",
|
|
81
|
+
"StageValueTimeStepper",
|
|
82
|
+
"ContinuousPetrovGalerkinTimeStepper",
|
|
83
|
+
"DiscontinuousGalerkinTimeStepper",
|
|
84
|
+
"MultistepTimeStepper",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
import importlib
|
|
90
|
+
|
|
91
|
+
importlib.import_module("firedrake")
|
|
92
|
+
from .labeling import TimeQuadratureLabel
|
|
93
|
+
from .discontinuous_galerkin_stepper import DiscontinuousGalerkinTimeStepper
|
|
94
|
+
from .galerkin_stepper import ContinuousPetrovGalerkinTimeStepper
|
|
95
|
+
|
|
96
|
+
from .pc import (
|
|
97
|
+
ClinesBase,
|
|
98
|
+
ClinesLD,
|
|
99
|
+
NystromAuxiliaryOperatorPC,
|
|
100
|
+
RanaBase,
|
|
101
|
+
RanaDU,
|
|
102
|
+
RanaLD,
|
|
103
|
+
IRKAuxiliaryOperatorPC,
|
|
104
|
+
)
|
|
105
|
+
from .stepper import TimeStepper
|
|
106
|
+
|
|
107
|
+
__all__ += [
|
|
108
|
+
"TimeQuadratureLabel",
|
|
109
|
+
"DiscontinuousGalerkinScheme",
|
|
110
|
+
"ContinuousPetrovGalerkinScheme",
|
|
111
|
+
"ClinesBase",
|
|
112
|
+
"ClinesLD",
|
|
113
|
+
"NystromAuxiliaryOperatorPC",
|
|
114
|
+
"RanaBase",
|
|
115
|
+
"RanaDU",
|
|
116
|
+
"RanaLD",
|
|
117
|
+
"IRKAuxiliaryOperatorPC",
|
|
118
|
+
"TimeStepper",
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
except ModuleNotFoundError:
|
|
122
|
+
pass
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from typing import Protocol, Any, Sequence
|
|
2
|
+
import ufl
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
import types
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Backend(Protocol):
|
|
8
|
+
def get_function_space(self, V: ufl.Coefficient) -> ufl.FunctionSpace:
|
|
9
|
+
"""Get a function space from the backend"""
|
|
10
|
+
|
|
11
|
+
def extract_bcs(bcs: Any) -> tuple[Any]:
|
|
12
|
+
"""Extract boundary conditions"""
|
|
13
|
+
|
|
14
|
+
class Function:
|
|
15
|
+
...
|
|
16
|
+
|
|
17
|
+
class DirichletBC:
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def get_stages(self, V: ufl.FunctionSpace, num_stages: int) -> ufl.Coefficient:
|
|
21
|
+
"""
|
|
22
|
+
Given a function space for a single time-step, get a duplicate of this space,
|
|
23
|
+
repeated `num_stages` times.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
V: Space for single step
|
|
27
|
+
num_stages: Number of stages
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
A coefficient in the new function space
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
class Constant:
|
|
34
|
+
"""MeshLess constant class"""
|
|
35
|
+
|
|
36
|
+
class MeshConstant:
|
|
37
|
+
def __init__(self, msh: ufl.Mesh):
|
|
38
|
+
"""Initialize a mesh constant over a domain"""
|
|
39
|
+
|
|
40
|
+
def Constant(self, val: float = 0.0):
|
|
41
|
+
"""Generate a constant in the backend language with a specific value"""
|
|
42
|
+
|
|
43
|
+
def ConstantOrZero(
|
|
44
|
+
x: float | complex, MC: MeshConstant | None = None
|
|
45
|
+
) -> ufl.core.expr.Expr:
|
|
46
|
+
"""
|
|
47
|
+
Create a constant with backend class if MeshConstant is not supplied.
|
|
48
|
+
Create UFL zero if `x` is sufficiently small
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def get_mesh_constant(MC: MeshConstant | None) -> ufl.core.expr.Expr:
|
|
52
|
+
"""Get a backend class to construct a mesh constant from"""
|
|
53
|
+
|
|
54
|
+
def TestFunction(space: ufl.FunctionSpace, part: int | None = None) -> ufl.Argument:
|
|
55
|
+
"""Return a test-function that can be used by forms in the backend."""
|
|
56
|
+
|
|
57
|
+
def TrialFunction(
|
|
58
|
+
space: ufl.FunctionSpace, part: int | None = None
|
|
59
|
+
) -> ufl.Argument:
|
|
60
|
+
"""Return a trial-function that can be used by forms in the backend."""
|
|
61
|
+
|
|
62
|
+
def create_variational_problem(
|
|
63
|
+
F: ufl.Form,
|
|
64
|
+
u: ufl.Coefficient,
|
|
65
|
+
bcs: DirichletBC | Sequence | None = None,
|
|
66
|
+
**kwargs,
|
|
67
|
+
) -> Any:
|
|
68
|
+
"""Create a variational problem in the backend language."""
|
|
69
|
+
|
|
70
|
+
def create_variational_solver(
|
|
71
|
+
problem: Any,
|
|
72
|
+
solver_parameters: dict | None = None,
|
|
73
|
+
**kwargs,
|
|
74
|
+
):
|
|
75
|
+
"""Create a variational solver in the backend language."""
|
|
76
|
+
|
|
77
|
+
def get_stage_spaces(V: ufl.FunctionSpace, num_stages: int) -> ufl.FunctionSpace:
|
|
78
|
+
"""Create a stage space with M number of components."""
|
|
79
|
+
|
|
80
|
+
def norm(
|
|
81
|
+
v: ufl.core.expr.Expr, norm_type: str = "L2", mesh: ufl.Mesh | None = None
|
|
82
|
+
) -> float:
|
|
83
|
+
"""Compute the norm of a function in the backend language."""
|
|
84
|
+
|
|
85
|
+
def assemble(expr: ufl.core.expr.Expr) -> Any:
|
|
86
|
+
"""Assemble a UFL expression in the backend language."""
|
|
87
|
+
|
|
88
|
+
def derivative(
|
|
89
|
+
form: ufl.Form,
|
|
90
|
+
u: ufl.Coefficient,
|
|
91
|
+
du: ufl.Argument | None = None,
|
|
92
|
+
coefficient_derivatives: dict | None = None,
|
|
93
|
+
) -> ufl.Form:
|
|
94
|
+
"""Compute the derivative of a form with respect to a coefficient in the backend language."""
|
|
95
|
+
|
|
96
|
+
def invalidate_jacobian(solver: Any):
|
|
97
|
+
"""Invalidate the Jacobian matrix in the backend language."""
|
|
98
|
+
|
|
99
|
+
class EquationBCSplit:
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
class EquationBC:
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def create_bounds_constrained_bc(V, g, sub_domain, bounds, solver_parameters=None) -> DirichletBC:
|
|
106
|
+
...
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def get_backend(backend: str | types.ModuleType) -> Backend:
|
|
110
|
+
"""Get backend class from backend name.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
backend: Name of the backend to get
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Backend class
|
|
117
|
+
"""
|
|
118
|
+
if isinstance(backend, types.ModuleType):
|
|
119
|
+
return backend
|
|
120
|
+
if backend == "firedrake":
|
|
121
|
+
from .backends import firedrake as fd_backend
|
|
122
|
+
|
|
123
|
+
return fd_backend
|
|
124
|
+
elif backend == "dolfinx":
|
|
125
|
+
from .backends import dolfinx as dx_backend
|
|
126
|
+
|
|
127
|
+
return dx_backend
|
|
128
|
+
else:
|
|
129
|
+
return import_module(backend)
|
|
File without changes
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""DOLFINx backend for Irksome"""
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from mpi4py import MPI
|
|
5
|
+
from petsc4py import PETSc
|
|
6
|
+
import basix.ufl
|
|
7
|
+
import dolfinx.fem.petsc
|
|
8
|
+
import ufl
|
|
9
|
+
import typing
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
def get_stage_space(V: ufl.FunctionSpace, num_stages: int) -> ufl.FunctionSpace:
|
|
13
|
+
if num_stages == 1:
|
|
14
|
+
me = V.ufl_elemet()
|
|
15
|
+
else:
|
|
16
|
+
el = V.ufl_element()
|
|
17
|
+
if el.num_sub_elements > 0:
|
|
18
|
+
me = basix.ufl.mixed_element(
|
|
19
|
+
np.tile(el.sub_elements, num_stages).tolist()
|
|
20
|
+
)
|
|
21
|
+
else:
|
|
22
|
+
me = basix.ufl.blocked_element(el, shape=(num_stages,))
|
|
23
|
+
return dolfinx.fem.functionspace(V.mesh, me)
|
|
24
|
+
|
|
25
|
+
def extract_bcs(bcs: typing.Any) -> tuple[typing.Any]:
|
|
26
|
+
"""Extract boundary conditions"""
|
|
27
|
+
return bcs
|
|
28
|
+
|
|
29
|
+
def create_variational_problem(F, u, bcs=None, aP=None, **kwargs):
|
|
30
|
+
"""Create a variational problem."""
|
|
31
|
+
if len(F.arguments()) == 2:
|
|
32
|
+
a, L = ufl.system(F)
|
|
33
|
+
return dolfinx.fem.petsc.LinearProblem(
|
|
34
|
+
a,
|
|
35
|
+
L,
|
|
36
|
+
u,
|
|
37
|
+
bcs=bcs,
|
|
38
|
+
petsc_options_prefix="IrkSomeLinearSolver",
|
|
39
|
+
P=aP,
|
|
40
|
+
**kwargs,
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
return dolfinx.fem.petsc.NonlinearProblem(
|
|
44
|
+
F,
|
|
45
|
+
u,
|
|
46
|
+
petsc_options_prefix="IrkSomeNonlinearSolver",
|
|
47
|
+
bcs=bcs,
|
|
48
|
+
petsc_options=kwargs.get("solver_parameters"),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def create_variational_solver(
|
|
52
|
+
problem: dolfinx.fem.petsc.LinearProblem | dolfinx.fem.petsc.NonlinearProblem,
|
|
53
|
+
**kwargs,
|
|
54
|
+
):
|
|
55
|
+
"""Create a variational solver that uses PETSc SNES or KSP."""
|
|
56
|
+
solver_parameters = kwargs.get("solver_parameters", {})
|
|
57
|
+
solver = problem.solver
|
|
58
|
+
solver_prefix = problem.solver.getOptionsPrefix()
|
|
59
|
+
opts = PETSc.Options(
|
|
60
|
+
)
|
|
61
|
+
opts.prefixPush(solver_prefix)
|
|
62
|
+
for k, v in solver_parameters.items():
|
|
63
|
+
opts.setValue(k, v)
|
|
64
|
+
solver.setFromOptions()
|
|
65
|
+
opts.prefixPop()
|
|
66
|
+
# For some strange reason delValue doesn't respect prefixes
|
|
67
|
+
for k, v in solver_parameters.items():
|
|
68
|
+
opts.delValue(f"{solver_prefix}{k}")
|
|
69
|
+
return problem
|
|
70
|
+
|
|
71
|
+
def get_function_space(u: ufl.Coefficient) -> ufl.FunctionSpace:
|
|
72
|
+
return u.ufl_function_space()
|
|
73
|
+
|
|
74
|
+
def get_stages(V: dolfinx.fem.FunctionSpace, num_stages: int) -> ufl.Coefficient:
|
|
75
|
+
"""
|
|
76
|
+
Given a function space for a single time-step, get a duplicate of this space,
|
|
77
|
+
repeated `num_stages` times.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
V: Space for single step
|
|
81
|
+
num_stages: Number of stages
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
A coefficient in the new function space
|
|
85
|
+
"""
|
|
86
|
+
if V.num_sub_spaces == 0:
|
|
87
|
+
el = basix.ufl.mixed_element([V.ufl_element()] * num_stages)
|
|
88
|
+
else:
|
|
89
|
+
el = basix.ufl.mixed_element(V.ufl_element().sub_elements * num_stages)
|
|
90
|
+
Vbig = dolfinx.fem.functionspace(V.mesh, el)
|
|
91
|
+
return dolfinx.fem.Function(Vbig)
|
|
92
|
+
|
|
93
|
+
class MeshConstant(object):
|
|
94
|
+
def __init__(self, msh):
|
|
95
|
+
self.msh = msh
|
|
96
|
+
try:
|
|
97
|
+
import basix.ufl
|
|
98
|
+
|
|
99
|
+
r_el = basix.ufl.real_element(
|
|
100
|
+
msh.basix_cell(), value_shape=(), dtype=dolfinx.default_scalar_type
|
|
101
|
+
)
|
|
102
|
+
self.V = dolfinx.fem.functionspace(msh, r_el)
|
|
103
|
+
except TypeError:
|
|
104
|
+
try:
|
|
105
|
+
import scifem
|
|
106
|
+
except ModuleNotFoundError:
|
|
107
|
+
raise RuntimeError(
|
|
108
|
+
"DOLFINx with real element support or Scifem is required to make mesh-constants"
|
|
109
|
+
)
|
|
110
|
+
self.V = scifem.create_real_functionspace(msh, ())
|
|
111
|
+
|
|
112
|
+
def Constant(self, val=0.0) -> ufl.Coefficient:
|
|
113
|
+
v = dolfinx.fem.Function(self.V)
|
|
114
|
+
v.value = val
|
|
115
|
+
return v
|
|
116
|
+
|
|
117
|
+
def get_mesh_constant(MC: MeshConstant | None) -> ufl.core.expr.Expr:
|
|
118
|
+
return MC.Constant if MC is not None else ufl.constantvalue.ComplexValue
|
|
119
|
+
|
|
120
|
+
class DirichletBC(dolfinx.fem.DirichletBC):
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
def norm(
|
|
124
|
+
v: ufl.core.expr.Expr, norm_type: str = "L2", mesh: ufl.Mesh | None = None
|
|
125
|
+
) -> float:
|
|
126
|
+
"""Compute the norm of a function in the backend language."""
|
|
127
|
+
if mesh is not None:
|
|
128
|
+
dx = ufl.Mesure("dx", domain=mesh)
|
|
129
|
+
else:
|
|
130
|
+
dx = ufl.dx
|
|
131
|
+
p = 2
|
|
132
|
+
if norm_type.startswith("L"):
|
|
133
|
+
p = int(norm_type[1:])
|
|
134
|
+
if p < 1:
|
|
135
|
+
raise ValueError(f"Invalid norm type {norm_type}")
|
|
136
|
+
expr = ufl.inner(v, v) ** (p / 2)
|
|
137
|
+
form = dolfinx.fem.form(expr * dx)
|
|
138
|
+
else:
|
|
139
|
+
raise NotImplementedError(f"Norm type {norm_type} not implemented")
|
|
140
|
+
norm_loc = dolfinx.fem.assemble_scalar(form)
|
|
141
|
+
return form.mesh.comm.Allreduce(MPI.IN_PLACE, norm_loc, op=MPI.SUM) ** (1 / p)
|
|
142
|
+
|
|
143
|
+
def assemble(expr: ufl.core.expr.Expr | float):
|
|
144
|
+
"""Assemble a UFL expression in the backend language."""
|
|
145
|
+
if isinstance(expr, float):
|
|
146
|
+
return float
|
|
147
|
+
else:
|
|
148
|
+
form = dolfinx.fem.form(expr)
|
|
149
|
+
if form.rank == 0:
|
|
150
|
+
return dolfinx.fem.assemble_scalar(form)
|
|
151
|
+
elif form.rank == 1:
|
|
152
|
+
return dolfinx.fem.assemble_vector(form)
|
|
153
|
+
elif form.rank == 2:
|
|
154
|
+
return dolfinx.fem.assemble_matrix(form)
|
|
155
|
+
else:
|
|
156
|
+
raise ValueError(f"Cannot assemble form of rank {form.rank}")
|
|
157
|
+
|
|
158
|
+
derivative = ufl.derivative
|
|
159
|
+
TrialFunction = ufl.TrialFunction
|
|
160
|
+
Function = dolfinx.fem.Function
|
|
161
|
+
TestFunction = ufl.TestFunction
|
|
162
|
+
|
|
163
|
+
class Constant(ufl.constantvalue.ScalarValue):
|
|
164
|
+
# NOTE: If dolfinx ever get's meshless constants we should change this
|
|
165
|
+
def assign(self, value):
|
|
166
|
+
self._value = value
|
|
167
|
+
|
|
168
|
+
class EquationBCSplit:
|
|
169
|
+
def __init__(self, *args, **kwargs):
|
|
170
|
+
raise NotImplementedError("DOLFINx does not support EquationBCSplit")
|
|
171
|
+
|
|
172
|
+
class EquationBC:
|
|
173
|
+
def __init__(self, *args, **kwargs):
|
|
174
|
+
raise NotImplementedError("DOLFINx does not support EquationBC")
|
|
175
|
+
|
|
176
|
+
def invalidate_jacobian(solver: dolfinx.fem.petsc.LinearProblem):
|
|
177
|
+
"""Invalidate the Jacobian matrix in the backend language."""
|
|
178
|
+
raise RuntimeError("DOLFINx does not support Jacobian invalidation")
|
|
179
|
+
|
|
180
|
+
def create_bounds_constrained_bc(V, g, sub_domain, bounds, solver_parameters=None):
|
|
181
|
+
raise NotImplementedError("Bounds-constrained BCs are not implemented for DOLFINx")
|
|
182
|
+
|
|
183
|
+
except ModuleNotFoundError:
|
|
184
|
+
pass
|