{"id":15284551,"url":"https://github.com/jonasbreuling/scipy_dae","last_synced_at":"2025-04-12T23:37:16.485Z","repository":{"id":223460488,"uuid":"760316033","full_name":"JonasBreuling/scipy_dae","owner":"JonasBreuling","description":"Python implementation of solvers for differential algebraic equation's (DAE's) that should be added to scipy one day.","archived":false,"fork":false,"pushed_at":"2025-03-20T07:14:45.000Z","size":83224,"stargazers_count":25,"open_issues_count":7,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-12T23:36:44.935Z","etag":null,"topics":["bdf","constraints","dae","differential-algebraic-equations","differential-equations","ida","implicit","implicit-differential-equations","navier-stokes-equations","ode","python","radau","scipy","step-size","sundials"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JonasBreuling.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-20T07:32:02.000Z","updated_at":"2025-03-21T22:13:52.000Z","dependencies_parsed_at":"2024-06-12T16:07:18.465Z","dependency_job_id":"dfc55914-d1c9-4b88-b28e-27ad85ea9de0","html_url":"https://github.com/JonasBreuling/scipy_dae","commit_stats":null,"previous_names":["jonasbreuling/pydae","jonasbreuling/scikit-dae","jonasbreuling/pydaes"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasBreuling%2Fscipy_dae","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasBreuling%2Fscipy_dae/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasBreuling%2Fscipy_dae/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JonasBreuling%2Fscipy_dae/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JonasBreuling","download_url":"https://codeload.github.com/JonasBreuling/scipy_dae/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647255,"owners_count":21139081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdf","constraints","dae","differential-algebraic-equations","differential-equations","ida","implicit","implicit-differential-equations","navier-stokes-equations","ode","python","radau","scipy","step-size","sundials"],"created_at":"2024-09-30T14:58:11.484Z","updated_at":"2025-04-12T23:37:16.472Z","avatar_url":"https://github.com/JonasBreuling.png","language":"Python","readme":"# scipy_dae - solving differential algebraic equations (DAEs) and implicit differential equations (IDEs) in Python\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/JonasBreuling/scipy_dae/actions/workflows/main.yml/badge.svg\"\u003e\u003cimg alt=\"Actions Status\" src=\"https://github.com/JonasBreuling/scipy_dae/actions/workflows/main.yml/badge.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/JonasBreuling/scipy_dae/branch/main\"\u003e\n\u003cimg src=\"https://codecov.io/gh/JonasBreuling/scipy_dae/branch/main/graph/badge.svg\" alt=\"Code coverage status badge\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://img.shields.io/badge/License-BSD_3--Clause-blue.svg\"\u003e\u003cimg alt=\"License: BSD 3\" src=\"https://img.shields.io/badge/License-BSD_3--Clause-blue.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/scipy_dae/\"\u003e\u003cimg alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/scipy_dae\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nPython implementation of solvers for differential algebraic equations (DAEs) and implicit differential equations (IDEs) that should be added to scipy one day.\n\nCurrently, two different methods are implemented.\n\n* Implicit **Radau IIA** methods of order 2s - 1 with arbitrary number of odd stages.\n* Implicit **backward differentiation formula (BDF)** of variable order with quasi-constant step-size and stability/ accuracy enhancement using numerical differentiation formula (NDF).\n\nMore information about both methods are given in the specific class documentation.\n\n## To pique your curiosity\n\nThe [Kármán vortex street](https://en.wikipedia.org/wiki/K%C3%A1rm%C3%A1n_vortex_street) solved by a finite element discretization of the [weak form of the incompressible Navier-Stokes equations](https://en.wikipedia.org/wiki/Navier%E2%80%93Stokes_equations#Weak_form) using [FEniCS](https://fenicsproject.org/) and the three stage Radau IIA method.\n\n[![Karman](https://github.com/user-attachments/assets/3f5202f7-7666-4e4a-94dc-26f0759abef7)](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/von_Karman.gif)\n\n## Basic usage\n\nThe Robertson problem of semi-stable chemical reaction is a simple system of differential algebraic equations of index 1. It demonstrates the basic usage of the package.\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom scipy_dae.integrate import solve_dae\n\n\ndef F(t, y, yp):\n    \"\"\"Define implicit system of differential algebraic equations.\"\"\"\n    y1, y2, y3 = y\n    y1p, y2p, y3p = yp\n\n    F = np.zeros(3, dtype=np.common_type(y, yp))\n    F[0] = y1p - (-0.04 * y1 + 1e4 * y2 * y3)\n    F[1] = y2p - (0.04 * y1 - 1e4 * y2 * y3 - 3e7 * y2**2)\n    F[2] = y1 + y2 + y3 - 1 # algebraic equation\n\n    return F\n\n\n# time span\nt0 = 0\nt1 = 1e7\nt_span = (t0, t1)\nt_eval = np.logspace(-6, 7, num=1000)\n\n# initial conditions\ny0 = np.array([1, 0, 0], dtype=float)\nyp0 = np.array([-0.04, 0.04, 0], dtype=float)\n\n# solver options\nmethod = \"Radau\"\n# method = \"BDF\" # alternative solver\natol = rtol = 1e-6\n\n# solve DAE system\nsol = solve_dae(F, t_span, y0, yp0, atol=atol, rtol=rtol, method=method, t_eval=t_eval)\nt = sol.t\ny = sol.y\n\n# visualization\nfig, ax = plt.subplots()\nax.plot(t, y[0], label=\"y1\")\nax.plot(t, y[1] * 1e4, label=\"y2 * 1e4\")\nax.plot(t, y[2], label=\"y3\")\nax.set_xlabel(\"t\")\nax.set_xscale(\"log\")\nax.legend()\nax.grid()\nplt.show()\n```\n\n![Robertson](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Robertson.png)\n\n## Advanced usage\n\nMore examples are given in the [examples](examples/) directory, which includes\n\n* ordinary differential equations (ODEs)\n    * [Van der Pol oscillator](examples/odes/van_der_pol.py)\n    * [Sparse brusselator](examples/odes/sparse_brusselator.py)\n    * [Stiff SE(3) Cosserat rod](examples/odes/se3_cosserat_rod.py)\n* differential algebraic equations (DAEs)\n    * [Robertson problem (index 1)](examples/daes/robertson.py)\n    * [Akzo Nobel problem (index 1)](examples/daes/akzo_nobel.py)\n    * [Stiff transistor amplifier (index 1)](examples/daes/stiff_transistor_amplifier.py)\n    * [Brenan's problem (index 1)](examples/daes/brenan.py)\n    * [Kvaernø's problem (index 1)](examples/daes/kvaerno.py)\n    * [Jay's probem (index 2)](examples/daes/jay.py)\n    * [Knife edge (index 2)](examples/daes/knife_edge.py)\n    * [Cartesian pendulum (index 3)](examples/daes/pendulum.py)\n    * [Particle on circular track (index 3)](examples/daes/arevalo.py)\n    * [Andrews' squeezer mechanism (index 3)](examples/daes/andrews.py)\n* implicit differential equations (IDEs)\n    * [Weissinger's implicit equation](examples/ides/weissinger.py)\n    * [Problem I.542 of E. Kamke](examples/ides/kamke.py)\n    * [Jackiewicz' implicit equation](examples/ides/jackiewicz.py)\n    * [Kvaernø's problem (nonlinear index 1)](examples/ides/kvaerno.py)\n\n## Work-precision\n\nIn order to investigate the work precision of the implemented solvers, we use different DAE examples with differentiation index 1, 2 and 3 as well as IDE examples.\n\n### Index 1 DAE - Brenan\n\n[Brenan's index 1 problem](https://doi.org/10.1137/1.9781611971224.ch4) is described by the system of differential algebraic equations\n\n$$\n\\begin{aligned}\n    \\dot{y}_1 - t \\dot{y}_2 \u0026= y_1 - (1 + t) y_2 \\\\\n    0 \u0026= y_2 - \\sin(t) .\n\\end{aligned}\n$$\n\nFor the consistent initial conditions $t_0 = 0$, $y_1(t_0) = 1$, $y_2(t_0) = 0$, $\\dot{y}_1 = -1$ and $\\dot{y}_2 = 1$, the analytical solution is given by $y_1(t) = e^{-t} + t \\sin(t)$ and $y_2(t) = \\sin(t)$.\n\nThis problem is solved for $atol = rtol = 10^{-(1 + m / 4)}$, where $m = 0, \\dots, 45$. The resulting error at $t_1 = 10$ is compared with the elapsed time of the used solvers in the figure below. For reference, the work-precision diagram of [sundials IDA solver](https://computing.llnl.gov/projects/sundials/ida) is also added. Note that the elapsed time is scaled by a factor of 100 since the sundials C-code is way faster.\n\n![Brenan_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Brenan_work_precision.png)\n\nClearly, the family of Radau IIA methods outplay the BDF/NDF methods for low tolerances. For medium to high tolerances, both methods are appropriate.\n\n\u003c!-- ### Robertson\n\nSimilar results are obtained for the Robertson problem. Since this problem does not have an analtical solution, the reference solution is taken from the [archimede ivp testset](https://archimede.uniba.it/~testset/report/rober.pdf). Since all three Radau IIA methods show saturation, it is questionable whether the reference solution is accurate enough.\n\n![Robertson_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Robertson_work_precision.png) --\u003e\n\n### Index 2 DAE - knife edge\n\nThe [knife edge index 2 problem](https://doi.org/10.1007/978-1-4939-3017-3) is a simple mechanical example with nonholonomic constraint. It is described by the system of differential algebraic equations\n\n$$\n\\begin{aligned}\n\t\\dot{x} \u0026= u \\\\\n\t\\dot{y} \u0026= v \\\\\n\t\\dot{\\varphi} \u0026= \\omega \\\\\n\tm \\dot{u} \u0026= m g \\sin\\alpha + \\sin\\varphi \\lambda \\\\\n\tm \\dot{v} \u0026= -\\cos\\varphi \\lambda \\\\\n\tJ \\dot{\\omega} \u0026= 0 \\\\\n\t0 \u0026= u \\sin\\varphi - v \\cos\\varphi .\n\\end{aligned}\n$$\n\nSince the implemented solvers are designed for index 1 DAEs we have to perform some sort of index reduction. Therefore, we transform the semi-explicit form into a general form as proposed by [Gear](https://doi.org/10.1137/0909004). The resulting index 1 system is given as\n\n$$\n\\begin{aligned}\n\t\\dot{x} \u0026= u \\\\\n\t\\dot{y} \u0026= v \\\\\n\t\\dot{\\varphi} \u0026= \\omega \\\\\n\tm \\dot{u} \u0026= m g \\sin\\alpha + \\sin\\varphi \\dot{\\Lambda} \\\\\n\tm \\dot{v} \u0026= -\\cos\\varphi \\dot{\\Lambda} \\\\\n\tJ \\dot{\\omega} \u0026= 0 \\\\\n\t0 \u0026= u \\sin\\varphi - v \\cos\\varphi .\n\\end{aligned}\n$$\n\nFor the initial conditions $t_0 = 0$, $x(t_0) = \\dot{x}(t_0) = y(t_0) = \\dot{y}(t_0) = \\varphi(t_0) = 0$ and $\\dot{\\varphi}(t_0) = \\Omega$, a closed form solution is given by\n\n$$\n\\begin{aligned}\n\tx(t) \u0026= \\frac{g \\sin\\alpha}{2 \\Omega^2} \\sin^2(\\Omega t) \\\\\n\ty(t) \u0026= \\frac{g \\sin\\alpha}{2 \\Omega^2} \\left(\\Omega t - \\frac{1}{2}\\sin(2 \\Omega t)\\right) \\\\\n\t\\varphi(t) \u0026= \\Omega t \\\\\n\tu(t) \u0026= \\frac{g \\sin\\alpha}{\\Omega} \\sin(\\Omega t) \\cos(\\Omega t) \\\\\n\tv(t) \u0026= \\frac{g \\sin\\alpha}{2 \\Omega} \\left(1 - \\cos(2 \\Omega t)\\right) = \\frac{g \\sin\\alpha}{\\Omega} \\sin^2(\\Omega t) \\\\\n\t\\omega(t) \u0026= \\Omega \\\\\n\t\\Lambda(t) \u0026= \\frac{2g \\sin\\alpha}{\\Omega} (\\cos(\\Omega t) - 1) ,\n    % (2 * m * g * salpha / Omega) * (np.cos(Omega * t) - 1)\n\\end{aligned}\n$$\n\nwith the Lagrange multiplier $\\dot{\\Lambda}(t) = - 2g \\sin\\alpha \\sin(\\Omega t)$.\n\nThis problem is solved for $atol = rtol = 10^{-(1 + m / 4)}$, where $m = 0, \\dots, 32$. The resulting error at $t_1 = 2 \\pi / \\Omega$ is compared with the elapsed time of the used solvers in the figure below.\n\n![knife_edge_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/knife_edge_work_precision.png)\n\n### Index 3 DAE - Arevalo\n\n[Arevalo's index 3 problem](https://link.springer.com/article/10.1007/BF01732606) describes the motion of a particle on a circular track. It is described by the system of differential algebraic equations\n\n$$\n\\begin{aligned}\n\t\\dot{x} \u0026= u \\\\\n\t\\dot{y} \u0026= v \\\\\n\t\\dot{u} \u0026= 2 y + x \\lambda \\\\\n\t\\dot{v} \u0026= -2 x + y \\lambda \\\\\n\t0 \u0026= x^2 + y^2 - 1 .\n\\end{aligned}\n$$\n\nSince the implemented solvers are designed for index 1 DAEs we have to perform some sort of index reduction. Therefore, we use the [stabilized index 1 formulation of Hiller and Anantharaman](https://doi.org/10.1002/nme.1620320803). The resulting index 1 system is given as\n\n$$\n\\begin{aligned}\n\t\\dot{x} \u0026= u + x \\dot{\\Gamma} \\\\\n\t\\dot{y} \u0026= v + y \\dot{\\Gamma} \\\\\n\t\\dot{u} \u0026= 2 y + x \\dot{\\Lambda} \\\\\n\t\\dot{v} \u0026= -2 x + y \\dot{\\Lambda} \\\\\n\t0 \u0026= x u + y v \\\\\n\t0 \u0026= x^2 + y^2 - 1 .\n\\end{aligned}\n$$\n\nThe analytical solution to this problem is given by\n\n$$\n\\begin{aligned}\n\tx(t) \u0026= \\sin(t^2) \\\\\n\ty(t) \u0026= \\cos(t^2) \\\\\n\tu(t) \u0026= 2 t \\cos(t^2) \\\\\n\tv(t) \u0026= -2 t \\sin(t^2) \\\\\n\t\\Lambda(t) \u0026= -\\frac{4}{3} t^3 \\\\\n\t\\Gamma(t) \u0026= 0 ,\n\\end{aligned}\n$$\n\nwith the Lagrange multipliers $\\dot{\\Lambda} = -4t^2$ and $\\dot{\\Gamma} = 0$.\n\nThis problem is solved for $atol = rtol = 10^{-(3 + m / 4)}$, where $m = 0, \\dots, 24$. The resulting error at $t_1 = 5$ is compared with the elapsed time of the used solvers in the figure below.\n\n![Arevalo_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Arevalo_work_precision.png)\n\n### IDE - Weissinger\n\nA simple example of an implicit differential equations is called [Weissinger's equation](https://www.mathworks.com/help/matlab/ref/ode15i.html#bu7u4dt-1)\n\n$$\n\tt y^2 (\\dot{y})^3 - y^3 (\\dot{y}^2) + t (t^2 + 1) \\dot{y} - t^2 y = 0 .\n$$\n\nIt has the analytical solution $y(t) = \\sqrt{t^2 + \\frac{1}{2}}$ and $\\dot{y}(t) = \\frac{t}{\\sqrt{t^2 + \\frac{1}{2}}}$.\n\nStarting at $t_0 = \\sqrt{1 / 2}$, this problem is solved for $atol = rtol = 10^{-(4 + m / 4)}$, where $m = 0, \\dots, 28$. The resulting error at $t_1 = 10$ is compared with the elapsed time of the used solvers in the figure below.\n\n![Weissinger_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Weissinger_work_precision.png)\n\n### Nonlinear index 1 DAE - Kvaernø\n\nIn a final example, an nonlinear index 1 DAE is investigated as proposed by [Kvaernø](https://doi.org/10.2307/2008502). The system is given by\n\n$$\n\\begin{aligned}\n\t(\\sin^2(\\dot{y}_1) + \\sin^2(y_2)) (\\dot{y}_2)^2  - (t - 6)^2 (t - 2)^2 y_1 e^{-t} \u0026= 0 \\\\\n\t(4 - t) (y_2 + y_1)^3 - 64 t^2 e^{-t} y_1 y_2 \u0026= 0 ,\n\\end{aligned}\n$$\n\nIt has the analytical solution $y_1(t) = t^4 e^{-t}$, $y_2(t) = t^3 e^{-t} (4 - t)$ and $\\dot{y}_1(t) = (4 t^3 - t^4) e^{-t}$, $y_2(t) = (-t^3 + (4 - t) 3 t^2 - (4 - t) t^3) e^{-t}$.\n\nStarting at $t_0 = 0.5$, this problem is solved for $atol = rtol = 10^{-(4 + m / 4)}$, where $m = 0, \\dots, 32$. The resulting error at $t_1 = 1$ is compared with the elapsed time of the used solvers in the figure below.\n\n![Kvaerno_work_precision](https://raw.githubusercontent.com/JonasBreuling/scipy_dae/main/data/img/Kvaerno_work_precision.png)\n\n## Install\n### Install through pip\nTo install scipy-dae package you can run the command\n```\npip install scipy-dae\n```\n\n### Install through git repository\nTo install the package through git installation you can download the repository and install it through\n```\npip install .\n```\n\n### Install for developing and testing\nAn editable developer mode can be installed via\n\n```bash\npython -m pip install -e .[dev]\n```\n\nThe tests can be started using\n\n```bash\npython -m pytest --cov\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasbreuling%2Fscipy_dae","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonasbreuling%2Fscipy_dae","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonasbreuling%2Fscipy_dae/lists"}