diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..30747e9e2 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "permissions": { + "defaultMode": "default", + "allow": [ + "Edit" + ], + "ask": [ + "Edit(/pina/**)", + "Edit(/tests/**)", + "Edit(/docs/**)", + "Bash" + ] + } +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2cbbcf345..8d8b19b63 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,34 +2,34 @@ # The default owners for everything in the repo # (Pull requests touching any file in "/" will require review from at least one of these) -* @mathLab/pina-developers -pina/ @mathLab/pina-developers -readme/ @mathLab/pina-developers -tests/ @mathLab/pina-developers -tutorials/ @mathLab/pina-developers -pyproject.toml @mathLab/pina-developers @ndem0 +* @PINA-org/pina-maintainers +pina/ @PINA-org/pina-maintainers +readme/ @PINA-org/pina-maintainers +tests/ @PINA-org/pina-maintainers +tutorials/ @PINA-org/pina-maintainers +pyproject.toml @PINA-org/pina-committee @ndem0 # Owners for documentation -docs/ @mathLab/pina-developers @dario-coscia +docs/ @PINA-org/pina-maintainers # Owners for JOSS joss/ @ndem0 @annaivagnes @dario-coscia # Owners for project-wide config (GitHub workflows, formatting, etc.) -.github/ @ndem0 @dario-coscia -.gitattributes @ndem0 @dario-coscia -.gitignore @ndem0 @dario-coscia +.github/ @PINA-org/pina-committee +.gitattributes @PINA-org/pina-committee +.gitignore @PINA-org/pina-committee # Security & policy files -CITATION.cff @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -CONTRIBUTING.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -LICENSE.rst @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -SECURITY.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -CODE_OF_CONDUCT.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -MAINTAINERS.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -ANTITRUST.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -CHARTER.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -GOVERNANCE.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -STEERING-COMMITTEE.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -TRADEMARKS.md @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia -utils @FilippoOlivo @GiovanniCanali @ndem0 @dario-coscia +CITATION.cff @PINA-org/pina-committee +CONTRIBUTING.md @PINA-org/pina-committee +LICENSE.rst @PINA-org/pina-committee +SECURITY.md @PINA-org/pina-committee +CODE_OF_CONDUCT.md @PINA-org/pina-committee +MAINTAINERS.md @PINA-org/pina-committee +ANTITRUST.md @PINA-org/pina-committee +CHARTER.md @PINA-org/pina-committee +GOVERNANCE.md @PINA-org/pina-committee +STEERING-COMMITTEE.md @PINA-org/pina-committee +TRADEMARKS.md @PINA-org/pina-committee +utils @PINA-org/pina-committee diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 100235776..8e43e31dc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ This PR fixes #ISSUE_NUMBER. ## Checklist -- [ ] Code follows the project’s [Code Style Guidelines](https://github.com/mathLab/PINA/blob/master/CONTRIBUTING.md#code-style--guidelines) +- [ ] Code follows the project’s [Code Style Guidelines](https://github.com/PINA-org/PINA/blob/master/CONTRIBUTING.md#code-style--guidelines) - [ ] Tests have been added or updated - [ ] Documentation has been updated if necessary - [ ] Pull request is linked to an open issue diff --git a/.github/workflows/monthly-tagger.yml b/.github/workflows/monthly-tagger.yml index ef7a7d902..2cbfccf34 100644 --- a/.github/workflows/monthly-tagger.yml +++ b/.github/workflows/monthly-tagger.yml @@ -36,8 +36,8 @@ jobs: - name: Create and push the tag run: | - python utils/mathlab_versioning.py set --only-date "post$(date +%y%m)" - VERS=$(python utils/mathlab_versioning.py get) + python utils/pina_versioning.py set --only-date "post$(date +%y%m)" + VERS=$(python utils/pina_versioning.py get) git config --global user.name 'Monthly Tag bot' git config --global user.email 'mtbot@noreply.github.com' git add pyproject.toml diff --git a/.opencode/commands/pina-agentic.md b/.opencode/commands/pina-agentic.md index 09fc8fe37..0c2874cdb 100644 --- a/.opencode/commands/pina-agentic.md +++ b/.opencode/commands/pina-agentic.md @@ -17,9 +17,9 @@ such as: skill loaded, I'have read the promt and I am ready, etc. **Hard constraints:** - Respect `.opencode/skills/RULES.md`. -- Never write files into the user's project directory. Inline code snippets - in chat are fine; if a file must be written, use a `/tmp/.pina-agent` location - and say so explicitly +- Ask before writing files into the user's project. Inline code snippets are + fine, but confirm the target path first. Anything under `pina/`, `tests/`, or + `docs/` requires explicit user approval before you modify it. - Avoid redundant operator calls. - Don't do broad sweeps of the repo. Targeted API lookups (grep/read a specific file to verify a constructor signature) are fine when the @@ -53,6 +53,5 @@ Guidelines: a session, not a one-shot handoff. - **Close the loop on delivery.** Once the script is finalized (working, sanity-checked, no open questions left), ask the user whether they'd like - it saved to a file and, if so, where — remember this respects the "never - write to the user's project" constraint, so confirm a scratch/output path - rather than assuming one. \ No newline at end of file + it saved to a file and, if so, where. Confirm the path before writing, and + get explicit approval for any source file change. \ No newline at end of file diff --git a/.opencode/opencode.json b/.opencode/opencode.json new file mode 100644 index 000000000..1510be3c8 --- /dev/null +++ b/.opencode/opencode.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://opencode.ai/config.json", + "permissions": [ + { + "action": "edit", + "resource": "*", + "effect": "allow" + }, + { + "action": "edit", + "resource": "pina/*", + "effect": "ask" + }, + { + "action": "edit", + "resource": "tests/*", + "effect": "ask" + }, + { + "action": "edit", + "resource": "docs/*", + "effect": "ask" + }, + { + "action": "shell", + "resource": "*", + "effect": "ask" + } + ] +} diff --git a/.opencode/skills/RULES.md b/.opencode/skills/RULES.md index af04cbd88..4181faa70 100644 --- a/.opencode/skills/RULES.md +++ b/.opencode/skills/RULES.md @@ -2,18 +2,7 @@ These rules apply to **every skill** in this repository. -1. **No source code modification** — Never modify, create, or delete any source - code files (`.py`, `.cpp`, `.js`, `.ts`, `.rs`, etc.) or any files under - `pina/`, `tests/`, `docs/`, or similar source directories. - -2. **Read-only guidance** — Skills exist solely to provide guidance, templates, - and interactive Q&A. Output explanations, code snippets for the user to - copy, and checklists — never write files to the user's project. - -3. **Scope** — If the user asks to edit or write source files, politely decline - and explain that this skill only provides guidance. - -4. **Avoid redundant operator calls in equations** — Differential operators +1. **Avoid redundant operator calls in equations** — Differential operators (`grad`, `div`, `laplacian`, etc.) are **not cached**: every call triggers a new backward pass through the autograd graph. Always compute an operator once for all relevant components and extract what you need, rather than @@ -43,7 +32,7 @@ These rules apply to **every skill** in this repository. This also applies to spatial gradients, divergences, and any other operator that can be computed for all components at once. -5. **Inference goes through the solver, not the raw model** — Always call +2. **Inference goes through the solver, not the raw model** — Always call `solver(input_tensor)` for evaluation at inference time, not `model(input_tensor)` or `solver.model(input_tensor)`. The solver handles label propagation and any post-processing internally. @@ -51,12 +40,12 @@ These rules apply to **every skill** in this repository. specific reason (e.g., multiple models with different forward passes at training vs. inference). -6. **Prefer solver defaults, acknowledge in chat** — Use the default values +3. **Prefer solver defaults, acknowledge in chat** — Use the default values for solver parameters (optimizer, scheduler, loss, weighting, etc.) unless the user explicitly provides different values. Let the user know in chat which defaults are active so they're aware of what's running under the hood. -7. **Use float values in domain fixed-point variables** — +4. **Use float values in domain fixed-point variables** — `CartesianDomain({"t": 0})` or `EllipsoidDomain({"t": 0})` stores the value `0` as a Python `int`, causing `torch.full` to produce an int64 tensor. This later fails when `requires_grad_()` is called (int tensors don't support @@ -74,7 +63,7 @@ These rules apply to **every skill** in this repository. EllipsoidDomain({"t": 0.0}) ``` -8. **Detach LabelTensors before converting to NumPy** — +5. **Detach LabelTensors before converting to NumPy** — A `LabelTensor` with `requires_grad=True` cannot be passed to `matplotlib` or `numpy` directly — PyTorch raises `"Can't call numpy() on Tensor that requires grad"`. Always call @@ -91,12 +80,15 @@ These rules apply to **every skill** in this repository. plt.plot(theta.detach().numpy(), dtheta_dt.detach().numpy()) ``` -9. **Don't call `problem.move_discretisation_into_conditions()` in user scripts** — +6. **Don't call `problem.move_discretisation_into_conditions()` in user scripts** — The Trainer calls this internally before training — the user doesn't need to invoke it manually. Keep user-facing scripts simple: `problem.discretise_domain(...)` per domain and nothing more. -10. **Smoke-Test Training Runs** - Before delivering training code, run a short +7. **Smoke-Test Training Runs** - Before delivering training code, run a short smoke test using only a few epochs to confirm that the pipeline executes successfully and does not fail. After the test passes, restore the final configuration to the intended number of training epochs. + +8. **Modify files** - If the request will modify source files (`pina`, `tests`), + announce which files and wait for the user's explicit approval before editing. \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 5ac1762de..963d5c637 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -75,5 +75,4 @@ ruff check . # lint ## Rules -- Never modify source code (`pina/`, `tests/`, `docs/`). Skills are read-only guidance. - Stay conversational — walk through the workflow naturally. diff --git a/API_scheme.md b/API_scheme.md index 800a04741..64ce6e4c7 100644 --- a/API_scheme.md +++ b/API_scheme.md @@ -2,7 +2,7 @@ Here is a high-level overview of PINA’s main modules. For full details, refer to the -documentation. +documentation. ```mermaid flowchart TB diff --git a/CHARTER.md b/CHARTER.md index 6a03b9605..e871ede6e 100644 --- a/CHARTER.md +++ b/CHARTER.md @@ -1,6 +1,6 @@ # Charter for the PINA Organization -This is the organizational charter for the PINA Organization. In this Charter and related documents, “PINA Organization” means the entity designated in this Charter as the governing body of the PINA project. At the time of writing, this is the PINA Steering Committee. If governance changes in the future, references to “PINA Organization” automatically refer to the successor entity named here without rewriting other policies. By adding their name to the [Steering Committee.md file](https://github.com/mathLab/PINA/blob/master/STEERING-COMMITTEE.md), Steering Committee members agree as follows. +This is the organizational charter for the PINA Organization. In this Charter and related documents, “PINA Organization” means the entity designated in this Charter as the governing body of the PINA project. At the time of writing, this is the PINA Steering Committee. If governance changes in the future, references to “PINA Organization” automatically refer to the successor entity named here without rewriting other policies. By adding their name to the [Steering Committee.md file](https://github.com/PINA-org/PINA/blob/master/STEERING-COMMITTEE.md), Steering Committee members agree as follows. ## 1. Mission @@ -19,7 +19,7 @@ By pursuing these goals, the Organization aims to be a cornerstone resource in c **2.1 Purpose**. The Steering Committee will be responsible for all technical oversight, project approval and oversight, policy oversight, and trademark management. -**2.2 Composition**. The Steering Committee voting members are listed in the [STEERING-COMMITEE.md](https://github.com/mathLab/PINA/blob/master/STEERING-COMMITTEE.md) file in the repository. +**2.2 Composition**. The Steering Committee voting members are listed in the [STEERING-COMMITEE.md](https://github.com/PINA-org/PINA/blob/master/STEERING-COMMITTEE.md) file in the repository. Voting members may be added or removed by no less than 75% affirmative vote of the Steering Committee. The Steering Committee will appoint a Chair responsible for organizing Steering Committee activity. @@ -39,11 +39,11 @@ In addition to the method set out in section 2.2, the membership of a Steering C ## 5. Trademarks -Any names, trademarks, service marks, logos, mascots, or similar indicators of source or origin and the goodwill associated with them arising out of the PINA's activities or PINA projects' activities (the "Marks"), are controlled by the PINA Organization. PINA Marks may be only used in accordance with the [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md). +Any names, trademarks, service marks, logos, mascots, or similar indicators of source or origin and the goodwill associated with them arising out of the PINA's activities or PINA projects' activities (the "Marks"), are controlled by the PINA Organization. PINA Marks may be only used in accordance with the [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md). ## 6. Antitrust Policy -The Steering Committee is bound by the [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md). +The Steering Committee is bound by the [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md). ## 7. No Confidentiality @@ -59,11 +59,11 @@ In order to be eligible to be a PINA project, a project must: - For code, a license on the Open Source Initiative's list of [Popular Licenses](https://opensource.org/licenses). - For data, a license on the Open Knowledge Foundation's list of [Recommended Conformant Licenses](http://opendefinition.org/licenses/). - For specifications, a community developed and maintained specification agreement, such the [Open Web Foundation Agreements](https://www.openwebfoundation.org/the-agreements) or [Community Specification Agreement](https://github.com/CommunitySpecification/1.0). -* Include and adhere to the PINA's policies, including the [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md), the [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md), and the [code of conduct](https://github.com/mathLab/PINA/blob/master/CODE_OF_CONDUCT.md). +* Include and adhere to the PINA's policies, including the [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md), the [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md), and the [code of conduct](https://github.com/PINA-org/PINA/blob/master/CODE_OF_CONDUCT.md). ## 9. Amendments -Amendments to this charter, the [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md), the [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md), or the [code of conduct](https://github.com/mathLab/PINA/blob/master/CODE_OF_CONDUCT.md) may only be made with at least a 75% affirmative vote of the Steering Committee. +Amendments to this charter, the [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md), the [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md), or the [code of conduct](https://github.com/PINA-org/PINA/blob/master/CODE_OF_CONDUCT.md) may only be made with at least a 75% affirmative vote of the Steering Committee. --- ## Attribution diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3bde485db..4532aad53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ We encourage all contributions, big or small! ## Reporting Bugs -If you find a bug, please open an [issue](https://github.com/mathLab/PINA/issues) and include: +If you find a bug, please open an [issue](https://github.com/PINA-org/PINA/issues) and include: - A clear and descriptive title - Steps to reproduce the problem - What you expected to happen @@ -42,7 +42,7 @@ If you find a bug, please open an [issue](https://github.com/mathLab/PINA/issues ## Suggesting Enhancements We welcome new ideas! If you have an idea to improve PINA: -1. Check the [issue tracker](https://github.com/mathLab/PINA/issues) or the [discussions](https://github.com/mathLab/PINA/discussions) to see if someone has already suggested it. +1. Check the [issue tracker](https://github.com/PINA-org/PINA/issues) or the [discussions](https://github.com/PINA-org/PINA/discussions) to see if someone has already suggested it. 2. If not, open a new issue describing: - The enhancement you'd like - Why it would be useful diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 63ffc753a..6890a18b0 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -1,6 +1,6 @@ # Governance Policy -This document provides the governance policy for the PINA. Maintainers agree to this policy and to abide by all PINA polices, including the [code of conduct](https://github.com/mathLab/PINA/blob/master/CODE_OF_CONDUCT.md), [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md), and [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md) by adding their name to the [maintainers.md file](https://github.com/mathLab/PINA/blob/master/MAINTAINERS.md). +This document provides the governance policy for the PINA. Maintainers agree to this policy and to abide by all PINA polices, including the [code of conduct](https://github.com/PINA-org/PINA/blob/master/CODE_OF_CONDUCT.md), [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md), and [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md) by adding their name to the [maintainers.md file](https://github.com/PINA-org/PINA/blob/master/MAINTAINERS.md). ## 1. Roles. diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 143706f80..da71fa663 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -2,17 +2,16 @@ # Maintainers -This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](https://github.com/mathLab/PINA/blob/master/GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/mathLab/PINA/blob/master/CODE_OF_CONDUCT.md), [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md), and [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies. +This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](https://github.com/PINA-org/PINA/blob/master/GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/PINA-org/PINA/blob/master/CODE_OF_CONDUCT.md), [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md), and [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies. | **GithubID** | **Email Address** | **Organization** | | ------------ | ------------------------ | ---------------------- | | @GiovanniCanali | giovanni.canali98@yahoo.it | SISSA | -| @dario-coscia | dariocos99@gmail.com | SISSA | +| @dario-coscia | dariocos99@gmail.com | CuspAI | | @ndem0 | demo.nicola@gmail.com | SISSA - FAST COMPUTING SRL | | @AleDinve | gdinvern@sissa.it | SISSA | | @annaivagnes | aivagnes@sissa.it | SISSA | -| @FilippoOlivo | filippo@filippoolivo.com | SISSA - FAST COMPUTING SRL | | @guglielmopadula | gpadula@sissa.it | SISSA | | @fpichi | fpichi@sissa.it | SISSA | diff --git a/README.md b/README.md index 2c1ec00f7..fcf6d380d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 PyPI downloads -
+
@@ -154,7 +154,7 @@ To install additional packages required for development, tests, docs, or tutoria

