Skip to content

Cleaning Solver - #836

Draft
ndem0 wants to merge 1 commit into
devfrom
solver_improvement
Draft

ndem0 wants to merge 1 commit into
devfrom
solver_improvement

Conversation

@ndem0

@ndem0 ndem0 commented Sep 23, 2026

Copy link
Copy Markdown
Member

Description

This PR fixes #ISSUE_NUMBER.

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Solver-specific _compute_condition_loss overrides in SelfAdaptive/Competitive don’t apply the new _weight_condition_loss hook, causing functional inconsistency vs BaseSolver’s updated loss pipeline.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
What changed in this PR

This PR refactors the solver subsystem to consolidate initialization in BaseSolver, simplify mixin responsibilities (notably multi-model vs ensemble forwarding), and separate additive regularization from multiplicative loss weighting via a new hook.

Changes:

  • Merge solver component setup + weighting/loss initialization into BaseSolver.__init__, updating core solver classes to pass all init args in one call.
  • Introduce BaseSolver.forward (default: first model) and remove redundant forward overrides from SelfAdaptive/Competitive solvers.
  • Split loss post-processing into two hooks: _regularize_condition_loss (additive) and _weight_condition_loss (multiplicative), migrating residual-based attention to the new weighting hook.
File Description
pina/​_src/​solver/​base_solver.py Expands __init__, adds default forward, and adds _weight_condition_loss hook into the loss pipeline.
pina/​_src/​solver/​single_model_solver.py Updates initialization to pass model/optimizer/scheduler/weighting/loss into BaseSolver.__init__.
pina/​_src/​solver/​multi_model_solver.py Updates initialization to pass models/optimizers/schedulers/weighting/loss into BaseSolver.__init__ and sets manual optimization directly.
pina/​_src/​solver/​ensemble_solver.py Updates initialization to pass models/optimizers/schedulers/weighting/loss into BaseSolver.__init__ and sets manual optimization directly.
pina/​_src/​solver/​mixin/​multi_model_mixin.py Removes stacking forward; mixin now focuses on multi-optimizer configuration + convenience properties.
pina/​_src/​solver/​mixin/​manual_optimization_mixin.py Removes _init_manual_optimization helper; callers now set automatic_optimization directly.
pina/​_src/​solver/​mixin/​residual_based_attention_mixin.py Renames residual-attention hook to _weight_condition_loss and updates docstring accordingly.
pina/​_src/​solver/​self_adaptive_physics_informed_solver.py Removes redundant forward override following BaseSolver default-forward addition.
pina/​_src/​solver/​competitive_physics_informed_solver.py Removes redundant forward override following BaseSolver default-forward addition.
pina/​_src/​solver/​REFACTORING.md Adds design/architecture documentation for the refactor and new hook responsibilities.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

"""
return self.model(x)

def _compute_condition_loss(self, condition, data, batch_idx):
"""
return self.model(x)

def _compute_condition_loss(self, condition, data, batch_idx):
@GiovanniCanali
GiovanniCanali changed the base branch from master to dev October 1, 2026 11:32
@GiovanniCanali
GiovanniCanali self-requested a review October 1, 2026 11:33
@ndem0
ndem0 force-pushed the solver_improvement branch from d56cf81 to f2e5bab Compare November 6, 2026 09:12
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

badge

Code Coverage Summary

