diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml deleted file mode 100644 index 77cbe2a8..00000000 --- a/.github/workflows/continuous-integration.yml +++ /dev/null @@ -1,35 +0,0 @@ -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - -name: Unit tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - test: - name: ${{ matrix.os }} / Python ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ ubuntu-latest, macos-latest ] - python-version: [3.9, '3.10', '3.11', '3.12', '3.13'] - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - python -m pip install --upgrade pip - python -m pip uninstall -y sympde - - name: Install SymPDE - run: | - python -m pip install . - - name: Test with pytest - run: | - cd - pytest -n auto --dist loadgroup --pyargs sympde -ra diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 00000000..61fb8c34 --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,86 @@ +# This workflow installs SymPDE and runs its tests with supported Python versions. +# It follows the testing layout used by Psydac while omitting Psydac-specific +# MPI, HDF5, PETSc, and example jobs. + +name: Unit tests + +on: + push: + branches: [ master ] + paths: + - 'sympde/**' + - 'pyproject.toml' + - '.github/workflows/testing.yml' + + pull_request: + branches: [ master ] + types: + - opened + - reopened + - synchronize + - ready_for_review + + workflow_dispatch: + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-latest ] + python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13', '3.14' ] + + name: ${{ matrix.os }} / Python ${{ matrix.python-version }} + + steps: + - uses: actions/checkout@v6 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: | + pyproject.toml + + - name: Upgrade pip, setuptools, and wheel + run: | + pip install --upgrade pip setuptools wheel + + - name: Install project + run: | + pip install .[test] + pip freeze + + - name: Initialize test directory + run: | + mkdir scratch + + - name: Run coverage tests on macOS + if: runner.os == 'macOS' + working-directory: ./scratch + run: >- + pytest -n auto --dist loadgroup + --cov sympde --cov-report term-missing --cov-report xml + --pyargs sympde -ra + + - name: Run tests on Ubuntu + if: runner.os == 'Linux' + working-directory: ./scratch + run: >- + pytest -n auto --dist loadgroup + --pyargs sympde -ra + + - name: Upload coverage report + if: runner.os == 'macOS' + uses: actions/upload-artifact@v4 + with: + name: coverage-report-${{ matrix.os }}-python-${{ matrix.python-version }} + path: scratch/coverage.xml + + - name: Print detailed coverage results on macOS + if: runner.os == 'macOS' + working-directory: ./scratch + run: | + coverage report --ignore-errors --show-missing --sort=cover diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..d61f2333 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,18 @@ +Maintainers +----------- +* Yaman Güçlü (original author, project lead) +* Martin Campos Pinto + +Contributors +------------ +* Ahmed Ratnani (original author) +* Said Hadjout (original author) +* Antoine Lavandier +* Martin Campos Pinto +* Tom Caruso +* Alisa Kirkinskaia +* Elena Moral Sánchez +* Alexander Hoffmann +* Valentin Carlier +* Paul Rigor +* Frederik Schnack diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..c481f87e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,78 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +## [0.20.0] - 2026-09-07 + +### Added + +- #185: Store interface orientations when exporting domain connectivity, allowing them to be restored when loading a domain. +- #185: Add consistency checks when constructing mapped domains. + +### Changed + +- #185: Require an explicit orientation when constructing multipatch interfaces, including through `Interface`, `Domain.join()`, and `Domain.from_file()`. This is a breaking change for callers and domain files that omitted orientation information. +- #185: Clean up expression evaluation and expand its API documentation. +- [DEVELOPER] Run tests in parallel with `pytest-xdist`, while keeping the HDF5 gallery tests serial. + +## [0.19.3] - 2026-07-17 + +### Fixed + +- #187: Avoid redundant symbolic expansion in `is_linear_expression()`, fixing severe slowdowns for some expressions. + +### Changed + +- #187: Refactor and document `is_linear_expression()` and remove its unused `integral` argument. + +## [0.19.2] - 2025-04-02 + +### Changed + +- #177: Drop support for Python 3.8 and require Python 3.9 or newer. +- #177: Add testing and installation support for Python 3.13. + +## [0.19.1] - 2025-03-05 + +### Added + +- #173: Add `Domain.subdomains` and `Domain.mappings`, which consistently return tuples for both single-patch and multipatch domains. +- #173: Allow `Domain.join()` to be called with a single patch. +- [DEVELOPER] Add terminal-expression tests for exact Navier–Stokes solutions. + +### Fixed + +- #170: Mark domain coordinates as real SymPy symbols, avoiding code-generation problems for complex expressions. +- #174: Fix README markup so the project description renders correctly on PyPI. + +### Changed + +- #172: Expand the source-installation and virtual-environment instructions. + +## [0.19.0] - 2024-08-14 + +### Added + +- #154: Add support and continuous-integration testing for Python 3.12. +- #158: Accept NumPy scalar values as parameters of analytical mappings. +- #155: Allow `Domain.join()` connectivity entries to reference patch objects directly instead of only their indices. + +### Changed + +- #155: Document `Domain.join()` and make joined-domain construction less dependent on patch ordering. +- #164: Document how SymPDE branches can be tested against the Psydac test suite. +- #165: Replace the obsolete build badge with the GitHub Actions CI badge. + +### Fixed + +- #167: Fix README markup rejected by the PyPI uploader. + +### Removed + +- #165: Remove the obsolete Travis CI configuration. + +[0.20.0]: https://github.com/pyccel/sympde/compare/v0.19.3...v0.20.0 +[0.19.3]: https://github.com/pyccel/sympde/compare/v0.19.2...v0.19.3 +[0.19.2]: https://github.com/pyccel/sympde/compare/v0.19.1...v0.19.2 +[0.19.1]: https://github.com/pyccel/sympde/compare/v0.19.0...v0.19.1 +[0.19.0]: https://github.com/pyccel/sympde/compare/v0.18.3...v0.19.0 diff --git a/README.md b/README.md new file mode 100644 index 00000000..764fae61 --- /dev/null +++ b/README.md @@ -0,0 +1,100 @@ +# SymPDE + +[![CI status](https://github.com/pyccel/sympde/actions/workflows/testing.yml/badge.svg?branch=master&event=push)](https://github.com/pyccel/sympde/actions/workflows/testing.yml) +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/pyccel/sympde/master) +[![Documentation Status](https://readthedocs.org/projects/sympde/badge/?version=latest)](http://sympde.readthedocs.io/en/latest/?badge=latest) + +**SymPDE** is a symbolic calculus library for partial differential equations and variational forms. +It can be used to provide capabilities similar to the [FEniCS](https://fenicsproject.org/) project by extending and writing your own *printing* functions. + +Examples of its use can be found in [Psydac](https://github.com/pyccel/psydac) and [Gelato](https://github.com/pyccel/gelato). + +## Installation + +### Set up a virtual environment + +We always recommend working in a Python virtual environment. +To create a new one, we recommend the [`venv`](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment) package: + +```bash +python3 -m venv +``` + +Here, `` is the location where the virtual environment will be created. +A new directory will be created at that location. + +To activate the environment from a new terminal session, run: + +```bash +source /bin/activate +``` + +### Option 1: Install from PyPI + +Make sure that the preferred virtual environment is activated, then run: + +```bash +pip install sympde +``` + +This downloads the correct version of SymPDE from [PyPI](https://pypi.org/project/sympde/) and installs it in the virtual environment. + +### Option 2: Install from sources + +First, clone the repository with Git and change to the repository directory: + +```bash +git clone https://github.com/pyccel/sympde.git +cd sympde +``` + +To check out a specific branch, tag, or commit named ``, run `git checkout `. + +- **Static mode** + + Install the source files in the virtual environment with: + + ```bash + pip install . + ``` + + Further changes to the cloned directory are not reflected in the installed package. This is why we call it a **static** installation. + +- **Editable mode** + + To make changes to the library and see them when the package is imported, install SymPDE in **editable** mode: + + ```bash + pip install --editable ".[test]" + ``` + +### Running the tests + +The complete test suite can be run from any directory with: + +```bash +pytest -n auto --dist loadgroup --pyargs sympde -ra +``` + +## For developers + +Because many important SymPDE features are only tested in Psydac, new pull requests should also be tested against the Psydac test suite. +This can be done by opening a pull request in Psydac whose only change is to install the corresponding SymPDE branch. +To achieve this, modify the line corresponding to `sympde` in Psydac's `pyproject.toml` file. + +For instance, to test a new SymPDE branch called `my_feature`, use: + +```python +# Our packages from PyPI +'sympde @ https://github.com/pyccel/sympde/archive/refs/heads/my_feature.zip', +``` + +Similarly, to test an unreleased version of SymPDE called `v0.18.4-trunk`, use: + +```python +# Our packages from PyPI +'sympde @ https://github.com/pyccel/sympde/archive/refs/tags/v0.18.4-trunk.zip', +``` + +Do not forget the comma at the end of the line, as this is an item in a list. +Also note the words `heads` and `tags` in the paths: the former is used for Git branches, while the latter is used for Git tags, which may or may not correspond to GitHub releases. diff --git a/README.rst b/README.rst deleted file mode 100644 index 1d4f0496..00000000 --- a/README.rst +++ /dev/null @@ -1,107 +0,0 @@ -SymPDE -====== - -|CI status| |binder| |docs| - -**SymPDE** is a symbolic calculus library for partial differential equations and variational forms. -It can be used to have similar capabilities as the fenics_ project, by extending and writing your own *printing* functions. - -An example of use can be found in psydac_ or gelato_. - -.. _psydac: https://github.com/pyccel/psydac -.. _gelato: https://github.com/pyccel/gelato -.. _fenics: https://fenicsproject.org/ - - -Installation -************ - -Set up a virtual environment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -We always recommend working in a Python virtual environment. -To create a new one we recommend the venv_ package:: - - python3 -m venv - -.. _venv: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment - -where ```` is the location to create the virtual environment. -(A new directory will be created at the required location.) - -In order to activate the environment from a new terminal session just run the command :: - - source /bin/activate - -Option 1: Install from PyPI -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Make sure that the preferred virtual environment is activated. Then simply run :: - - pip3 install sympde - -This will download the correct version of SymPDE from PyPI_ and install it in the virtual environment. - -.. _PyPI: https://pypi.org/project/sympde/ - -Option 2: Install from sources -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -First, clone the repository with Git to download the source files, and change the current directory:: - - git clone https://github.com/pyccel/sympde.git - cd sympde - -To check out a specific branch/tag/commit named ````, just use ``git checkout ``. - -* **Static mode** - - To install the source files in the virtual environment just run:: - - python3 -m pip install . - - Further changes to the cloned directory are not reflected in the installed package. This is why we call it a **static** installation. - -* **Editable mode** - - In order to make changes to the library, and see these changes when the package is imported, SymPDE should be installed in **editable** mode:: - - python3 -m pip install --editable . - - -For developers -************** - -Because many important features of SymPDE are only tested in Psydac, new PRs should also be tested against the test suite of Psydac. -This can be done by opening a PR in Psydac, where the only change consists of installing the corresponding branch of SymPDE. -To achieve this, one just needs to modify the line corresponding to ``sympde`` in the ``pyproject.yaml`` file. - -For instance, to test a new SymPDE branch called ``my_feature``, one should write - -.. code-block:: python - - # Our packages from PyPi - 'sympde @ https://github.com/pyccel/sympde/archive/refs/heads/my_feature.zip', - -Similarly, to test an unreleased version of SymPDE called ``v0.18.4-trunk``, one should write - -.. code-block:: python - - # Our packages from PyPi - 'sympde @ https://github.com/pyccel/sympde/archive/refs/tags/v0.18.4-trunk.zip', - -Do not forget the comma at the end of the line, as this is an item in a list. -Also, pay attention to the words ``head`` and ``tags`` in the path: the former is used for Git branches, the latter is used for Git tags (which may or may not correspond to GitHub releases). - - -.. |CI status| image:: https://github.com/pyccel/sympde/actions/workflows/continuous-integration.yml/badge.svg?branch=master&event=push - :alt: CI status - :target: https://github.com/pyccel/sympde/actions/workflows/continuous-integration.yml - -.. |docs| image:: https://readthedocs.org/projects/sympde/badge/?version=latest - :alt: Documentation Status - :target: http://sympde.readthedocs.io/en/latest/?badge=latest - -.. |binder| image:: https://mybinder.org/badge_logo.svg - :alt: Run notebooks in Binder - :target: https://mybinder.org/v2/gh/pyccel/sympde/master diff --git a/bin/run_tests.sh b/bin/run_tests.sh deleted file mode 100755 index da2ed3e0..00000000 --- a/bin/run_tests.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -python3 -m pytest sympde/core/tests/test_geometry.py -python3 -m pytest sympde/core/tests/test_derivatives.py -python3 -m pytest sympde/core/tests/test_space.py -python3 -m pytest sympde/core/tests/test_mapping.py -python3 -m pytest sympde/core/tests/test_model_1d.py -python3 -m pytest sympde/core/tests/test_model_2d.py - -#python3 -m pytest sympde/core/tests/test_expr_1d.py -python3 -m pytest sympde/core/tests/test_expr_2d.py -#python3 -m pytest sympde/core/tests/test_expr_3d.py - -python3 -m pytest sympde/printing/tests/test_latex.py - -python3 -m pytest sympde/gallery/tests/test_poisson.py -python3 -m pytest sympde/gallery/tests/test_stokes.py -python3 -m pytest sympde/gallery/tests/test_wave.py diff --git a/TODO.rst b/old/TODO.rst similarity index 100% rename from TODO.rst rename to old/TODO.rst diff --git a/pyproject.toml b/pyproject.toml index e45220c4..ecd04efc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,32 +1,45 @@ [build-system] -requires = ["setuptools >= 64.0", "wheel"] +requires = ["setuptools >= 77.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "sympde" version = "0.20.0" description = "Symbolic calculus for partial differential equations (and variational forms)" -readme = "README.rst" +readme = "README.md" requires-python = ">= 3.9" -license = {file = "LICENSE"} -authors = [{name = "Ahmed Ratnani", email = "ratnaniahmed@gmail.com"}] +license = "MIT" +license-files = ["LICENSE", "AUTHORS"] +authors = [{name = "SymPDE development team"}] maintainers = [ {name = "Yaman Güçlü", email = "yaman.guclu@gmail.com"}, {name = "Said Hadjout"}, ] -keywords = ["math"] -classifiers = ["Programming Language :: Python :: 3"] +keywords = ["finite elements", "partial differential equations", "symbolic mathematics"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Scientific/Engineering :: Mathematics", +] dependencies = [ 'sympy >= 1.5, < 1.10', 'h5py', - 'pytest', - 'pytest-xdist', 'pyyaml', 'numpy', 'matplotlib' ] +[project.optional-dependencies] +test = [ + "pytest >= 8", + "pytest-cov >= 5", + "pytest-xdist >= 3", +] + [project.urls] +Issues = "https://github.com/pyccel/sympde/issues" Repository = "https://github.com/pyccel/sympde" [tool.setuptools.packages.find] @@ -34,4 +47,28 @@ include = ["sympde*"] namespaces = false [tool.setuptools.package-data] -"*" = ["README.rst"] +"*" = ["README.md"] + +[tool.pytest.ini_options] +minversion = "8.0" +addopts = ["--strict-markers"] +python_files = ["test_*.py"] +python_classes = [] +python_functions = ["test_*"] + +[tool.coverage.run] +branch = true +source = ["sympde"] +omit = ["*/tests/*"] + +[tool.coverage.report] +ignore_errors = true +exclude_also = [ + "def __repr__", + "if self\\.debug", + "raise AssertionError", + "raise NotImplementedError", + "if False:", + "if __name__ == .__main__.:", + "@(abc\\.)?abstractmethod", +] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index a1500aee..00000000 --- a/pytest.ini +++ /dev/null @@ -1,8 +0,0 @@ -# this file shows to pytest what to collect -# here we avoid collecting test classes (which are not used in SPL) -# this is to avoid getting the warning on TestFunction -# TODO can we exlude TestFunction from python_classes pattern? -[pytest] -python_files = test_*.py -python_classes = -python_functions = test_*