Getting started with PINA

       - +      @@ -169,19 +169,19 @@ Solving a differential problem in PINA follows a clean four-step pipeline
  1. Define the problem and constraints using the - Problem API. + Problem API.
  2. Design your model using PyTorch, PyTorch Geometric, or import from the - Model API. + Model API.
  3. Select or build a Solver using the - Solver API. + Solver API.
  4. Train with the - Trainer API, + Trainer API, powered by PyTorch Lightning.
@@ -368,7 +368,7 @@ If you would like to contribute, please read the

- Contributors @@ -381,6 +381,76 @@ If you would like to contribute, please read the


+ +
+ +

Fundings

+
+ +

+ A significant part of PINA has been developed either as a + by-product of funded research projects or through contributions + from researchers holding university-funded positions. + We gratefully acknowledge this support, particularly from: +

+ + + +
+ + ERC Logo + +
+ +

+ We also acknowledge the contribution of Maria Strazzullo to the early development of the package. + Special thanks go to all the students and researchers from different universities who have contributed to its development. + Finally, we warmly thank all the contributors + who are the true heart of PINA! +

+ +
+ + Contributing Universities + +
+ +
+
+ +

Citation

diff --git a/SECURITY.md b/SECURITY.md index a425740c2..794df5667 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,4 +16,4 @@ Security fixes are given priority and might be enough to cause a new version to ## Reporting a Vulnerability -To ensure vulnerability reports reach the maintainers as quickly as possible, the preferred way is to use the ["Report a vulnerability"](https://github.com/mathLab/PINA/security/advisories/new) button under the "Security" tab of the associated GitHub project. This creates a private communication channel between the reporter and the maintainers. +To ensure vulnerability reports reach the maintainers as quickly as possible, the preferred way is to use the ["Report a vulnerability"](https://github.com/PINA-org/PINA/security/advisories/new) button under the "Security" tab of the associated GitHub project. This creates a private communication channel between the reporter and the maintainers. diff --git a/STEERING-COMMITTEE.md b/STEERING-COMMITTEE.md index b97c3a0b9..a44326596 100644 --- a/STEERING-COMMITTEE.md +++ b/STEERING-COMMITTEE.md @@ -1,13 +1,12 @@ # Steering Committee -This document lists the members of the Organization's Steering Committee (in alphabetical order). Voting members may be added once approved by the Steering Committee as described in the [charter](github.com/mathLab/PINA/blob/master/CHARTER.md). By adding your name to this list you are agreeing to abide by all Organization polices, including the [charter](github.com/mathLab/PINA/blob/master/CHARTER.md), the [code of conduct](https://github.com/mathLab/PINA/blob/master/CODE_OF_CONDUCT.md), the [trademark policy](https://github.com/mathLab/PINA/blob/master/TRADEMARKS.md), and the [antitrust policy](https://github.com/mathLab/PINA/blob/master/ANTITRUST.md). If you are serving on the Steering Committee because of your affiliation with another organization (designated below), you represent that you have authority to bind that organization to these policies. +This document lists the members of the Organization's Steering Committee (in alphabetical order). Voting members may be added once approved by the Steering Committee as described in the [charter](https://github.com/PINA-org/PINA/blob/master/CHARTER.md). By adding your name to this list you are agreeing to abide by all Organization polices, including the [charter](https://github.com/PINA-org/PINA/blob/master/CHARTER.md), the [code of conduct](https://github.com/PINA-org/PINA/blob/master/CODE_OF_CONDUCT.md), the [trademark policy](https://github.com/PINA-org/PINA/blob/master/TRADEMARKS.md), and the [antitrust policy](https://github.com/PINA-org/PINA/blob/master/ANTITRUST.md). If you are serving on the Steering Committee because of your affiliation with another organization (designated below), you represent that you have authority to bind that organization to these policies. | **NAME** | **Handle** | **Affiliated Organization** | | ------------ | ------------ | --------------------------- | | Giovanni Canali | @GiovanniCanali | SISSA | -| Dario Coscia | @dario-coscia | SISSA | +| Dario Coscia | @dario-coscia | CuspAI | | Nicola Demo | @ndem0 | SISSA - FAST COMPUTING SRL | -| Filippo Olivo | @FilippoOlivo | SISSA - FAST COMPUTING SRL | --- ## Attribution diff --git a/docs/source/_contributing.rst b/docs/source/_contributing.rst index b981f6ba7..ea2073534 100644 --- a/docs/source/_contributing.rst +++ b/docs/source/_contributing.rst @@ -22,7 +22,7 @@ We encourage all contributions, big or small! Reporting Bugs -------------- -If you find a bug, please open an `issue `_ and include: +If you find a bug, please open an `issue `_ and include: - A clear and descriptive title - Steps to reproduce the problem @@ -36,7 +36,7 @@ Suggesting Enhancements We welcome new ideas! If you have an idea to improve PINA: -1. Check the `issue tracker `_ or the `discussions `_ to see if someone has already suggested it. +1. Check the `issue tracker `_ or the `discussions `_ to see if someone has already suggested it. 2. If not, open a new issue describing: - The enhancement you would like - Why it would be useful diff --git a/docs/source/_installation.rst b/docs/source/_installation.rst index a0bca26f5..1e4eb3541 100644 --- a/docs/source/_installation.rst +++ b/docs/source/_installation.rst @@ -29,7 +29,7 @@ The official distribution is on GitHub. Clone the repository: .. code-block:: bash - git clone https://github.com/mathLab/PINA + git clone https://github.com/PINA-org/PINA Then install in editable mode: diff --git a/docs/source/_team.rst b/docs/source/_team.rst index f1fc47422..fbd48acd0 100644 --- a/docs/source/_team.rst +++ b/docs/source/_team.rst @@ -5,27 +5,16 @@ PINA Team ========== -**PINA** is part of the `PyTorch ecosystem `_ and currently developed at the `SISSA MathLab `_, in collaboration with `Fast Computing `_. - -.. image:: https://img.shields.io/badge/PyTorch%20ecosystem-EE4C2C?style=for-the-badge&logo=pytorch&logoColor=white&labelColor=555 - :target: https://pytorch.landscape2.io/?item=modeling--ai-for-science-and-engineering--pina - :align: center - :width: 300 - -.. figure:: index_files/fast_mathlab.png - :align: center - :width: 500 - -A significant part of **PINA** has been written either as a by-product of funded projects or by people on university-funded positions. We are very grateful for this support. In particular, we acknowledge: +**PINA** is part of the `PyTorch ecosystem `_ . A significant part of **PINA** has been written either as a by-product of funded projects or by people on university-funded positions. We are very grateful for this support. In particular, we acknowledge: * `H2020 ERC CoG 2015 AROMA-CFD project 681447 `_, P.I. Professor `Prof. Gianluigi Rozza `_ at `SISSA MathLab `_. * `Next Generation EU `_ for environmental and digital transition in Italy. -.. figure:: index_files/foudings.png +.. figure:: index_files/fundings.png :align: center :width: 500 -We also acknowledge the contribution of `Maria Strazzullo `_ in the early development of the package. A special thank you goes to all the students and researchers from different universities who contributed to the package. Finally, we warmly thank all the `contributors `_ who are the real heart of **PINA**! +We also acknowledge the contribution of `Maria Strazzullo `_ in the early development of the package. A special thank you goes to all the students and researchers from different universities who contributed to the package. Finally, we warmly thank all the `contributors `_ who are the real heart of **PINA**! .. figure:: index_files/university_dev_pina.png :align: center diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html index c1bc42107..7c0e1c383 100644 --- a/docs/source/_templates/layout.html +++ b/docs/source/_templates/layout.html @@ -6,7 +6,7 @@

