Skip to content

Conversation

@adendek
Copy link

@adendek adendek commented Jan 18, 2026

Description

This PR resolves #756 by implementing a major structural refactor. Following the design patterns of modern scientific libraries like JAX and Optax, it introduces a pina/_src directory to house internal logic while exposing a clean, flat public API.

API Stability Notice

The public interface remains unchanged. Existing user scripts and external calls to PINA classes will continue to work as expected. This refactor purely reorganizes the internal source code and "hoists" definitions to their respective package levels for cleaner access.

Key Changes

  • Source/API Separation: Moved all implementation logic to pina/_src, leaving top-level directories as "hoisted" interfaces.
  • Core Consolidation: Migrated foundational components (Graph, LabelTensor, Operator, Trainer) into a centralized pina._src.core/ module.
  • Documentation Standard: Rewrote and standardized docstrings for all major modules to better reflect PINA's scientific and physical modeling capabilities.

Checklist

  • Code follows the project’s Code Style Guidelines
  • Tests have been added or updated
  • Documentation has been updated if necessary
  • Pull request is linked to an open issue

- Restructured the repository to separate internal logic (`pina/_src`) from
  the public API.
- Migrated central components (Graph, LabelTensor, Operator, Trainer) into
  `pina/_src/core/` for better organization.
- Updated all subpackage `__init__.py` files to expose a clean, flat
  import surface for users.
- Standardized module docstrings across Solvers, Models, Equations,
  Domains, and Callbacks to improve documentation quality.
- Optimized internal dictionary handling in tensor storage functions.
@dario-coscia
Copy link
Collaborator

Hi @adendek ! Thanks for the PR. At the moment, all tests are failing, probably due to an import error. Can you check it? Also, the docs must be updated by updating the corresponding rst files

@dario-coscia dario-coscia requested review from dario-coscia and removed request for a team January 19, 2026 08:46
@adendek
Copy link
Author

adendek commented Jan 19, 2026

I'fixed the UT and formatting. I guess they should be fine now.

I'll need a little bit more time to update the docs.

@GiovanniCanali GiovanniCanali self-requested a review January 19, 2026 08:59
@adendek
Copy link
Author

adendek commented Jan 21, 2026

Hello @dario-coscia, I have successfully refactored the Sphinx documentation to align with the new _src structure.

As shown in the latest CI run executed on my fork, the testdocs build is now passing without warnings, and all 15 unit test jobs are green. This confirms that the internal reorganization has not broken the public API or the documentation pipeline.

image

So the PR is ready to be reviewed.

@ndem0
Copy link
Member

ndem0 commented Jan 22, 2026

Dear @adendek, thanks a lot!
Everything looks fine to me, but there is a single test (coverage) still failing.
After a quick investigation, it looks like the tests we run for the coverage report are failing:

