diff --git a/.gitignore b/.gitignore index e52d345..665350f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ venv freegs/_version.py asv_bench/.asv/ docs/_build +docs/generated diff --git a/docs/_templates/custom-class-template.rst b/docs/_templates/custom-class-template.rst new file mode 100644 index 0000000..4a2889e --- /dev/null +++ b/docs/_templates/custom-class-template.rst @@ -0,0 +1,32 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + :members: + :undoc-members: + :show-inheritance: + + {% block methods %} + .. automethod:: __init__ + + {% if methods %} + .. rubric:: {{ _('Methods') }} + + .. autosummary:: + {% for item in methods %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: {{ _('Attributes') }} + + .. autosummary:: + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/_templates/custom-module-template.rst b/docs/_templates/custom-module-template.rst new file mode 100644 index 0000000..f46f9f6 --- /dev/null +++ b/docs/_templates/custom-module-template.rst @@ -0,0 +1,66 @@ +{{ fullname | escape | underline}} + +.. automodule:: {{ fullname }} + + {% block attributes %} + {% if attributes %} + .. rubric:: {{ _('Module Attributes') }} + + .. autosummary:: + :toctree: + {% for item in attributes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block functions %} + {% if functions %} + .. rubric:: {{ _('Functions') }} + + .. autosummary:: + :toctree: + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + .. rubric:: {{ _('Classes') }} + + .. autosummary:: + :toctree: + :template: custom-class-template.rst + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + .. rubric:: {{ _('Exceptions') }} + + .. autosummary:: + :toctree: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + +{% block modules %} +{% if modules %} +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: custom-module-template.rst + :recursive: +{% for item in modules %} + {{ item }} +{%- endfor %} +{% endif %} +{% endblock %} diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..d35e137 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,10 @@ +=============== + API Reference +=============== + +.. autosummary:: + :toctree: generated + :template: custom-module-template.rst + :recursive: + + freegs diff --git a/docs/api/freegs.boundary.rst b/docs/api/freegs.boundary.rst deleted file mode 100644 index 0c01c13..0000000 --- a/docs/api/freegs.boundary.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.boundary module -====================== - -.. automodule:: freegs.boundary - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.coil.rst b/docs/api/freegs.coil.rst deleted file mode 100644 index eb6a478..0000000 --- a/docs/api/freegs.coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.coil module -================== - -.. automodule:: freegs.coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.control.rst b/docs/api/freegs.control.rst deleted file mode 100644 index ca3b2dc..0000000 --- a/docs/api/freegs.control.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.control module -===================== - -.. automodule:: freegs.control - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.critical.rst b/docs/api/freegs.critical.rst deleted file mode 100644 index c7bd0eb..0000000 --- a/docs/api/freegs.critical.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.critical module -====================== - -.. automodule:: freegs.critical - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.divgeo.rst b/docs/api/freegs.divgeo.rst deleted file mode 100644 index db3624b..0000000 --- a/docs/api/freegs.divgeo.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.divgeo module -==================== - -.. automodule:: freegs.divgeo - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.dump.rst b/docs/api/freegs.dump.rst deleted file mode 100644 index 2c75ac5..0000000 --- a/docs/api/freegs.dump.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.dump module -================== - -.. automodule:: freegs.dump - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.equilibrium.rst b/docs/api/freegs.equilibrium.rst deleted file mode 100644 index 3974ae8..0000000 --- a/docs/api/freegs.equilibrium.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.equilibrium module -========================= - -.. automodule:: freegs.equilibrium - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.fieldtracer.rst b/docs/api/freegs.fieldtracer.rst deleted file mode 100644 index 4af6444..0000000 --- a/docs/api/freegs.fieldtracer.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.fieldtracer module -========================= - -.. automodule:: freegs.fieldtracer - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.filament_coil.rst b/docs/api/freegs.filament_coil.rst deleted file mode 100644 index c34add8..0000000 --- a/docs/api/freegs.filament_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.filament\_coil module -============================ - -.. automodule:: freegs.filament_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.geqdsk.rst b/docs/api/freegs.geqdsk.rst deleted file mode 100644 index a8ddb1a..0000000 --- a/docs/api/freegs.geqdsk.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.geqdsk module -==================== - -.. automodule:: freegs.geqdsk - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.gradshafranov.rst b/docs/api/freegs.gradshafranov.rst deleted file mode 100644 index cd1422f..0000000 --- a/docs/api/freegs.gradshafranov.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.gradshafranov module -=========================== - -.. automodule:: freegs.gradshafranov - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.jtor.rst b/docs/api/freegs.jtor.rst deleted file mode 100644 index c5929c4..0000000 --- a/docs/api/freegs.jtor.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.jtor module -================== - -.. automodule:: freegs.jtor - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.machine.rst b/docs/api/freegs.machine.rst deleted file mode 100644 index d91d254..0000000 --- a/docs/api/freegs.machine.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.machine module -===================== - -.. automodule:: freegs.machine - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.multi_coil.rst b/docs/api/freegs.multi_coil.rst deleted file mode 100644 index 2d9596c..0000000 --- a/docs/api/freegs.multi_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.multi\_coil module -========================= - -.. automodule:: freegs.multi_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.multigrid.rst b/docs/api/freegs.multigrid.rst deleted file mode 100644 index 2cd14df..0000000 --- a/docs/api/freegs.multigrid.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.multigrid module -======================= - -.. automodule:: freegs.multigrid - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.optimise.rst b/docs/api/freegs.optimise.rst deleted file mode 100644 index c7e758e..0000000 --- a/docs/api/freegs.optimise.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.optimise module -====================== - -.. automodule:: freegs.optimise - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.optimiser.rst b/docs/api/freegs.optimiser.rst deleted file mode 100644 index aee1d6c..0000000 --- a/docs/api/freegs.optimiser.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.optimiser module -======================= - -.. automodule:: freegs.optimiser - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.picard.rst b/docs/api/freegs.picard.rst deleted file mode 100644 index 976b0ab..0000000 --- a/docs/api/freegs.picard.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.picard module -==================== - -.. automodule:: freegs.picard - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.plotting.rst b/docs/api/freegs.plotting.rst deleted file mode 100644 index e8240d0..0000000 --- a/docs/api/freegs.plotting.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.plotting module -====================== - -.. automodule:: freegs.plotting - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.polygons.rst b/docs/api/freegs.polygons.rst deleted file mode 100644 index df04f73..0000000 --- a/docs/api/freegs.polygons.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.polygons module -====================== - -.. automodule:: freegs.polygons - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.pre_calc_coil.rst b/docs/api/freegs.pre_calc_coil.rst deleted file mode 100644 index 721242e..0000000 --- a/docs/api/freegs.pre_calc_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.pre\_calc\_coil module -============================= - -.. automodule:: freegs.pre_calc_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.quadrature.rst b/docs/api/freegs.quadrature.rst deleted file mode 100644 index 1181ab1..0000000 --- a/docs/api/freegs.quadrature.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.quadrature module -======================== - -.. automodule:: freegs.quadrature - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.rst b/docs/api/freegs.rst deleted file mode 100644 index 24213c7..0000000 --- a/docs/api/freegs.rst +++ /dev/null @@ -1,50 +0,0 @@ -freegs package -============== - -.. automodule:: freegs - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - :maxdepth: 4 - - freegs.boundary - freegs.coil - freegs.control - freegs.critical - freegs.divgeo - freegs.dump - freegs.equilibrium - freegs.fieldtracer - freegs.filament_coil - freegs.geqdsk - freegs.gradshafranov - freegs.jtor - freegs.machine - freegs.multi_coil - freegs.multigrid - freegs.optimise - freegs.optimiser - freegs.picard - freegs.plotting - freegs.polygons - freegs.pre_calc_coil - freegs.quadrature - freegs.shaped_coil - freegs.test_critical - freegs.test_equilibrium - freegs.test_filament_coil - freegs.test_jtor - freegs.test_linearsolve - freegs.test_machine - freegs.test_optimise - freegs.test_optimiser - freegs.test_polygons - freegs.test_quadrature - freegs.test_readwrite - freegs.test_sensors - freegs.test_shaped_coil diff --git a/docs/api/freegs.shaped_coil.rst b/docs/api/freegs.shaped_coil.rst deleted file mode 100644 index d1f0e45..0000000 --- a/docs/api/freegs.shaped_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.shaped\_coil module -========================== - -.. automodule:: freegs.shaped_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_critical.rst b/docs/api/freegs.test_critical.rst deleted file mode 100644 index f3e779a..0000000 --- a/docs/api/freegs.test_critical.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_critical module -============================ - -.. automodule:: freegs.test_critical - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_equilibrium.rst b/docs/api/freegs.test_equilibrium.rst deleted file mode 100644 index 11ec666..0000000 --- a/docs/api/freegs.test_equilibrium.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_equilibrium module -=============================== - -.. automodule:: freegs.test_equilibrium - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_filament_coil.rst b/docs/api/freegs.test_filament_coil.rst deleted file mode 100644 index 3082075..0000000 --- a/docs/api/freegs.test_filament_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_filament\_coil module -================================== - -.. automodule:: freegs.test_filament_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_jtor.rst b/docs/api/freegs.test_jtor.rst deleted file mode 100644 index c103f86..0000000 --- a/docs/api/freegs.test_jtor.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_jtor module -======================== - -.. automodule:: freegs.test_jtor - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_linearsolve.rst b/docs/api/freegs.test_linearsolve.rst deleted file mode 100644 index 1114446..0000000 --- a/docs/api/freegs.test_linearsolve.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_linearsolve module -=============================== - -.. automodule:: freegs.test_linearsolve - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_machine.rst b/docs/api/freegs.test_machine.rst deleted file mode 100644 index 30097e5..0000000 --- a/docs/api/freegs.test_machine.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_machine module -=========================== - -.. automodule:: freegs.test_machine - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_optimise.rst b/docs/api/freegs.test_optimise.rst deleted file mode 100644 index b0190f5..0000000 --- a/docs/api/freegs.test_optimise.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_optimise module -============================ - -.. automodule:: freegs.test_optimise - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_optimiser.rst b/docs/api/freegs.test_optimiser.rst deleted file mode 100644 index 73f310b..0000000 --- a/docs/api/freegs.test_optimiser.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_optimiser module -============================= - -.. automodule:: freegs.test_optimiser - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_polygons.rst b/docs/api/freegs.test_polygons.rst deleted file mode 100644 index e8b5ce6..0000000 --- a/docs/api/freegs.test_polygons.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_polygons module -============================ - -.. automodule:: freegs.test_polygons - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_quadrature.rst b/docs/api/freegs.test_quadrature.rst deleted file mode 100644 index fdba0e7..0000000 --- a/docs/api/freegs.test_quadrature.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_quadrature module -============================== - -.. automodule:: freegs.test_quadrature - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_readwrite.rst b/docs/api/freegs.test_readwrite.rst deleted file mode 100644 index 46642d4..0000000 --- a/docs/api/freegs.test_readwrite.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_readwrite module -============================= - -.. automodule:: freegs.test_readwrite - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_sensors.rst b/docs/api/freegs.test_sensors.rst deleted file mode 100644 index 7485feb..0000000 --- a/docs/api/freegs.test_sensors.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_sensors module -=========================== - -.. automodule:: freegs.test_sensors - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/freegs.test_shaped_coil.rst b/docs/api/freegs.test_shaped_coil.rst deleted file mode 100644 index 0d5da40..0000000 --- a/docs/api/freegs.test_shaped_coil.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs.test\_shaped\_coil module -================================ - -.. automodule:: freegs.test_shaped_coil - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/modules.rst b/docs/api/modules.rst deleted file mode 100644 index ec7cbea..0000000 --- a/docs/api/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -freegs -====== - -.. toctree:: - :maxdepth: 4 - - freegs diff --git a/docs/conf.py b/docs/conf.py index 09990a1..c43b07c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -46,11 +46,16 @@ def __getattr__(cls, name): # ones. extensions = [ "sphinx.ext.autodoc", + "sphinx.ext.autosummary", "sphinx.ext.coverage", - "sphinx.ext.imgmath", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", "sphinx.ext.viewcode", + "sphinx_autodoc_typehints", ] +autosummary_generate = True + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -95,26 +100,38 @@ def __getattr__(cls, name): # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False +# Numpy-doc config +napoleon_google_docstring = False +napoleon_numpy_docstring = True +napoleon_attr_annotations = True +napoleon_preprocess_types = True # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "alabaster" +html_theme = "sphinx_book_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # -# html_theme_options = {} +html_theme_options = { + "repository_url": "https://github.com/freegs-plasma/freegs", + "repository_branch": "main", + "path_to_docs": "docs", + "use_edit_page_button": True, + "use_repository_button": True, + "use_issues_button": True, + "home_page_in_toc": False, +} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] - # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. @@ -169,3 +186,14 @@ def __getattr__(cls, name): "Miscellaneous", ), ] + +# -- Options for intersphinx extension --------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), + "xarray": ("https://docs.xarray.dev/en/latest", None), + "pint": ("https://pint.readthedocs.io/en/stable/", None), +} diff --git a/docs/index.rst b/docs/index.rst index 07c7fdd..230f861 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,7 +20,7 @@ Welcome to FreeGS's documentation! :maxdepth: 2 :caption: API reference: - api/modules + API Reference Indices and tables ------------------ diff --git a/freegs/__init__.py b/freegs/__init__.py index 914a8f9..dcdb28a 100644 --- a/freegs/__init__.py +++ b/freegs/__init__.py @@ -29,7 +29,7 @@ """ -from importlib_metadata import metadata +from importlib.metadata import metadata from .equilibrium import Equilibrium diff --git a/freegs/critical.py b/freegs/critical.py index f79248c..556093e 100644 --- a/freegs/critical.py +++ b/freegs/critical.py @@ -49,22 +49,19 @@ def find_critical(R, Z, psi, discard_xpoints=True): Inputs ------ - - R - R(nr, nz) 2D array of major radii - Z - Z(nr, nz) 2D array of heights - psi - psi(nr, nz) 2D array of psi values + R: + R(nr, nz) 2D array of major radii + Z: + Z(nr, nz) 2D array of heights + psi: + psi(nr, nz) 2D array of psi values Returns ------- - - Two lists of critical points - - opoint, xpoint - - Each of these is a list of tuples with (R, Z, psi) points - - The first tuple is the primary O-point (magnetic axis) - and primary X-point (separatrix) + opoint: list + List of O-points (magnetic axes) consisting of ``(R, Z, psi)`` tuples + xpoint: list + List of X-points (magnetic axes) consisting of ``(R, Z, psi)`` tuples """ @@ -241,19 +238,22 @@ def core_mask(R, Z, psi, opoint, xpoint=[], psi_bndry=None): Inputs ------ - R[nx,ny] - 2D array of major radius (R) values - Z[nx,ny] - 2D array of height (Z) values - psi[nx,ny] - 2D array of poloidal flux - - opoint, xpoint - Values returned by find_critical + R[nx,ny]: + 2D array of major radius (R) values + Z[nx,ny]: + 2D array of height (Z) values + psi[nx,ny]: + 2D array of poloidal flux + opoint, xpoint : + Values returned by find_critical If psi_bndry is not None, then that is used to find the separatrix, not the X-points. Returns ------- - - A 2D array [nx,ny] which is 1 inside the core, 0 outside + numpy.ndarray + A 2D array [nx,ny] which is 1 inside the core, 0 outside """ diff --git a/freegs/dump.py b/freegs/dump.py index e14abf9..3822962 100644 --- a/freegs/dump.py +++ b/freegs/dump.py @@ -108,9 +108,9 @@ def __enter__(self): def __exit__(self, type, value, traceback): self.close() - def write_equilibrium(self, equilibrium): + def write_equilibrium(self, equilibrium: Equilibrium): """ - Write `equilbrium` to file + Write ``equilbrium`` to file """ self.handle["coil_dtype"] = Coil.dtype @@ -181,14 +181,9 @@ def write_equilibrium(self, equilibrium): # type to restore it to later coils_group[label].attrs["freegs type"] = coil.__class__.__name__ - def read_equilibrium(self): + def read_equilibrium(self) -> Equilibrium: """ Read an equilibrium from the file - - Returns - ------- - Equilibrium - A new `Equilibrium` object """ equilibrium_group = self.handle[self.EQUILIBRIUM_GROUP_NAME] diff --git a/freegs/equilibrium.py b/freegs/equilibrium.py index 4bf5eeb..2584470 100644 --- a/freegs/equilibrium.py +++ b/freegs/equilibrium.py @@ -3,6 +3,8 @@ state, including plasma and coil currents """ +from typing import Optional + from numpy import pi, meshgrid, linspace, exp, array import numpy as np from scipy import interpolate @@ -29,62 +31,68 @@ class Equilibrium: Represents the equilibrium state, including plasma and coil currents - Data members - ------------ - - These can be read, but should not be modified directly - - R[nx,ny] - Z[nx,ny] - - Rmin, Rmax - Zmin, Zmax - - tokamak - The coils and circuits - - Private data members - - _applyBoundary() - _solver - Grad-Shafranov elliptic solver - _profiles An object which calculates the toroidal current - _constraints Control system which adjusts coil currents to meet constraints - e.g. X-point location and flux values + Attributes + ---------- + R[nx,ny]: + Read-only + Z[nx,ny]: + Read-only + Rmin, Rmax: + Read-only + Zmin, Zmax: + Read-only + tokamak: + The coils and circuits + _applyBoundary: + _solver: + Grad-Shafranov elliptic solver + _profiles: + An object which calculates the toroidal current + _constraints: + Control system which adjusts coil currents to meet constraints + e.g. X-point location and flux values """ def __init__( self, - tokamak=machine.EmptyTokamak(), - Rmin=0.1, - Rmax=2.0, - Zmin=-1.0, - Zmax=1.0, - nx=65, - ny=65, + tokamak: machine.Machine = machine.EmptyTokamak(), + Rmin: float = 0.1, + Rmax: float = 2.0, + Zmin: float = -1.0, + Zmax: float = 1.0, + nx: int = 65, + ny: int = 65, boundary=freeBoundary, - psi=None, - current=0.0, - order=4, - check_limited=False, + psi: Optional[float] = None, + current: float = 0.0, + order: int = 4, + check_limited: bool = False, ): """Initialises a plasma equilibrium - Rmin, Rmax - Range of major radius R [m] - Zmin, Zmax - Range of height Z [m] - - nx - Resolution in R. This must be 2^n + 1 - ny - Resolution in Z. This must be 2^m + 1 - - boundary - The boundary condition, either freeBoundary or fixedBoundary - - psi - Magnetic flux. If None, use concentric circular flux - surfaces as starting guess - - current - Plasma current (default = 0.0) - - order - The order of the differential operators to use. - Valid values are 2 or 4. - - check_limited - Boolean, checks if the plasma is limited. + Parameters + ---------- + tokamak: + The set of coils and currents + Rmin, Rmax: + Range of major radius R [m] + Zmin, Zmax: + Range of height Z [m] + nx: + Resolution in R. This must be ``2^n + 1`` + ny: + Resolution in Z. This must be ``2^m + 1`` + boundary: + The boundary condition, either `freeBoundary` or `fixedBoundary` + psi: + Magnetic flux. If None, use concentric circular flux + surfaces as starting guess + current: + Plasma current + order: + The order of the differential operators to use. Valid values are 2 or 4 + check_limited: + Checks if the plasma is limited """ self.tokamak = tokamak @@ -113,7 +121,7 @@ def __init__( if psi is None: # Starting guess for psi xx, yy = meshgrid(linspace(0, 1, nx), linspace(0, 1, ny), indexing="ij") - psi = exp(-((xx - 0.5) ** 2 + (yy - 0.5) ** 2) / 0.4 ** 2) + psi = exp(-((xx - 0.5) ** 2 + (yy - 0.5) ** 2) / 0.4**2) psi[0, :] = 0.0 psi[:, 0] = 0.0 @@ -183,13 +191,16 @@ def callSolver(self, psi, rhs): """ Calls the psi solver, passing the initial guess and RHS arrays - psi Initial guess for the solution (used if iterative) - rhs + Parameters + ---------- + psi: + Initial guess for the solution (used if iterative) + rhs: Returns ------- - - Solution psi + float: + Solution psi """ return self._solver(psi, rhs) @@ -352,13 +363,13 @@ def q(self, psinorm=None, npsi=100): psinorm_inner = np.linspace(0.01, 0.99, num=npsi) q_inner = critical.find_safety(self, psinorm=psinorm_inner) - interp = interpolate.interp1d(psinorm_inner, q_inner, - kind = "quadratic", - fill_value = "extrapolate") + interp = interpolate.interp1d( + psinorm_inner, q_inner, kind="quadratic", fill_value="extrapolate" + ) result = interp(psinorm) else: result = critical.find_safety(self, psinorm=psinorm) - + # Convert to a scalar if only one result if np.size(result) == 1: return float(result) @@ -385,7 +396,8 @@ def rhotor(self, psi=None): """ Calculates normalised toroidal flux at specified values of poloidal flux. - >>> rhotor = sqrt ( tor_flux/max(tor_flux)). + + >>> rhotor = sqrt ( tor_flux/max(tor_flux)). Maximum toroidal flux shoud be at LCFS. """ @@ -437,20 +449,25 @@ def solve(self, profiles, Jtor=None, psi=None, psi_bndry=None): This performs the linear Grad-Shafranov solve - profiles - An object describing the plasma profiles. - At minimum this must have methods: - .Jtor(R, Z, psi, psi_bndry) -> [nx, ny] - .pprime(psinorm) - .ffprime(psinorm) - .pressure(psinorm) - .fpol(psinorm) + Parameters + ---------- + profiles: + An object describing the plasma profiles. + At minimum this must have methods: - Jtor : 2D array - If supplied, specifies the toroidal current at each (R,Z) point - If not supplied, Jtor is calculated from profiles by finding O,X-points + - ``.Jtor(R, Z, psi, psi_bndry) -> [nx, ny]`` + - ``.pprime(psinorm)`` + - ``.ffprime(psinorm)`` + - ``.pressure(psinorm)`` + - ``.fpol(psinorm)`` - psi_bndry - Poloidal flux to use as the separatrix (plasma boundary) - If not given then X-point locations are used. + Jtor : + If supplied, a 2D array specifying the toroidal current at each + (R,Z) point. If not supplied, Jtor is calculated from profiles by + finding O,X-points + psi_bndry: + Poloidal flux to use as the separatrix (plasma boundary). If not + given then X-point locations are used. """ self._profiles = profiles @@ -630,18 +647,18 @@ def _updatePlasmaPsi(self, plasma_psi): # Update the plasma axis and boundary flux as well as mask self._updateBoundaryPsi() - def plot(self, axis=None, show=True, oxpoints=True): + def plot(self, axis=None, show=True, oxpoints=True) -> plt.Axes: """ Plot the equilibrium flux surfaces - axis - Specify the axis on which to plot - show - Call matplotlib.pyplot.show() before returning - oxpoints - Plot X points as red circles, O points as green circles - - Returns - ------- - - axis object from Matplotlib + Parameters + ---------- + axis : + Specify the axis on which to plot + show : + Call matplotlib.pyplot.show() before returning + oxpoints : + Plot X points as red circles, O points as green circles """ from .plotting import plotEquilibrium @@ -1374,7 +1391,6 @@ def newDomain(eq, Rmin=None, Rmax=None, Zmin=None, Zmax=None, nx=None, ny=None): if __name__ == "__main__": - # Test the different spline interpolation routines from numpy import ravel diff --git a/freegs/fieldtracer.py b/freegs/fieldtracer.py index 7109f53..db48419 100644 --- a/freegs/fieldtracer.py +++ b/freegs/fieldtracer.py @@ -148,9 +148,15 @@ def follow(self, Rstart, Zstart, angles, rtol=None, backward=False): class LineCoordinates: """Coordinates of a field line - R Major radius [m] - Z Height [m] - length Field line length [m] + + Attributes + ---------- + R: + Major radius [m] + Z: + Height [m] + length: + Field line length [m] All {R, Z, length} are NumPy arrays of the same shape """ @@ -166,26 +172,30 @@ def traceFieldLines(eq, solwidth=0.03, nlines=10, nturns=50, npoints=200, axis=N Inputs ------ - - eq Equilibrium object - solwidth The width of the SOL in meters - nlines Number of field lines to follow - nturns Number of times around the tokamak to follow - npoints Maximum number of points per line. May hit a wall - - axis Matplotlib figure Axis. If given, field lines - are plotted on the axis + eq: + Equilibrium object + solwidth: + The width of the SOL in meters + nlines: + Number of field lines to follow + nturns: + Number of times around the tokamak to follow + npoints: + Maximum number of points per line. May hit a wall + axis: + Matplotlib figure Axis. If given, field lines are plotted on the axis Returns ------- + forward: LineCoordinates + The forward field line coordinates + backward: LineCoordinates + The backward field line coordinates - The forward and backward field line coordinates - stored in LineCoordinates objects - - >>> forward, backward = traceFieldLines(eq) + Example + ------- - forward and backward have data members - R, Z, length 2D arrays of shape (npoints, nlines) + >>> forward, backward = traceFieldLines(eq) """ ft = FieldTracer(eq) diff --git a/freegs/filament_coil.py b/freegs/filament_coil.py index 9f6950d..2df7d1e 100644 --- a/freegs/filament_coil.py +++ b/freegs/filament_coil.py @@ -204,21 +204,27 @@ def __init__( """ Inputs ------ - shape - Outline of the coil shape as a list of points [(r1,z1), (r2,z2), ...] - Must have more than two points. If not provided, plotting the coil - may not be entirely accurate. - - Rfil, Zfil - Locations of coil filaments (lists/arrays). This is optional. - If these are not provided then the filaments themselves are populated - automatically across the cross-section of the coil. - - current - current in each turn of the coil in Amps - Nfils - Number of filaments. Only used when Rfil is None. - turns - Number of turns in point coil(s) block. Total block current is current * turns - control - enable or disable control system. - - Note: The number of filaments does not equal the number of turns; each turn - of the coil might consist of multiple filaments. + shape: + Outline of the coil shape as a list of points ``[(r1,z1), + (r2,z2), ...]`` Must have more than two points. If not + provided, plotting the coil may not be entirely accurate. + Rfil, Zfil: + Locations of coil filaments (lists/arrays). This is optional. + If these are not provided then the filaments themselves are populated + automatically across the cross-section of the coil. + current : + Current in each turn of the coil in Amps + Nfils : + Number of filaments. Only used when Rfil is None. + turns : + Number of turns in point coil(s) block. Total block current is current * turns + control : + Enable or disable control system. + + Note + ---- + The number of filaments does not equal the number of turns; + each turn of the coil might consist of multiple filaments. """ diff --git a/freegs/geqdsk.py b/freegs/geqdsk.py index c459eba..749f8b6 100755 --- a/freegs/geqdsk.py +++ b/freegs/geqdsk.py @@ -43,20 +43,29 @@ ) import math import numpy as np +from typing import Optional, TYPE_CHECKING from scipy.integrate import romb +if TYPE_CHECKING: + import matplotlib.pyplot as plt + def write(eq, fh, label=None, oxpoints=None, fileformat=geqdsk.write): """ Write a GEQDSK equilibrium file, given a FreeGS Equilibrium object - eq - Equilibrium object - fh - file handle - - label - Text label to put in the file - oxpoints - O- and X-points (opoint, xpoint) returned by critical.find_critical - If not given, it will be calculated using critical.find_critical + Parameters + ---------- + eq: + Equilibrium object + fh: + file handle + label: + Text label to put in the file + oxpoints: + O- and X-points ``(opoint, xpoint)`` returned by `critical.find_critical`. + If not given, it will be calculated using `critical.find_critical` """ # Get poloidal flux psi = eq.psi() @@ -155,70 +164,73 @@ def ceilPow2(val): def read( fh, machine, - rtol=1e-3, - ntheta=8, - show=False, - axis=None, - pause=0.0001, - cocos=1, - domain=None, - blend=0.0, - fit_sol=False, - maxits=50, - current_bounds=None, -): + rtol: float=1e-3, + ntheta: int=8, + show: bool=False, + axis: Optional["plt.Axes"] =None, + pause: float=0.0001, + cocos: int=1, + domain: Optional[list]=None, + blend: float=0.0, + fit_sol: bool=False, + maxits: int=50, + current_bounds: Optional[list]=None, +) -> Equilibrium: """ Reads a G-EQDSK format file - fh : File handle - machine : Machine object defining coil locations - rtol : float + A nonlinear solve will be performed, using Picard iteration + + Parameters + ---------- + fh : + File handle + machine : + Machine object defining coil locations + rtol : Relative error in nonlinear solve - ntheta : integer + ntheta : Number of points in poloidal angle on the separatrix this is used to constrain the plasma shape - show : Boolean + show : Set to true to show solution in a new figure - axis : Matplotlib Axis object - Set to an axis for plotting. Implies show=True - pause : float - Delay between output plots. If negative, waits for window to be closed - cocos : integer + axis : + Set to an axis for plotting. Implies show=True + pause : + Delay between output plots. If negative, waits for window to be closed + cocos : COordinate COnventions. Not fully handled yet, only whether psi is divided by 2pi or not. if < 10 then psi is divided by 2pi, otherwise not. - domain : list/tuple of 4 elements - Sets the (R,Z) domain to solve for - (Rmin, Rmax, Zmin, Zmax) - blend : float between 0 and 1 + domain : + Sets the (R,Z) domain to solve for ``(Rmin, Rmax, Zmin, Zmax)`` + blend : Weighting of the previous poloidal flux at each step of the Picard iteration. The default (0.0) is to use no blending. Blending slows convergence, but can stabilise some oscillating - unstable solutions. - fit_sol : Boolean + unstable solutions. Must be in ``[0, 1]`` + fit_sol : If False (default) then only the poloidal flux inside the separatrix is used to constrain the coil currents. This is particularly for reading SCENE input, which is not valid outside the separatrix. If True, the whole domain is used in the fitting. This is useful if the locations of strike points need to be constrained. - maxits : integer + maxits : Maximum number of iterations. Set to None for no limit. If this limit is exceeded then a RuntimeError is raised. - current_bounds: List of tuples + current_bounds: Optional list of tuples representing constraints on coil currents to be used when reconstructing the equilibrium from the geqdsk file. - [(l1,u1),(l2,u2)...(lN,uN)] - - A nonlinear solve will be performed, using Picard iteration + ``[(l1,u1),(l2,u2)...(lN,uN)]`` Returns ------- + eq: ~.Equilibrium + An :class:`~.Equilibrium` object. In addition, the following is available: - An Equilibrium object eq. In addition, the following is available: - - eq.control - The control system - eq._profiles - The profiles object + - eq.control - The control system + - eq._profiles - The profiles object """ diff --git a/freegs/multi_coil.py b/freegs/multi_coil.py index d1337ea..6614ac6 100644 --- a/freegs/multi_coil.py +++ b/freegs/multi_coil.py @@ -30,10 +30,11 @@ class MultiCoil(Coil): """ This class is multifunctional and can model several coil arrangements: + 1. A single PF coil 2. A block of several PF coil filaments, modelled as - a) a single point in (R,Z) - b) a list of (R,Z) points for each filament in the block + a. a single point in (R,Z) + b. a list of (R,Z) points for each filament in the block In both cases, the specified coil(s) can also be mirrored in Z=0 and connected in a circuit sharing the same power supply. In such a case, @@ -44,13 +45,20 @@ class MultiCoil(Coil): public members -------------- - R, Z - Location of the point coil/Locations of coil filaments - current - current in the coil(s) in Amps - turns - Number of turns if using point coils - control - enable or disable control system - mirror - enable or disable mirroring of coil block in Z=0 - polarity - wiring of coil blocks in circuit - area - Cross-section area in m^2 + R, Z: + Location of the point coil/Locations of coil filaments + current: + current in the coil(s) in Amps + turns: + Number of turns if using point coils + control: + enable or disable control system + mirror: + enable or disable mirroring of coil block in Z=0 + polarity: + wiring of coil blocks in circuit + area: + Cross-section area in m^2 For multiple point coils, the total toroidal current carried by the point coil block is current * turns @@ -82,28 +90,38 @@ def __init__( area=AreaCurrentLimit(), ): """ - R, Z - Location of the coil centre. If modified moves all filaments - Rfil, Zfil - Locations of coil filaments (lists) - - current - current in each turn of the coil in Amps - turns - Number of turns in point coil(s) block. Total block current is current * turns - This is only used if R,Z are a single point - control - enable or disable control system - mirror - mirror the point/detailed coil block in Z=0, creating a circuit - polarity - Wiring of the circuit: same or opposite direction, [Block 1, Block 2] - area - Cross-section area of block in m^2 - Area can be a fixed value (e.g. 0.025 for 5x5cm coil), or can be specified using a function which takes a coil as an input argument. To specify a current density limit, use: - area = AreaCurrentLimit(current_density) + area = AreaCurrentLimit(current_density) where current_density is in A/m^2. The area of the coil will be recalculated as the coil current is changed. The most important effect of the area is on the coil self-force: The smaller the area the larger the hoop force for a given current. + + Parameters + ---------- + R, Z: + Location of the coil centre. If modified moves all filaments + Rfil, Zfil: + Locations of coil filaments (lists) + current: + current in each turn of the coil in Amps + turns: + Number of turns in point coil(s) block. Total block current is ``current * turns``. + This is only used if R,Z are a single point + control: + enable or disable control system + mirror: + mirror the point/detailed coil block in Z=0, creating a circuit + polarity: + Wiring of the circuit: same or opposite direction, ``[Block 1, Block 2]`` + area: + Cross-section area of block in m^2 + """ # Store locations as an internal list if hasattr(R, "__len__"): diff --git a/freegs/multigrid.py b/freegs/multigrid.py index 75c1f58..6f72771 100644 --- a/freegs/multigrid.py +++ b/freegs/multigrid.py @@ -175,8 +175,8 @@ def restrict(orig, out=None, avg=False): Returns ------- - - A 2D numpy array of size [(nx-1)/2+1, (ny-1)/2+1] + numpy.ndarray + A 2D numpy array of size [(nx-1)/2+1, (ny-1)/2+1] """ nx = orig.shape[0] diff --git a/freegs/optimise.py b/freegs/optimise.py index cbe1942..b321b33 100644 --- a/freegs/optimise.py +++ b/freegs/optimise.py @@ -158,34 +158,41 @@ def optimise(eq, controls, measure, maxgen=10, N=10, CR=0.3, F=1.0, monitor=None """Use Differential Evolution to optimise an Equilibrium https://en.wikipedia.org/wiki/Differential_evolution - eq is an Equilibrium to be used as starting solution - These are deep copied, and passed as arguments - to controls and measure functions - - controls A list of control objects. These objects must - have methods: - .set(eq, value) which modifies the given Equilibrium - .get(eq) which returns the value from the Equilibrium - - measure(eq) is a function which returns a score (value) for a - given Equilibrium. The optimiser tries to minimise this - value. - - maxgen is the maximum number of generations - - N >= 4 is the population size - CR [0,1] is the crossover probability - F [0,2] is the differential weight - - monitor(generation, best, population) - - A function to be called each generation with the best - Equilibrium and the whole population - generation = integer - best = (score, object) - population = [(score, object)] - - Returns the Equilibrium with the lowest measure (score). + Parameters + ---------- + eq: + `Equilibrium` to be used as starting solution. These are deep + copied, and passed as arguments to controls and measure + functions + controls: + List of control objects. These objects must have methods: + + - ``.set(eq, value)`` which modifies the given `Equilibrium` + - ``.get(eq)`` which returns the value from the `Equilibrium` + + measure(eq): + Function which returns a score (value) for a given + `Equilibrium`. The optimiser tries to minimise this value. + maxgen: + Maximum number of generations + N: + Population size (must be >= 4) + CR: + Crossover probability (must be in ``[0,1]``) + F: + Differential weight (must be in ``[0,2]``) + monitor(generation, best, population): + A function to be called each generation with the best + Equilibrium and the whole population + + - generation = integer + - best = (score, object) + - population = [(score, object)] + + Returns + ------- + ~.Equilibrium: + The :class:`~.Equilibrium` with the lowest measure (score). """ diff --git a/freegs/optimiser.py b/freegs/optimiser.py index 4b4626c..f36910c 100644 --- a/freegs/optimiser.py +++ b/freegs/optimiser.py @@ -77,39 +77,47 @@ def pickUnique(N, m, e): def optimise(obj, controls, measure, maxgen=10, N=10, CR=0.3, F=1.0, monitor=None): - """Use Differential Evolution to optimise an object + """Use Differential Evolution to optimise an Equilibrium https://en.wikipedia.org/wiki/Differential_evolution - obj is an object to be used as starting solution - These objects are deep copied, and passed as arguments - to controls and measure functions - - controls A list of control objects. These objects must - have methods: - .set(object, value) which modifies the given object - .get(object) which returns the value from the object - - measure(object) is a function which returns a score (value) for a - given object. The optimiser tries to minimise this - value. - - maxgen is the maximum number of generations - - N >= 4 is the population size - CR [0,1] is the crossover probability - F [0,2] is the differential weight - - monitor(generation, best, population) - - A function to be called each generation with the best - solution and the whole population - generation = integer - best = (score, object) - population = [(score, object)] - - Returns the object with the lowest measure (score). + Parameters + ---------- + eq: + `Equilibrium` to be used as starting solution. These are deep + copied, and passed as arguments to controls and measure + functions + controls: + List of control objects. These objects must have methods: + + - ``.set(eq, value)`` which modifies the given `Equilibrium` + - ``.get(eq)`` which returns the value from the `Equilibrium` + + measure(eq): + Function which returns a score (value) for a given + `Equilibrium`. The optimiser tries to minimise this value. + maxgen: + Maximum number of generations + N: + Population size (must be >= 4) + CR: + Crossover probability (must be in ``[0,1]``) + F: + Differential weight (must be in ``[0,2]``) + monitor(generation, best, population): + A function to be called each generation with the best + Equilibrium and the whole population + + - generation = integer + - best = (score, object) + - population = [(score, object)] + + Returns + ------- + ~.Equilibrium: + The :class:`~.Equilibrium` with the lowest measure (score). """ + _set_random_seed_if_called_in_pytest() assert N >= 4 diff --git a/freegs/picard.py b/freegs/picard.py index 94d40ee..8b40609 100644 --- a/freegs/picard.py +++ b/freegs/picard.py @@ -44,27 +44,41 @@ def solve( """ Perform Picard iteration to find solution to the Grad-Shafranov equation - eq - an Equilibrium object (equilibrium.py) - profiles - A Profile object for toroidal current (jtor.py) - - rtol - Relative tolerance (change in psi)/( max(psi) - min(psi) ) - atol - Absolute tolerance, change in psi - blend - Blending of previous and next psi solution - psi{n+1} <- psi{n+1} * (1-blend) + blend * psi{n} - - show - If true, plot the plasma equilibrium at each nonlinear step - axis - Specify a figure to plot onto. Default (None) creates a new figure - pause - Delay between output plots. If negative, waits for window to be closed - - maxits - Maximum number of iterations. Set to None for no limit. - If this limit is exceeded then a RuntimeError is raised. - - convergenceInfo - True/False toggle for outputting convergence data. - - check_limited - True/False toggle to control checking for limited plasmas. - wait_for_limited - True/False toggle to keep iterating until the plasma is limited. - limit_it - Integer > Sometimes waiting some number of interations before checking if - a plasma is limited can improve convergence. This sets the number of iterations to wait. + Parameters + ---------- + eq : + an Equilibrium object (equilibrium.py) + profiles : + A Profile object for toroidal current (jtor.py) + + rtol: + Relative tolerance (change in psi)/( max(psi) - min(psi) ) + atol: + Absolute tolerance, change in psi + blend: + Blending of previous and next psi solution + + psi{n+1} <- psi{n+1} * (1-blend) + blend * psi{n} + + show: + If true, plot the plasma equilibrium at each nonlinear step + axis: + Specify a figure to plot onto. Default (None) creates a new figure + pause: + Delay between output plots. If negative, waits for window to be closed + maxits: + Maximum number of iterations. Set to None for no limit. + If this limit is exceeded then a RuntimeError is raised. + convergenceInfo: + True/False toggle for outputting convergence data. + check_limited: + True/False toggle to control checking for limited plasmas. + wait_for_limited: + True/False toggle to keep iterating until the plasma is limited. + limit_it: + Sometimes waiting some number of interations before checking + if a plasma is limited can improve convergence. This sets the + number of iterations to wait. """ if constrain is not None: diff --git a/freegs/shaped_coil.py b/freegs/shaped_coil.py index 33470ce..ba876b8 100644 --- a/freegs/shaped_coil.py +++ b/freegs/shaped_coil.py @@ -66,12 +66,17 @@ def __init__(self, shape, current=0.0, turns=1, control=True, npoints=6): """ Inputs ------ - shape outline of the coil shape as a list of points [(r1,z1), (r2,z2), ...] - Must have more than two points - current The current in the circuit. The total current is current * turns - turns Number of turns in point coil(s) block. Total block current is current * turns - control enable or disable control system - npoints Number of quadrature points per triangle. Valid choices: 1, 3, 6 + shape: + Outline of the coil shape as a list of points ``[(r1,z1), + (r2,z2), ...]``. Must have more than two points + current: + The current in the circuit. The total current is current * turns + turns: + Number of turns in point coil(s) block. Total block current is current * turns + control: + enable or disable control system + npoints: + Number of quadrature points per triangle. Valid choices: 1, 3, 6 """ assert len(shape) > 2 diff --git a/pyproject.toml b/pyproject.toml index beff0ff..038b155 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,6 @@ dependencies = [ "matplotlib>=1.3", "h5py>=2.10.0", "Shapely>=1.7.1", - "importlib-metadata<4.3,>=1.1.0", "freeqdsk>=0.1.0", ] dynamic = ["version"] @@ -40,7 +39,9 @@ tests = [ "pytest", ] docs = [ - "sphinx>=3.4,<5", + "sphinx >= 5.3", + "sphinx_autodoc_typehints >= 1.19", + "sphinx-book-theme >= 0.4.0rc1", ] [tool.setuptools]