Filename                                                                       Stmts    Miss  Cover    Missing
---------------------------------------------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------
__init__.py                                                                       20       4  80.00%   43-54
graph.py                                                                           2       0  100.00%
label_tensor.py                                                                    2       0  100.00%
operator.py                                                                        2       0  100.00%
trainer.py                                                                         2       0  100.00%
type_checker.py                                                                    2       0  100.00%
utils.py                                                                           2       0  100.00%
_src/__init__.py                                                                   0       0  100.00%
_src/adaptive_function/__init__.py                                                 0       0  100.00%
_src/adaptive_function/adaptive_celu.py                                            6       0  100.00%
_src/adaptive_function/adaptive_elu.py                                             6       0  100.00%
_src/adaptive_function/adaptive_exp.py                                             6       0  100.00%
_src/adaptive_function/adaptive_function_interface.py                             13       0  100.00%
_src/adaptive_function/adaptive_gelu.py                                            6       0  100.00%
_src/adaptive_function/adaptive_mish.py                                            6       0  100.00%
_src/adaptive_function/adaptive_relu.py                                            6       0  100.00%
_src/adaptive_function/adaptive_sigmoid.py                                         6       0  100.00%
_src/adaptive_function/adaptive_silu.py                                            6       0  100.00%
_src/adaptive_function/adaptive_siren.py                                           6       0  100.00%
_src/adaptive_function/adaptive_softmax.py                                         6       0  100.00%
_src/adaptive_function/adaptive_softmin.py                                         6       0  100.00%
_src/adaptive_function/adaptive_tanh.py                                            6       0  100.00%
_src/adaptive_function/base_adaptive_function.py                                  43       2  95.35%   142, 146
_src/callback/__init__.py                                                          0       0  100.00%
_src/callback/optim/__init__.py                                                    0       0  100.00%
_src/callback/optim/switch_optimizer.py                                           20       0  100.00%
_src/callback/optim/switch_scheduler.py                                           20       0  100.00%
_src/callback/processing/__init__.py                                               0       0  100.00%
_src/callback/processing/data_normalizer.py                                       79       4  94.94%   115, 160, 213, 215
_src/callback/processing/metric_tracker.py                                        29       1  96.55%   102
_src/callback/processing/pina_progress_bar.py                                     26       1  96.15%   111
_src/callback/refinement/__init__.py                                               0       0  100.00%
_src/callback/refinement/base_refinement.py                                       49       3  93.88%   71, 78, 96
_src/callback/refinement/r3_refinement.py                                         25       0  100.00%
_src/callback/refinement/refinement_interface.py                                  14       0  100.00%
_src/condition/__init__.py                                                         0       0  100.00%
_src/condition/base_condition.py                                                  15       2  86.67%   20, 42
_src/condition/condition.py                                                       16       3  81.25%   39, 46-49
_src/condition/condition_interface.py                                             18       0  100.00%
_src/condition/domain_equation_condition.py                                       37       4  89.19%   58, 89-91
_src/condition/graph_condition.py                                                 27       3  88.89%   20-22
_src/condition/graph_input_equation_condition.py                                  16       0  100.00%
_src/condition/graph_input_target_condition.py                                     7       0  100.00%
_src/condition/graph_time_series_condition.py                                     39       1  97.44%   140
_src/condition/input_equation_condition.py                                        24       0  100.00%
_src/condition/input_target_condition.py                                          23       1  95.65%   39
_src/condition/tensor_condition.py                                                30       2  93.33%   36-37
_src/condition/time_series_condition.py                                           72       1  98.61%   261
_src/core/__init__.py                                                              0       0  100.00%
_src/core/data_module.py                                                          74       1  98.65%   209
_src/core/graph.py                                                               122      21  82.79%   110-111, 123, 135, 137, 153, 155, 174-180, 193, 328, 494-506
_src/core/label_tensor.py                                                        284      23  91.90%   81, 148, 165, 177, 182, 188-193, 277, 285, 310, 312, 356, 372, 542, 589, 687, 722-731, 768
_src/core/operator.py                                                             72       2  97.22%   268, 503
_src/core/trainer.py                                                              82       5  93.90%   120-126, 201-209, 293
_src/core/type_checker.py                                                         22       0  100.00%
_src/core/utils.py                                                                73       5  93.15%   158, 201, 204, 207, 304
_src/domain/__init__.py                                                            0       0  100.00%
_src/domain/base_domain.py                                                        68       0  100.00%
_src/domain/base_operation.py                                                     45       4  91.11%   63, 106, 129, 139
_src/domain/cartesian_domain.py                                                   54       1  98.15%   68
_src/domain/difference.py                                                         27       0  100.00%
_src/domain/domain_interface.py                                                   25       0  100.00%
_src/domain/ellipsoid_domain.py                                                   81       4  95.06%   98, 108-109, 253
_src/domain/exclusion.py                                                          35       1  97.14%   107
_src/domain/intersection.py                                                       34       1  97.06%   97
_src/domain/operation_interface.py                                                 9       0  100.00%
_src/domain/simplex_domain.py                                                     83       5  93.98%   212, 226, 237, 249, 288
_src/domain/union.py                                                              24       0  100.00%
_src/equation/__init__.py                                                          0       0  100.00%
_src/equation/base_equation.py                                                    14       1  92.86%   54
_src/equation/equation.py                                                         16       1  93.75%   72
_src/equation/equation_interface.py                                                6       0  100.00%
_src/equation/system_equation.py                                                  23       0  100.00%
_src/equation/zoo/__init__.py                                                      0       0  100.00%
_src/equation/zoo/acoustic_wave_equation.py                                       14       0  100.00%
_src/equation/zoo/advection_equation.py                                           30       0  100.00%
_src/equation/zoo/allen_cahn_equation.py                                          16       0  100.00%
_src/equation/zoo/burgers_equation.py                                             24       0  100.00%
_src/equation/zoo/diffusion_reaction_equation.py                                  17       0  100.00%
_src/equation/zoo/fixed_flux.py                                                   13       0  100.00%
_src/equation/zoo/fixed_gradient.py                                               13       0  100.00%
_src/equation/zoo/fixed_laplacian.py                                              18       2  88.89%   77-82
_src/equation/zoo/fixed_value.py                                                  12       0  100.00%
_src/equation/zoo/helmholtz_equation.py                                           14       0  100.00%
_src/equation/zoo/poisson_equation.py                                             12       0  100.00%
_src/loss/__init__.py                                                              0       0  100.00%
_src/loss/base_dual_loss.py                                                       10       0  100.00%
_src/loss/dual_loss_interface.py                                                   7       0  100.00%
_src/loss/lp_loss.py                                                              19       0  100.00%
_src/loss/power_loss.py                                                           15       0  100.00%
_src/loss/sinkhorn_loss.py                                                        28       0  100.00%
_src/model/__init__.py                                                             0       0  100.00%
_src/model/average_neural_operator.py                                             31       2  93.55%   86, 95
_src/model/deeponet.py                                                            85      13  84.71%   179-182, 201, 232, 271, 281, 291, 301, 311, 321, 476, 486
_src/model/equivariant_graph_neural_operator.py                                   51       1  98.04%   228
_src/model/feed_forward.py                                                        89      11  87.64%   68, 215, 220, 298-312
_src/model/fourier_neural_operator.py                                             78      10  87.18%   112-116, 126, 171-175, 234, 236, 258, 371
_src/model/graph_neural_operator.py                                               40       2  95.00%   70, 72
_src/model/kernel_neural_operator.py                                              34       6  82.35%   99-100, 119-120, 139-140
_src/model/kolmogorov_arnold_network.py                                           14       0  100.00%
_src/model/low_rank_neural_operator.py                                            27       2  92.59%   103, 112
_src/model/multi_feed_forward.py                                                  12       5  58.33%   36-42
_src/model/pirate_network.py                                                      28       1  96.43%   129
_src/model/sindy.py                                                               21       0  100.00%
_src/model/spline.py                                                             124       6  95.16%   133, 156, 164, 236, 450, 475
_src/model/spline_surface.py                                                      68      12  82.35%   159-160, 195-198, 208, 221-226, 266
_src/model/vectorized_spline.py                                                  153      16  89.54%   208, 311, 317, 347-348, 408, 410, 446, 448, 450, 529, 542, 621-630, 647
_src/model/block/__init__.py                                                       0       0  100.00%
_src/model/block/average_neural_operator_block.py                                 12       0  100.00%
_src/model/block/convolution.py                                                   64      13  79.69%   95, 99, 103, 109, 115, 129, 132, 177, 187, 197, 207, 217, 227
_src/model/block/convolution_2d.py                                               146      27  81.51%   177, 184, 304, 336, 401-455, 478
_src/model/block/embedding.py                                                     48       7  85.42%   103, 153-156, 165, 178
_src/model/block/fourier_block.py                                                 31       0  100.00%
_src/model/block/gno_block.py                                                     22       4  81.82%   83-87, 97
_src/model/block/integral.py                                                      18       4  77.78%   31-34, 80
_src/model/block/kan_block.py                                                     43       0  100.00%
_src/model/block/low_rank_block.py                                                24       0  100.00%
_src/model/block/orthogonal.py                                                    37       0  100.00%
_src/model/block/pirate_network_block.py                                          25       1  96.00%   98
_src/model/block/pod_block.py                                                     75      10  86.67%   65-68, 80, 93, 123, 160-165, 200, 225
_src/model/block/rbf_block.py                                                    179      25  86.03%   18, 42, 53, 64, 75, 86, 97, 234, 291, 293, 309, 312, 340, 346, 374, 378, 522-535
_src/model/block/residual.py                                                      46       0  100.00%
_src/model/block/spectral.py                                                      83       4  95.18%   152, 160, 292, 300
_src/model/block/stride.py                                                        28       7  75.00%   66, 69, 72, 78, 83-85
_src/model/block/utils_convolution.py                                             22       3  86.36%   58-60
_src/model/block/message_passing/__init__.py                                       0       0  100.00%
_src/model/block/message_passing/deep_tensor_network_block.py                     21       0  100.00%
_src/model/block/message_passing/en_equivariant_network_block.py                  47       1  97.87%   174
_src/model/block/message_passing/equivariant_graph_neural_operator_block.py       36       0  100.00%
_src/model/block/message_passing/interaction_network_block.py                     23       0  100.00%
_src/model/block/message_passing/radial_field_network_block.py                    20       0  100.00%
_src/optim/__init__.py                                                             0       0  100.00%
_src/optim/optimizer_interface.py                                                  7       0  100.00%
_src/optim/scheduler_interface.py                                                  7       0  100.00%
_src/optim/torch_optimizer.py                                                     14       0  100.00%
_src/optim/torch_scheduler.py                                                     16       0  100.00%
_src/problem/__init__.py                                                           0       0  100.00%
_src/problem/base_problem.py                                                      93      10  89.25%   54-55, 67-74, 234-239
_src/problem/inverse_problem.py                                                   23       0  100.00%
_src/problem/parametric_problem.py                                                 9       0  100.00%
_src/problem/problem_interface.py                                                 25       0  100.00%
_src/problem/spatial_problem.py                                                    9       0  100.00%
_src/problem/time_dependent_problem.py                                             9       0  100.00%
_src/problem/zoo/__init__.py                                                       0       0  100.00%
_src/problem/zoo/acoustic_wave_problem.py                                         33       2  93.94%   27-28
_src/problem/zoo/advection_problem.py                                             25       1  96.00%   24
_src/problem/zoo/allen_cahn_problem.py                                            25       0  100.00%
_src/problem/zoo/burgers_problem.py                                               23       1  95.65%   25
_src/problem/zoo/diffusion_reaction_problem.py                                    35       3  91.43%   27-35
_src/problem/zoo/helmholtz_problem.py                                             30       0  100.00%
_src/problem/zoo/inverse_poisson_problem.py                                       53       3  94.34%   51-57
_src/problem/zoo/poisson_problem.py                                               17       0  100.00%
_src/problem/zoo/supervised_problem.py                                            17       0  100.00%
_src/solver/autoregressive_ensemble_solver.py                                      8       0  100.00%
_src/solver/autoregressive_single_model_solver.py                                  8       0  100.00%
_src/solver/base_solver.py                                                       133       5  96.24%   248, 255, 450, 471, 516
_src/solver/causal_physics_informed_single_model_solver.py                        70       5  92.86%   149, 168, 230, 315, 340
_src/solver/competitive_physics_informed_solver.py                                59       1  98.31%   254
_src/solver/ensemble_solver.py                                                     8       0  100.00%
_src/solver/gradient_physics_informed_single_model_solver.py                      11       0  100.00%
_src/solver/multi_model_solver.py                                                  8       0  100.00%
_src/solver/physics_informed_ensemble_solver.py                                    9       0  100.00%
_src/solver/physics_informed_single_model_solver.py                                9       0  100.00%
_src/solver/rba_physics_informed_single_model_solver.py                           11       0  100.00%
_src/solver/self_adaptive_physics_informed_solver.py                              72       2  97.22%   135, 292
_src/solver/single_model_solver.py                                                 6       0  100.00%
_src/solver/solver_interface.py                                                   21       0  100.00%
_src/solver/supervised_ensemble_solver.py                                          7       0  100.00%
_src/solver/supervised_single_model_solver.py                                      7       0  100.00%
_src/solver/mixin/autoregressive_mixin.py                                         50      11  78.00%   159-186
_src/solver/mixin/condition_aggregator_mixin.py                                   13       0  100.00%
_src/solver/mixin/ensemble_mixin.py                                               19       0  100.00%
_src/solver/mixin/gradient_enhanced_mixin.py                                      34       2  94.12%   67, 76
_src/solver/mixin/manual_optimization_mixin.py                                    14       0  100.00%
_src/solver/mixin/multi_model_mixin.py                                            21       0  100.00%
_src/solver/mixin/physics_informed_mixin.py                                        8       0  100.00%
_src/solver/mixin/residual_based_attention_mixin.py                               46       0  100.00%
_src/solver/mixin/single_model_mixin.py                                           19       0  100.00%
_src/weighting/__init__.py                                                         0       0  100.00%
_src/weighting/base_weighting.py                                                  28       1  96.43%   49
_src/weighting/linear_weighting.py                                                16       0  100.00%
_src/weighting/no_weighting.py                                                     4       0  100.00%
_src/weighting/ntk_weighting.py                                                   18       0  100.00%
_src/weighting/scalar_weighting.py                                                13       0  100.00%
_src/weighting/self_adaptive_weighting.py                                         12       0  100.00%
_src/weighting/weighting_interface.py                                             11       0  100.00%
adaptive_function/__init__.py                                                     15       0  100.00%
callback/__init__.py                                                              15       3  80.00%   37-46
condition/__init__.py                                                             19       5  73.68%   47-58
data/__init__.py                                                                   9       9  0.00%    3-25
domain/__init__.py                                                                11       0  100.00%
equation/__init__.py                                                              13       4  69.23%   44-54
equation/zoo.py                                                                   12       0  100.00%
loss/__init__.py                                                                  14       4  71.43%   31-41
model/__init__.py                                                                 16       0  100.00%
model/block/__init__.py                                                           14       0  100.00%
model/block/message_passing.py                                                     6       0  100.00%
optim/__init__.py                                                                 11       3  72.73%   25-34
problem/__init__.py                                                               13       3  76.92%   26-35
problem/zoo.py                                                                    10       0  100.00%
solver/__init__.py                                                                27       6  77.78%   95-109
solver/mixin.py                                                                   10      10  0.00%    3-29
weighting/__init__.py                                                              8       0  100.00%
TOTAL                                                                           5652     396  92.99%

Results for commit: f2e5bab

Minimum allowed coverage is 80.123%

♻️ This comment has been updated with latest results

This branch has not been deployed

No deployments
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.

2 participants