{% trans copyright=copyright|e %}© Copyright {{ copyright }}, PINA Developers.{% endtrans %}
+ href="https://github.com/PINA-org/PINA/">PINA Developers.{% endtrans %}
Created using Sphinx and the PyData Theme.

diff --git a/docs/source/conf.py b/docs/source/conf.py index 7f5f4f8c7..9e09f6600 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -127,7 +127,7 @@ "icon_links": [ { "name": "GitHub", - "url": "https://github.com/mathLab/PINA", + "url": "https://github.com/PINA-org/PINA", "icon": "fab fa-github", "type": "fontawesome", }, diff --git a/docs/source/index.rst b/docs/source/index.rst index 924a7fdbf..39d6c4773 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,7 +16,7 @@ Welcome to PINA's documentation! Get Started Quickstart - View on GitHub + View on GitHub
@@ -185,7 +185,7 @@ Physics-Informed Neural Networks (PINNs), Neural Operators, and more. API <_rst/_code> Tutorials <_tutorial> Contributing <_contributing> - Team & Foundings <_team.rst> + Team & Fundings <_team.rst> Installing <_installation> Cite PINA <_cite.rst> License <_LICENSE.rst> diff --git a/docs/source/index_files/foudings.png b/docs/source/index_files/fundings.png similarity index 100% rename from docs/source/index_files/foudings.png rename to docs/source/index_files/fundings.png diff --git a/joss/paper.md b/joss/paper.md index b63d46d43..133266e85 100644 --- a/joss/paper.md +++ b/joss/paper.md @@ -62,8 +62,8 @@ Among all these frameworks, PINA wants to emerge for its easiness of usage, allo Built over PyTorch --- in order to inherit the \verb+autograd+ module and all the other features already implemented --- PINA provides indeed documented API to explain usage and capabilities of the different classes. We have built several abstract interfaces not only for better structure of the source code but especially to give the final user an easy entry point to implement their own extensions, like new loss functions, new training procedures, and so on. This aspect, together with the capability to use all the PyTorch models, makes it possible to incorporate almost any existing architecture into the PINA framework. We have decided to build it on top of PyTorch in order to exploit the \verb+autograd+ module, as well as all the other features implemented in this framework. The final outcome is then a library with incremental complexity, capable of being used by the new users to perform the first investigation using PINNs, but also as a core framework to actively develop new features to improve the discussed methodology. -The high-level structure of the package is depicted in our [API](https://github.com/mathLab/PINA/tree/master/readme/API_color.png); the approximated solution of a differential equation can be implemented using PINA in a few lines of code thanks to the intuitive and user-friendly interface. -Besides the user-friendly interface, PINA also offers several examples and tutorials, aiming to guide new users toward an easy exploration of the software features. The online documentation is released at \url{https://mathlab.github.io/PINA/}, while the robustness of the package is continuously monitored by unit tests. +The high-level structure of the package is depicted in our [API](https://github.com/PINA-org/PINA/tree/master/readme/PINA_API.png); the approximated solution of a differential equation can be implemented using PINA in a few lines of code thanks to the intuitive and user-friendly interface. +Besides the user-friendly interface, PINA also offers several examples and tutorials, aiming to guide new users toward an easy exploration of the software features. The online documentation is released at \url{https://PINA-org.github.io/PINA/}, while the robustness of the package is continuously monitored by unit tests. PINA workflow is characterized by 3 main steps: the problem formulation, the model definition, i.e., the structure of the neural network used, and the training, eventually followed by the data visualization. diff --git a/pina/_src/core/label_tensor.py b/pina/_src/core/label_tensor.py index d97ef077d..4aebb7206 100644 --- a/pina/_src/core/label_tensor.py +++ b/pina/_src/core/label_tensor.py @@ -374,24 +374,52 @@ def cat(tensors, dim=0): return cat_tensor @staticmethod - def stack(tensors): + def stack(tensors, dim=0): """ Stacks a list of tensors along a new dimension. For more details, see :meth:`torch.stack`. :param list[LabelTensor] tensors: A list of tensors to stack. All tensors must have the same shape. + :param int dim: Dimension along which to stack the tensors. Default is 0. :return: A new :class:`~pina.label_tensor.LabelTensor` instance obtained by stacking the input tensors. :rtype: LabelTensor """ + if not tensors: + return [] + if len(tensors) == 1: + return tensors[0] + + # In PyTorch, stacking adds a new dimension, so valid dims are - (ndim + 1) <= dim <= ndim + ndim = tensors[0].ndim + if dim < 0: + dim = ndim + 1 + dim + if dim < 0 or dim > ndim: + raise IndexError( + f"Dimension out of range (expected to be in range of [{-(ndim + 1)}, {ndim}], but got {dim})" + ) + + # Check that all tensors have consistent labels + tensors_labels = [tensor.stored_labels for tensor in tensors] + for key in tensors_labels[0]: + if any( + tensors_labels[i].get(key) != tensors_labels[0][key] + for i in range(len(tensors_labels)) + ): + raise RuntimeError("All tensors must have the same labels.") # Perform stacking in torch - new_tensor = torch.stack(tensors) + new_tensor = torch.stack(tensors, dim=dim) + + # Shift label dimension indices at or after `dim` by +1 + labels = {} + for key, value in tensors[0]._labels.items(): + if key >= dim: + labels[key + 1] = value + else: + labels[key] = value - # Increase labels keys by 1 - labels = tensors[0]._labels - labels = {key + 1: value for key, value in labels.items()} new_tensor._labels = labels return new_tensor diff --git a/pina/_src/problem/zoo/inverse_poisson_problem.py b/pina/_src/problem/zoo/inverse_poisson_problem.py index 9a5a8d908..b30b5d596 100644 --- a/pina/_src/problem/zoo/inverse_poisson_problem.py +++ b/pina/_src/problem/zoo/inverse_poisson_problem.py @@ -154,11 +154,11 @@ def __init__(self, load=True, data_size=1.0): # Define URLs for input and output data input_url = ( - "https://github.com/mathLab/PINA/raw/refs/heads/master" + "https://github.com/PINA-org/PINA/raw/refs/heads/master" "/tutorials/tutorial7/data/pts_0.5_0.5" ) output_url = ( - "https://github.com/mathLab/PINA/raw/refs/heads/master" + "https://github.com/PINA-org/PINA/raw/refs/heads/master" "/tutorials/tutorial7/data/pinn_solution_0.5_0.5" ) diff --git a/pyproject.toml b/pyproject.toml index c15169843..0b0c276e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,8 +47,8 @@ tutorial = [ ] [project.urls] -Homepage = "https://mathlab.github.io/PINA/" -Repository = "https://github.com/mathLab/PINA" +Homepage = "https://pina-org.github.io/PINA/" +Repository = "https://github.com/PINA-org/PINA" [build-system] requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning>=2.0,<3", ] diff --git a/tests/test_label_tensor/test_label_tensor.py b/tests/test_label_tensor/test_label_tensor.py index ca4ae2f1a..e770fe3a8 100644 --- a/tests/test_label_tensor/test_label_tensor.py +++ b/tests/test_label_tensor/test_label_tensor.py @@ -229,6 +229,166 @@ def test_vstack_2D(): assert lt_stacked.full_labels[1]["name"] == "second" +def test_stack_2D(): + data_1 = torch.rand(20, 3) + labels = {1: {"dof": ["x", "y", "z"], "name": "vars"}} + lt1 = LabelTensor(data_1, labels) + lt2 = LabelTensor(data_1, labels) + + # Test default dim=0 + lt_stacked_0 = LabelTensor.stack([lt1, lt2], dim=0) + assert lt_stacked_0.shape == (2, 20, 3) + assert lt_stacked_0.full_labels[0]["dof"] == range(2) + assert lt_stacked_0.full_labels[0]["name"] == 0 + assert lt_stacked_0.full_labels[1]["dof"] == range(20) + assert lt_stacked_0.full_labels[1]["name"] == 1 + assert lt_stacked_0.full_labels[2]["dof"] == ["x", "y", "z"] + assert lt_stacked_0.full_labels[2]["name"] == "vars" + assert lt_stacked_0.stored_labels == { + 2: {"dof": ["x", "y", "z"], "name": "vars"} + } + assert lt_stacked_0.labels == ["x", "y", "z"] + + # Test dim=1 + lt_stacked_1 = LabelTensor.stack([lt1, lt2], dim=1) + assert lt_stacked_1.shape == (20, 2, 3) + assert lt_stacked_1.full_labels[0]["dof"] == range(20) + assert lt_stacked_1.full_labels[0]["name"] == 0 + assert lt_stacked_1.full_labels[1]["dof"] == range(2) + assert lt_stacked_1.full_labels[1]["name"] == 1 + assert lt_stacked_1.full_labels[2]["dof"] == ["x", "y", "z"] + assert lt_stacked_1.full_labels[2]["name"] == "vars" + assert lt_stacked_1.stored_labels == { + 2: {"dof": ["x", "y", "z"], "name": "vars"} + } + assert lt_stacked_1.labels == ["x", "y", "z"] + + # Test dim=2 and negative dim=-1 + lt_stacked_2 = LabelTensor.stack([lt1, lt2], dim=2) + lt_stacked_neg = LabelTensor.stack([lt1, lt2], dim=-1) + for lt_s in [lt_stacked_2, lt_stacked_neg]: + assert lt_s.shape == (20, 3, 2) + assert lt_s.full_labels[0]["dof"] == range(20) + assert lt_s.full_labels[0]["name"] == 0 + assert lt_s.full_labels[1]["dof"] == ["x", "y", "z"] + assert lt_s.full_labels[1]["name"] == "vars" + assert lt_s.full_labels[2]["dof"] == range(2) + assert lt_s.full_labels[2]["name"] == 2 + assert lt_s.stored_labels == { + 1: {"dof": ["x", "y", "z"], "name": "vars"} + } + assert lt_s.labels is None + + +def test_stack_3D(): + data_1 = torch.rand(20, 3, 2) + labels_1 = { + 1: {"dof": ["a", "b", "c"], "name": "first"}, + 2: {"dof": ["x", "y"], "name": "second"}, + } + lt1 = LabelTensor(data_1, labels_1) + data_2 = torch.rand(20, 3, 2) + lt2 = LabelTensor(data_2, labels_1) + + # Test dim=0 (and dim=-4) + lt_stacked_0 = LabelTensor.stack([lt1, lt2], dim=0) + lt_stacked_neg4 = LabelTensor.stack([lt1, lt2], dim=-4) + for lt_s in [lt_stacked_0, lt_stacked_neg4]: + assert lt_s.shape == (2, 20, 3, 2) + assert lt_s.full_labels[0]["dof"] == range(2) + assert lt_s.full_labels[0]["name"] == 0 + assert lt_s.full_labels[1]["dof"] == range(20) + assert lt_s.full_labels[1]["name"] == 1 + assert lt_s.full_labels[2]["dof"] == ["a", "b", "c"] + assert lt_s.full_labels[2]["name"] == "first" + assert lt_s.full_labels[3]["dof"] == ["x", "y"] + assert lt_s.full_labels[3]["name"] == "second" + assert lt_s.stored_labels == { + 2: {"dof": ["a", "b", "c"], "name": "first"}, + 3: {"dof": ["x", "y"], "name": "second"}, + } + assert lt_s.labels == ["x", "y"] + + # Test dim=1 (and dim=-3) + lt_stacked_1 = LabelTensor.stack([lt1, lt2], dim=1) + lt_stacked_neg3 = LabelTensor.stack([lt1, lt2], dim=-3) + for lt_s in [lt_stacked_1, lt_stacked_neg3]: + assert lt_s.shape == (20, 2, 3, 2) + assert lt_s.full_labels[0]["dof"] == range(20) + assert lt_s.full_labels[0]["name"] == 0 + assert lt_s.full_labels[1]["dof"] == range(2) + assert lt_s.full_labels[1]["name"] == 1 + assert lt_s.full_labels[2]["dof"] == ["a", "b", "c"] + assert lt_s.full_labels[2]["name"] == "first" + assert lt_s.full_labels[3]["dof"] == ["x", "y"] + assert lt_s.full_labels[3]["name"] == "second" + assert lt_s.stored_labels == { + 2: {"dof": ["a", "b", "c"], "name": "first"}, + 3: {"dof": ["x", "y"], "name": "second"}, + } + assert lt_s.labels == ["x", "y"] + + # Test dim=2 (and dim=-2) + lt_stacked_2 = LabelTensor.stack([lt1, lt2], dim=2) + lt_stacked_neg2 = LabelTensor.stack([lt1, lt2], dim=-2) + for lt_s in [lt_stacked_2, lt_stacked_neg2]: + assert lt_s.shape == (20, 3, 2, 2) + assert lt_s.full_labels[0]["dof"] == range(20) + assert lt_s.full_labels[0]["name"] == 0 + assert lt_s.full_labels[1]["dof"] == ["a", "b", "c"] + assert lt_s.full_labels[1]["name"] == "first" + assert lt_s.full_labels[2]["dof"] == range(2) + assert lt_s.full_labels[2]["name"] == 2 + assert lt_s.full_labels[3]["dof"] == ["x", "y"] + assert lt_s.full_labels[3]["name"] == "second" + assert lt_s.stored_labels == { + 1: {"dof": ["a", "b", "c"], "name": "first"}, + 3: {"dof": ["x", "y"], "name": "second"}, + } + assert lt_s.labels == ["x", "y"] + + # Test dim=3 (and dim=-1) + lt_stacked_3 = LabelTensor.stack([lt1, lt2], dim=3) + lt_stacked_neg1 = LabelTensor.stack([lt1, lt2], dim=-1) + for lt_s in [lt_stacked_3, lt_stacked_neg1]: + assert lt_s.shape == (20, 3, 2, 2) + assert lt_s.full_labels[0]["dof"] == range(20) + assert lt_s.full_labels[0]["name"] == 0 + assert lt_s.full_labels[1]["dof"] == ["a", "b", "c"] + assert lt_s.full_labels[1]["name"] == "first" + assert lt_s.full_labels[2]["dof"] == ["x", "y"] + assert lt_s.full_labels[2]["name"] == "second" + assert lt_s.full_labels[3]["dof"] == range(2) + assert lt_s.full_labels[3]["name"] == 3 + assert lt_s.stored_labels == { + 1: {"dof": ["a", "b", "c"], "name": "first"}, + 2: {"dof": ["x", "y"], "name": "second"}, + } + assert lt_s.labels is None + + +def test_stack_errors(): + data_1 = torch.rand(20, 3) + lt1 = LabelTensor(data_1, {1: {"dof": ["x", "y", "z"], "name": "vars"}}) + lt2 = LabelTensor(data_1, {1: {"dof": ["a", "b", "c"], "name": "vars"}}) + + # Empty list + assert LabelTensor.stack([]) == [] + + # Single tensor + assert LabelTensor.stack([lt1]) is lt1 + + # Out of range dim + with pytest.raises(IndexError): + LabelTensor.stack([lt1, lt1], dim=3) + with pytest.raises(IndexError): + LabelTensor.stack([lt1, lt1], dim=-4) + + # Inconsistent labels + with pytest.raises(RuntimeError): + LabelTensor.stack([lt1, lt2]) + + def test_sorting(): data = torch.ones(20, 5) data[:, 0] = data[:, 0] * 4 diff --git a/utils/mathlab_versioning.py b/utils/pina_versioning.py similarity index 100% rename from utils/mathlab_versioning.py rename to utils/pina_versioning.py