Run python3 -m pytest --cov-report term --cov-report xml:cobertura.xml --cov=pina
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.0.2, pluggy-1.6.0
rootdir: /home/runner/work/PINA/PINA
configfile: pyproject.toml
plugins: cov-7.0.0
collected 2219 items
tests/test_adaptive_function.py ....................................     [  1%]
tests/test_block/test_convolution.py ....                                [  1%]
tests/test_block/test_embedding.py ..................................... [  3%]
.                                                                        [  3%]
tests/test_block/test_fourier.py .........                               [  3%]
tests/test_block/test_low_rank_block.py ....                             [  4%]
tests/test_block/test_orthogonal.py ........................             [  5%]
tests/test_block/test_pirate_network_block.py ......                     [  5%]
tests/test_block/test_pod.py ......................................      [  7%]
tests/test_block/test_rbf.py ........................................... [  9%]
........................................................................ [ 12%]
........................................................................ [ 15%]
.........................................................                [ 18%]
tests/test_block/test_residual.py ...........                            [ 18%]
tests/test_block/test_spectral_convolution.py .........                  [ 19%]
tests/test_callback/test_metric_tracker.py ..                            [ 19%]
tests/test_callback/test_normalizer_data_callback.py ................... [ 20%]
..............................................................           [ 22%]
tests/test_callback/test_pina_progress_bar.py ..                         [ 22%]
tests/test_callback/test_r3_refinement.py ...                            [ 23%]
tests/test_callback/test_switch_optimizer.py ........                    [ 23%]
tests/test_callback/test_switch_scheduler.py ........                    [ 23%]
tests/test_condition.py ....                                             [ 23%]
tests/test_data/test_data_module.py .......................              [ 24%]
tests/test_data/test_graph_dataset.py ......                             [ 25%]
tests/test_data/test_tensor_dataset.py ....                              [ 25%]
tests/test_domain/test_cartesian_domain.py ............................. [ 26%]
........................................................................ [ 29%]
.....................                                                    [ 30%]
tests/test_domain/test_difference.py ................................... [ 32%]
..                                                                       [ 32%]
tests/test_domain/test_ellipsoid_domain.py ............................. [ 33%]
.....................................................................    [ 36%]
tests/test_domain/test_exclusion.py .................................... [ 38%]
.                                                                        [ 38%]
tests/test_domain/test_intersection.py ................................. [ 40%]
....                                                                     [ 40%]
tests/test_domain/test_simplex_domain.py ............................... [ 41%]
.......                                                                  [ 42%]
tests/test_domain/test_union.py .....................................    [ 43%]
tests/test_equation/test_equation.py ..                                  [ 43%]
tests/test_equation/test_equation_factory.py ........................... [ 45%]
........................................................................ [ 48%]
....................                                                     [ 49%]
tests/test_equation/test_system_equation.py ......                       [ 49%]
tests/test_graph.py ........................                             [ 50%]
tests/test_label_tensor/test_label_tensor.py ..........................  [ 51%]
tests/test_label_tensor/test_label_tensor_01.py ............             [ 52%]
tests/test_loss/test_lp_loss.py ....                                     [ 52%]
tests/test_loss/test_power_loss.py ....                                  [ 52%]
tests/test_messagepassing/test_deep_tensor_network_block.py ......       [ 52%]
tests/test_messagepassing/test_equivariant_network_block.py ............ [ 53%]
................                                                         [ 54%]
tests/test_messagepassing/test_equivariant_operator_block.py ........... [ 54%]
...........                                                              [ 55%]
tests/test_messagepassing/test_interaction_network_block.py ........     [ 55%]
tests/test_messagepassing/test_radial_field_network_block.py .....       [ 55%]
tests/test_model/test_average_neural_operator.py ...                     [ 55%]
tests/test_model/test_deeponet.py ................                       [ 56%]
tests/test_model/test_equivariant_graph_neural_operator.py ............. [ 57%]
........................................................................ [ 60%]
...                                                                      [ 60%]
tests/test_model/test_feed_forward.py ....                               [ 60%]
tests/test_model/test_fourier_neural_operator.py .......                 [ 61%]
tests/test_model/test_graph_neural_operator.py ..........                [ 61%]
tests/test_model/test_kernel_neural_operator.py ...                      [ 61%]
tests/test_model/test_low_rank_neural_operator.py ...                    [ 61%]
tests/test_model/test_mionet.py .......                                  [ 62%]
tests/test_model/test_pirate_network.py ........................         [ 63%]
tests/test_model/test_residual_feed_forward.py ...                       [ 63%]
tests/test_model/test_sindy.py ......                                    [ 63%]
tests/test_model/test_spline.py ........................................ [ 65%]
.........                                                                [ 65%]
tests/test_model/test_spline_surface.py ................................ [ 67%]
........................................................................ [ 70%]
....................................                                     [ 72%]
tests/test_operator.py ..................                                [ 72%]
tests/test_optimizer.py ........                                         [ 73%]
tests/test_package.py .                                                  [ 73%]
tests/test_problem.py ..........                                         [ 73%]
tests/test_problem_zoo/test_acoustic_wave.py ..                          [ 73%]
tests/test_problem_zoo/test_advection.py ..                              [ 73%]
tests/test_problem_zoo/test_allen_cahn.py ....                           [ 74%]
tests/test_problem_zoo/test_diffusion_reaction.py ..                     [ 74%]
tests/test_problem_zoo/test_helmholtz.py ..                              [ 74%]
tests/test_problem_zoo/test_inverse_poisson_2d_square.py ....            [ 74%]
tests/test_problem_zoo/test_poisson_2d_square.py .                       [ 74%]
tests/test_problem_zoo/test_supervised_problem.py ..                     [ 74%]
tests/test_scheduler.py .....                                            [ 74%]
tests/test_solver/test_causal_pinn.py ...........................        [ 76%]
tests/test_solver/test_competitive_pinn.py ............................. [ 77%]
.........................                                                [ 78%]
tests/test_solver/test_ensemble_pinn.py ..........................       [ 79%]
tests/test_solver/test_ensemble_supervised_solver.py .FFFFFFFF.......... [ 80%]
......FF..........FF...........                                          [ 81%]
tests/test_solver/test_garom.py .FFFF....FFFF....FFFF.....               [ 83%]
tests/test_solver/test_gradient_pinn.py ................................ [ 84%]
....................                                                     [ 85%]
tests/test_solver/test_pinn.py ......................................... [ 87%]
...........                                                              [ 87%]
tests/test_solver/test_rba_pinn.py ..................................... [ 89%]
.....................................................................    [ 92%]
tests/test_solver/test_reduced_order_model_solver.py .FFFFFFFF........FF [ 93%]
..FF...                                                                  [ 93%]
tests/test_solver/test_self_adaptive_pinn.py ........................... [ 94%]
...                                                                      [ 95%]
tests/test_solver/test_supervised_solver.py .FFFFFFFF................FF. [ 96%]
.........FF...........                                                   [ 97%]
tests/test_type_checker.py ..                                            [ 97%]
tests/test_utils.py .............                                        [ 97%]
tests/test_weighting/test_linear_weighting.py ................           [ 98%]
tests/test_weighting/test_ntk_weighting.py ..................            [ 99%]
tests/test_weighting/test_scalar_weighting.py ......                     [ 99%]
tests/test_weighting/test_self_adaptive_weighting.py .....               [100%]

