{ "cells": [ { "cell_type": "markdown", "id": "dbbb73cb-a632-4056-bbca-b483b2ad5f9c", "metadata": {}, "source": [ "# Tutorial: Reduced Order Modeling with POD-RBF and POD-NN Approaches for Fluid Dynamics\n", "\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mathLab/PINA/blob/master/tutorials/tutorial9/tutorial.ipynb)" ] }, { "cell_type": "markdown", "id": "84508f26-1ba6-4b59-926b-3e340d632a15", "metadata": {}, "source": [ "The goal of this tutorial is to demonstrate how to use the **PINA** library to apply a reduced-order modeling technique, as outlined in [1]. These methods share several similarities with machine learning approaches, as they focus on predicting the solution to differential equations, often parametric PDEs, in real-time.\n", "\n", "In particular, we will utilize **Proper Orthogonal Decomposition** (POD) in combination with two different regression techniques: **Radial Basis Function Interpolation** (POD-RBF) and **Neural Networks**(POD-NN) [2]. This process involves reducing the dimensionality of the parametric solution manifold through POD and then approximating it in the reduced space using a regression model (either a neural network or an RBF interpolation). In this example, we'll use a simple multilayer perceptron (MLP) as the regression model, but various architectures can be easily substituted.\n", "\n", "Let's start with the necessary imports." ] }, { "cell_type": "code", "execution_count": null, "id": "00d1027d-13f2-4619-9ff7-a740568f13ff", "metadata": {}, "outputs": [], "source": [ "## routine needed to run the notebook on Google Colab\n", "try:\n", " import google.colab\n", "\n", " IN_COLAB = True\n", "except:\n", " IN_COLAB = False\n", "if IN_COLAB:\n", " !pip install \"pina-mathlab[tutorial]\"\n", "\n", "%matplotlib inline\n", "\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "import torch\n", "import numpy as np\n", "import warnings\n", "\n", "from pina import Trainer\n", "from pina.model import FeedForward\n", "from pina.solver import SupervisedSolver\n", "from pina.optim import TorchOptimizer\n", "from pina.problem.zoo import SupervisedProblem\n", "from pina.model.block import PODBlock, RBFBlock\n", "\n", "warnings.filterwarnings(\"ignore\")" ] }, { "cell_type": "markdown", "id": "5138afdf-bff6-46bf-b423-a22673190687", "metadata": {}, "source": [ "We utilize the [Smithers](https://github.com/mathLab/Smithers) library to gather the parametric snapshots. Specifically, we use the `NavierStokesDataset` class, which contains a collection of parametric solutions to the Navier-Stokes equations in a 2D L-shaped domain. The parameter in this case is the inflow velocity.\n", "\n", "The dataset comprises 500 snapshots of the velocity fields (along the $x$, $y$ axes, and the magnitude), as well as the pressure fields, along with their corresponding parameter values.\n", "\n", "To visually inspect the snapshots, let's also plot the data points alongside the reference solution. This reference solution represents the expected output of our model." ] }, { "cell_type": "code", "execution_count": 2, "id": "2c55d972-09a9-41de-9400-ba051c28cdcb", "metadata": {}, "outputs": [ { "data": { "image/png": "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AAAAhxDGAAAAAAAAAAA4hDAGAAAAAAAAACDWMOaDH/ygeuQjH6lGR0fVE5/4RHXDDTeokHn729+uZsyYMeVy5JFHqtC49tpr1SmnnKJWrFiRvYfLLrtsyu16xrOe/H7AAQeoefPmqdWrV6vbb79dhfyezjjjjGm/u+c85zlKMmvXrlXHHXecWrhwodp///3V85//fPXTn/50yn127typzjzzTLXvvvuqBQsWqBe96EXqvvvuU6mB1sgErUFrYgOtkQlag9bEBlojE7QGrQkmjPnMZz6jzj777GzrqJtuukkde+yx6tnPfrbasGGDCpmjjjpK3XvvvZOXb33rWyo0tm/fnv0+tNBX8fd///fq/e9/v/rwhz+svvOd76j58+dnvzv9Rxvqe9Jo4Sj+7i6++GIlmWuuuSYTieuvv1599atfVbt371YnnXRS9l5z/uIv/kJ94QtfUJdcckl2/3vuuUe98IUvVCmB1sgFrUFrYgKtkQtag9bEBFojF7QGrelMzxHHH39878wzz5z8fnx8vLdixYre2rVre6GyZs2a3rHHHuv7ZRhF/0lceumlk99PTEz0li9f3vuHf/iHyes2bdrUGxkZ6V188cW9EN+T5vTTT+8973nP64XMhg0bsvd2zTXXTP5e5syZ07vkkksm7/PjH/84u891113XSwW0JgzQmnBAa6pBa8IArQkHtKYatCYM0Jpw2CBIa5xUxuzatUvdeOONWWlWzsyZM7Pvr7vuOhUyutRMl3Edeuih6rTTTlO//OUvVUzcddddav369VN+d4sXL85KJEP/3V199dVZqdoRRxyhXvOa16gHH3xQhcTmzZuzr/vss0/2VZ9jOukt/q50yefKlSuD/13VBa0JF7RGLmjNdNCacEFr5ILWTAetCRe0Ri6bBWmNkzDmgQceUOPj42rZsmVTrtff6z/SUNEn00UXXaSuvPJKdeGFF2Yn3VOf+lS1detWFQv57ye2350ur/vkJz+pvv71r6t3vetdWTnaySefnP2dhsDExIQ666yz1JOf/GR19NFHZ9fp38fcuXPV3nvvHdXvqgloTbigNTJBa6pBa8IFrZEJWlMNWhMuaI1MJoRpzWyrzx45+g8v55hjjsmE5eCDD1af/exn1Ste8Qqvrw0G8+IXv3jy34997GOz399hhx2WJb0nnniiko7ue7z11luD7K+F5qA14YLWQEigNeGC1kBIoDXhgtYEWBmzdOlSNWvWrGkTifX3y5cvV7Gg07TDDz9c3XHHHSoW8t9P7L87XSKp/05D+N297nWvU1dccYW66qqr1IEHHjh5vf596HLWTZs2Rf27GgRaEy5ojTzQmv6gNeGC1sgDrekPWhMuaI08XidQa5yEMbrs5/GPf3xWzlQsEdLfr1q1SsXCtm3b1J133pltXxYLhxxySPZHWPzdbdmyJZsIHtPv7u677876HSX/7vQcLS0il156qfrGN76R/W6K6HNszpw5U35Xets23YMb0+9qEGhNuKA1ckBrhoPWhAtaIwe0ZjhoTbigNXLoSdaaniM+/elPZ9OjL7root5tt93We9WrXtXbe++9e+vXr++Fypve9Kbe1Vdf3bvrrrt63/72t3urV6/uLV26NJvQHBJbt27tff/7388u+k/i3e9+d/bvX/ziF9ntF1xwQfa7uvzyy3s//OEPswnahxxySG/Hjh29EN+Tvu3Nb35zNh1b/+6+9rWv9R73uMf1Hv3oR/d27tzZk8prXvOa3uLFi7O/uXvvvXfy8utf/3ryPq9+9at7K1eu7H3jG9/ofe973+utWrUqu6QEWiMXtAatiQm0Ri5oDVoTE2iNXNAatKYrzsIYzQc+8IHsTc6dOzfbpu3666/vhcypp57aO+CAA7L384hHPCL7/o477uiFxlVXXZWdbOWL3ros35rtrW99a2/ZsmXZ/wxOPPHE3k9/+tNeqO9Jn3gnnXRSb7/99su2MTv44IN7r3zlK8X/T63q/ejLxz/+8cn7aHF/7Wtf21uyZElvr7326r3gBS/IxCY10BqZoDVoTWygNTJBa9Ca2EBrZILWoDVdmaH/Y7f2BgAAAAAAAAAAnM6MAQAAAAAAAACA30AYAwAAAAAAAADgEMIYAAAAAAAAAACHEMYAAAAAAAAAADiEMAYAAAAAAAAAwCGEMQAAAAAAAAAADiGMAQAAAAAAAABwCGEMAAAAAAAAAIBDCGMAAAAAAAAAABxCGAMAAAAAAAAA4BDCGAAAAAAAAAAAhxDGAAAAAAAAAAAod/x/8Zt1/VUJr6MAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from smithers.dataset import NavierStokesDataset\n", "\n", "dataset = NavierStokesDataset()\n", "\n", "fig, axs = plt.subplots(1, 4, figsize=(14, 3))\n", "for ax, p, u in zip(axs, dataset.params[:4], dataset.snapshots[\"mag(v)\"][:4]):\n", " ax.tricontourf(dataset.triang, u, levels=16)\n", " ax.set_title(f\"$\\mu$ = {p[0]:.2f}\")" ] }, { "cell_type": "markdown", "id": "bef4d79d", "metadata": {}, "source": [ "The *snapshots*—i.e., the numerical solutions computed for several parameters—and the corresponding parameters are the only data we need to train the model, enabling us to predict the solution for any new test parameter. To properly validate the accuracy, we will split the 500 snapshots into the training dataset (90% of the original data) and the testing dataset (the remaining 10%) inside the `Trainer`.\n", "\n", "It is now time to define the problem!" ] }, { "cell_type": "code", "execution_count": 3, "id": "bd081bcd-192f-4370-a013-9b73050b5383", "metadata": {}, "outputs": [], "source": [ "u = torch.tensor(dataset.snapshots[\"mag(v)\"]).float()\n", "p = torch.tensor(dataset.params).float()\n", "problem = SupervisedProblem(input_=p, output_=u)" ] }, { "cell_type": "markdown", "id": "3b255526", "metadata": {}, "source": [ "We can then build a `POD-NN` model (using an MLP architecture as approximation) and compare it with a `POD-RBF` model (using a Radial Basis Function interpolation as approximation).\n", "\n", "## POD-NN reduced order model\n", "Let's build the `PODNN` class" ] }, { "cell_type": "code", "execution_count": null, "id": "2edc981a", "metadata": {}, "outputs": [], "source": [ "class PODNN(torch.nn.Module):\n", " def __init__(self, pod_rank, layers, func):\n", " super().__init__()\n", " self.pod = PODBlock(pod_rank)\n", " self.nn = FeedForward(\n", " input_dimensions=1,\n", " output_dimensions=pod_rank,\n", " layers=layers,\n", " func=func,\n", " )\n", "\n", " def forward(self, x):\n", " coefficents = self.nn(x)\n", " return self.pod.expand(coefficents)\n", "\n", " def fit_pod(self, x):\n", " self.pod.fit(x)" ] }, { "cell_type": "markdown", "id": "9295214e", "metadata": {}, "source": [ "We highlight that the POD modes are directly computed by means of the singular value decomposition (SVD) over the input data, and not trained using the backpropagation approach. Only the weights of the MLP are actually trained during the optimization loop." ] }, { "cell_type": "code", "execution_count": 5, "id": "2166dc87", "metadata": {}, "outputs": [], "source": [ "pod_nn = PODNN(pod_rank=20, layers=[10, 10, 10], func=torch.nn.Tanh)\n", "pod_nn_stokes = SupervisedSolver(\n", " problem=problem,\n", " model=pod_nn,\n", " optimizer=TorchOptimizer(torch.optim.Adam, lr=0.0001),\n", " use_lt=False,\n", ")" ] }, { "cell_type": "markdown", "id": "9bc5c5e8", "metadata": {}, "source": [ "Before starting, we need to fit the POD basis on the training dataset. This can be easily done in **PINA** as well:" ] }, { "cell_type": "code", "execution_count": 14, "id": "79116088", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'data': {'input': tensor([[62.9303],\n", " [69.6048],\n", " [38.4262],\n", " [11.9993],\n", " [70.7476],\n", " [61.6883],\n", " [ 6.7950],\n", " [20.0604],\n", " [40.6300],\n", " [12.1874],\n", " [ 3.1027],\n", " [59.4681],\n", " [17.2394],\n", " [25.0710],\n", " [58.7048],\n", " [66.0357],\n", " [13.7871],\n", " [59.3463],\n", " [74.2256],\n", " [56.6014],\n", " [30.6884],\n", " [11.8451],\n", " [20.1443],\n", " [58.2840],\n", " [11.6013],\n", " [67.0447],\n", " [33.0565],\n", " [35.4567],\n", " [39.9778],\n", " [32.1195],\n", " [65.4172],\n", " [39.3765],\n", " [24.4306],\n", " [43.9765],\n", " [65.3786],\n", " [68.0972],\n", " [45.5336],\n", " [60.1751],\n", " [30.3036],\n", " [ 4.2553],\n", " [13.1969],\n", " [62.9486],\n", " [11.1034],\n", " [77.9286],\n", " [27.0189],\n", " [11.8553],\n", " [71.2748],\n", " [48.5574],\n", " [67.5883],\n", " [ 2.3839],\n", " [ 3.1263],\n", " [39.8775],\n", " [57.4624],\n", " [49.3585],\n", " [25.1034],\n", " [18.8859],\n", " [54.6693],\n", " [34.5382],\n", " [75.3122],\n", " [71.9857],\n", " [42.1083],\n", " [77.9504],\n", " [44.6426],\n", " [ 5.1886],\n", " [29.1004],\n", " [39.1846],\n", " [71.9006],\n", " [46.0576],\n", " [20.5980],\n", " [57.7879],\n", " [75.6277],\n", " [18.4263],\n", " [59.9036],\n", " [43.4923],\n", " [ 2.4096],\n", " [35.4380],\n", " [56.6536],\n", " [37.5632],\n", " [29.2638],\n", " [77.4696],\n", " [69.8695],\n", " [ 8.5057],\n", " [23.3454],\n", " [46.1825],\n", " [ 2.3475],\n", " [16.4427],\n", " [43.3628],\n", " [31.4625],\n", " [39.4601],\n", " [35.0521],\n", " [60.8462],\n", " [75.7216],\n", " [46.5139],\n", " [16.9278],\n", " [60.1908],\n", " [18.5865],\n", " [21.9701],\n", " [15.8536],\n", " [55.5883],\n", " [12.2705],\n", " [25.5779],\n", " [75.8837],\n", " [37.3164],\n", " [53.8189],\n", " [28.2707],\n", " [39.5087],\n", " [55.8740],\n", " [64.1151],\n", " [25.4312],\n", " [56.6943],\n", " [18.0838],\n", " [18.8715],\n", " [22.4502],\n", " [50.3284],\n", " [ 9.9762],\n", " [51.2143],\n", " [22.6805],\n", " [27.1969],\n", " [27.2697],\n", " [62.1914],\n", " [29.1255],\n", " [25.5252],\n", " [69.3314],\n", " [23.0740],\n", " [11.9543],\n", " [ 8.0329],\n", " [70.0234],\n", " [62.0862],\n", " [58.3692],\n", " [76.3979],\n", " [41.2897],\n", " [47.3468],\n", " [74.5410],\n", " [74.3037],\n", " [57.6083],\n", " [13.6068],\n", " [73.7192],\n", " [10.4125],\n", " [37.1647],\n", " [32.4120],\n", " [62.3430],\n", " [ 2.9503],\n", " [38.8866],\n", " [55.3095],\n", " [20.1033],\n", " [47.8751],\n", " [49.2108],\n", " [31.7676],\n", " [19.6507],\n", " [46.0040],\n", " [10.3772],\n", " [63.4158],\n", " [66.4410],\n", " [39.4769],\n", " [54.0489],\n", " [ 5.2420],\n", " [55.8336],\n", " [19.5176],\n", " [11.7735],\n", " [47.5848],\n", " [52.0378],\n", " [68.1622],\n", " [28.1602],\n", " [78.8191],\n", " [ 1.5335],\n", " [28.3442],\n", " [56.2587],\n", " [25.8309],\n", " [56.4272],\n", " [16.6158],\n", " [ 5.0642],\n", " [72.0677],\n", " [38.7616],\n", " [46.5296],\n", " [32.4527],\n", " [ 1.9560],\n", " [16.6125],\n", " [ 1.4628],\n", " [32.5421],\n", " [43.3538],\n", " [71.8118],\n", " [18.9924],\n", " [ 6.7808],\n", " [50.1427],\n", " [31.0796],\n", " [44.3744],\n", " [13.0667],\n", " [54.4075],\n", " [68.4848],\n", " [45.8608],\n", " [71.5114],\n", " [70.0880],\n", " [ 6.4931],\n", " [54.3336],\n", " [ 4.5854],\n", " [57.9890],\n", " [ 4.4567],\n", " [ 5.8390],\n", " [54.4788],\n", " [66.2623],\n", " [67.5109],\n", " [56.1005],\n", " [35.3731],\n", " [13.1377],\n", " [ 1.0448],\n", " [10.6533],\n", " [43.4558],\n", " [56.2985],\n", " [32.6332],\n", " [37.7039],\n", " [16.5381],\n", " [37.4334],\n", " [22.9689],\n", " [27.7113],\n", " [69.4806],\n", " [72.1631],\n", " [62.1094],\n", " [64.1897],\n", " [52.3485],\n", " [54.7471],\n", " [23.7721],\n", " [ 2.9344],\n", " [16.6461],\n", " [75.6024],\n", " [74.6463],\n", " [42.1152],\n", " [75.4130],\n", " [ 1.8505],\n", " [59.8561],\n", " [69.6021],\n", " [41.6988],\n", " [39.2469],\n", " [31.1444],\n", " [43.7623],\n", " [59.9418],\n", " [54.1852],\n", " [76.2606],\n", " [64.9288],\n", " [34.0440],\n", " [61.4536],\n", " [14.1176],\n", " [18.0217],\n", " [41.1807],\n", " [20.9807],\n", " [18.6234],\n", " [59.8440],\n", " [75.4189],\n", " [62.7048],\n", " [ 4.3917],\n", " [39.3068],\n", " [22.8537],\n", " [47.4871],\n", " [54.2336],\n", " [64.7892],\n", " [27.2568],\n", " [36.1772],\n", " [24.7665],\n", " [17.3789],\n", " [77.3491],\n", " [43.7027],\n", " [21.9006],\n", " [77.2732],\n", " [58.2636],\n", " [74.0533],\n", " [52.1413],\n", " [16.3418],\n", " [44.8621],\n", " [66.6646],\n", " [30.2331],\n", " [29.4183],\n", " [16.3126],\n", " [ 2.7135],\n", " [13.1188],\n", " [ 5.1976],\n", " [58.2013],\n", " [32.8872],\n", " [60.2680],\n", " [71.1017],\n", " [63.6098],\n", " [25.2483],\n", " [39.9540],\n", " [21.9234],\n", " [ 7.1370],\n", " [ 6.9859],\n", " [59.3271],\n", " [46.5611],\n", " [ 3.8455],\n", " [42.3983],\n", " [67.9013],\n", " [12.4052],\n", " [ 3.6047],\n", " [12.7990],\n", " [44.9117],\n", " [29.8836],\n", " [55.3731],\n", " [59.4771],\n", " [30.6991],\n", " [76.0530],\n", " [12.9745],\n", " [ 3.4163],\n", " [69.5650],\n", " [21.6818],\n", " [55.9859],\n", " [63.2105],\n", " [31.2600],\n", " [69.9810],\n", " [67.6433],\n", " [63.1569],\n", " [ 6.7593],\n", " [49.4732],\n", " [57.0699],\n", " [20.5354],\n", " [36.8145],\n", " [44.8119],\n", " [78.1705],\n", " [54.7712],\n", " [21.6635],\n", " [55.2618],\n", " [ 1.0821],\n", " [23.7851],\n", " [42.7934],\n", " [15.9782],\n", " [41.3088],\n", " [34.6568],\n", " [22.3629],\n", " [24.6012],\n", " [ 8.4395],\n", " [11.0584],\n", " [25.8380],\n", " [ 9.8315],\n", " [50.2540],\n", " [32.3607],\n", " [65.7044],\n", " [38.1189],\n", " [33.9563],\n", " [72.3834],\n", " [ 7.2291],\n", " [48.0025],\n", " [58.5983],\n", " [61.8395],\n", " [67.5923],\n", " [79.6642],\n", " [77.6723],\n", " [59.5426],\n", " [33.9265],\n", " [ 2.2516],\n", " [42.6297],\n", " [70.2720],\n", " [ 7.3774],\n", " [79.4375],\n", " [75.6756],\n", " [53.5453],\n", " [67.0573],\n", " [57.3002],\n", " [32.8375],\n", " [47.3265],\n", " [77.1869],\n", " [15.1796],\n", " [35.2564],\n", " [59.5709],\n", " [71.3325],\n", " [55.5114],\n", " [ 5.5506],\n", " [49.5813],\n", " [67.2036],\n", " [28.3424],\n", " [78.9061],\n", " [63.2471],\n", " [77.1184],\n", " [16.9706],\n", " [24.1396],\n", " [46.7296],\n", " [21.1801],\n", " [13.7958],\n", " [63.5612],\n", " [23.1194],\n", " [56.1641],\n", " [41.9497],\n", " [78.6188],\n", " [36.4321],\n", " [42.8694],\n", " [17.0279],\n", " [21.7124],\n", " [36.9340],\n", " [70.0557],\n", " [ 4.4955],\n", " [29.0410],\n", " [17.1994],\n", " [30.1172],\n", " [14.9533],\n", " [57.8508],\n", " [ 5.0984],\n", " [52.3402],\n", " [13.9732],\n", " [54.3866],\n", " [73.2008],\n", " [65.9082],\n", " [58.5098],\n", " [ 1.5027],\n", " [10.9692],\n", " [ 2.2434],\n", " [38.2506],\n", " [64.2607],\n", " [76.8894],\n", " [ 5.7972],\n", " [ 2.6118],\n", " [45.0798],\n", " [25.3582],\n", " [76.7246],\n", " [65.1198],\n", " [23.9905],\n", " [44.0284],\n", " [75.4402],\n", " [ 5.9481],\n", " [38.8662],\n", " [51.3641],\n", " [49.3622],\n", " [37.0966],\n", " [33.0696],\n", " [27.0639],\n", " [11.8883],\n", " [76.6635],\n", " [79.9875],\n", " [ 1.1146],\n", " [18.1830],\n", " [38.3944],\n", " [77.8681],\n", " [49.6939],\n", " [26.3080],\n", " [72.9662],\n", " [71.9192],\n", " [55.3076],\n", " [54.4914],\n", " [57.5270],\n", " [33.1837],\n", " [44.5100],\n", " [39.2002],\n", " [ 3.2662],\n", " [ 6.1431],\n", " [58.2313],\n", " [15.8349],\n", " [45.4998],\n", " [30.6056],\n", " [42.9006],\n", " [10.1169],\n", " [12.4275],\n", " [53.7738],\n", " [75.6024],\n", " [11.3320],\n", " [54.8824]]),\n", " 'target': tensor([[0.0000e+00, 1.7153e-29, 2.1090e-24, ..., 1.3309e+01, 2.5842e+01,\n", " 1.4591e-01],\n", " [0.0000e+00, 6.9364e-28, 3.7834e-24, ..., 1.4712e+01, 2.7046e+01,\n", " 3.9227e-01],\n", " [0.0000e+00, 7.4496e-27, 3.8185e-23, ..., 8.1462e+00, 1.8578e+01,\n", " 2.0960e+00],\n", " ...,\n", " [0.0000e+00, 9.2999e-27, 1.3844e-21, ..., 1.5971e+01, 2.7905e+01,\n", " 8.1396e-01],\n", " [0.0000e+00, 1.9608e-27, 2.1849e-26, ..., 2.3973e+00, 5.9919e+00,\n", " 2.7392e+00],\n", " [0.0000e+00, 2.0007e-23, 1.1228e-20, ..., 1.1616e+01, 2.3978e+01,\n", " 7.5582e-01]])}}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trainer.data_module.train_dataset.get_all_data()" ] }, { "cell_type": "code", "execution_count": 15, "id": "1f229d30", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "GPU available: True (mps), used: False\n", "TPU available: False, using: 0 TPU cores\n", "HPU available: False, using: 0 HPUs\n", "\n", " | Name | Type | Params | Mode \n", "----------------------------------------------------\n", "0 | _pina_models | ModuleList | 460 | train\n", "1 | _loss_fn | MSELoss | 0 | train\n", "----------------------------------------------------\n", "460 Trainable params\n", "0 Non-trainable params\n", "460 Total params\n", "0.002 Total estimated model params size (MB)\n", "13 Modules in train mode\n", "0 Modules in eval mode\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "40f8c9624a824387b969aebe0b2a8fb2", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Training: | | 0/? [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "idx = torch.randint(0, len(u_test), (4,))\n", "u_idx_rbf = pod_rbf(p_test[idx])\n", "u_idx_nn = pod_nn_stokes(p_test[idx])\n", "\n", "\n", "fig, axs = plt.subplots(4, 5, figsize=(14, 9))\n", "\n", "relative_error_rbf = np.abs(u_test[idx] - u_idx_rbf.detach())\n", "relative_error_rbf = np.where(\n", " u_test[idx] < 1e-7, 1e-7, relative_error_rbf / u_test[idx]\n", ")\n", "\n", "relative_error_nn = np.abs(u_test[idx] - u_idx_nn.detach())\n", "relative_error_nn = np.where(\n", " u_test[idx] < 1e-7, 1e-7, relative_error_nn / u_test[idx]\n", ")\n", "\n", "for i, (idx_, rbf_, nn_, rbf_err_, nn_err_) in enumerate(\n", " zip(idx, u_idx_rbf, u_idx_nn, relative_error_rbf, relative_error_nn)\n", "):\n", "\n", " axs[0, 0].set_title(f\"Real Snapshots\")\n", " axs[0, 1].set_title(f\"POD-RBF\")\n", " axs[0, 2].set_title(f\"POD-NN\")\n", " axs[0, 3].set_title(f\"Error POD-RBF\")\n", " axs[0, 4].set_title(f\"Error POD-NN\")\n", "\n", " cm = axs[i, 0].tricontourf(\n", " dataset.triang, rbf_.detach()\n", " ) # POD-RBF prediction\n", " plt.colorbar(cm, ax=axs[i, 0])\n", "\n", " cm = axs[i, 1].tricontourf(\n", " dataset.triang, nn_.detach()\n", " ) # POD-NN prediction\n", " plt.colorbar(cm, ax=axs[i, 1])\n", "\n", " cm = axs[i, 2].tricontourf(dataset.triang, u_test[idx_].flatten()) # Truth\n", " plt.colorbar(cm, ax=axs[i, 2])\n", "\n", " cm = axs[i, 3].tripcolor(\n", " dataset.triang, rbf_err_, norm=matplotlib.colors.LogNorm()\n", " ) # Error for POD-RBF\n", " plt.colorbar(cm, ax=axs[i, 3])\n", "\n", " cm = axs[i, 4].tripcolor(\n", " dataset.triang, nn_err_, norm=matplotlib.colors.LogNorm()\n", " ) # Error for POD-NN\n", " plt.colorbar(cm, ax=axs[i, 4])\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "49e51233", "metadata": {}, "source": [ "## What's Next?\n", "\n", "Congratulations on completing this tutorial using **PINA** to apply reduced order modeling techniques with **POD-RBF** and **POD-NN**! There are several directions you can explore next:\n", "\n", "1. **Extend to More Complex Problems**: Try using more complex parametric domains or PDEs. For example, you can explore Navier-Stokes equations in 3D or more complex boundary conditions.\n", "\n", "2. **Combine POD with Deep Learning Techniques**: Investigate hybrid methods, such as combining **POD-NN** with convolutional layers or recurrent layers, to handle time-dependent problems or more complex spatial dependencies.\n", "\n", "3. **Evaluate Performance on Larger Datasets**: Work with larger datasets to assess how well these methods scale. You may want to test on datasets from simulations or real-world problems.\n", "\n", "4. **Hybrid Models with Physics Informed Networks (PINN)**: Integrate **POD** models with PINN frameworks to include physics-based regularization in your model and improve predictions for more complex scenarios, such as turbulent fluid flow.\n", "\n", "5. **...and many more!**: The potential applications of reduced order models are vast, ranging from material science simulations to real-time predictions in engineering applications.\n", "\n", "For more information and advanced tutorials, refer to the [PINA Documentation](https://mathlab.github.io/PINA/).\n", "\n", "### References\n", "1. Rozza G., Stabile G., Ballarin F. (2022). Advanced Reduced Order Methods and Applications in Computational Fluid Dynamics, Society for Industrial and Applied Mathematics. \n", "2. Hesthaven, J. S., & Ubbiali, S. (2018). Non-intrusive reduced order modeling of nonlinear problems using neural networks. Journal of Computational Physics, 363, 55-78." ] } ], "metadata": { "kernelspec": { "display_name": "pina", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.21" } }, "nbformat": 4, "nbformat_minor": 5 }