{ "info": { "author": "Nico Schl\u00f6mer", "author_email": "nico.schloemer@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Mathematics" ], "description": "# pacopy\n\n[![CircleCI](https://img.shields.io/circleci/project/github/nschloe/pacopy/master.svg)](https://circleci.com/gh/nschloe/pacopy/tree/master)\n[![codecov](https://img.shields.io/codecov/c/github/nschloe/pacopy.svg)](https://codecov.io/gh/nschloe/pacopy)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Documentation Status](https://readthedocs.org/projects/pacopy/badge/?version=latest)](https://pacopy.readthedocs.org/en/latest/?badge=latest)\n[![PyPi Version](https://img.shields.io/pypi/v/pacopy.svg)](https://pypi.org/project/pacopy)\n[![GitHub stars](https://img.shields.io/github/stars/nschloe/pacopy.svg?logo=github&label=Stars&logoColor=white)](https://github.com/nschloe/pacopy)\n\npacopy provides various algorithms of [numerical parameter\ncontinuation](https://en.wikipedia.org/wiki/Numerical_continuation) for PDEs in Python.\n\npacopy is backend-agnostic, so it doesn't matter if your problem is formulated with\n[SciPy](https://www.scipy.org/), [FEniCS](https://fenicsproject.org/),\n[pyfvm](https://github.com/nschloe/pyfvm), or any other Python package. The only thing\nthe user must provide is a class with some simple methods, e.g., a function evaluation\n`f(u, lmbda)`, a Jacobian a solver `jacobian_solver(u, lmbda, rhs)` etc.\n\nSome pacopy documentation is available [here](https://pacopy.readthedocs.org/en/latest/?badge=latest).\n\n\n### Examples\n\n#### Bratu\n\n\n\nThe classical [Bratu\nproblem](https://en.wikipedia.org/wiki/Liouville%E2%80%93Bratu%E2%80%93Gelfand_equation)\nin 1D with Dirichlet boundary conditions. To reproduce the plot, you first have to\nspecify the problem; this is the classical finite-difference approximation:\n```python\nclass Bratu1d(object):\n def __init__(self):\n self.n = 51\n h = 1.0 / (self.n - 1)\n\n self.H = numpy.full(self.n, h)\n self.H[0] = h / 2\n self.H[-1] = h / 2\n\n self.A = (\n scipy.sparse.diags([-1.0, 2.0, -1.0], [-1, 0, 1], shape=(self.n, self.n))\n / h ** 2\n )\n return\n\n def inner(self, a, b):\n \"\"\"The inner product of the problem. Can be numpy.dot(a, b), but factoring in\n the mesh width stays true to the PDE.\n \"\"\"\n return numpy.dot(a, self.H * b)\n\n def norm2_r(self, a):\n \"\"\"The norm in the range space; used to determine if a solution has been found.\n \"\"\"\n return numpy.dot(a, a)\n\n def f(self, u, lmbda):\n \"\"\"The evaluation of the function to be solved\n \"\"\"\n out = self.A.dot(u) - lmbda * numpy.exp(u)\n out[0] = u[0]\n out[-1] = u[-1]\n return out\n\n def df_dlmbda(self, u, lmbda):\n \"\"\"The function's derivative with respect to the parameter. Used in Euler-Newton\n continuation.\n \"\"\"\n out = -numpy.exp(u)\n out[0] = 0.0\n out[-1] = 0.0\n return out\n\n def jacobian_solver(self, u, lmbda, rhs):\n \"\"\"A solver for the Jacobian problem.\n \"\"\"\n M = self.A.copy()\n d = M.diagonal().copy()\n d -= lmbda * numpy.exp(u)\n M.setdiag(d)\n # Dirichlet conditions\n M.data[0][self.n - 2] = 0.0\n M.data[1][0] = 1.0\n M.data[1][self.n - 1] = 1.0\n M.data[2][1] = 0.0\n return scipy.sparse.linalg.spsolve(M.tocsr(), rhs)\n```\nThen pass the object to any of pacopy's methods, e.g., the Euler-Newton (arclength)\ncontinuation:\n```python\nproblem = Bratu1d()\n# Initial guess\nu0 = numpy.zeros(problem.n)\n# Initial parameter value\nlmbda0 = 0.0\n\nlmbda_list = []\nvalues_list = []\ndef callback(k, lmbda, sol):\n # Use the callback for plotting, writing data to files etc.\n fig = plt.figure()\n ax1 = fig.add_subplot(111)\n ax1.set_xlabel(\"$\\\\lambda$\")\n ax1.set_ylabel(\"$||u||_2$\")\n ax1.grid()\n\n lmbda_list.append(lmbda)\n values_list.append(numpy.sqrt(problem.inner(sol, sol)))\n\n ax1.plot(lmbda_list, values_list, \"-x\", color=\"#1f77f4\")\n ax1.set_xlim(0.0, 4.0)\n ax1.set_ylim(0.0, 6.0)\n return\n\n# Natural parameter continuation\n# pacopy.natural(problem, u0, lmbda0, callback, max_steps=100)\n\npacopy.euler_newton(\n problem, u0, lmbda0, callback, max_steps=500, newton_tol=1.0e-10\n)\n```\n\n\n#### Ginzburg\u2013Landau\n\n![ginzburg-landau](https://nschloe.github.io/pacopy/ginzburg-landau.gif)\n\nThe [Ginzburg-Landau\nequations](https://en.wikipedia.org/wiki/Ginzburg%E2%80%93Landau_theory) model the\nbehavior of extreme type-II superconductors under a magnetic field. The above example\n(to be found in full detail\n[here](https://github.com/nschloe/pacopy/blob/master/test/test_ginzburg_landau.py))\nshows parameter continuation in the strength of the magnetic field. The plot on the\nright-hand side shows the complex-valued solution using\n[cplot](https://github.com/nschloe/cplot).\n\n\n### Installation\n\npacopy is [available from the Python Package\nIndex](https://pypi.org/project/pacopy/), so simply type\n```\npip install -U pacopy\n```\nto install or upgrade.\n\n### Testing\n\nTo run the pacopy unit tests, check out this repository and type\n```\npytest\n```\n\n### Distribution\n\nTo create a new release\n\n1. bump the `__version__` number,\n\n2. publish to PyPi and GitHub:\n ```\n make publish\n ```\n\n### License\n\npacopy is published under the [MIT license](https://en.wikipedia.org/wiki/MIT_License).\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nschloe/pacopy", "keywords": "", "license": "License :: OSI Approved :: MIT License", "maintainer": "", "maintainer_email": "", "name": "pacopy", "package_url": "https://pypi.org/project/pacopy/", "platform": "", "project_url": "https://pypi.org/project/pacopy/", "project_urls": { "Homepage": "https://github.com/nschloe/pacopy" }, "release_url": "https://pypi.org/project/pacopy/0.1.1/", "requires_dist": null, "requires_python": "", "summary": "Numerical continuation in Python", "version": "0.1.1" }, "last_serial": 5542607, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "69beaa5e6c1c434b5cae9c65851ac5b6", "sha256": "62e77091515dd6167a577cf2464c9f9178d1a86bafe6eb13fec9ad27a2e671a0" }, "downloads": -1, "filename": "pacopy-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "69beaa5e6c1c434b5cae9c65851ac5b6", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8442, "upload_time": "2018-09-17T20:07:42", "url": "https://files.pythonhosted.org/packages/62/c0/b254078d6343ca3901f39841fa74084a5479b7be0a8b09a5f026719a5401/pacopy-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c5880903899ccef63a07b6be94e1fe60", "sha256": "fc4c018b5acf919cd005b89e08649a6b07e030fbc48e565c5086f83c7ac9f931" }, "downloads": -1, "filename": "pacopy-0.1.0.tar.gz", "has_sig": false, "md5_digest": "c5880903899ccef63a07b6be94e1fe60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17793, "upload_time": "2018-09-17T20:07:43", "url": "https://files.pythonhosted.org/packages/55/84/6947e2795404c1dfda1b23c0f922083c190421ae652981237e96afacf21d/pacopy-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "e4a6c4705f552df77e3aa52775729bb1", "sha256": "c86f156abb942181bd8e2c11ac7d273ce4f5a88b240eee5ae4bd2450f2e71a7b" }, "downloads": -1, "filename": "pacopy-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e4a6c4705f552df77e3aa52775729bb1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10027, "upload_time": "2019-07-16T20:42:01", "url": "https://files.pythonhosted.org/packages/87/ed/4531b44c94098c74d2c381b9ee09e9f37b0d28e282b1d4107ed4b49373d2/pacopy-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f1bed1b7a8d318f3861c7da26156c5a1", "sha256": "04cf6acdbbe138ae685ea860265dd347818aa6199127e729871821b762876d8e" }, "downloads": -1, "filename": "pacopy-0.1.1.tar.gz", "has_sig": false, "md5_digest": "f1bed1b7a8d318f3861c7da26156c5a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18540, "upload_time": "2019-07-16T20:42:02", "url": "https://files.pythonhosted.org/packages/71/0e/30d9f603709661c6ebe041d2a20b9f8f02bee0aaa31e977b08b5ac6d19ea/pacopy-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e4a6c4705f552df77e3aa52775729bb1", "sha256": "c86f156abb942181bd8e2c11ac7d273ce4f5a88b240eee5ae4bd2450f2e71a7b" }, "downloads": -1, "filename": "pacopy-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e4a6c4705f552df77e3aa52775729bb1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10027, "upload_time": "2019-07-16T20:42:01", "url": "https://files.pythonhosted.org/packages/87/ed/4531b44c94098c74d2c381b9ee09e9f37b0d28e282b1d4107ed4b49373d2/pacopy-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f1bed1b7a8d318f3861c7da26156c5a1", "sha256": "04cf6acdbbe138ae685ea860265dd347818aa6199127e729871821b762876d8e" }, "downloads": -1, "filename": "pacopy-0.1.1.tar.gz", "has_sig": false, "md5_digest": "f1bed1b7a8d318f3861c7da26156c5a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18540, "upload_time": "2019-07-16T20:42:02", "url": "https://files.pythonhosted.org/packages/71/0e/30d9f603709661c6ebe041d2a20b9f8f02bee0aaa31e977b08b5ac6d19ea/pacopy-0.1.1.tar.gz" } ] }