Change PODLayer name (#251)

* rename PODBlock
* add tutorial rst

---------

Co-authored-by: Dario Coscia <dariocoscia@Dario-Coscia.local>
Co-authored-by: Dario Coscia <dariocoscia@Dario-Coscia.lan>
This commit is contained in:
Dario Coscia
2024-02-29 16:01:01 +01:00
committed by GitHub
parent c2529d325a
commit c92a2832d5
7 changed files with 30 additions and 30 deletions

View File

@@ -38,4 +38,4 @@ Supervised Learning
:titlesonly:
Unstructured convolutional autoencoder via continuous convolution<tutorials/tutorial4/tutorial.rst>
POD-NN for reduced order modeling<tutorials/tutorial8/tutorial.rst>

View File

@@ -38,7 +38,7 @@ minimum PINA version to run this tutorial is the ``0.1``.
from pina.geometry import CartesianDomain
from pina.problem import ParametricProblem
from pina.model.layers import PODLayer
from pina.model.layers import PODBlock
from pina import Condition, LabelTensor, Trainer
from pina.model import FeedForward
from pina.solvers import SupervisedSolver
@@ -130,7 +130,7 @@ architecture that takes in input the parameter and return the *modal
coefficients*, so the reduced dimension representation (the coordinates
in the POD space). Such latent variable is the projected to the original
space using the POD modes, which are computed and stored in the
``PODLayer`` object.
``PODBlock`` object.
.. code:: ipython3
@@ -145,7 +145,7 @@ space using the POD modes, which are computed and stored in the
"""
super().__init__()
self.pod = PODLayer(pod_rank)
self.pod = PODBlock(pod_rank)
self.nn = FeedForward(
input_dimensions=1,
output_dimensions=pod_rank,
@@ -168,8 +168,8 @@ space using the POD modes, which are computed and stored in the
def fit_pod(self, x):
"""
Just call the :meth:`pina.model.layers.PODLayer.fit` method of the
:attr:`pina.model.layers.PODLayer` attribute.
Just call the :meth:`pina.model.layers.PODBlock.fit` method of the
:attr:`pina.model.layers.PODBlock` attribute.
"""
self.pod.fit(x)

View File

@@ -8,7 +8,7 @@ __all__ = [
"FourierBlock1D",
"FourierBlock2D",
"FourierBlock3D",
"PODLayer",
"PODBlock",
]
from .convolution_2d import ContinuousConvBlock
@@ -19,4 +19,4 @@ from .spectral import (
SpectralConvBlock3D,
)
from .fourier import FourierBlock1D, FourierBlock2D, FourierBlock3D
from .pod import PODLayer
from .pod import PODBlock

View File

@@ -6,7 +6,7 @@ from .stride import Stride
from .utils_convolution import optimizing
class PODLayer(torch.nn.Module):
class PODBlock(torch.nn.Module):
"""
POD layer: it projects the input field on the proper orthogonal
decomposition basis. It needs to be fitted to the data before being used

View File

@@ -1,22 +1,22 @@
import torch
import pytest
from pina.model.layers.pod import PODLayer
from pina.model.layers.pod import PODBlock
x = torch.linspace(-1, 1, 100)
toy_snapshots = torch.vstack([torch.exp(-x**2)*c for c in torch.linspace(0, 1, 10)])
def test_constructor():
pod = PODLayer(2)
pod = PODLayer(2, True)
pod = PODLayer(2, False)
pod = PODBlock(2)
pod = PODBlock(2, True)
pod = PODBlock(2, False)
with pytest.raises(TypeError):
pod = PODLayer()
pod = PODBlock()
@pytest.mark.parametrize("rank", [1, 2, 10])
def test_fit(rank, scale):
pod = PODLayer(rank, scale)
pod = PODBlock(rank, scale)
assert pod._basis == None
assert pod.basis == None
assert pod._scaler == None
@@ -26,7 +26,7 @@ def test_fit(rank, scale):
@pytest.mark.parametrize("scale", [True, False])
@pytest.mark.parametrize("rank", [1, 2, 10])
def test_fit(rank, scale):
pod = PODLayer(rank, scale)
pod = PODBlock(rank, scale)
pod.fit(toy_snapshots)
n_snap = toy_snapshots.shape[0]
dof = toy_snapshots.shape[1]
@@ -43,7 +43,7 @@ def test_fit(rank, scale):
assert pod.scaler == None
def test_forward():
pod = PODLayer(1)
pod = PODBlock(1)
pod.fit(toy_snapshots)
c = pod(toy_snapshots)
assert c.shape[0] == toy_snapshots.shape[0]
@@ -55,7 +55,7 @@ def test_forward():
assert c.shape[1] == pod.rank
assert c.shape[0] == 1
pod = PODLayer(2, False)
pod = PODBlock(2, False)
pod.fit(toy_snapshots)
c = pod(toy_snapshots)
torch.testing.assert_close(c, (pod.basis @ toy_snapshots.T).T)
@@ -66,7 +66,7 @@ def test_forward():
@pytest.mark.parametrize("scale", [True, False])
@pytest.mark.parametrize("rank", [1, 2, 10])
def test_expand(rank, scale):
pod = PODLayer(rank, scale)
pod = PODBlock(rank, scale)
pod.fit(toy_snapshots)
c = pod(toy_snapshots)
torch.testing.assert_close(pod.expand(c), toy_snapshots)
@@ -75,7 +75,7 @@ def test_expand(rank, scale):
@pytest.mark.parametrize("scale", [True, False])
@pytest.mark.parametrize("rank", [1, 2, 10])
def test_reduce_expand(rank, scale):
pod = PODLayer(rank, scale)
pod = PODBlock(rank, scale)
pod.fit(toy_snapshots)
torch.testing.assert_close(
pod.expand(pod.reduce(toy_snapshots)),

View File

@@ -55,7 +55,7 @@
"from pina.geometry import CartesianDomain\n",
"\n",
"from pina.problem import ParametricProblem\n",
"from pina.model.layers import PODLayer\n",
"from pina.model.layers import PODBlock\n",
"from pina import Condition, LabelTensor, Trainer\n",
"from pina.model import FeedForward\n",
"from pina.solvers import SupervisedSolver\n",
@@ -172,7 +172,7 @@
"id": "6b264569-57b3-458d-bb69-8e94fe89017d",
"metadata": {},
"source": [
"Then, we define the model we want to use: basically we have a MLP architecture that takes in input the parameter and return the *modal coefficients*, so the reduced dimension representation (the coordinates in the POD space). Such latent variable is the projected to the original space using the POD modes, which are computed and stored in the `PODLayer` object."
"Then, we define the model we want to use: basically we have a MLP architecture that takes in input the parameter and return the *modal coefficients*, so the reduced dimension representation (the coordinates in the POD space). Such latent variable is the projected to the original space using the POD modes, which are computed and stored in the `PODBlock` object."
]
},
{
@@ -193,7 +193,7 @@
" \"\"\"\n",
" super().__init__()\n",
" \n",
" self.pod = PODLayer(pod_rank)\n",
" self.pod = PODBlock(pod_rank)\n",
" self.nn = FeedForward(\n",
" input_dimensions=1,\n",
" output_dimensions=pod_rank,\n",
@@ -216,8 +216,8 @@
"\n",
" def fit_pod(self, x):\n",
" \"\"\"\n",
" Just call the :meth:`pina.model.layers.PODLayer.fit` method of the\n",
" :attr:`pina.model.layers.PODLayer` attribute.\n",
" Just call the :meth:`pina.model.layers.PODBlock.fit` method of the\n",
" :attr:`pina.model.layers.PODBlock` attribute.\n",
" \"\"\"\n",
" self.pod.fit(x)"
]

View File

@@ -26,7 +26,7 @@ import pina
from pina.geometry import CartesianDomain
from pina.problem import ParametricProblem
from pina.model.layers import PODLayer
from pina.model.layers import PODBlock
from pina import Condition, LabelTensor, Trainer
from pina.model import FeedForward
from pina.solvers import SupervisedSolver
@@ -85,7 +85,7 @@ class SnapshotProblem(ParametricProblem):
}
# Then, we define the model we want to use: basically we have a MLP architecture that takes in input the parameter and return the *modal coefficients*, so the reduced dimension representation (the coordinates in the POD space). Such latent variable is the projected to the original space using the POD modes, which are computed and stored in the `PODLayer` object.
# Then, we define the model we want to use: basically we have a MLP architecture that takes in input the parameter and return the *modal coefficients*, so the reduced dimension representation (the coordinates in the POD space). Such latent variable is the projected to the original space using the POD modes, which are computed and stored in the `PODBlock` object.
# In[33]:
@@ -101,7 +101,7 @@ class PODNN(torch.nn.Module):
"""
super().__init__()
self.pod = PODLayer(pod_rank)
self.pod = PODBlock(pod_rank)
self.nn = FeedForward(
input_dimensions=1,
output_dimensions=pod_rank,
@@ -124,8 +124,8 @@ class PODNN(torch.nn.Module):
def fit_pod(self, x):
"""
Just call the :meth:`pina.model.layers.PODLayer.fit` method of the
:attr:`pina.model.layers.PODLayer` attribute.
Just call the :meth:`pina.model.layers.PODBlock.fit` method of the
:attr:`pina.model.layers.PODBlock` attribute.
"""
self.pod.fit(x)