scikit-sundae 1.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.
- scikit_sundae-1.0.0/LICENSE +28 -0
- scikit_sundae-1.0.0/MANIFEST.in +2 -0
- scikit_sundae-1.0.0/PKG-INFO +199 -0
- scikit_sundae-1.0.0/README.md +114 -0
- scikit_sundae-1.0.0/SUNDIALS_LICENSE +29 -0
- scikit_sundae-1.0.0/pyproject.toml +88 -0
- scikit_sundae-1.0.0/setup.cfg +4 -0
- scikit_sundae-1.0.0/setup.py +163 -0
- scikit_sundae-1.0.0/src/scikit_sundae.egg-info/PKG-INFO +199 -0
- scikit_sundae-1.0.0/src/scikit_sundae.egg-info/SOURCES.txt +25 -0
- scikit_sundae-1.0.0/src/scikit_sundae.egg-info/dependency_links.txt +1 -0
- scikit_sundae-1.0.0/src/scikit_sundae.egg-info/requires.txt +30 -0
- scikit_sundae-1.0.0/src/scikit_sundae.egg-info/top_level.txt +1 -0
- scikit_sundae-1.0.0/src/sksundae/__init__.py +64 -0
- scikit_sundae-1.0.0/src/sksundae/_cy_common.pxd +18 -0
- scikit_sundae-1.0.0/src/sksundae/_cy_common.pyx +108 -0
- scikit_sundae-1.0.0/src/sksundae/_cy_cvode.pyx +1023 -0
- scikit_sundae-1.0.0/src/sksundae/_cy_ida.pyx +1100 -0
- scikit_sundae-1.0.0/src/sksundae/c_cvode.pxd +79 -0
- scikit_sundae-1.0.0/src/sksundae/c_ida.pxd +85 -0
- scikit_sundae-1.0.0/src/sksundae/c_nvector.pxd +8 -0
- scikit_sundae-1.0.0/src/sksundae/c_sundials.pxd +79 -0
- scikit_sundae-1.0.0/src/sksundae/c_sunlinsol.pxd +11 -0
- scikit_sundae-1.0.0/src/sksundae/c_sunmatrix.pxd +19 -0
- scikit_sundae-1.0.0/src/sksundae/cvode.py +360 -0
- scikit_sundae-1.0.0/src/sksundae/ida.py +398 -0
- scikit_sundae-1.0.0/src/sksundae/utils.py +141 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Alliance for Sustainable Energy, LLC
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: scikit-sundae
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: SUNDIALS bindings to differential aglebraic equation solvers.
|
|
5
|
+
Author: Corey R. Randall
|
|
6
|
+
Author-email: corey.randall@nrel.gov
|
|
7
|
+
Maintainer: Corey R. Randall
|
|
8
|
+
Maintainer-email: corey.randall@nrel.gov
|
|
9
|
+
License: BSD 3-Clause License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2024, Alliance for Sustainable Energy, LLC
|
|
12
|
+
|
|
13
|
+
Redistribution and use in source and binary forms, with or without
|
|
14
|
+
modification, are permitted provided that the following conditions are met:
|
|
15
|
+
|
|
16
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
17
|
+
list of conditions and the following disclaimer.
|
|
18
|
+
|
|
19
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
20
|
+
this list of conditions and the following disclaimer in the documentation
|
|
21
|
+
and/or other materials provided with the distribution.
|
|
22
|
+
|
|
23
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
24
|
+
contributors may be used to endorse or promote products derived from
|
|
25
|
+
this software without specific prior written permission.
|
|
26
|
+
|
|
27
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
28
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
29
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
30
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
31
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
32
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
33
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
34
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
35
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
36
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
37
|
+
|
|
38
|
+
Project-URL: Homepage, https://github.com/NREL/scikit-sundae
|
|
39
|
+
Project-URL: Documentation, https://scikit-sundae.readthedocs.io/
|
|
40
|
+
Project-URL: Repository, https://github.com/NREL/scikit-sundae
|
|
41
|
+
Project-URL: Issues, https://github.com/NREL/scikit-sundae/issues
|
|
42
|
+
Keywords: sundials,dae,ode,integrator,ivp
|
|
43
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
44
|
+
Classifier: Intended Audience :: Science/Research
|
|
45
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
46
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
47
|
+
Classifier: Programming Language :: Python :: 3
|
|
48
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
49
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
50
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
51
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
52
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
53
|
+
Requires-Python: <3.14,>=3.9
|
|
54
|
+
Description-Content-Type: text/markdown
|
|
55
|
+
License-File: LICENSE
|
|
56
|
+
License-File: SUNDIALS_LICENSE
|
|
57
|
+
Requires-Dist: numpy
|
|
58
|
+
Provides-Extra: dev
|
|
59
|
+
Requires-Dist: nox; extra == "dev"
|
|
60
|
+
Requires-Dist: pandas; extra == "dev"
|
|
61
|
+
Requires-Dist: pytest; extra == "dev"
|
|
62
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
63
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
64
|
+
Requires-Dist: genbadge[all]; extra == "dev"
|
|
65
|
+
Requires-Dist: flake8; extra == "dev"
|
|
66
|
+
Requires-Dist: autopep8; extra == "dev"
|
|
67
|
+
Requires-Dist: codespell; extra == "dev"
|
|
68
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
69
|
+
Requires-Dist: myst-nb; extra == "dev"
|
|
70
|
+
Requires-Dist: sphinx-design; extra == "dev"
|
|
71
|
+
Requires-Dist: sphinx-autoapi; extra == "dev"
|
|
72
|
+
Requires-Dist: sphinx-favicon; extra == "dev"
|
|
73
|
+
Requires-Dist: sphinx-copybutton; extra == "dev"
|
|
74
|
+
Requires-Dist: pydata-sphinx-theme; extra == "dev"
|
|
75
|
+
Requires-Dist: matplotlib; extra == "dev"
|
|
76
|
+
Provides-Extra: docs
|
|
77
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
78
|
+
Requires-Dist: myst-nb; extra == "docs"
|
|
79
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
|
80
|
+
Requires-Dist: sphinx-autoapi; extra == "docs"
|
|
81
|
+
Requires-Dist: sphinx-favicon; extra == "docs"
|
|
82
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
83
|
+
Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
84
|
+
Requires-Dist: matplotlib; extra == "docs"
|
|
85
|
+
|
|
86
|
+
<!-- <img alt='Logo' style='width: 75%; min-width: 250px; max-width: 500px;'
|
|
87
|
+
src='https://github.com/NREL/scikit-sundae/blob/main/images/readme_logo.png?raw=true'/> -->
|
|
88
|
+
|
|
89
|
+
# scikit-SUNDAE
|
|
90
|
+
|
|
91
|
+
[![CI][ci-b]][ci-l]
|
|
92
|
+
![tests][test-b]
|
|
93
|
+
![coverage][cov-b]
|
|
94
|
+
[![pep8][pep-b]][pep-l]
|
|
95
|
+
|
|
96
|
+
[ci-b]: https://github.com/NREL/scikit-sundae/actions/workflows/ci.yml/badge.svg
|
|
97
|
+
[ci-l]: https://github.com/NREL/scikit-sundae/actions/workflows/ci.yml
|
|
98
|
+
|
|
99
|
+
[test-b]: https://github.com/NREL/scikit-sundae/blob/main/images/tests.svg?raw=true
|
|
100
|
+
[cov-b]: https://github.com/NREL/scikit-sundae/blob/main/images/coverage.svg?raw=true
|
|
101
|
+
|
|
102
|
+
[pep-b]: https://img.shields.io/badge/code%20style-pep8-orange.svg
|
|
103
|
+
[pep-l]: https://www.python.org/dev/peps/pep-0008
|
|
104
|
+
|
|
105
|
+
## Summary
|
|
106
|
+
scikit-SUNDAE provides Python bindings to [SUNDIALS](https://sundials.readthedocs.io/) integrators. The implicit differential algebraic (IDA) solver and C-based variable-coefficient ordinary differential equations (CVODE) solver are both included.
|
|
107
|
+
|
|
108
|
+
The name SUNDAE combines (SUN)DIALS and DAE, which stands for differential algebraic equations. Solvers specific to DAE problems are not frequently available in Python. An ordinary differential equation (ODE) solver is also included for completeness. ODEs can be categorized as a subset of DAEs (i.e., DAEs with no algebraic constraints).
|
|
109
|
+
|
|
110
|
+
## Installation
|
|
111
|
+
scikit-SUNDAE is installable via either `pip` or `conda`. To install from [PyPI](https://pypi.org/project/scikit-sundae/) use the following command.
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
pip install scikit-sundae
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If you prefer using the `conda` package manager, you can install scikit-SUNDAE from the `conda-forge` channel using the command below.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
conda install -c conda-forge scikit-sundae
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Both sources contain binary installations. If your combination of operating system and CPU architecture is not supported, please submit an [issue](https://github.com/NREL/scikit-sundae/issues/) to let us know. If you'd prefer to build from source, please see the [documentation](https://scikit-sundae.readthedocs.io/en/latest/user_guide/installation.html).
|
|
124
|
+
|
|
125
|
+
## Get Started
|
|
126
|
+
You are now ready to start solving. Run one of the following examples to check your installation. Afterward, check out the [documentation](https://scikit-sundae.readthedocs.io/) for a full list of options (including event functions), detailed examples, and more.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# Use the CVODE integrator to solve the Van der Pol equation
|
|
130
|
+
|
|
131
|
+
from sksundae.cvode import CVODE
|
|
132
|
+
import matplotlib.pyplot as plt
|
|
133
|
+
|
|
134
|
+
def rhsfn(t, y, yp):
|
|
135
|
+
yp[0] = y[1]
|
|
136
|
+
yp[1] = 1000*(1 - y[0]**2)*y[1] - y[0]
|
|
137
|
+
|
|
138
|
+
solver = CVODE(rhsfn)
|
|
139
|
+
soln = solver.solve([0, 3000], [2, 0])
|
|
140
|
+
|
|
141
|
+
plt.plot(soln.t, soln.y[:, 0])
|
|
142
|
+
plt.show()
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The `CVODE` solver demonstrated above is only capable of solving pure ODEs. The constant parameters and time span used above match an example given by [MATLAB](https://www.mathworks.com/help/matlab/ref/ode15s.html) for easy comparison. If you are trying to solve a DAE, you will want to use the `IDA` solver instead. A minimal DAE example is given below for the Robertson problem. As with the CVODE example, the parameters below are chosen to match an online [MATLAB](https://www.mathworks.com/help/matlab/ref/ode15s.html) example for easy comparison.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
# Use the IDA integrator to solve the Robertson problem
|
|
149
|
+
|
|
150
|
+
from sksundae.ida import IDA
|
|
151
|
+
import matplotlib.pyplot as plt
|
|
152
|
+
|
|
153
|
+
def resfn(t, y, yp, res):
|
|
154
|
+
res[0] = yp[0] + 0.04*y[0] - 1e4*y[1]*y[2]
|
|
155
|
+
res[1] = yp[1] - 0.04*y[0] + 1e4*y[1]*y[2] + 3e7*y[1]**2
|
|
156
|
+
res[2] = y[0] + y[1] + y[2] - 1
|
|
157
|
+
|
|
158
|
+
solver = IDA(resfn, algebraic_idx=[2], calc_initcond='yp0')
|
|
159
|
+
soln = solver.solve([4e-6, 4e6], [1, 0, 0], [0, 0, 0])
|
|
160
|
+
|
|
161
|
+
plt.plot(soln.t, soln.y)
|
|
162
|
+
plt.legend(['y0', 'y1', 'y2'])
|
|
163
|
+
plt.show()
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Notes:**
|
|
167
|
+
* If you are new to Python, check out [Spyder IDE](https://www.spyder-ide.org/). Spyder is a powerful interactive development environment (IDE) that can make programming in Python more approachable to new users.
|
|
168
|
+
* Check the [solve_ivp](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html) documentation from scipy or the [scipy-dae](https://pypi.org/project/scipy-dae/) package repository if you are looking for common examples to test out and compare against. Translating an example from another package can help you learn how to use scikit-SUNDAE before trying to solve more challenging problems.
|
|
169
|
+
|
|
170
|
+
## Citing this Work
|
|
171
|
+
This work was authored by researchers at the National Renewable Energy Laboratory (NREL). If you use use this package in your work, please include the following citation:
|
|
172
|
+
|
|
173
|
+
> Randall, Corey R. "scikit-SUNDAE: A scikit with Python bindings to SUNDIALS Differential Algebraic Equation solvers [SWR-24-137]." Computer software. url: https://github.com/NREL/scikit-sundae. doi: https://doi.org/10.11578/dc.20241104.3.
|
|
174
|
+
|
|
175
|
+
For convenience, we also provide the following for your BibTex:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
@misc{Randall-2024,
|
|
179
|
+
title = {{scikit-SUNDAE: A scikit with Python bindings to SUNDIALS Differential Algebraic Equation solvers [SWR-24-137]}},
|
|
180
|
+
author = {Randall, Corey R.},
|
|
181
|
+
doi = {10.11578/dc.20241104.3},
|
|
182
|
+
url = {https://github.com/NREL/scikit-sundae},
|
|
183
|
+
year = {2024},
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Acknowledgements
|
|
188
|
+
scikit-SUNDAE was originally inspired by [scikits.odes](https://scikits-odes.readthedocs.io/) which also offers Python bindings to SUNDIALS. The API for scikit-SUNDAE was mostly adopted from scikits.odes; however, all of our source code is original. If you are comparing the two:
|
|
189
|
+
|
|
190
|
+
1. **scikits.odes:** includes iterative solvers and some optional solvers (e.g., LAPACK). The package only provides source distributions, so users must configure and compile SUNDAILS on their own.
|
|
191
|
+
2. **scikit-SUNDAE:** includes more flexible events function capabilities (e.g., direction detection and terminal flags), scipy-like output, and provides both binary and source distributions. Iterative and optional solvers are not available.
|
|
192
|
+
|
|
193
|
+
Our binary distributions include pre-compiled dynamic SUNDIALS libraries. These are self-contained and will not affect other, existing installations you may already have. To be in compliance with SUNDIALS distribution requirements, all scikit-SUNDAE distributions include a copy of the [SUNDIALS license](https://github.com/LLNL/sundials/blob/main/LICENSE).
|
|
194
|
+
|
|
195
|
+
## Contributing
|
|
196
|
+
If you'd like to contribute to this package, please look through the existing [issues](https://github.com/NREL/scikit-sundae/issues). If the bug you've caught or the feature you'd like to add isn't already reported, please submit a new issue. You should also read through the [developer guidelines](https://scikit-sundae.readthedocs.io/en/latest/development/) if you plan to work on the issue yourself.
|
|
197
|
+
|
|
198
|
+
## Disclaimer
|
|
199
|
+
This work was authored by the National Renewable Energy Laboratory (NREL), operated by Alliance for Sustainable Energy, LLC, for the U.S. Department of Energy (DOE). The views expressed in the repository do not necessarily represent the views of the DOE or the U.S. Government.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<!-- <img alt='Logo' style='width: 75%; min-width: 250px; max-width: 500px;'
|
|
2
|
+
src='https://github.com/NREL/scikit-sundae/blob/main/images/readme_logo.png?raw=true'/> -->
|
|
3
|
+
|
|
4
|
+
# scikit-SUNDAE
|
|
5
|
+
|
|
6
|
+
[![CI][ci-b]][ci-l]
|
|
7
|
+
![tests][test-b]
|
|
8
|
+
![coverage][cov-b]
|
|
9
|
+
[![pep8][pep-b]][pep-l]
|
|
10
|
+
|
|
11
|
+
[ci-b]: https://github.com/NREL/scikit-sundae/actions/workflows/ci.yml/badge.svg
|
|
12
|
+
[ci-l]: https://github.com/NREL/scikit-sundae/actions/workflows/ci.yml
|
|
13
|
+
|
|
14
|
+
[test-b]: https://github.com/NREL/scikit-sundae/blob/main/images/tests.svg?raw=true
|
|
15
|
+
[cov-b]: https://github.com/NREL/scikit-sundae/blob/main/images/coverage.svg?raw=true
|
|
16
|
+
|
|
17
|
+
[pep-b]: https://img.shields.io/badge/code%20style-pep8-orange.svg
|
|
18
|
+
[pep-l]: https://www.python.org/dev/peps/pep-0008
|
|
19
|
+
|
|
20
|
+
## Summary
|
|
21
|
+
scikit-SUNDAE provides Python bindings to [SUNDIALS](https://sundials.readthedocs.io/) integrators. The implicit differential algebraic (IDA) solver and C-based variable-coefficient ordinary differential equations (CVODE) solver are both included.
|
|
22
|
+
|
|
23
|
+
The name SUNDAE combines (SUN)DIALS and DAE, which stands for differential algebraic equations. Solvers specific to DAE problems are not frequently available in Python. An ordinary differential equation (ODE) solver is also included for completeness. ODEs can be categorized as a subset of DAEs (i.e., DAEs with no algebraic constraints).
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
scikit-SUNDAE is installable via either `pip` or `conda`. To install from [PyPI](https://pypi.org/project/scikit-sundae/) use the following command.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
pip install scikit-sundae
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If you prefer using the `conda` package manager, you can install scikit-SUNDAE from the `conda-forge` channel using the command below.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
conda install -c conda-forge scikit-sundae
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Both sources contain binary installations. If your combination of operating system and CPU architecture is not supported, please submit an [issue](https://github.com/NREL/scikit-sundae/issues/) to let us know. If you'd prefer to build from source, please see the [documentation](https://scikit-sundae.readthedocs.io/en/latest/user_guide/installation.html).
|
|
39
|
+
|
|
40
|
+
## Get Started
|
|
41
|
+
You are now ready to start solving. Run one of the following examples to check your installation. Afterward, check out the [documentation](https://scikit-sundae.readthedocs.io/) for a full list of options (including event functions), detailed examples, and more.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# Use the CVODE integrator to solve the Van der Pol equation
|
|
45
|
+
|
|
46
|
+
from sksundae.cvode import CVODE
|
|
47
|
+
import matplotlib.pyplot as plt
|
|
48
|
+
|
|
49
|
+
def rhsfn(t, y, yp):
|
|
50
|
+
yp[0] = y[1]
|
|
51
|
+
yp[1] = 1000*(1 - y[0]**2)*y[1] - y[0]
|
|
52
|
+
|
|
53
|
+
solver = CVODE(rhsfn)
|
|
54
|
+
soln = solver.solve([0, 3000], [2, 0])
|
|
55
|
+
|
|
56
|
+
plt.plot(soln.t, soln.y[:, 0])
|
|
57
|
+
plt.show()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The `CVODE` solver demonstrated above is only capable of solving pure ODEs. The constant parameters and time span used above match an example given by [MATLAB](https://www.mathworks.com/help/matlab/ref/ode15s.html) for easy comparison. If you are trying to solve a DAE, you will want to use the `IDA` solver instead. A minimal DAE example is given below for the Robertson problem. As with the CVODE example, the parameters below are chosen to match an online [MATLAB](https://www.mathworks.com/help/matlab/ref/ode15s.html) example for easy comparison.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# Use the IDA integrator to solve the Robertson problem
|
|
64
|
+
|
|
65
|
+
from sksundae.ida import IDA
|
|
66
|
+
import matplotlib.pyplot as plt
|
|
67
|
+
|
|
68
|
+
def resfn(t, y, yp, res):
|
|
69
|
+
res[0] = yp[0] + 0.04*y[0] - 1e4*y[1]*y[2]
|
|
70
|
+
res[1] = yp[1] - 0.04*y[0] + 1e4*y[1]*y[2] + 3e7*y[1]**2
|
|
71
|
+
res[2] = y[0] + y[1] + y[2] - 1
|
|
72
|
+
|
|
73
|
+
solver = IDA(resfn, algebraic_idx=[2], calc_initcond='yp0')
|
|
74
|
+
soln = solver.solve([4e-6, 4e6], [1, 0, 0], [0, 0, 0])
|
|
75
|
+
|
|
76
|
+
plt.plot(soln.t, soln.y)
|
|
77
|
+
plt.legend(['y0', 'y1', 'y2'])
|
|
78
|
+
plt.show()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Notes:**
|
|
82
|
+
* If you are new to Python, check out [Spyder IDE](https://www.spyder-ide.org/). Spyder is a powerful interactive development environment (IDE) that can make programming in Python more approachable to new users.
|
|
83
|
+
* Check the [solve_ivp](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html) documentation from scipy or the [scipy-dae](https://pypi.org/project/scipy-dae/) package repository if you are looking for common examples to test out and compare against. Translating an example from another package can help you learn how to use scikit-SUNDAE before trying to solve more challenging problems.
|
|
84
|
+
|
|
85
|
+
## Citing this Work
|
|
86
|
+
This work was authored by researchers at the National Renewable Energy Laboratory (NREL). If you use use this package in your work, please include the following citation:
|
|
87
|
+
|
|
88
|
+
> Randall, Corey R. "scikit-SUNDAE: A scikit with Python bindings to SUNDIALS Differential Algebraic Equation solvers [SWR-24-137]." Computer software. url: https://github.com/NREL/scikit-sundae. doi: https://doi.org/10.11578/dc.20241104.3.
|
|
89
|
+
|
|
90
|
+
For convenience, we also provide the following for your BibTex:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
@misc{Randall-2024,
|
|
94
|
+
title = {{scikit-SUNDAE: A scikit with Python bindings to SUNDIALS Differential Algebraic Equation solvers [SWR-24-137]}},
|
|
95
|
+
author = {Randall, Corey R.},
|
|
96
|
+
doi = {10.11578/dc.20241104.3},
|
|
97
|
+
url = {https://github.com/NREL/scikit-sundae},
|
|
98
|
+
year = {2024},
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Acknowledgements
|
|
103
|
+
scikit-SUNDAE was originally inspired by [scikits.odes](https://scikits-odes.readthedocs.io/) which also offers Python bindings to SUNDIALS. The API for scikit-SUNDAE was mostly adopted from scikits.odes; however, all of our source code is original. If you are comparing the two:
|
|
104
|
+
|
|
105
|
+
1. **scikits.odes:** includes iterative solvers and some optional solvers (e.g., LAPACK). The package only provides source distributions, so users must configure and compile SUNDAILS on their own.
|
|
106
|
+
2. **scikit-SUNDAE:** includes more flexible events function capabilities (e.g., direction detection and terminal flags), scipy-like output, and provides both binary and source distributions. Iterative and optional solvers are not available.
|
|
107
|
+
|
|
108
|
+
Our binary distributions include pre-compiled dynamic SUNDIALS libraries. These are self-contained and will not affect other, existing installations you may already have. To be in compliance with SUNDIALS distribution requirements, all scikit-SUNDAE distributions include a copy of the [SUNDIALS license](https://github.com/LLNL/sundials/blob/main/LICENSE).
|
|
109
|
+
|
|
110
|
+
## Contributing
|
|
111
|
+
If you'd like to contribute to this package, please look through the existing [issues](https://github.com/NREL/scikit-sundae/issues). If the bug you've caught or the feature you'd like to add isn't already reported, please submit a new issue. You should also read through the [developer guidelines](https://scikit-sundae.readthedocs.io/en/latest/development/) if you plan to work on the issue yourself.
|
|
112
|
+
|
|
113
|
+
## Disclaimer
|
|
114
|
+
This work was authored by the National Renewable Energy Laboratory (NREL), operated by Alliance for Sustainable Energy, LLC, for the U.S. Department of Energy (DOE). The views expressed in the repository do not necessarily represent the views of the DOE or the U.S. Government.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2002-2024, Lawrence Livermore National Security and Southern
|
|
4
|
+
Methodist University. All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# pyproject.toml
|
|
2
|
+
|
|
3
|
+
[build-system]
|
|
4
|
+
requires = ["setuptools", "cython", "numpy"]
|
|
5
|
+
build-backend = "setuptools.build_meta"
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "scikit-sundae"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
dynamic = ["version"]
|
|
11
|
+
requires-python = ">=3.9,<3.14"
|
|
12
|
+
license = { file = "LICENSE" }
|
|
13
|
+
description = "SUNDIALS bindings to differential aglebraic equation solvers."
|
|
14
|
+
keywords = ["sundials", "dae", "ode", "integrator", "ivp"]
|
|
15
|
+
authors = [
|
|
16
|
+
{ name = "Corey R. Randall" },
|
|
17
|
+
{ email = "corey.randall@nrel.gov" },
|
|
18
|
+
]
|
|
19
|
+
maintainers = [
|
|
20
|
+
{ name = "Corey R. Randall" },
|
|
21
|
+
{ email = "corey.randall@nrel.gov" },
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 5 - Production/Stable",
|
|
25
|
+
"Intended Audience :: Science/Research",
|
|
26
|
+
"License :: OSI Approved :: BSD License",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.9",
|
|
30
|
+
"Programming Language :: Python :: 3.10",
|
|
31
|
+
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Programming Language :: Python :: 3.13",
|
|
34
|
+
]
|
|
35
|
+
dependencies = ["numpy"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools]
|
|
38
|
+
include-package-data = true
|
|
39
|
+
license-files = [
|
|
40
|
+
"NOTICE*",
|
|
41
|
+
"AUTHORS*",
|
|
42
|
+
"COPYING*",
|
|
43
|
+
"LICENSE*",
|
|
44
|
+
"SUNDIALS_LICENSE",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.dynamic]
|
|
48
|
+
version = {attr = "sksundae.__version__"}
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.packages.find]
|
|
51
|
+
where = ["src"]
|
|
52
|
+
|
|
53
|
+
[project.optional-dependencies]
|
|
54
|
+
dev = [
|
|
55
|
+
"nox",
|
|
56
|
+
"pandas",
|
|
57
|
+
"pytest",
|
|
58
|
+
"pytest-cov",
|
|
59
|
+
"pytest-xdist",
|
|
60
|
+
"genbadge[all]",
|
|
61
|
+
"flake8",
|
|
62
|
+
"autopep8",
|
|
63
|
+
"codespell",
|
|
64
|
+
"sphinx",
|
|
65
|
+
"myst-nb",
|
|
66
|
+
"sphinx-design",
|
|
67
|
+
"sphinx-autoapi",
|
|
68
|
+
"sphinx-favicon",
|
|
69
|
+
"sphinx-copybutton",
|
|
70
|
+
"pydata-sphinx-theme",
|
|
71
|
+
"matplotlib",
|
|
72
|
+
]
|
|
73
|
+
docs = [
|
|
74
|
+
"sphinx",
|
|
75
|
+
"myst-nb",
|
|
76
|
+
"sphinx-design",
|
|
77
|
+
"sphinx-autoapi",
|
|
78
|
+
"sphinx-favicon",
|
|
79
|
+
"sphinx-copybutton",
|
|
80
|
+
"pydata-sphinx-theme",
|
|
81
|
+
"matplotlib",
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[project.urls]
|
|
85
|
+
Homepage = "https://github.com/NREL/scikit-sundae"
|
|
86
|
+
Documentation = "https://scikit-sundae.readthedocs.io/"
|
|
87
|
+
Repository = "https://github.com/NREL/scikit-sundae"
|
|
88
|
+
Issues = "https://github.com/NREL/scikit-sundae/issues"
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# setup.py
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import setuptools
|
|
6
|
+
from warnings import warn
|
|
7
|
+
|
|
8
|
+
import numpy
|
|
9
|
+
from Cython.Build import cythonize
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def find_sundials():
|
|
13
|
+
search_paths = []
|
|
14
|
+
|
|
15
|
+
SUNDIALS_PREFIX = os.environ.get('SUNDIALS_PREFIX')
|
|
16
|
+
if SUNDIALS_PREFIX:
|
|
17
|
+
search_paths.append(SUNDIALS_PREFIX)
|
|
18
|
+
|
|
19
|
+
CONDA_PREFIX = os.environ.get('CONDA_PREFIX')
|
|
20
|
+
if CONDA_PREFIX:
|
|
21
|
+
search_paths.extend([
|
|
22
|
+
CONDA_PREFIX,
|
|
23
|
+
os.path.join(CONDA_PREFIX, 'Library'),
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
search_paths.extend([
|
|
27
|
+
'/usr',
|
|
28
|
+
'/usr/local',
|
|
29
|
+
'C:/SUNDIALS',
|
|
30
|
+
'C:/Program Files/SUNDIALS',
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
for BASE in search_paths:
|
|
34
|
+
include_dir = os.path.join(BASE, 'include')
|
|
35
|
+
CONFIG_H = os.path.join(include_dir, 'sundials', 'sundials_config.h')
|
|
36
|
+
if os.path.exists(CONFIG_H):
|
|
37
|
+
return BASE, CONFIG_H
|
|
38
|
+
|
|
39
|
+
raise FileNotFoundError("Can't find SUNDIALS installation in any of the"
|
|
40
|
+
f" {search_paths=}. Set the environment variable"
|
|
41
|
+
" SUNDIALS_PREFIX to the parent directory of the"
|
|
42
|
+
" 'include' and 'lib' directories and retry the"
|
|
43
|
+
" installation.")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def parse_config_h(file):
|
|
47
|
+
|
|
48
|
+
config = {}
|
|
49
|
+
define_rx = re.compile(r"#define\s+(\w+)(?:\s+(.*))?")
|
|
50
|
+
|
|
51
|
+
for line in file:
|
|
52
|
+
|
|
53
|
+
line = line.strip()
|
|
54
|
+
if define_rx.match(line):
|
|
55
|
+
|
|
56
|
+
name, value = define_rx.match(line).group(1, 2)
|
|
57
|
+
if isinstance(value, str):
|
|
58
|
+
value = value.strip('"')
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
config[name] = int(value)
|
|
62
|
+
except (ValueError, TypeError): # Catch non int and NoneType
|
|
63
|
+
config[name] = value
|
|
64
|
+
|
|
65
|
+
return {k: config[k] for k in sorted(config)}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_extensions():
|
|
69
|
+
|
|
70
|
+
# Parse sundials_config.h
|
|
71
|
+
BASE, CONFIG_H = find_sundials()
|
|
72
|
+
with open(CONFIG_H, 'r') as f:
|
|
73
|
+
config = parse_config_h(f)
|
|
74
|
+
|
|
75
|
+
# Write the pxi file to match types to sundials_config.h
|
|
76
|
+
with open('src/sksundae/config.pxi', 'w') as f:
|
|
77
|
+
|
|
78
|
+
SUNDIALS_VERSION = config.get('SUNDIALS_VERSION')
|
|
79
|
+
MAJOR_VERSION = SUNDIALS_VERSION.split('.')[0]
|
|
80
|
+
if int(MAJOR_VERSION) < 7:
|
|
81
|
+
raise RuntimeError(f"sksundae - incompatible {SUNDIALS_VERSION=}."
|
|
82
|
+
" MAJOR_VERSION must be at least 7.")
|
|
83
|
+
|
|
84
|
+
if config.get('SUNDIALS_SINGLE_PRECISION'):
|
|
85
|
+
precision = 'single'
|
|
86
|
+
elif config.get('SUNDIALS_DOUBLE_PRECISION'):
|
|
87
|
+
precision = 'double'
|
|
88
|
+
elif config.get('SUNDIALS_EXTENDED_PRECISION'):
|
|
89
|
+
precision = 'extended'
|
|
90
|
+
else:
|
|
91
|
+
warn("Couldn't find SUNDIALS_PRECISION. Defaulting to double.")
|
|
92
|
+
precision = 'double'
|
|
93
|
+
|
|
94
|
+
if config.get('SUNDIALS_INT32_T'):
|
|
95
|
+
indexsize = 'int32'
|
|
96
|
+
elif config.get('SUNDIALS_INT64_T'):
|
|
97
|
+
indexsize = 'int64'
|
|
98
|
+
else:
|
|
99
|
+
warn("Couldn't find SUNDIALS_INDEX_SIZE. Defaulting to int32.")
|
|
100
|
+
indexsize = 'int32'
|
|
101
|
+
|
|
102
|
+
f.write(f"DEF SUNDIALS_VERSION = \"{SUNDIALS_VERSION}\"\n")
|
|
103
|
+
f.write(f"DEF SUNDIALS_FLOAT_TYPE = \"{precision}\"\n")
|
|
104
|
+
f.write(f"DEF SUNDIALS_INT_TYPE = \"{indexsize}\"\n")
|
|
105
|
+
|
|
106
|
+
# Specify include_dirs, library_dirs, and libraries for each extension
|
|
107
|
+
SUNDIALS_INCLUDE_DIRS = [numpy.get_include(), os.path.join(BASE, 'include')]
|
|
108
|
+
SUNDIALS_LIBRARY_DIRS = [os.path.join(BASE, 'lib')]
|
|
109
|
+
|
|
110
|
+
LIBRARIES = [
|
|
111
|
+
'sundials_core',
|
|
112
|
+
'sundials_nvecserial',
|
|
113
|
+
'sundials_sunlinsoldense',
|
|
114
|
+
'sundials_sunlinsolband',
|
|
115
|
+
'sundials_sunmatrixdense',
|
|
116
|
+
'sundials_sunmatrixband',
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
# Define the extension modules
|
|
120
|
+
extensions = [
|
|
121
|
+
setuptools.Extension(
|
|
122
|
+
name='sksundae._cy_common',
|
|
123
|
+
sources=['src/sksundae/_cy_common.pyx'],
|
|
124
|
+
include_dirs=SUNDIALS_INCLUDE_DIRS,
|
|
125
|
+
library_dirs=SUNDIALS_LIBRARY_DIRS,
|
|
126
|
+
libraries=LIBRARIES,
|
|
127
|
+
),
|
|
128
|
+
setuptools.Extension(
|
|
129
|
+
name='sksundae._cy_cvode',
|
|
130
|
+
sources=['src/sksundae/_cy_cvode.pyx'],
|
|
131
|
+
include_dirs=SUNDIALS_INCLUDE_DIRS,
|
|
132
|
+
library_dirs=SUNDIALS_LIBRARY_DIRS,
|
|
133
|
+
libraries=LIBRARIES + ['sundials_cvode'],
|
|
134
|
+
),
|
|
135
|
+
setuptools.Extension(
|
|
136
|
+
name='sksundae._cy_ida',
|
|
137
|
+
sources=['src/sksundae/_cy_ida.pyx'],
|
|
138
|
+
include_dirs=SUNDIALS_INCLUDE_DIRS,
|
|
139
|
+
library_dirs=SUNDIALS_LIBRARY_DIRS,
|
|
140
|
+
libraries=LIBRARIES + ['sundials_ida'],
|
|
141
|
+
),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
ext_modules = cythonize(
|
|
145
|
+
extensions,
|
|
146
|
+
compiler_directives={'language_level': 3},
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
return ext_modules
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Run the setup
|
|
153
|
+
BUILD_SDIST = os.environ.get('BUILD_SDIST', 0)
|
|
154
|
+
|
|
155
|
+
if int(BUILD_SDIST): # Don't compile extensions if just building sdist
|
|
156
|
+
setuptools.setup(
|
|
157
|
+
include_package_data=True,
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
setuptools.setup(
|
|
161
|
+
include_package_data=True,
|
|
162
|
+
ext_modules=get_extensions(),
|
|
163
|
+
)
|