But all the other unittest are green. I think there is only something wrong in the action environment.

@adendek
Copy link
Author

adendek commented Jan 22, 2026

Hello @ndem0,

This is one of the most bizarre CI discrepancies I have encountered. I have reviewed the workflow configuration, and while the logic seems sound, I noticed a few points worth investigating.

Workflow Improvement (Explicit Versioning). Currently, the coverage job does not explicitly define a Python version, meaning it defaults to whatever is pre-installed on the runner (often the latest available). We should improve this by explicitly pinning the version to ensure consistency with the unittests job:

coverage:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10'] # Explicitly defined
        
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    # ... remaining steps

Environmental Comparison Even without the pin, the software environment in the failing run looks reasonable and matches the standard:

Failing Run: Python 3.12.3, pytest-9.0.2, pluggy-1.6.0, cov-7.0.0

Unit Tests (Success): Almost identical (Python 3.12.12).

The Fork Success What is most confusing is that the exact same code passed all checks on my personal fork. The logs show identical versions of Python, pytest, and the coverage plugin.

Before I start refactoring the workflow structure to hunt for a phantom bug, could you please manually re-trigger the coverage test? I want to rule out a transient "fluke" or a runner-specific environment glitch.

image

If it fails again, I will dive deeper into the workflow configuration.

@dario-coscia
Copy link
Collaborator

Hi @ndem0, I think coverage is from our side, the fix in #646 didn't work and we had to revert it

@dario-coscia
Copy link
Collaborator

Hi @adendek! Green flag from myside, great job! It will be very useful for the future of the package.
Just one thing, can you squash all commits in one commit "update package structure"? After that we can merge

Copy link
Collaborator

@GiovanniCanali GiovanniCanali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a naive question, but why do we have so many empty __init__.py files in the src directory? Are they still needed?

@adendek
Copy link
Author

adendek commented Jan 22, 2026

Hi @adendek! Green flag from myside, great job! It will be very useful for the future of the package. Just one thing, can you squash all commits in one commit "update package structure"? After that we can merge

I guess it will be easier if you do this during the merge process. You can select the options to squash merge.

image

I am not even able to make the merge on my own.

image

This might be a naive question, but why do we have so many empty init.py files in the src directory? Are they still needed?

The __init__.py files serves as the formal declaration that a directory is a Regular Package rather than a Namespace Package.

It signals to the Python interpreter that the directory contains modules that can be imported. Without it (in Python 3.3+), the folder is treated as a Namespace Package, which can lead to unpredictable behavior when multiple directories share the same name across the sys.path.

Essential tools in the PINA pipeline—specifically Sphinx for documentation and pytest for coverage—frequently rely on the presence of __init__.py to recursively discover source code and build the module tree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants