diff --git a/docs/source/_rst/_tutorial.rst b/docs/source/_rst/_tutorial.rst index 87e6d9f..0612e9b 100644 --- a/docs/source/_rst/_tutorial.rst +++ b/docs/source/_rst/_tutorial.rst @@ -38,4 +38,4 @@ Supervised Learning :titlesonly: Unstructured convolutional autoencoder via continuous convolution - + POD-NN for reduced order modeling diff --git a/docs/source/_rst/tutorials/tutorial8/tutorial.rst b/docs/source/_rst/tutorials/tutorial8/tutorial.rst index f58e865..5d7f3a9 100644 --- a/docs/source/_rst/tutorials/tutorial8/tutorial.rst +++ b/docs/source/_rst/tutorials/tutorial8/tutorial.rst @@ -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) diff --git a/pina/model/layers/__init__.py b/pina/model/layers/__init__.py index a6e4e0b..95505c1 100644 --- a/pina/model/layers/__init__.py +++ b/pina/model/layers/__init__.py @@ -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 diff --git a/pina/model/layers/pod.py b/pina/model/layers/pod.py index f696d03..3e56274 100644 --- a/pina/model/layers/pod.py +++ b/pina/model/layers/pod.py @@ -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 diff --git a/tests/test_layers/test_pod.py b/tests/test_layers/test_pod.py index 878ae5a..23b30ce 100644 --- a/tests/test_layers/test_pod.py +++ b/tests/test_layers/test_pod.py @@ -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)), diff --git a/tutorials/tutorial8/tutorial.ipynb b/tutorials/tutorial8/tutorial.ipynb index e85c81e..6a11689 100644 --- a/tutorials/tutorial8/tutorial.ipynb +++ b/tutorials/tutorial8/tutorial.ipynb @@ -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)" ] diff --git a/tutorials/tutorial8/tutorial.py b/tutorials/tutorial8/tutorial.py index 0311964..3feb97b 100644 --- a/tutorials/tutorial8/tutorial.py +++ b/tutorials/tutorial8/tutorial.py @@ -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)