Compare commits
1 Commits
dev
...
fix-codacy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40747c56ff |
2
.github/workflows/monthly-tagger.yml
vendored
2
.github/workflows/monthly-tagger.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
||||
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
|
||||
6
.github/workflows/tester.yml
vendored
6
.github/workflows/tester.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: "Testing Pull Request"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- "master"
|
||||
- "dev"
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
||||
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -75,4 +75,4 @@ jobs:
|
||||
threshold: 80.123
|
||||
fail: true
|
||||
publish: true
|
||||
coverage-summary-title: "Code Coverage Summary"
|
||||
coverage-summary-title: "Code Coverage Summary"
|
||||
|
||||
4
.github/workflows/tutorial_exporter.yml
vendored
4
.github/workflows/tutorial_exporter.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
@@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="readme/pina_logo.png">
|
||||
<img src="readme/pina_logo.png"
|
||||
<a href="https://github.com/mathLab/PINA/raw/master/readme/pina_logo.png">
|
||||
<img src="https://github.com/mathLab/PINA/raw/master/readme/pina_logo.png"
|
||||
alt="PINA logo"
|
||||
style="width: 220px; aspect-ratio: 1 / 1; object-fit: contain;">
|
||||
</a>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 411 KiB After Width: | Height: | Size: 177 KiB |
@@ -1,6 +1,7 @@
|
||||
"""Module for the Equation."""
|
||||
|
||||
import inspect
|
||||
|
||||
from .equation_interface import EquationInterface
|
||||
|
||||
|
||||
@@ -48,10 +49,6 @@ class Equation(EquationInterface):
|
||||
:raises RuntimeError: If the underlying equation signature length is not
|
||||
2 (direct problem) or 3 (inverse problem).
|
||||
"""
|
||||
# Move the equation to the input_ device
|
||||
self.to(input_.device)
|
||||
|
||||
# Call the underlying equation based on its signature length
|
||||
if self.__len_sig == 2:
|
||||
return self.__equation(input_, output_)
|
||||
if self.__len_sig == 3:
|
||||
|
||||
@@ -239,19 +239,19 @@ class Advection(Equation): # pylint: disable=R0903
|
||||
)
|
||||
|
||||
# Ensure consistency of c length
|
||||
if self.c.shape[-1] != len(input_lbl) - 1 and self.c.shape[-1] > 1:
|
||||
if len(self.c) != (len(input_lbl) - 1) and len(self.c) > 1:
|
||||
raise ValueError(
|
||||
"If 'c' is passed as a list, its length must be equal to "
|
||||
"the number of spatial dimensions."
|
||||
)
|
||||
|
||||
# Repeat c to ensure consistent shape for advection
|
||||
c = self.c.repeat(output_.shape[0], 1)
|
||||
if c.shape[1] != (len(input_lbl) - 1):
|
||||
c = c.repeat(1, len(input_lbl) - 1)
|
||||
self.c = self.c.repeat(output_.shape[0], 1)
|
||||
if self.c.shape[1] != (len(input_lbl) - 1):
|
||||
self.c = self.c.repeat(1, len(input_lbl) - 1)
|
||||
|
||||
# Add a dimension to c for the following operations
|
||||
c = c.unsqueeze(-1)
|
||||
self.c = self.c.unsqueeze(-1)
|
||||
|
||||
# Compute the time derivative and the spatial gradient
|
||||
time_der = grad(output_, input_, components=None, d="t")
|
||||
@@ -262,7 +262,7 @@ class Advection(Equation): # pylint: disable=R0903
|
||||
tmp = tmp.transpose(-1, -2)
|
||||
|
||||
# Compute advection term
|
||||
adv = (tmp * c).sum(dim=tmp.tensor.ndim - 2)
|
||||
adv = (tmp * self.c).sum(dim=tmp.tensor.ndim - 2)
|
||||
|
||||
return time_der + adv
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Module for the Equation Interface."""
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import torch
|
||||
|
||||
|
||||
class EquationInterface(metaclass=ABCMeta):
|
||||
@@ -34,33 +33,3 @@ class EquationInterface(metaclass=ABCMeta):
|
||||
:return: The computed residual of the equation.
|
||||
:rtype: LabelTensor
|
||||
"""
|
||||
|
||||
def to(self, device):
|
||||
"""
|
||||
Move all tensor attributes to the specified device.
|
||||
|
||||
:param torch.device device: The target device to move the tensors to.
|
||||
:return: The instance moved to the specified device.
|
||||
:rtype: EquationInterface
|
||||
"""
|
||||
# Iterate over all attributes of the Equation
|
||||
for key, val in self.__dict__.items():
|
||||
|
||||
# Move tensors in dictionaries to the specified device
|
||||
if isinstance(val, dict):
|
||||
self.__dict__[key] = {
|
||||
k: v.to(device) if torch.is_tensor(v) else v
|
||||
for k, v in val.items()
|
||||
}
|
||||
|
||||
# Move tensors in lists to the specified device
|
||||
elif isinstance(val, list):
|
||||
self.__dict__[key] = [
|
||||
v.to(device) if torch.is_tensor(v) else v for v in val
|
||||
]
|
||||
|
||||
# Move tensor attributes to the specified device
|
||||
elif torch.is_tensor(val):
|
||||
self.__dict__[key] = val.to(device)
|
||||
|
||||
return self
|
||||
|
||||
@@ -101,10 +101,6 @@ class SystemEquation(EquationInterface):
|
||||
:return: The aggregated residuals of the system of equations.
|
||||
:rtype: LabelTensor
|
||||
"""
|
||||
# Move the equation to the input_ device
|
||||
self.to(input_.device)
|
||||
|
||||
# Compute the residual for each equation
|
||||
residual = torch.hstack(
|
||||
[
|
||||
equation.residual(input_, output_, params_)
|
||||
@@ -112,7 +108,6 @@ class SystemEquation(EquationInterface):
|
||||
]
|
||||
)
|
||||
|
||||
# Skip reduction if not specified
|
||||
if self.reduction is None:
|
||||
return residual
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class EnEquivariantNetworkBlock(MessagePassing):
|
||||
DOI: `<https://doi.org/10.48550/arXiv.2102.09844>`_.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
def __init__( # pylint: disable=R0913, R0917
|
||||
self,
|
||||
node_feature_dim,
|
||||
edge_feature_dim,
|
||||
@@ -143,7 +143,9 @@ class EnEquivariantNetworkBlock(MessagePassing):
|
||||
func=activation,
|
||||
)
|
||||
|
||||
def forward(self, x, pos, edge_index, edge_attr=None, vel=None):
|
||||
def forward(
|
||||
self, x, pos, edge_index, edge_attr=None, vel=None
|
||||
): # pylint: disable=R0917
|
||||
"""
|
||||
Forward pass of the block, triggering the message-passing routine.
|
||||
|
||||
@@ -169,7 +171,9 @@ class EnEquivariantNetworkBlock(MessagePassing):
|
||||
edge_index=edge_index, x=x, pos=pos, edge_attr=edge_attr, vel=vel
|
||||
)
|
||||
|
||||
def message(self, x_i, x_j, pos_i, pos_j, edge_attr):
|
||||
def message(
|
||||
self, x_i, x_j, pos_i, pos_j, edge_attr
|
||||
): # pylint: disable=R0917
|
||||
"""
|
||||
Compute the message to be passed between nodes and edges.
|
||||
|
||||
@@ -234,7 +238,9 @@ class EnEquivariantNetworkBlock(MessagePassing):
|
||||
|
||||
return agg_message, agg_m_ij
|
||||
|
||||
def update(self, aggregated_inputs, x, pos, edge_index, vel):
|
||||
def update(
|
||||
self, aggregated_inputs, x, pos, edge_index, vel
|
||||
): # pylint: disable=R0917
|
||||
"""
|
||||
Update node features, positions, and optionally velocities.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class EquivariantGraphNeuralOperatorBlock(torch.nn.Module):
|
||||
<https://arxiv.org/abs/2401.11037>`_
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
def __init__( # pylint: disable=R0913, R0917
|
||||
self,
|
||||
node_feature_dim,
|
||||
edge_feature_dim,
|
||||
@@ -101,7 +101,9 @@ class EquivariantGraphNeuralOperatorBlock(torch.nn.Module):
|
||||
flow=flow,
|
||||
)
|
||||
|
||||
def forward(self, x, pos, vel, edge_index, edge_attr=None):
|
||||
def forward( # pylint: disable=R0917
|
||||
self, x, pos, vel, edge_index, edge_attr=None
|
||||
):
|
||||
"""
|
||||
Forward pass of the Equivariant Graph Neural Operator block.
|
||||
|
||||
@@ -182,7 +184,11 @@ class EquivariantGraphNeuralOperatorBlock(torch.nn.Module):
|
||||
weights = torch.complex(real[..., :modes], img[..., :modes])
|
||||
|
||||
# Convolution in Fourier space
|
||||
fourier = torch.fft.rfftn(x, dim=[0])[:modes]
|
||||
# torch.fft.rfftn and irfftn are callable functions, but pylint
|
||||
# incorrectly flags them as E1102 (not callable).
|
||||
fourier = torch.fft.rfftn(x, dim=[0])[:modes] # pylint: disable=E1102
|
||||
out = torch.einsum(einsum_idx, fourier, weights)
|
||||
|
||||
return torch.fft.irfftn(out, s=x.shape[0], dim=0)
|
||||
return torch.fft.irfftn( # pylint: disable=E1102
|
||||
out, s=x.shape[0], dim=0
|
||||
)
|
||||
|
||||
@@ -5,7 +5,9 @@ from ..utils import check_positive_integer
|
||||
from .block.message_passing import EquivariantGraphNeuralOperatorBlock
|
||||
|
||||
|
||||
class EquivariantGraphNeuralOperator(torch.nn.Module):
|
||||
# Disable pylint warnings for too few public methods (since this is a simple
|
||||
# model class in a standard PyTorch style)
|
||||
class EquivariantGraphNeuralOperator(torch.nn.Module): # pylint: disable=R0903
|
||||
"""
|
||||
Equivariant Graph Neural Operator (EGNO) for modeling 3D dynamics.
|
||||
|
||||
@@ -32,7 +34,9 @@ class EquivariantGraphNeuralOperator(torch.nn.Module):
|
||||
<https://arxiv.org/abs/2401.11037>`_
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
# Disable pylint warnings for too many arguments in init (since this is a
|
||||
# model class with many configurable parameters)
|
||||
def __init__( # pylint: disable=R0913, R0917, R0914
|
||||
self,
|
||||
n_egno_layers,
|
||||
node_feature_dim,
|
||||
|
||||
@@ -48,10 +48,11 @@ class HelmholtzProblem(SpatialProblem):
|
||||
:type alpha: float | int
|
||||
"""
|
||||
super().__init__()
|
||||
check_consistency(alpha, (int, float))
|
||||
self.alpha = alpha
|
||||
|
||||
def forcing_term(input_):
|
||||
self.alpha = alpha
|
||||
check_consistency(alpha, (int, float))
|
||||
|
||||
def forcing_term(self, input_):
|
||||
"""
|
||||
Implementation of the forcing term.
|
||||
"""
|
||||
|
||||
@@ -71,7 +71,9 @@ class PINNInterface(SupervisedSolverInterface, metaclass=ABCMeta):
|
||||
"""
|
||||
# Override the compilation, compiling only for torch < 2.8, see
|
||||
# related issue at https://github.com/mathLab/PINA/issues/621
|
||||
if torch.__version__ >= "2.8":
|
||||
if torch.__version__ < "2.8":
|
||||
self.trainer.compile = True
|
||||
else:
|
||||
self.trainer.compile = False
|
||||
warnings.warn(
|
||||
"Compilation is disabled for torch >= 2.8. "
|
||||
|
||||
@@ -174,7 +174,11 @@ class SolverInterface(lightning.pytorch.LightningModule, metaclass=ABCMeta):
|
||||
:return: The result of the parent class ``setup`` method.
|
||||
:rtype: Any
|
||||
"""
|
||||
if self.trainer.compile and not self._is_compiled():
|
||||
if stage == "fit" and self.trainer.compile:
|
||||
self._setup_compile()
|
||||
if stage == "test" and (
|
||||
self.trainer.compile and not self._is_compiled()
|
||||
):
|
||||
self._setup_compile()
|
||||
return super().setup(stage)
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
"""Module for the Trainer."""
|
||||
|
||||
import sys
|
||||
import warnings
|
||||
import torch
|
||||
import lightning
|
||||
from .utils import check_consistency, custom_warning_format
|
||||
from .utils import check_consistency
|
||||
from .data import PinaDataModule
|
||||
from .solver import SolverInterface, PINNInterface
|
||||
|
||||
# set the warning for compile options
|
||||
warnings.formatwarning = custom_warning_format
|
||||
warnings.filterwarnings("always", category=UserWarning)
|
||||
|
||||
|
||||
class Trainer(lightning.pytorch.Trainer):
|
||||
"""
|
||||
@@ -54,8 +49,7 @@ class Trainer(lightning.pytorch.Trainer):
|
||||
:param float val_size: The percentage of elements to include in the
|
||||
validation dataset. Default is ``0.0``.
|
||||
:param bool compile: If ``True``, the model is compiled before training.
|
||||
Default is ``False``. For Windows users, it is always disabled. Not
|
||||
supported for python version greater or equal than 3.14.
|
||||
Default is ``False``. For Windows users, it is always disabled.
|
||||
:param bool repeat: Whether to repeat the dataset data in each
|
||||
condition during training. For further details, see the
|
||||
:class:`~pina.data.data_module.PinaDataModule` class. Default is
|
||||
@@ -110,17 +104,8 @@ class Trainer(lightning.pytorch.Trainer):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# checking compilation and automatic batching
|
||||
# compilation disabled for Windows and for Python 3.14+
|
||||
if (
|
||||
compile is None
|
||||
or sys.platform == "win32"
|
||||
or sys.version_info >= (3, 14)
|
||||
):
|
||||
if compile is None or sys.platform == "win32":
|
||||
compile = False
|
||||
warnings.warn(
|
||||
"Compilation is disabled for Python 3.14+ and for Windows.",
|
||||
UserWarning,
|
||||
)
|
||||
|
||||
repeat = repeat if repeat is not None else False
|
||||
|
||||
@@ -340,23 +325,3 @@ class Trainer(lightning.pytorch.Trainer):
|
||||
if batch_size is not None:
|
||||
check_consistency(batch_size, int)
|
||||
return pin_memory, num_workers, shuffle, batch_size
|
||||
|
||||
@property
|
||||
def compile(self):
|
||||
"""
|
||||
Whether compilation is required or not.
|
||||
|
||||
:return: ``True`` if compilation is required, ``False`` otherwise.
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._compile
|
||||
|
||||
@compile.setter
|
||||
def compile(self, value):
|
||||
"""
|
||||
Setting the value of compile.
|
||||
|
||||
:param bool value: Whether compilation is required or not.
|
||||
"""
|
||||
check_consistency(value, bool)
|
||||
self._compile = value
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "pina-mathlab"
|
||||
version = "0.2.5"
|
||||
version = "0.2.3"
|
||||
description = "Physic Informed Neural networks for Advance modeling."
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
@@ -19,7 +19,7 @@ dependencies = [
|
||||
"torch_geometric",
|
||||
"matplotlib",
|
||||
]
|
||||
requires-python = ">=3.10"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
[project.optional-dependencies]
|
||||
doc = [
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 411 KiB After Width: | Height: | Size: 51 KiB |
@@ -104,7 +104,7 @@ def test_advection_equation(c):
|
||||
|
||||
# Should fail if c is a list and its length != spatial dimension
|
||||
with pytest.raises(ValueError):
|
||||
equation = Advection([1, 2, 3])
|
||||
Advection([1, 2, 3])
|
||||
residual = equation.residual(pts, u)
|
||||
|
||||
|
||||
|
||||
BIN
tutorials/static/pina_logo.png
vendored
BIN
tutorials/static/pina_logo.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 411 KiB After Width: | Height: | Size: 51 KiB |
Reference in New Issue
Block a user