From 999c298f2144236fa989bd6965a6452eca12f7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Simonis?= Date: Thu, 30 Oct 2025 16:33:24 +0100 Subject: [PATCH 1/5] This PR fixes the docstrings in cython --- cyprecice/cyprecice.pyx | 49 +++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/cyprecice/cyprecice.pyx b/cyprecice/cyprecice.pyx index da1bdf2d..db014b19 100644 --- a/cyprecice/cyprecice.pyx +++ b/cyprecice/cyprecice.pyx @@ -39,12 +39,13 @@ cdef class Participant: """ Main Application Programming Interface of preCICE. To adapt a solver to preCICE, follow the following main structure: - - Create an object of Participant with Participant() - - Initialize preCICE with Participant::initialize() - - Advance to the next (time)step with Participant::advance() - - Finalize preCICE with Participant::finalize() - - We use solver, simulation code, and participant as synonyms. - - The preferred name in the documentation is participant. + + - Create an object of Participant with Participant() + - Initialize preCICE with Participant::initialize() + - Advance to the next (time)step with Participant::advance() + - Finalize preCICE with Participant::finalize() + - We use solver, simulation code, and participant as synonyms. + - The preferred name in the documentation is participant. """ # fake __init__ needed to display docstring for __cinit__ (see https://stackoverflow.com/a/42733794/5158031) @@ -105,10 +106,10 @@ cdef class Participant: method to finally exchange the data. This function handles: - - Parallel communication to the coupling partner/s is setup. - - Meshes are exchanged between coupling partners and the parallel partitions are created. - - [Serial Coupling Scheme] If the solver is not starting the simulation, coupling data is received - from the coupling partner's first computation. + + - Parallel communication to the coupling partner/s is setup. + - Meshes are exchanged between coupling partners and the parallel partitions are created. + - [Serial Coupling Scheme] If the solver is not starting the simulation, coupling data is received from the coupling partner's first computation. Returns ------- @@ -206,8 +207,10 @@ cdef class Participant: """ Checks if the coupled simulation is still ongoing. A coupling is ongoing as long as - - the maximum number of timesteps has not been reached, and - - the final time has not been reached. + + - the maximum number of timesteps has not been reached, and + - the final time has not been reached. + The user should call finalize() after this function returns false. Returns @@ -227,8 +230,9 @@ cdef class Participant: """ Checks if the current coupling timewindow is completed. The following reasons require several solver time steps per coupling time step: - - A solver chooses to perform subcycling. - - An implicit coupling timestep iteration is not yet converged. + + - A solver chooses to perform subcycling. + - An implicit coupling timestep iteration is not yet converged. Returns ------- @@ -790,6 +794,7 @@ cdef class Participant: Examples -------- Write scalar data for a 2D problem with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -797,6 +802,7 @@ cdef class Participant: >>> participant.write_data(mesh_name, data_name, vertex_ids, values) Write vector data for a 2D problem with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -804,6 +810,7 @@ cdef class Participant: >>> participant.write_data(mesh_name, data_name, vertex_ids, values) Write vector data for a 3D (D=3) problem with 5 (N=5) vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -811,6 +818,7 @@ cdef class Participant: >>> participant.write_data(mesh_name, data_name, vertex_ids, values) Write vector data for a 3D (D=3) problem with 5 (N=5) vertices, where the values are provided as a list of tuples: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -873,6 +881,7 @@ cdef class Participant: Examples -------- Read scalar data for a 2D problem with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -882,6 +891,7 @@ cdef class Participant: >>> (5, ) Read vector data for a 2D problem with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -891,6 +901,7 @@ cdef class Participant: >>> (5, 2) Read vector data for a 3D system with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2, 3, 4, 5] @@ -951,6 +962,7 @@ cdef class Participant: Examples -------- Write scalar data for a 2D problem with 5 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> coordinates = np.array([[c1_x, c1_y], [c2_x, c2_y], [c3_x, c3_y], [c4_x, c4_y], [c5_x, c5_y]]) @@ -958,6 +970,7 @@ cdef class Participant: >>> participant.write_and_map_data(mesh_name, data_name, coordinates, values) Write scalar data for a 2D problem with 5 vertices, where the coordinates are provided as a list of tuples, and the values are provided as a list of scalars: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> coordinates = [(c1_x, c1_y), (c2_x, c2_y), (c3_x, c3_y), (c4_x, c4_y), (c5_x, c5_y)] @@ -1008,6 +1021,7 @@ cdef class Participant: Examples -------- Read scalar data for a 2D problem with 2 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> coordinates = np.array([[1.0, 1.0], [2.0, 2.0]]) @@ -1017,6 +1031,7 @@ cdef class Participant: >>> (2, ) Read scalar data for a 2D problem with 2 vertices, where the coordinates are provided as a list of tuples: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> coordinates = [(1.0, 1.0), (2.0, 2.0)] @@ -1075,6 +1090,7 @@ cdef class Participant: Examples -------- Write gradient vector data for a 2D problem with 2 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2] @@ -1082,6 +1098,7 @@ cdef class Participant: >>> participant.write_gradient_data(mesh_name, data_name, vertex_ids, gradients) Write gradient vector data for a 2D problem with 2 vertices, where the gradients are provided as a list of tuples: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2] @@ -1089,6 +1106,7 @@ cdef class Participant: >>> participant.write_gradient_data(mesh_name, data_name, vertex_ids, gradients) Write vector data for a 3D problem with 2 vertices: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> vertex_ids = [1, 2] @@ -1134,6 +1152,7 @@ cdef class Participant: Examples -------- Check if gradient data is required for a data: + >>> mesh_name = "MeshOne" >>> data_name = "DataOne" >>> participant.is_gradient_data_required(mesh_name, data_name) @@ -1238,6 +1257,7 @@ cdef class Participant: Examples -------- Start a profiling section with the event name "EventOne": + >>> event_name = "EventOne" >>> participant.start_profiling_section(event_name) """ @@ -1250,6 +1270,7 @@ cdef class Participant: Examples -------- Stop the last profiling section: + >>> participant.stop_last_profiling_section() """ self.thisptr.stopLastProfilingSection() From 572d8eb790a39ffb610dc9e76be6065815c2795b Mon Sep 17 00:00:00 2001 From: Ishaan Desai Date: Tue, 3 Feb 2026 10:35:11 +0100 Subject: [PATCH 2/5] Add pkg-config as a required dependency on the system, and minor formatting --- README.md | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 9e7f9c33..0e639e4c 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,10 @@ Please refer to [the preCICE documentation](https://www.precice.org/installation ## Required dependencies -**preCICE**: Refer to [the preCICE documentation](https://precice.org/installation-overview.html) for information on building and installation. - -**C++**: A working C++ compiler, e.g., `g++`. - -**MPI**: `mpi4py` requires MPI to be installed on your system. +- preCICE: Refer to [the preCICE documentation](https://precice.org/installation-overview.html) for information on building and installation. +- A working C++ compiler, e.g., `g++`. +- `mpi4py` requires MPI to be installed on your system. +- pkg-config. ## Installing the package @@ -42,19 +41,19 @@ We recommend using `pip` (version 19.0.0 or newer required). You can check your For system installs of preCICE, installation works out of the box. There are different ways how pip can be used to install pyprecice. pip will fetch cython and other build-time dependencies, compile the bindings and finally install the package pyprecice. -* (recommended) install [pyprecice from PyPI](https://pypi.org/project/pyprecice/) +- (recommended) install [pyprecice from PyPI](https://pypi.org/project/pyprecice/) ```bash $ pip install pyprecice ``` -* provide the link to this repository to pip (replace `` with the branch you want to use, preferably `master` or `develop`) +- provide the link to this repository to pip (replace `` with the branch you want to use, preferably `master` or `develop`) ```bash $ pip install https://github.com/precice/python-bindings.git@ ``` -* if you already cloned this repository, execute the following command from this directory: +- if you already cloned this repository, execute the following command from this directory: ```bash $ pip install . @@ -66,8 +65,8 @@ For system installs of preCICE, installation works out of the box. There are dif If preCICE (the C++ library) was installed in a custom prefix, or only built but not installed at all, you have to extend the following environment variables: -* `LIBRARY_PATH`, `LD_LIBRARY_PATH` to the library location, or `$prefix/lib` -* `CPATH` either to the `src` directory or the `$prefix/include` +- `LIBRARY_PATH`, `LD_LIBRARY_PATH` to the library location, or `$prefix/lib` +- `CPATH` either to the `src` directory or the `$prefix/include` The preCICE documentation provides more information on [linking preCICE](https://precice.org/installation-linking.html). @@ -109,13 +108,13 @@ $ python3 setup.py install ``` **Options:** - * `--include-dirs=`, default: `''` + - `--include-dirs=`, default: `''` Path to the headers of preCICE, point to the sources `$PRECICE_ROOT/src`, or the your custom install prefix `$prefix/include`. **NOTES:** - * If you have built preCICE using CMake, you can pass the path to the CMake binary directory using `--library-dirs`. - * It is recommended to use preCICE as a shared library here. + - If you have built preCICE using CMake, you can pass the path to the CMake binary directory using `--library-dirs`. + - It is recommended to use preCICE as a shared library here. 4. Install the bindings @@ -264,8 +263,8 @@ boost 1.65.1 was installed per the `boost and yaml-cpp` guide above. In order to have the right python dependencies, a packaged conda environment was transferred to SuperMUC. The following dependencies were installed: -* numpy -* mpi4py +- numpy +- mpi4py With the python environment active, we have to feed the right python file directories to the cmake command. Note that -DPYTHON_LIBRARY expects a python shared library. You can likely modify the version to fit what is required. @@ -335,10 +334,10 @@ Bindings versions up to `v3.0.0.0` have four digits, where the first three digit ## Contributors -* [Benjamin Rodenberg](https://github.com/BenjaminRodenberg) -* [Ishaan Desai](https://github.com/IshaanDesai) -* [Saumitra Vinay Joshi](https://github.com/saumiJ) contributed first working prototype in [`3db9c9` on `precice/precice`](https://github.com/precice/precice/commit/3db9c95e527db1e1cacb2fd116a5ce13ee877513) -* [Frédéric Simonis](https://github.com/fsimonis) -* [Florian Lindner](https://github.com/floli) -* [Benjamin Uekermann](https://github.com/uekerman) -* [Gerasimos Chourdakis](https://github.com/MakisH) +- [Benjamin Rodenberg](https://github.com/BenjaminRodenberg) +- [Ishaan Desai](https://github.com/IshaanDesai) +- [Saumitra Vinay Joshi](https://github.com/saumiJ) contributed first working prototype in [`3db9c9` on `precice/precice`](https://github.com/precice/precice/commit/3db9c95e527db1e1cacb2fd116a5ce13ee877513) +- [Frédéric Simonis](https://github.com/fsimonis) +- [Florian Lindner](https://github.com/floli) +- [Benjamin Uekermann](https://github.com/uekerman) +- [Gerasimos Chourdakis](https://github.com/MakisH) From 10e6a3fc2602dc724152409de23c569bbd9ebfd9 Mon Sep 17 00:00:00 2001 From: AdityaGupta716 Date: Sun, 22 Feb 2026 20:12:37 +0530 Subject: [PATCH 3/5] Add tests for mesh connectivity functions (#160) (#251) * Update test_bindings_module.py * Fix black formatting --- test/test_bindings_module.py | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/test_bindings_module.py b/test/test_bindings_module.py index 9c9f865a..6ba49f35 100644 --- a/test/test_bindings_module.py +++ b/test/test_bindings_module.py @@ -667,3 +667,54 @@ def test_write_vector_gradient_data_non_contiguous(self): self.assertTrue( np.array_equiv(np.array(write_data).flatten(), read_data.flatten()) ) + + def test_set_mesh_edge(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + participant.set_mesh_edge(fake_mesh_name, 0, 1) + + def test_set_mesh_edges(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.array([[0, 1], [1, 2]]) + participant.set_mesh_edges(fake_mesh_name, vertices) + + def test_set_mesh_edges_empty(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.empty((0, 2), dtype=int) + participant.set_mesh_edges(fake_mesh_name, vertices) + + def test_set_mesh_triangle(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + participant.set_mesh_triangle(fake_mesh_name, 0, 1, 2) + + def test_set_mesh_triangles(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.array([[0, 1, 2], [1, 2, 3]]) + participant.set_mesh_triangles(fake_mesh_name, vertices) + + def test_set_mesh_triangles_empty(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.empty((0, 3), dtype=int) + participant.set_mesh_triangles(fake_mesh_name, vertices) + + def test_set_mesh_quad(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + participant.set_mesh_quad(fake_mesh_name, 0, 1, 2, 3) + + def test_set_mesh_quads(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.array([[0, 1, 2, 3], [1, 2, 3, 4]]) + participant.set_mesh_quads(fake_mesh_name, vertices) + + def test_set_mesh_quads_empty(self): + participant = precice.Participant("test", "dummy.xml", 0, 1) + fake_mesh_name = "FakeMesh" + vertices = np.empty((0, 4), dtype=int) + participant.set_mesh_quads(fake_mesh_name, vertices) From 346829e4b8dc065de71f64747492dff3ae56dffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Simonis?= Date: Thu, 2 Apr 2026 13:29:38 +0200 Subject: [PATCH 4/5] Add documentation rendering (#250) * Add cython signatures * Add documentation based on sphinx * Add changelog --- .gitignore | 2 ++ CHANGELOG.md | 4 ++++ docs/build.sh | 19 +++++++++++++++++++ docs/conf.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 10 ++++++++++ docs/precice.rst | 6 ++++++ setup.py | 1 + 7 files changed, 87 insertions(+) create mode 100755 docs/build.sh create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/precice.rst diff --git a/.gitignore b/.gitignore index 2130ba7e..833e4c93 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ .idea # Pycharm related file *.so build +docs/_build +docs/.docs_venv *.egg-info __pycache__ env diff --git a/CHANGELOG.md b/CHANGELOG.md index e8b76275..146f489c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## latest + +* Added support for documentation rendering https://github.com/precice/python-bindings/pull/250 + ## 3.3.1 * Remove root user option from the usage of the preCICE image in the release workflow https://github.com/precice/python-bindings/commit/0a9ccd449e875f0165bebc968b3a23d6d9094b0d diff --git a/docs/build.sh b/docs/build.sh new file mode 100755 index 00000000..3f79de44 --- /dev/null +++ b/docs/build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +if [[ ! -f "../pyproject.toml" ]]; then + echo "Please run from the docs directory." + exit 1 +fi + +TARGET=singlehtml + +python3 -m venv --clear .docs_venv + +echo "Installing dependencies" +.docs_venv/bin/pip install sphinx myst_parser sphinx-rtd-theme + +echo "Installing python bindings" +.docs_venv/bin/pip install --force --no-cache .. + +echo "Building the website" +.docs_venv/bin/sphinx-build -M ${TARGET} . _build diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..b4e996a2 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,45 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +import datetime + +project = "pyprecice" +author = "The preCICE developers" +copyright = f"{datetime.datetime.now().year}, {author}" + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "myst_parser", +] + +intersphinx_mapping = { + "python": ("https://docs.python.org/3/", None), + "numpy": ("https://numpy.org/doc/stable/", None), + "mpi4py": ("https://mpi4py.readthedocs.io/en/latest/", None), +} + +# exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".docs_venv"] +include_patterns = ["*.rst", "*.md"] + +html_theme = "sphinx_rtd_theme" + +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", +} + +autodoc_class_signature = "separated" +autodoc_typehints = "description" +autodoc_typehints_format = "short" +autodoc_member_order = "bysource" + +suppress_warnings = ["myst.xref_missing"] + +# The cython detection relyies on a built and installed version of the package +try: + import precice +except: + raise RuntimeError("Cannot import precice. Please install pyprecice first") diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..271e3e49 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,10 @@ +The preCICE python bindings +=========================== + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + precice + MigrationGuide + ReleaseGuide diff --git a/docs/precice.rst b/docs/precice.rst new file mode 100644 index 00000000..93b58d72 --- /dev/null +++ b/docs/precice.rst @@ -0,0 +1,6 @@ +The pyprecice package +===================== + +.. automodule:: cyprecice + :members: + :undoc-members: diff --git a/setup.py b/setup.py index f3a3c2b2..2cdcf5ff 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ def get_extensions(): extra_compile_args=compile_args, extra_link_args=link_args, define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")], + cython_directives={"embedsignature": True}, ) ] From c3a9eff642f19cb5e2ee40f85aef4b20cbcc9d84 Mon Sep 17 00:00:00 2001 From: Ishaan Desai Date: Tue, 7 Apr 2026 16:53:38 +0200 Subject: [PATCH 5/5] Bump version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 146f489c..fcb0ccbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## latest +## 3.4.0 * Added support for documentation rendering https://github.com/precice/python-bindings/pull/250