diff --git a/examples/backup/BackUp_1.ipynb b/examples/backup/BackUp_1.ipynb new file mode 100644 index 00000000..29d79a09 --- /dev/null +++ b/examples/backup/BackUp_1.ipynb @@ -0,0 +1,583 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Backup 1: Applying hard constraints\n", + "\n", + "For some problems, it is advantageous to apply prior knowledge about the solution in the network architecture, instead of the training process via additional loss terms. For example, in simple domains a Dirichlet boundary condition could be added to the network output with a corresponding characteristic function. Since the boundary condition is then naturally fulfilled, one has to consider fewer terms in the final loss and the optimization may become easier.\n", + "\n", + "Here we consider the example: \n", + "\\begin{align*}\n", + " \\partial_y u(x,y) &= \\frac{u(x,y)}{y}, \\text{ in } [0, 1] \\times [0, 1] \\\\\n", + " u_1(x, 0) &= 0 , \\text{ for } x \\in [0, 1] \\\\\n", + " u_2(x, 1) &= \\sin(20\\pi*x) , \\text{ for } x \\in [0, 1] \\\\\n", + " \\vec{n} \\nabla u(x, y) &= 0 , \\text{ for } x \\in \\{0, 1\\}, y \\in \\{0, 1\\}\\\\\n", + "\\end{align*}\n", + "\n", + "This problem has the simple solution $u(x, y) = y\\sin(20\\pi x)$. But because of the high frequencies of the sinus term, a training of the boundary condition is rather problematic. One reason for this is the usage of the MSE inside the loss function, which promotes to just learn the mean value of our boundary function. Another reason is the spectral bias of neural networks.\n", + "\n", + "In the following, the problem is firstly implemented the normal way, where all above equations are used to define different loss terms. This will not lead to a correct/useful solution. (Until the first results, no comments will be given regarding the implementation. Since just the basics are used)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import torchphysics as tp\n", + "import pytorch_lightning as pl\n", + "import torch\n", + "import math\n", + "\n", + "# Parameter of the problem\n", + "width, height = 1.0, 1.0\n", + "frequenz = 20.0 * math.pi\n", + "\n", + "def bc_fn(x):\n", + " return torch.cos(frequenz*x)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# First we define the space and domain:\n", + "X = tp.spaces.R1('x')\n", + "Y = tp.spaces.R1('y')\n", + "XY = X*Y\n", + "U = tp.spaces.R1('u')\n", + "\n", + "\n", + "x_axis = tp.domains.Interval(X, 0, 1)\n", + "y_axis = tp.domains.Interval(Y, 0, 1)\n", + "square = tp.domains.Parallelogram(XY, [0, 0], [1, 0], [0, 1])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Create the samplers for the boundary and inside the domain. The boundary samplers, \n", + "# should sample either for the left and right boundary(x_sampler), or for the top and bottom (y_sampler)\n", + "inner_sampler = ...\n", + "y_sampler = ...\n", + "x_sampler = ..." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "model = tp.models.FCN(input_space=XY, output_space=U, hidden=(50, 50, 50, 50))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we try to learn the solution without any extensions of the generall PINN approach, e.g. we just use all\n", + "conditions for training." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "tol = 0.0001 # to not devide by small numbers if y is close to 0\n", + "\n", + "def pde_residual(u, y):\n", + " # TODO implement the PDE\n", + " return \n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def dirichlet_residual(u, x, y):\n", + " return u - y * bc_fn(x)\n", + "\n", + "# TODO: add the PINNCondition for the Dirichlet boundary\n", + "dirichlet_condition = ..." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def neumann_residual(u, x):\n", + " return tp.utils.grad(u, x) # = 0\n", + "\n", + "neumann_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=x_sampler,\n", + " residual_fn=neumann_residual,\n", + " name='neuman_condition', weight=1/60)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 7.9 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "7.9 K Trainable params\n", + "0 Non-trainable params\n", + "7.9 K Total params\n", + "0.031 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "022c52c8dba64f649c72183c081f4f3e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d554be39f5fe42e095af39fc57387e0e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "32b9e76df538477589ad053a87af8bc0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Start to train all 3 conditions:\n", + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "\n", + "solver = tp.solver.Solver([pde_condition, dirichlet_condition, neumann_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=5000,\n", + " logger=False,\n", + " benchmark=True,\n", + " enable_checkpointing=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The training was done with Adam and a learning rate of 0.001 and just for 5000 iterations. But just choosing a different algorithm or lr values will not improve the results easily. The loss will in general hover around some constant value near 0.25.\n", + "\n", + "Having a look at the learned solution, most of the time we either get a solution that is close to zero or has just captured a few oscillations of the boundary function." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.)\n", + " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/problem/domains/domain2D/parallelogram.py:134: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2985.)\n", + " bary_coords = torch.stack(torch.meshgrid((x, y))).T.reshape(-1, 2)\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/utils/plotting/plot_functions.py:416: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:204.)\n", + " embed_point = Points(torch.tensor([center]), domain.space)\n" + ] + }, + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'learned solution')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u: u, plot_sampler, plot_type='contour_surface')\n", + "plt.title('learned solution')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also plot the error, since we know the analytical solution." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'error')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u,x,y: u-torch.cos(20*math.pi*x)*y, plot_sampler, plot_type='contour_surface')\n", + "plt.title('Error')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we want to build the boundary condition into out network.\n", + "We start by resetting our network (defining a new one). With fewer parameters, because we implement the high frequencies via hard constrains and therefore the network now has to learn a simpler function.\n", + "\n", + "For the hard constraints, we create the following python-function, where we choose the ansatz to just multiply the network output with the boundary function:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "model = tp.models.FCN(input_space=XY, output_space=U, hidden=(10, 10))\n", + "\n", + "def constrain_fn(u, x):\n", + " return u*bc_fn(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The hard constraints now have to be always be applied inside our residual functions of the different conditions. One important point is, that our constraints do not automatically fulfill any boundary condition. So we still have all previous conditions.\n", + "\n", + "Choosing for example the constraint:\n", + ", would naturally fulfill the boundary condition at . What we choose is somewhat arbitrary, important for this problem is that the oscillation appears in the constrain function." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "def pde_residual(u, x, y):\n", + " u = constrain_fn(u, x) # plug in output of model to apply constraint\n", + " return tp.utils.grad(u, y) - u/(y + tol)\n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition')\n", + "\n", + "# TODO: Implement Dirichlet and Neumann residual and condition\n", + "def dirichlet_residual(u, x, y):\n", + " return \n", + "\n", + "dirichlet_condition = ...\n", + "\n", + "def neumann_residual(u, x):\n", + " return \n", + "\n", + "neumann_condition = ..." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 151 \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "151 Trainable params\n", + "0 Non-trainable params\n", + "151 Total params\n", + "0.001 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7753517e24194525abfb4610cc530c62", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aa9e3632f6e14203a33d7b398e873ba2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "944d1c463d6a4165823ae9acf8c132b0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "\n", + "solver = tp.solver.Solver([pde_condition, dirichlet_condition, neumann_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=5000,\n", + " logger=False,\n", + " benchmark=True,\n", + " checkpoint_callback=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'learned solution')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, constrain_fn, plot_sampler, plot_type='contour_surface')\n", + "plt.title('learned solution')" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Error')" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u,x,y: constrain_fn(u,x)-torch.cos(20*math.pi*x)*y, plot_sampler, plot_type='contour_surface')\n", + "plt.title('Error')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/backup/BackUp_2.ipynb b/examples/backup/BackUp_2.ipynb new file mode 100644 index 00000000..38b0579c --- /dev/null +++ b/examples/backup/BackUp_2.ipynb @@ -0,0 +1,382 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Backup 2: The DeepRitz-Method\n", + "\n", + "While PINNs usually utilize the strong formulation of the PDE, there are other concepts that use different formulations of the PDE for training the network, one of them is the DeepRitz method. There, the energy formulation\n", + "of the problem is used.\n", + "\n", + "Let us considere the following simple Laplace equation with a singularity at (0, 0):\n", + "\\begin{align*}\n", + " -\\Delta u &= 1 \\text{ in } \\Omega, \\\\\n", + " u &= 0 \\text{ on } \\partial \\Omega,\n", + "\\end{align*} \n", + "\n", + "with $\\Omega=([-1, 1] \\times [-1, 1]) \\setminus ([0, 1] \\times \\{0\\})$.\n", + "\n", + "Then the energy functional for this problem is given by:\n", + "\\begin{equation}\n", + " E(v) = \\int_\\Omega \\frac{1}{2}\\|\\nabla v\\|^2 \\text{d}x\n", + "\\end{equation}\n", + "The solution $u$ of the strong formulation minimizes the energy functional, namely $E(u) \\leq E(v)$ for all $v$ in the corresponding function space.\n", + "\n", + "The DeepRitz method still tries to learn the solution $u$, but now minimizes $E$ in the training instead of using the strong formulation. To include the boundary condition, the functional also is extended:\n", + "\\begin{equation}\n", + " E(v) = \\int_\\Omega \\frac{1}{2}\\|\\nabla v\\|^2 \\text{d}x + \\int_{\\partial\\Omega} \\frac{1}{2}\\|v\\|^2 \\text{d}o\n", + "\\end{equation}\n", + "\n", + "The following cells, show the usage of DeepRitz in TorchPhysics." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import torchphysics as tp \n", + "import torch\n", + "import pytorch_lightning as pl\n", + "\n", + "X = tp.spaces.R1('x') \n", + "Y = tp.spaces.R1('y')\n", + "U = tp.spaces.R1('u')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the square [-1, 1] x [-1, 1] \n", + "square = \n", + "line = tp.domains.Interval(X, 0, 1) * tp.domains.Point(Y, 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Here we create the sampler. For DeepRitz we need to approximate the integral, therefore one usually needs more points\n", + "# then in the PINN approach to get a good estimate.\n", + "# But since in the energy functional the derivatives are of lower order, this generally does not lead to memory problems.\n", + "inner_sampler = tp.samplers.RandomUniformSampler(square, n_points=100000) \n", + "\n", + "bound_sampler = tp.samplers.RandomUniformSampler(square.boundary, n_points=40000)\n", + "bound_sampler += tp.samplers.RandomUniformSampler(line, n_points=10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The classic DeepRitz method uses a ResNet-architecture instead of a FCN. This is also implemented and used here: " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Add the input and output space\n", + "model = tp.models.DeepRitzNet(input_space=, output_space=, width=20, depth=4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The transformation of the mathematical equations is handled similar to the PINN approach. For each integral in the energy functional, we define a condition.\n", + "\n", + "Instead of a *PINNCondition*, we now use a *DeepRitzCondition*. While the *PINNCondition* compute the mean squared error over the output of the residual function, the *DeepRitzCondition* only sums up the output to approximate the interval." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# The integral for the boundary\n", + "def bound_residual(u):\n", + " return u**2\n", + "\n", + "bound_cond = tp.conditions.DeepRitzCondition(module=model, sampler=bound_sampler, \n", + " integrand_fn=bound_residual, weight=100)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# The integral for the inner part.\n", + "# TODO: Following the implementation in the above cell, complete the condition below:\n", + "# Hint: to compute the norm over a batch of vectors called v, the call\n", + "# torch.sum(v, dim=1, keepdim=True) is useful.\n", + "def energy_residual(u, x, y):\n", + " return\n", + "\n", + "pde_cond = tp.conditions.DeepRitzCondition(..., weight=1.0)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 3.4 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "3.4 K Trainable params\n", + "0 Non-trainable params\n", + "3.4 K Total params\n", + "0.014 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0df36ef876cb4728ae2fe7a55a0895c1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f1b2f181ee7047a8966f5ce0be602497", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "01ed1b7d5f8f43c9810c6a1a6cce041c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "solver = tp.solver.Solver(train_conditions=[bound_cond, pde_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1, # or None if CPU is used\n", + " max_steps=4000, # number of training steps\n", + " logger=False,\n", + " benchmark=True,\n", + " checkpoint_callback=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also use different optimizer algorithms, like LBFGS to may get better convergence.\n", + "\n", + "One point we have to keep in mind, is to fix the inputs of the neural network for LBFGS to work." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 3.4 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "3.4 K Trainable params\n", + "0 Non-trainable params\n", + "3.4 K Total params\n", + "0.014 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "abdf252e6a5748958e99c3fc709cb674", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "065a0ddcf6f642d19e3bfd6d616011c4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "29878664f043434a85f42f7560e52485", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.LBFGS, lr=0.05, \n", + " optimizer_args={'max_iter': 2, 'history_size': 100})\n", + "\n", + "pde_cond.sampler = pde_cond.sampler.make_static() \n", + "bound_cond.sampler = bound_cond.sampler.make_static() \n", + "solver = tp.solver.Solver(train_conditions=[bound_cond, pde_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=2000, # number of training steps\n", + " logger=False,\n", + " benchmark=True,\n", + " checkpoint_callback=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.)\n", + " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/problem/domains/domain2D/parallelogram.py:134: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2985.)\n", + " bary_coords = torch.stack(torch.meshgrid((x, y))).T.reshape(-1, 2)\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/utils/plotting/plot_functions.py:416: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:204.)\n", + " embed_point = Points(torch.tensor([center]), domain.space)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=640, device='cuda')\n", + "fig = tp.utils.plot(model, lambda u : u, plot_sampler, plot_type='contour_surface')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/backup/BackUp_Sol_1.ipynb b/examples/backup/BackUp_Sol_1.ipynb new file mode 100644 index 00000000..da342342 --- /dev/null +++ b/examples/backup/BackUp_Sol_1.ipynb @@ -0,0 +1,594 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Backup 1: Applying hard constraints\n", + "\n", + "For some problems, it is advantageous to apply prior knowledge about the solution in the network architecture, instead of the training process via additional loss terms. For example, in simple domains a Dirichlet boundary condition could be added to the network output with a corresponding characteristic function. Since the boundary condition is then naturally fulfilled, one has to consider fewer terms in the final loss and the optimization may become easier.\n", + "\n", + "Here we consider the example: \n", + "\\begin{align*}\n", + " \\partial_y u(x,y) &= \\frac{u(x,y)}{y}, \\text{ in } [0, 1] \\times [0, 1] \\\\\n", + " u_1(x, 0) &= 0 , \\text{ for } x \\in [0, 1] \\\\\n", + " u_2(x, 1) &= \\sin(20\\pi*x) , \\text{ for } x \\in [0, 1] \\\\\n", + " \\vec{n} \\nabla u(x, y) &= 0 , \\text{ for } x \\in \\{0, 1\\}, y \\in \\{0, 1\\}\\\\\n", + "\\end{align*}\n", + "\n", + "This problem has the simple solution $u(x, y) = y\\sin(20\\pi x)$. But because of the high frequencies of the sinus term, a training of the boundary condition is rather problematic. One reason for this is the usage of the MSE inside the loss function, which promotes to just learn the mean value of our boundary function. Another reason is the spectral bias of neural networks.\n", + "\n", + "In the following, the problem is firstly implemented the normal way, where all above equations are used to define different loss terms. This will not lead to a correct/useful solution. (Until the first results, no comments will be given regarding the implementation. Since just the basics are used)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import torchphysics as tp\n", + "import pytorch_lightning as pl\n", + "import torch\n", + "import math\n", + "\n", + "# Parameter of the problem\n", + "width, height = 1.0, 1.0\n", + "frequenz = 20.0 * math.pi\n", + "\n", + "def bc_fn(x):\n", + " return torch.cos(frequenz*x)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# First we define the space and domain:\n", + "X = tp.spaces.R1('x')\n", + "Y = tp.spaces.R1('y')\n", + "XY = X*Y\n", + "U = tp.spaces.R1('u')\n", + "\n", + "\n", + "x_axis = tp.domains.Interval(X, 0, 1)\n", + "y_axis = tp.domains.Interval(Y, 0, 1)\n", + "square = tp.domains.Parallelogram(XY, [0, 0], [1, 0], [0, 1])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Create the samplers for the boundary and inside the domain. The boundary samplers, \n", + "# should sample either for the left and right boundary(x_sampler), or for the top and bottom (y_sampler)\n", + "inner_sampler = tp.samplers.RandomUniformSampler(square, n_points=50000)\n", + "y_sampler = tp.samplers.RandomUniformSampler(x_axis*y_axis.boundary, n_points=20000)\n", + "x_sampler = tp.samplers.RandomUniformSampler(x_axis.boundary*y_axis, n_points=20000)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "model = tp.models.FCN(input_space=XY, output_space=U, hidden=(50, 50, 50, 50))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we try to learn the solution without any extensions of the generall PINN approach, e.g. we just use all\n", + "conditions for training." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "tol = 0.0001 # to not devide by small numbers if y is close to 0\n", + "\n", + "def pde_residual(u, y):\n", + " # TODO implement the PDE\n", + " return tp.utils.grad(u, y) - u/(y + tol)\n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def dirichlet_residual(u, x, y):\n", + " return u - y * bc_fn(x)\n", + "\n", + "# TODO: add the PINNCondition for the Dirichlet boundary\n", + "dirichlet_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=y_sampler,\n", + " residual_fn=dirichlet_residual,\n", + " name='diri_condition')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def neumann_residual(u, x):\n", + " return tp.utils.grad(u, x) # = 0\n", + "\n", + "neumann_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=x_sampler,\n", + " residual_fn=neumann_residual,\n", + " name='neuman_condition', weight=1/60)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 7.9 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "7.9 K Trainable params\n", + "0 Non-trainable params\n", + "7.9 K Total params\n", + "0.031 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "022c52c8dba64f649c72183c081f4f3e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d554be39f5fe42e095af39fc57387e0e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "32b9e76df538477589ad053a87af8bc0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Start to train all 3 conditions:\n", + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "\n", + "solver = tp.solver.Solver([pde_condition, dirichlet_condition, neumann_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=5000,\n", + " logger=False,\n", + " benchmark=True,\n", + " enable_checkpointing=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The training was done with Adam and a learning rate of 0.001 and just for 5000 iterations. But just choosing a different algorithm or lr values will not improve the results easily. The loss will in general hover around some constant value near 0.25.\n", + "\n", + "Having a look at the learned solution, most of the time we either get a solution that is close to zero or has just captured a few oscillations of the boundary function." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.)\n", + " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/problem/domains/domain2D/parallelogram.py:134: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2985.)\n", + " bary_coords = torch.stack(torch.meshgrid((x, y))).T.reshape(-1, 2)\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/utils/plotting/plot_functions.py:416: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:204.)\n", + " embed_point = Points(torch.tensor([center]), domain.space)\n" + ] + }, + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'learned solution')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u: u, plot_sampler, plot_type='contour_surface')\n", + "plt.title('learned solution')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also plot the error, since we know the analytical solution." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'error')" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u,x,y: u-torch.cos(20*math.pi*x)*y, plot_sampler, plot_type='contour_surface')\n", + "plt.title('Error')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we want to build the boundary condition into out network.\n", + "We start by resetting our network (defining a new one). With fewer parameters, because we implement the high frequencies via hard constrains and therefore the network now has to learn a simpler function.\n", + "\n", + "For the hard constraints, we create the following python-function, where we choose the ansatz to just multiply the network output with the boundary function:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "model = tp.models.FCN(input_space=XY, output_space=U, hidden=(10, 10))\n", + "\n", + "def constrain_fn(u, x):\n", + " return u*bc_fn(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The hard constraints now have to be always be applied inside our residual functions of the different conditions. One important point is, that our constraints do not automatically fulfill any boundary condition. So we still have all previous conditions.\n", + "\n", + "Choosing for example the constraint:\n", + ", would naturally fulfill the boundary condition at . What we choose is somewhat arbitrary, important for this problem is that the oscillation appears in the constrain function." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "def pde_residual(u, x, y):\n", + " u = constrain_fn(u, x) # plug in output of model to apply constraint\n", + " return tp.utils.grad(u, y) - u/(y + tol)\n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition')\n", + "\n", + "# TODO: Implement Dirichlet and Neumann residual\n", + "def dirichlet_residual(u, x, y):\n", + " u = constrain_fn(u, x) # again apply constraint\n", + " return u - y * bc_fn(x)\n", + "\n", + "dirichlet_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=y_sampler,\n", + " residual_fn=dirichlet_residual,\n", + " name='diri_condition')\n", + "\n", + "def neumann_residual(u, x):\n", + " u = constrain_fn(u, x) # again apply constraint\n", + " return tp.utils.grad(u, x) # = 0\n", + "\n", + "neumann_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=x_sampler,\n", + " residual_fn=neumann_residual,\n", + " name='neuman_condition', weight=1/60)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 151 \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "151 Trainable params\n", + "0 Non-trainable params\n", + "151 Total params\n", + "0.001 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7753517e24194525abfb4610cc530c62", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aa9e3632f6e14203a33d7b398e873ba2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "944d1c463d6a4165823ae9acf8c132b0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "\n", + "solver = tp.solver.Solver([pde_condition, dirichlet_condition, neumann_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=5000,\n", + " logger=False,\n", + " benchmark=True,\n", + " checkpoint_callback=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'learned solution')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, constrain_fn, plot_sampler, plot_type='contour_surface')\n", + "plt.title('learned solution')" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Error')" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEWCAYAAAB1xKBvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABXvElEQVR4nO29fZgkV3nY+3t7ZqdnekZiVrtivKsFr5AWLrKwBawlbK6dkcEgSIJI+Ajc2BY2QhcH5eM62IYHX0QkOwEMIXHAIbJRjImJ+IgNi69sWYDGJGAUrSyBJQHWSlpgtcvK2t0RzM5sz/T2e/+oUz2na6qqT3VXdVd3n9/z9NPd1dWnTlWdOu95P857RFXxeDwej6cTlUFXwOPxeDzDgRcYHo/H43HCCwyPx+PxOOEFhsfj8Xic8ALD4/F4PE54geHxeDweJ7zA8Hg8Ho8TXmB4SoWIHBaRNRFZsV4fHHS9PB4PTA66Ah5PDP9QVT+ftoOITKpqI7JtQlXPuh4k6/4ez7jjNQzPUCAibxCRL4vIB0TkBPAuEfkDEfnPInKbiJwGrhSRZ4vIkogsi8gDIvIKq4wt+w/shDyeIcQLDM8wcQXwCLAA/JbZ9n+Zz+cAdwGfA/4CeCrwz4E/EpFnWWXY+/+v/lTb4xkNvMDwlJHPGA0hfL3JbD+qqv9JVRuquma2fVZVv6yqTeAyYA54t6quq+oXgT8FXm+V3dpfVc/07Yw8nhHACwxPGXmlqs5br98z278bs6+9bTfwXSM8Qr4NXJCwv8fjyYAXGJ5hIi61sr3tKPA0EbHb9dOBxzqU4fF4HPACwzNK3AWsAr8mIttEZBH4h8Ctg6yUxzMqeIHhKSOfi8zD+BOXP6nqOoGAeBnwBPC7wC+o6jcLrKvHMzaIX0DJ4/F4PC54DcPj8Xg8TniB4fF4PB4nvMDweDwejxNeYHg8Ho/HiaFLPrhz507du3ev8/6nT59mdna2uAr1AX8Og2fY6w/jeQ733HPPE6p6fi/HfKaInnbc9yjcrqpX9XK8MjN0AmPv3r0cPHjQef+lpSUWFxeLq1Af8OcweIa9/jCe5yAi3+71mKeBf+a472/Azl6PV2a8Scrj8Xg8TgydhuHxeDz9pALMDLoSJcFrGB6Px+NxwmsYHo/Hk8IEcO6gK1ESvIbh8Xg8HicKExgicouIPC4i9yf8LiLyOyJySES+LiLPK6ouHo/H0y2hD8PlNeoUqWH8AZAWj/wyYJ95XQf85wLr4vF4PJ4eKcyHoapfEpG9KbtcDfyhBulyvyoi8yKyS1WPFVUnj8fjyYr3YWwySKf3BbQvl3nEbNsiMETkOgIthIWFBZaWlpwPsrKywvsPLFGZa1CrrDHLaWZYZY7TVNfXYR1oWi+s90lgGppVqMs060yxxgzrTLUdo2L+ICgTnGWCBlNsmM9nmaTR2rdplLomFRRp2wa0ttk0V3bwp0sfbtumCE0qNFvvFdS8b9an2fo8aeoS1mdCG1QawFkCPVOgOQlNqXDW7N2kwgaTNJikwTbOMsE62zjLZNs5TrLR+lyl3l52A1iHlcoelv74/TAdXNONyiR1qmwwSZ3pVu0a5rhnTdOscoYq60xRp8o6Veps22gEZdv3y75/U8Ex6pUp1pkyJVSpR+4brd2Ds6xyhm00gmM0G0HbCG4wK2f2sHTH+2ECmuYWbcgUZ5lgg200mGCD4HvYJsTckc07tHmXJPIetgG7TYSfxSwSWGFz5VlB29qK/f8mlbbrGF7b2ZVt/LelW1v3LLizZ83dXWdyowkbwf1ineAzwDagFrzWKtOcoUqdaVaZYYMpGkyy3txGc30SzgTXf6a2ylN4knP5Puc0V2CZYAbc+ubr7Fk4o0ETmQDm5oAFqM9P8QQ7Ocl5rB+vwjI8/1lBVVZWVjI9/558GYooKVW9GbgZYP/+/ZplpufS0hJvrSwyt/8JLqvdy34e4DLu5cf4ChcfOwL3ETRmgDpBowaYBc4D9sDpfRUerl7Mt3gWh7mI4yywzDxT1FvHqbFGlTrzLDPPMrs5yrnm8w5OtPZbM5bOVWrmkFOsmc/h9yj1pX/KuYv/tX2b+V+DKqvMsEatrawZVqmaHm+GVbaz3KrPbo4y//0VJk+Y850FpqExC8vnzlGnygl2sMw8j7LX/Gs7R9nV+lylyS6Os5tjzHOK3RxjgeNcxMMsfP9EUPZJ4HFgFZZq72Nx9a3BPNh98NiuHRxlF4e5kG9xCcvMs8pMq/xVpgG4mMfYy2H28ijnc5iLeJgLjp2AsPzTbHZs4bksQGMfHD53D4+yl8e42JSwt+1ah9fGrvsO+xy+Y7Wjo+9j8dK30jBZKerVCsequznKbpaZZ4V5jpnPdapUqTNj2kR4L3ZwgnlOUWW97f5E72vQTmpt3+17GX6328papD2tMM8aNXM95znFPD+xtJuvLR5ubdnNMeY4xQKPc1H9ELNHm8EQ7jsEi93az8JzgGfDoV3BNf0W+7mXyzjMhRxlN0eP76L52CwcBn4ILn3e3byYr3Mld/Lj9c8ze1sT/jfwEPANWDsBh0/DIWAFuBi44oXAm+HQK/fwVf4pv8+1HPnDi+F24JdBm4OZrV4BzunrEcvLIKOkHgOeZn3fQ/vay7lwzwlgDmq11bbtq9SCh3+WQFCcJOiEzpgXYPqsNsIHFmCdauzv9j5ZiBMWcZ1KehlBnUIBEqXWoW4z9dUt+61RM5pVta3DDb4HwmqVGdMJ1pk8TdDZ2B2OzRmoWsK2vbxa63MSYafN6aAsThPcvzrBPUv4a4016lRbr3BbInXzsuo9GZNUqG7Vux5z8KiQSsP1fidpS2lUjKZi37O2uoX3LDzn8PmA1nMxE3O91pmiWTfnPZdSAaus46fhOPB9YA1YANgR/Bweo8Yq/JDZvgNE7nI/WU8hDFJgHAB+wURLvQB4shD/xQQwDVOsb+kc6tXKZiMOR9un2ex0Ih1d2MlVqbNqxUSE5cY9TDZrGeMo7M7DFkKdOou4Tivbcds1p7DM8JzD31eZaXW+bdf2DGyRB2FLc8jitmrErk1ipxsKiw7l2vcmWrYTm9agWKEBtDSL8PqsmeuztS7x2kV0n/ay2zUPF6LtxDZphWUlDm52RF7m2YgK+lVmWF216hQzyGqjGuyzRjA6DIXGuZO0CahQW2cPcD4mBGkwngQfJbVJYSYpEfnvwCKwU0SOADcQWENR1Q8DtwEvJ9BKV4FfLKouzDWomdFv2ODrTLFWrTFbXdkckdbZFBT2yyJ80KPCJ27EHBIVFKsZHnrY+qDnhmsKzgh2J7PKTPBgJxFev7r5fKb957Dz7tSJz7BqzC0z1KsVJmebQXmhVgiBCdHcs3q10vZfoGVCXDcCbobVNrNiIhEtI65TTBLia8ykto04ouamTthCpMp6rFAJ22toKkscVJwhUUOLO41QE6xU6zSnJwP7UhJWueHdDrWL886jJZzC56V1b+ZI11w8faPIKKnXd/hdgbcUdfxOtB4qWzCEnRpsdgqdRkwZySosspBl9JlX+Wmmo6yEGkueZfZM6BeJUK03mamutcxwQUfd2xizxuqW9pFVeIT71lgzpsTObWKLmTJjBvRabZXVH7Sf+7rRSOtUg4HZ9Mpm2ZHyZyB4zsxv4TWosQZzDYbE1ToW+DvhwFq12I44DtvJmTZoGwRxpowt9vAeiRMaWf05LmWG2gY4mKoShAckBCsYE5ULYacdJzSi2Nc/yzUPo60KxWgCsZpb5NplNzANxujjw2o3Gf3UICU+w6yOyzRnejdO0BZdmqaidHT253ScfpDkp3DBdqr3SrKpa6v2kKUNOJvJpq1XJ+YabV/TAgrONUPVGUxnPEuyKSysh2fgjIWGUalmsyG3Gm5CA+7k3E6iSHOUjYvdvNUhhn6bM7SNALs9xy3EdbwlERxr1NKjpGxS3Ei2cOhGUHSKXNsse6pnLSvuvra1y2kS/TRlshT2E5/efJMSj78HQB8fiJ40goKIG1UnOaWL9pfAph08DAPN65rFRWHF4iDYOl2HTgLEVVhsltfdNcjkeO9iNF87xxJE1v9jj5t1ldgR0i5E5CoR+ZbJofe2mN+rIvIJ8/td0WwZIvJ0EVkRkbda2/6liNwvIg+IyL+ytr9LRB4TkfvM6+W91n8sNIy86HZ+xSCoU+1rfZ1H6kWQ0rH3OiKPLT+ijXUiL/NUt8ywluiQbxN4/Vju27oU59DZN1Cp1mm2uqnBhdWe69pTNpJ/EpEJ4EPAzxJktrhbRA6o6oPWbm8ETqnqxSLyOuA9wD+xfv/3wJ9ZZV4KvAm4nGAO/Z+LyJ+q6iGzywdU9X2Ote+I1zCg6xGMU0hmDgiaT8fnQLWeHsLbVed3pvMuLsReg3rC5wS6moORAy6aQZIZsBdfRdGDhinqTNn3xTxLnQYQMxHB0ZHRCKu9HDikqo+o6jpwK0FOPZurgY+az58GXiQiAiAirwQeBR6w9n82cJeqrqpqA/hL4B8XdQJjIzCcO/eMwsN1ZN2N/6JwDaE/8q44SuILKQMuQiScz2ObiVrRVo6RgIPWlgZBpRIIOJcXwbyzg9brOquopPx5xO1jBMCTwA4RmQN+Hfg3kf3vB35KRHaISI1gbpudQeN6s3zELSKyvbcr4U1SXdOLdhGXA8imkzaRFpvf61wACNKD1KtbO4ZoZ2E7jdtG7nEdeTPltzzJu/xoKG3ku6tQj7untv8i1C7itIy4NpK3DyxMCdMLlWqd5kpKl5I2GAuvqWliw2T+jfCEqu4voNx3EZiXVozCAYCqfkNE3gP8BUHrvI8gNScES0bcBKh5fz/wS71UYqwFRtABJsxyyGDP7eRQ7Fd0VJQ1an0zZW1h2AQDxfphuu3g7ZQgfelEi/Jj2OW2hEJy9FGbkGyZowZjTqxUYMb1uqS3S5f8eeE+R0RkEngKQT6DK4BXi8h7gXmgKSJnVPWDqvoR4CMAIvJvCTQXVPV4WKiI/B7wp45nkcjYmKQ6MkKRGMNApxFtT0K2JKaqQflLiiY29Yid3NOaj+Fiwoq7SkOsYaRxN7BPRC4UkSngdQQ59WwOANeYz68GvqgBP6Wqe1V1L/AfgH+rqh8EEJGnmvenE/gvPm6+77LK/UcE5queGGsNI09ym7fQB/IwPxTJoDrajscN56wk/rz540gKi8goO1Yjm0sJE+qFQbpOKuQyoFTVhohcT5CwfQK4RVUfEJEbgYOqeoBAU/iYiBwiSKv5Ooei/4eI7CBI9P8WVV02298rIpcRmKQOA/93r+fgBUaOxJmm8phsVTaypLzIyuCimAbXI6UNNpKSCXZ7jKT7tlatMVtAEpqk483MslUT7Gj2GX4hrKq3ESRetbe90/p8BnhNhzLeFfn+Uwn7/XzXFU1grExSZVBze3VWluEcbEZyJN0jna5JtwOIbgVHXKfdSzuK/jdp8mGssLDCY8/F52gaNkZfw8hRJOY9u9mlPJfOpR+zrnOhg0lnaM5jgGRxfocp4Z1xNLvY96nGWiupY+2cNVbqXWpqZY7WrdCfSY1DwFhpGN3Q8A2lewpyPneaXNgPkpITumpccaNyVzPfMAjW1LDzyCS8JC2jKLOnp3tGX8PIwrgKB3sdEE88XcqojgtMdUkeYbax/4/zLWQkc7JPF84BpONexeA1jBZew4gjoXGUzX8QpSvHbUlCUPtJqRZo6oGsmobzehjRFScjix7FPQdTLn4Z+7ky5q9OaUFq56z5kPcS4TUMjyeJPgjTYQrHdiGLdjE04RJCuX0sfWQsNIy21MtR/OjF48lM19p2jPY+A4FfYzr+d0958BqGZyzpaJbKKcNuVqrUM+UD61vKkB7YkoKn29H6oAZ3E4xKttyeGQsNY9wYu4yiPpgmE3kLmDAiqi09SJSo5pBVk/AddinwGoZn+BkB+VhUCGk4UzzP8uPWE0+vQ/KxnXSpQQsL78No4TWMESRT5zCmNuN+LX41anSTPj9J43Vexc5TGvwt8xQ3esohpr8IRk1Y9M2PEeNDmKK+ZbJiapBJDG2CI9JearXVAjJcZWSCsR1YRfEaRhTfMIojJ8FUr/ah2frouY7YgjecuZ5VWGwh7fnzz+bA8QJjhBj2VAqli/YZkQ4q03V1FOq536tOx/U+hFLgTVKenihylTpP/qR19I1ZmDxBe+ccMwZxERax7aLKlo5/KLLVeqd3C69heDJTpCbjBdBgSAzFrhLb0feESTUy06HMlmCaa20YekTkKhH5logcEpG3xfxeFZFPmN/vEpG9ZvvlInKfeX1NRP6R2T4tIv/bbHtARP6NVdaFpoxDpsyeF4L3AgNGxvQwKpRSaPgnpSNO+aRi6CQ4Bk6FQGi5vFIQkQngQ8DLgEuA14vIJZHd3gicUtWLgQ8A7zHb7wf2q+plwFXAfzFrfteBn1HVHwMuA64SkReY/7wH+IAp65Qpuyf8Y1ByXNYzKJ3t34G1aoEpuv0AYDgZ/ft2OXBIVR9R1XXgVuDqyD5XAx81nz8NvEhERFVXVTVc/3aaYNlVzHrfYSDZNvNSERHgZ0wZmDJf2esJjJ3AGPZkb8OwFgLQ88OftIpbWRjndVKibTBvjTB2kNQprW2RhGG1Li/YKSIHrdd1VkkXAN+1vh8x24jbxwiIJ4EdACJyhYg8APwN8OZQgIjIhIjcBzwO3KGqd5n/LFtCJu5YmSlUYDjY654uIneKyL0i8nUReXlRdSmlmaNg8tY8or6LxPLjOtNKym/d4FhOr0vijgN5X6PUFCERWm6JhPvZrZlrgDyhqvut1815Fayqd6nqjwA/DrxdRKbN9rPGVLUHuFxELs3rmFEKExiO9rrfAD6pqs8FXgf8bu4VKbEOVVZTUqHmopLSrSN/aDS+EjIzLPmkwigpl1c6jwFPs77vMdti9zE+iqcAJ+wdVPUbBNkcL41sXwbuJPBxnADmTRlJx8pMkd2pi71O2YysewpwtMD6eAwtgdCFs7FUcz3iOpwBm4rKrMlWul02MAOJ2kU18tn6nllwDC93A/tM9NIUwSD5QGSfA8A15vOrgS+qqpr/TAKIyA8D/wdwWETOF5F5s30G+Fngm6qqBMLj1aasa4DP9noCEpSbPyLyauAqVb3WfP954ApVvd7aZxfwF8B2gkf9xap6T0xZ1wHXASwsLDz/1ltvda7H8e+vcHRumpnKGaaoM0PwXmWdKnW2bTSCOINVAvE1QTA7ZRKYCt4blQobTNFgkjNUabCNDbYBwUMoaNv7BA0mOcsEZ1vbQzSyzmTTktnhb+H+4QPeWDmfbXOPo0hr//Bz07yfZdK8T7T+O8HZ1l5hfbaxEdRvowlnCZYerZiXBOffqFRQKtSpUmeKDaZYZ4p1c84hFVN2lfW2azu53oSGKdv0USvNPcw1jwTHmYbGdIV1qqwxzTpVNthGgwnOtmo6wQRnW/cqLH8bG2zTdSobwDpBGvLQajEVlM0UNLfBhmzWe92cS53pVtnBfQru1SQNs1ekXZjrs9Lcw9zkkc1rNQkblUk22NZ2jaL3FDDX/CzbWG8dK7y34btYnXl4L7V1byeizXoLtjCw20VQTvBeXZlhY24z98YEDaZaddtgW7NBqgVoAurbpjjDNHWqrfezTLTq2TRtuMYac6xQY5Uaq2w70wiesfB+1YPP6w2YmiQYNp4TvK9OzbDCHCvMcpo51leqsAw8Cc/64RXm5txVjSuvvPIeVd3v/IcY9u8RPfgv3PaVXyf1eMbs/h8IeppbVPW3RORG4KCqHjBmpo8BzwVOAq9T1UdM//k2YIOgVd6oqp8RkR8lcGhPELTMT6rqjeZYzyAYqJ8H3Av8nKr2NOIb9MS91wN/oKrvF5GfAD4mIpeqattQyNgBbwbYv3+/Li4uOh/g/bct8a4XXMoltQfZy6NcwjfYy6Ocz2Eu4mEuOHYCHgIeIWjMOwgu77nA06CxA5bPneMouznMXk6wm+MscJRdQPBgVKkz03pfZZ5ltrPMuSwzwypV6ymM2ottk0b4W7h/aLJ6YunNXLD4O9SZau0ffm5QZZUZlplnjRp1qqwxwwxrzHOKKuvMsNqqz26OMs8yO4+tBEprnWC0NwtMw+nzKqxVg3Ie5iIeZS/H2N16t5lhlRpr7OUwe3mUp/MgF3KYnY+uBE39NK3cQEv197G4+tbgOHvgiUvneJS9PMglHOZCjrKL5bYrN888y233bIHD7OYou+pHmT3aDFyDx4HvmArtA54a3LfTuyscq+7mqKn7YS7kMHs5xEWtsrezzA5OMM8yCxxnF0e3tovTwbVZWnkfi09/a3Cc2aBdHD93Bw9zEadZ4Bi7OMyFAG25lWqsMc8y85xiN8eY4xQLPN5y6odBGLbmtsw8q9Ra93iZ+YTWvcm0Zd6028WaVc4zlp7LscUvt/abN+1hgcfZwQkWvn+Cye/ElW7YAYd27THX85LWvVvmXNMGt7eE5mXcx0/yNzyXe7mEe7jg/hNwH4EN4RsE1/YhOPw47H0q8CLzej7cfeGlPMRP8hV+kq/wYxz50sXwFeAzcOfvLpHl+S8bqnobcFtk2zutz2eA18T872MEgiS6/esEwiXuWI8QWHpyo0iTlIu97o3AJwFU9a8Ixoc7C6zTwKn2yYnXq+mom6ykeTNFvbOJJzRtDLlZYyzWMIm5R5ky1vr8XgOnSIHhYq/7DsG4AhF5NkGT+LsC69R3uhEQwxDZ4+yw79CR52LzTzlG9FpmPl4XgqjMfox+USpfV68YM6rTa8QpTGCY+N/rgdsJlNBPquoDInKjiLzC7PavgTeJyNeA/w68QYtyqgwhRUbgtOYRhAPb6fS5BUV1gtHU2INkEB39oDS5RDNpD5pa5rkzY9DBjhqF+jAc7HUPAi8ssg6jgCJtD3WcBhKurNYV/RIUs5H3YSRSd1vTqlLv2bQ0FqYpaA+RnWYzcqqMQqTCcLfZHCnxLAVPt5RmNntJH7J+aBLRY/TLd5ULm7OWU0m6jnlOtqux6pyryVM8XmCElLRzy5vVHMxcSf6LbjScrR1rEPxa9Kp4mYTGmLSNLUQER5LJMvO9sjr+0icehKCXzGfi3tDjBcYAsEebZZ3tHUdaXWuspZ9L2NJSTA5Fj/z7vTRr2vnkIbj7hqPGAXlrFyXRlD0tBj0PY6SoU43tNGuslrODyGHN7SkzvW8LVWIX3+mFvKPHOgrrpOtjCT2fGmQM8D6MFl7DGCLK0DnZnWyeI8BBjSb7rXXAYMKm89Rke2qHtobpO+Ghw2sYJSfLwznDau5RNrmEvc4SpHYoirATKrID6sPQatARUvVqhcku803VWGO92/q73rdBXR6hnNFbA8BrGCWlyFFo4R1TPx+uaGeTk9BwWe+iDLPhhxbTBMco8eBIMBYCI0t+/m7p1HlEJzUVFWaZeYZtlzOxk7ZvEUZ2+QmCJKnOHc1USXXPKLBGalZyn8nt2kVCZrc8H4Mc4WdbQGmkGQuB4elAh4ex6EiurjSeDnVOWtOjmjVkdzbhsyc7GTr9Ng3bm4NKgxcYY0DcXIcojdnAhh1mqi2aIKtujVVmYusT1jmuc+9mgSevRRRPeK9iU4S4CF5r+1BNdBwjvNN7CIiur9CJTp1jIBBWUvdJK9M5oskOrbWXaO0wYuzJgWqRFsrcqwCpV93vSadjhenox45ZImvJdWBQ63r7sNoWXsMYErKGMobrcCSZk+rVSmZVv4jQ12iZXZu/SvJAj7sms7nOR4b7WJJ71w9E5CoR+ZaIHBKRt8X8XhWRT5jf7xKRvWb7DhG5U0RWROSDkf9MicjNIvK3IvJNEXmV2f4GEfk7EbnPvK7ttf6jr2GUWCRWWY9dUCntYStz6vNuhFouFN3h2MpOnx3qZb7fPRHesw7Xs2WSHGQeqXBN716LEZkAPkSwjOoR4G4ROWCSsIa8ETilqheLyOuA9wD/hGB5t/+XYB3vS9tL5h3A46r6TBGpECwBF/IJe5XTXilxd5o/g041kDX9cxk7C/saRhc4ahMAXTiLXZzRW8xM0wmfHXBenCkjo65lRAV93HVMHDyMkTYRw+XAIVV9RFXXCZZPvTqyz9UES64CfBp4kYiIqp5W1f9FIDii/BLw7wBUtamqTxRT/TETGEUx6AlXPTGgCBSXTjXcJ1MHnHIrXAcMecyvcKlzKdPF5IQtVHKbrzIoLSP0YbiF1e4UkYPW6zqrpAsIFhYOOWK2EbePWVPoSYKFo2MRkXnz8SYR+WsR+ZSILFi7vEpEvi4inxaRp8UUkQkvMDz9wxpddhKyTqGv/ZTTHZ6UwF80HI7rUkYgjY7m8YSq7rdeNxd8vEmC5a+/oqrPA/4KeJ/57XPAXlX9UeAONjWXrvECw2ZI473DTLFpTu40XGY1R4kNd40bMZdQ+erVNOl6vUbdNNUzrm1jrlFoNTqS3xKtjwH2KH+P2Ra7j4hMAk8hPZbsBLAK/LH5/ingeQCqekJVw0b4+8DzO9awA15glBC7403yY4T7lLFTcu1Q7fMc1HmEwiNR0Dp2ar36m6JmmzpTzkEEZUiRn2kypH1NZ9u/J7adIR3MRbgb2CciF4rIFPA64EBknwPANebzq4Evpi1bbX77HLBoNr0IeBBARHZZu76CYKnsnhj9KCnDILKSxtFLqvNC80tF5hWk1bGra2nPw+hAlXq2pIcZtJgiEjTmSaArDtC3MU28W7UHujXVbWlnA7ptWulOC99SjmpDRK4HbidIOHKLqj4gIjcCB1X1APAR4GMicgg4SSBUABCRw8C5wJSIvBJ4iYmw+nXzn/8A/B3wi+Yv/0JEXgE0TFlv6PUcxkZgeLbSmIXJDOthTFHPNqEuh/U2Bh3Z1kbKKLeUfoFucRAaaec7FQlWaGlPdqdbXpldKKp6G3BbZNs7rc9ngNck/HdvwvZvAz8ds/3twNt7qO4WvMBIYoidcC4mirVqjWp9Zcu25DLXOMV818ezSRut1VhzMsU0ZmEyatmd7Vx+SKc695LqeySwhWOC8IiaEfOaoV82tJJlZv9otxnvwygBnTovRTKbo1xHvNHONclcE44SuzJHFdmH5CDYO5pMChw82Oan0qZLd3PobqGj6S8aJhtzjFJpmJ7xEBh5rjM8CuTVMaU+zHEdTMm0to7Cr2T1LZJu20R0sNPxmibJkBTZUqnWBzvT29Ni9E1S3YjEgiMyXBzfnVKEuBD3/zpTzjPOba0mySTVMbqpSz9GGCrszGz7e9rotpeIrDhzVxkj1YaGWdyFwYCSDzalkiFDcraknsPGWGgYnnSi9tnSmkaS6IcmIO1fkzqQqHlrJqvgy0g/Q2qzZOhNZYw0t1HDC4woo+ezK4Qkc1SisAlbWsz1DTu9jnMionTR8WS2iXdxjGGZ8d0NWUJ+2zSvIZ5HEfgQq06vUccLDEfKmAgwjizhnfaIMcuiRJ063awj0axZbrt9MIsyHcXVZ5SFhmd88QKjxCR1pFk72LzIPDpPGVXamkhPZhWHrLhx/pDwXLoRIq4C0VVodDtRb1AzvKPtrytBPERO7CYV1oxxsdNr1PECY0BkTXXuQtiB2FpG3mGJXZUXduQOikF00lcSaZ321lnrxTzIWTr6aOfeq8ZahnQgPeOoKNbOWQsEzBCbtUaF0Y+ScqVKz7OSuzvs1kWU0shbu7A71yRTT96zmOM6+xnWthzfWTj1qSPpNCGwSn0s7NhxRCftZVrGt0qpHeFNKiOdij4LhWoYnZYjNPu8VkQeFJEHROTjRdZnGCnK/FR0x5ZH7p2BMx15T6DfYbWD1i4GfXzP4ChMw3BZjlBE9hHkOnmhqp4SkafmXpGKw1T9SAy/J6CTZuHUUcbkJarWm32NRquxxrI1hyTvDs9F+K5Ry8U8WObOesokjczTDFqGpKHNLjItjCpFahguyxG+CfiQqp4CUNXHi6hImr9gmEbCRWkbdoRUkuOu51G0la02t3j+Hknr2LJEjeVBaPIYBtNHWjtMFRa9PmtD5CgfVSQl1XpvBYu8GrhKVa81338euMJekFxEPgP8LfBCgnS/71LVP48p6zrgOoCFhYXn33rrrc71OP6DH/DEOZNMsc421qmyzhR1qqxTpc62ZiMYAZ8hyBtWIdC7rNdGZZINtrHBNtbZRsN8BqjQRNDW5wnOMkGDSc6az2epJCQka5peVBGaVFrvW1jZDnOnEs+xaf3P/n+FZuvYFbRVF0GZpMGEBgvTNCWsR6WtnEawlzmbSRqWQho957Yro+tUFDhrdlZYObOHuakjUIHmNtiQKXNNJ9lgqnW1mqaGDSaZpME2Gq3yp9gwtQjqXmkAGwTJmzH3axs0J+GshHsG57BBcLzg7kxQockkZxFz1vY5hJ8nN5qggJj6zx6haSbwNaXSqndYq7NMotEZftBqE+ExJ8yFCa+hfb86tYmkttTeHiqtNhGUEfx/28osG3OnkVabaDLFRqudbtP14JomlTsJdZlm3Xqa6ky1jhHWF2CaNaapM8Ma05yhurEe3Ksz5p6tm1fD3Lc5AoFSg9XKDKepsRbGtzVnaK5Owgo8a26FuTl3yXHllVfeo6r7nf8Qw7P3z+gfHrzYad/L5f6ej1dmBu30ngT2ESz+sQf4kog8R1WX7Z3MMoc3A+zfv18XFxedD/D+z3+Rmxd3spfD7OUouznGXh7lfA5zEQ+z8P0TTD5EsLRIncBUsgN4KnAeNHbA8XN3cJRdHGM3J9jNcRY4SrA2SY211uh7hjXmOcU8y2xnmXNZZp7lVA1nlVprsZykRXN06dXI4qcTy2gYk8gqM63/RyfDValzLsutlfl2cIIqdWbqq63RdJ1qS8NYpcZxnsoy2znBDpaZ5zibSwXb57zAcXZwgh0cZzdH2VU/SrXe3EydfgaWHnofi7vfCrNweneFY9XdHDXX8hi7WGY7a8xwinnWqXKCHezgBAscZxdHmWeZ3RxlgcfZwQnm66eYPdkM1hsLV0l+WnDvTp9XYbm63dQoOIdj5v4Fd2eeGmvMsxxcA3PfdnOMHRxvHWvnsc00D0vfeB//5/63trSjtWqNo+w2d3ie4+ZznHkqbBM11pgzn4NrmGzyS2oT0y6ZiKnRoNpqD6E5ZdfSCzm2+OXWcWdYZbe5tttZZlf9aHBNEzh9XoWHqxdznKdyjIs5zF4eZa85RpVVpluO70s4wrP4FpfwIBfxIBcfOwJHge8Ax9n8/J3gnvFC4AXQuAzuPfdSvsN+7uUyHuQS7lu9jJWDO+HrcOdPLpHl+c8DpTKwUPayUaRtwGU5wiPAAVXdUNVHCbSNfQXWyef9ScDFDh9eu+g1TLLvtsx9odM4g0kiad5ELLPZyo6yNU13fn6CtPbm7eJsahYG21w5iplqOwUCiUhVRD5hfr9LRPZav73dbP+WiLy0U5lmZb+7zPZPmFX+eqJIgeGyHOFnMEsLishO4JnAIwXWyROhCFt9L2Xm2Umkdci9OlNtAWt/LnJAUrTD2/W+jdtou0mFOlNOrzSsQKCXAZcArxeRSyK7vRE4paoXAx8A3mP+ewlBH/ojwFXA74rIRIcy3wN8wJR1ypTdE4UJDFVtAOFyhN8APhkuR2iWDcT8dkJEHgTuBH5VVdMWPM9MxSVKyqbH0eqokNT44zrEolabyytCxmXiXp7n0ElodOpwx1LzGI9JeS6BQFcDHzWfPw28SETEbL9VVevGGnPIlBdbpvnPz5gyMGW+stcTKNSH4bAcoQK/Yl6DZRbanvMqMF2eiB5XZljteQTYS6TOKrWWjX6Q2NFeYVhtmKK9kxYTPYfQtGb7L2zihaibsKszNXTLu/Y7tLdWWw2Shg9IqDSz+TB2ishB6/vNxgcLcAGbHjcITPJXRP7f2sesAf4kgZfnAuCrkf9eYD7HlbkDWDYD9+j+XTNop3dfKEMs97gQ2v/r1QrVenNz3fAweKjHhz7v0Xdavqesa56PI65L6o4RT/goqRHAacTXw2SyQWYnjaakiEZIuZI1edqgznmNGarVOrMxi9U0Zvs/hwKCa76csOZ5XuWPNQOcgxGmN88Bl0CgcJ8jIjIJPIUgFjDtv3HbTwDzIjJptIy4Y2VmuOwtntywhUMeD0Ovzl77/64aYSP0N9mvLo9ZNsZi1B7mkRofXAKBDgDXmM+vBr5oTPcHgNeZKKoLCaJJ/3dSmeY/d5oyMGV+ttcTGHkNw8npnbHRVqmPZMhfFrrSLow5ykUD2FxMKXhfZYZ5kicvuhJNkteJ0H/R3Dofz5lOPoph9GOk4STwqwmfS0iQfLD3jMfGJxEGAk0At4SBQMBBVT0AfAT4mIgcAk4SCADMfp8EHiSY7vgWVT0LEFemOeSvA7eKyG8C95qye2LkBUYa45C/HpJH0nWquY2yQy0lzundOcvrescRdb8FdHA+W01eacIuj4CDYSQ0l6V1qo1Zq7OZJTCYONB230cgNYhDINAZ4DUJ//0t4LdcyjTbHyGIosqNsRAYYaNz6nQcnLLJacDLa+KAYCTbiy18hjXWmHHWLkLHdxxxkVhxKc6LYpg0xEH7L1zzrfX8fCUcZ2rA2lfGKKmRxvswQnIK2ctiWhiGRHMQdFhJnVbZhaSnexqz3SfnjDVLldz05OnMyAuMCluTK9ojobZ5Fo5pzu1OMq7DHNTotZvjhiN6O4dUGkVHRvVDAJUxzDoMFx70pL1QQLgICr9u+fgxFiaprvCzvfNlInjLMmLNtGpbx126N2v0Mnkzizlp0MIipK8p/13XoplmYBP31K+H0WLkNYyQbuzAcQ+OSzlZIipGsSG25VnqorPtWkPLuUOJ1t0luiutfXjzXYQRcGKPG2OhYeRpgsjL+TUs/gtXop3hWrXGTD0fZ22qdjCN81rsSR121sFEJ8d8WJ53lDpScsHhnd6bjLyG4bLgTBsRrcJtVDm6ttw8R8VZTB398jN0Or8kDcklJDtNELl0QGnaZ9UsBjYMxA6OvMl3KBkLDcMm9iGOzhJOGUC6pIBwSW43LPQrzDWJ1PUkqhUmTze3bOtUXmgyHGVB78mPIL25D/ECBw1DRP65iGzvR2XKStxoskp9KG3SearWzhlZe3AaF/WgZr134TK2NkX5n8pq/sgtR1e3t7TkpqtxwEXDWADuFpG/Bm4BbteiFgIviHB14EydREYHqmvZcdpFER1EmpZTZ6ptVbl+z3jPQwjUqSaafDqV3+naDBNV1vtW55n6av5zKRLKC5YSrps0PKswFy7+3X8UGZusEJ3oOPRT1d8gSHT1EeANwEMi8m9F5KKC65YLEjMPo1uyOEfj9i2TKarXurgIyL5ljc150au0DrhbYRcnpLodKAzKd+F6PzfzgCWYf+M+e4YCJ1uB0Si+Z14NYDvwaRF5b4F1K5xVasFDME1sxtMtYZXmAbcfBFc7eKcOugwj226FSB6pK8IRpc0gzX6uI8pe71se2uWwOL+HldCH4fIadVx8GP9SRO4B3gt8GXiOqv4y8HzgVQXXbzDkMPKxOwKXjngQD31WNTvsvLvpxMNsr538Gb04oouacDaI9TWGFec5NLbJdxafNmRIcDEKngf8Y1X9tr1RVZsi8g+KqVZ+ZA6r7YFBJ4kbFbIIpMYsTJ7Zuj0P85/LXBI7024//QllYcqKOosu5JWZagfhPCCnd17pzUcBFx/GDVFhYf32jfyr1D9qXXbwZY1iyYv0+P+tnXna9ShidF6ELyjOJBalKJPDKLSnuMHSlvNy1ADjrkelOnwRiaPIyE/cgwwj1hTV2G7E0Ycjda7AiI84w0y2Lp1p1BxVxmsTNQ32KvCqrDtpnmH7GkbhUXSyzTImiywCETlPRO4QkYfMe+x0BhG5xuzzkIhcY23/LRH5rohsWchFRF4rIg+KyAMi8nFr+1kRuc+8oqv/bWFsJu51bHRVsHcJ7eFJHeGoTPrKK1wwMEcMXgAMs7/BRVgMk4M7UVDOEqwlB0Mxt0KRTKs09sDbgC+o6rtF5G3m+6/bO4jIecANwH5AgXtE5ICqngI+B3wQeCjyn33A24EXquopEXmq9fOaql7mWsGR1zDssNpoJx+aNvqanXPIyOJPsDszF42j186vJRwyZDKd6TAfx0XopQnZMGXHMKXuGBje0R3lauCj5vNHgVfG7PNS4A5VPWmExB3AVQCq+lVVPRbznzcBHzL7o6qPd1vBsdAw4kY6qR1DzNrTSSlBws4nPEa36azLMDrPiyyr8g2KOMGRNhlQE8ZWo3TfiqRerTCZFIDiKjimoY8xLC0yOr13ishB6/vNqnqz438XrA7/ewSTpqNcAHzX+n7EbEvjmQAi8mWChQbepap/bn6bNvVtAO9W1c+kFTQWAiON1trNDnn5Z1jlVIc8Uva+6ccdro7GZd1t2DqLHJLNRGW4Bt1GtpVpEmYvrMWswZ4Hefk1hjDy8AlV3Z/0o4h8HvihmJ/eYX9RVRWRvGYdTxJMvl4E9gBfEpHnqOoy8MOq+piIPAP4ooj8jao+nFbQSBMNq+3GTGB3DjXWenZMxnWUoxCSmWXNcJdzTdNS1pjJPB8kyTnvTUcloINZuHbOGisDmhqeZ3pzVX1x0m8iclxEdqnqMRHZBcSZjh4j6PhD9gBLHQ57BLhLVTeAR0XkbwkEyN2q+pip1yMisgQ8F0gUGCPvw4DNXFJJxE0mi5vlbTeabmYh15lK7CiHXVhkIc+8PPZ96iXJITimO0mo+6CW5Q3pJPRKE33lusLeeHIACKOergE+G7PP7cBLRGS7iaJ6idmWxmcwQkZEdhKYqB4xZVSt7S8EHkwraOQFhlgaRscOwWE94zhbZjiqth/a6AOaJBBcHuQKzaFQzaOdVlqE2aZjuJ77ucV16t0cI6z/IFI+jM0AYggER7BEa19Sg7wb+FkReQh4sfmOiOwXkd8HUNWTwE3A3eZ1o9mGiLxXRI4ANRE5IiLvMuXeDpwQkQeBO4FfVdUTwLOBgyLyNbP93aqaKjBG3iTlzDRwhi3RNnGdT9aHOa+Hf4bV8owUMxKmB3cNe80jh1Q/rpWrb8emztRIm8GGMe1/GTCd+Itith8ErrW+30KQOTy6368BvxazXYFfMS97+1eA52Sp49gIjLhGXGeKNWaY59SW39aqtcQRQxYHcK+j5xlWicl80ZFVZjKZSbpx4nZ7bp1MUjOsZTZb+dDo/jIQjXcO+H7/D+tTg2wy8iapCs2Ok/ba4vnJZguPM0flRdxDOQymqV6ICnaX87WFRd7mI7u8fq2J0E9zVN7tKZN24ejPGLR/yLNJoQJDRK4SkW+JyCEzczFpv1eJiIpIYjha0TQc/BfQ3nizpHzIk1EQGnGdYj/OK/CZdO6AXDWuQfka8rpWpTJxllRLbFKJTMdMfo06hQkMEZkAPgS8DLgEeL2IXBKz3znAvwTuKqouEJg58uyQei0rGnWVtfxBCw3XyZBtI/SqWyBA2rHsa1a29QeK1gijWmw/24CL1u1cnwyz8kNqteEfJI0CRWoYlwOHVPURVV0HbiWY+h7lJuA90JWpviMVmj2rtJ06tqzmqE6jukELA+j/yLPfTuDMa3qPvvW2eDIue+wpH1LU8twi8mrgKlW91nz/eeAKVb3e2ud5wDtU9VVm0shbTURAtKzrgOsAFhYWnn/rrbc61+PEyinW5upMcNa8GlRoMtn6HmybbG6G3zYliOpRKjSpcJYJ611oMNmWKiIM3a1Y7+G/xbxDeqejSOJvzZUdVOZObN1uldc0/7e3bdZHW98lpl7R/yliziB4b7TOf3JL2UBw/ThLhWbrmtq/C03WVi5gZu4xAM5aV98uX1tXLjjuZnmb90zQVvkVmkxog4ppwk2BszJpfgnulyJt9Q/Ll7Zr0myVHx5TUCZptM5hbWUX1bnjbdcqLL/ZVkply/UJv1esa560dHBaO7D/E9em1GoDdn3C61pdmWFj7nRbew3vxDY2tjwHNuEzscEUDSZZZxvrVNlgW1vbC+szTZ0pEzY9xTpVPUOlAWwQJKEIP58lSFZRBWrQmKpwhpnWv9eYbpXSODPFsxorzM25Zyy88sor70mbee3CzP5n68UH/9Bp3/vl8p6PV2YGFiUlIhXg3xOsE56KycVyM8D+/ft1cXHR+Th/sPQpvrZ4mHmWmecU8yxTY40587nKOjs4wXz9FNV6k3q10oqQCoxYNRNNVWOZeRpUWWWmlVfKHhkHe6/RJBjBTrPaSm+dNmLvpMGcWfo5phf/25btdpkNY56xozlCzSocTdv1qbLelsJjtc3UE5xv+L7CfOv87XMNmWeZ7SwzzWrrs21OqFLnvqUbuWzxnQDWnZhvK3/zuNVWPqroPauybr6vBr+b+wawfO5c231bZp46UyyzvXXPwvLt+R/hNbHPIWwXIfcv3cBFi+9tu1Zh+WvUWu0ijmib6JZoW4OoiW6qtS2sj31dn7H0XI4tfrlVTnjOCxxlO8vBHfn+lszYLXPUWrXGUXZznKdykt0cYzePsrdluw+PB3ARh9nLo1zIYS7gMBfVDzF7sglHCeYvf5/g82kC38VzgH3wxIVzPMglPMpeDnMhD/JsDnM+h9nL4w8+nTsfXyLL8+/JlyIFxmPA06zve8y2kHOAS4ElEYEgv8oBEXlFnJbRLRU01fyQZRElO7VEmj05eryizTv1GGFRJGUwmYWsVWtU61s7OU8+9Dp7PpVpAoGRQhkipNQ4vT3F+jDuBvaJyIUiMgW8jmDqOwCq+qSq7lTVvaq6F/gqkKuwsLE78SQBkufDkWdOJUFHeqJXEdjXdXMt8q3X0OW69hpO2y9B3m0b6XVA0/MCR5ZvIy6QYVwWUBoGCtMwVLUhItcTTEufAG5R1QdE5EbgoKp2XN0pD2xbctoDFa7fHDVHRalaaxiHdDviHpf0D91EM6WFvkYz4hY1Co5L097NBEd7lLxGrVQaWhou17XGWjaBOIQD9WDiXonCjwdIoT4MVb0NuC2y7Z0J+y4WWZckVqm1OgXXtBVFZayNI8hiWzw1Vjs+FFlSk+SxJkYZUkwkaReDFPa2wMkrXcxqQWnO82KKdZhrxOdv9fSNsUgN0qnjslNlR0fDnToG++F1HUl229mMQgr0MlAGQTTKZNKgSjpZzyZYotU/dzAGqUHCUMS4RtzLJLAZVp0ejOiqelk6/HH1W+TdoWe9t0kj9jzMEqNkjuqaIRASnnjGQsOwO6Bo1IVtDw87lqj/wkXlj4aw2h2D1wqGi2Hp1MtI0rVbq9aYxYpmmwVO9qdOvdJsVlhd9T4MGAMNIzqBKo6kkaNrR1+G0D+bIsN4u+1Mw4mO/UjnkaYJJKXviJoT82YYzGB1qtSrlWK1CxuvaQwdIy8wXAmdm0nRUUnCI0lY9NrpJJmjsqysNowpmV0FUq/mIa9FFEvmrLWzpKYOqbFKpVp+odsLInKeiNwhIg+Z9+0J+11j9nlIRK6xtv+5iHxNRB4QkQ+bfH6IyE0i8nURuU9E/kJEdpvtIiK/Y5LDft1k3khlLARGOLO5UyeRNd6+F82iU/JBm2FZca/fxN2vuG15jO57zSW1ae4cXdNGUZr2oDX45tkKqz+YcXr1yNuAL6jqPuAL5nsbInIecANwBUG+vhsswfJaVf0xggnR5wOvMdt/W1V/VFUvA/4UCCNVX0awtvc+gtRL/7lTBUdeYCTl7HFlLcGXEdeIXWd4J5W5WU6+zu6yZXXNQqdrYZ9bGc9z0J1dmYhdOqBDQsIxm7R3NfBR8/mjwCtj9nkpcIeqnlTVU8AdwFUAqhouLzUJTEHQ+VnbIdDlwk7xauAPNeCrwLyI7Eqr4Fg4vV1YpdY2FyFbNJN7o44TEGkhuDOs4pL4YlDmp7gOPbyW0bkYRXXorvNnshCdHBj9zdOZWGE/RM7uFio0685td6eI2Nkqbja58FxYUNVj5vP3gIWYfS4Avmt9P2K2ASAitxNoHn8GfNra/lvALwBPAld2KOsYCYy8hlGh2dEcFXYArnZxlzQjIZ20iUGTNEdlHExgnbSXsD24tIsq9TZtomaMjvbvw06awM+kCXTwVyRRO2cotLUnVHW/9WoTFiLyeRG5P+bVtvSDWYc7s3lEVV8K7CKYU/8z1vZ3qOrTgD8Crk/4e0fGXsOIG91HR5Dh9+isWtdOIC9BkdesXk9x9GqCGqbUIZ3oqIlVSU0+WBoh2xRYyaerVNUXJ/0mIsdFZJeqHjOmobh57Y8Bi9b3PcBS5BhnROSzBCanOyL//yOC7Bs30DlB7BZGXsNIIzqpLrotrXPOszG3Z7rdmsLaMzjcl2rt3dw2qoMBJ8HRgTHxZRwAwqina4DPxuxzO/ASEdlunN0vAW4XkbnQ/yAik8DfB75pvu+z/n91uN0c7xdMtNQLgCctk1gsI69hiDUPIyl1R/jZRVikjfI7zSa3CddkGEeSOmE79UmR16YXQdwP/0WZtQyX88/b0T/w56RJQeuBbuHdwCdF5I3At4HXAojIfuDNqnqtqp4UkZsIsoED3Gi2LRAsD1ElUATuBD4clisizzJn8m3gzWb7bcDLgUPAKvCLnSo48gID0juIOlOptuy4ByROaGR5wLOORsP05lk6qzJ3Op6tRNvTMN2/zBlrbWYj72nHGfF1vVX1BPCimO0HgWut77cAt0T2OQ78eEK5r0rYrsBbstRxLARGHNGHMXxAs5oF0h7quLKiYaBJo6e0cocpCWEeWWvzICnDcF6dcpV6KcN6+81IhhE3wSlUcQwYeR9GmBokmuspjmiHktYpuyYfbC8vvkPJy3adXdiV++FOW8Ww1/K6YZBCuqyJKNPuS9Y6x87T8JSKsdUwbJU/apYqomPodvQZtxTsqDpH+0mZOuBe72c/2kQ41yXX6zYLncYB4UBvoJpL/3wYpWfkNQxwy/cUFyWVtr8Lg7JBuzkmR9senEReHV6WtlBURF0//pcFp0imaYKoKFub8JrF0DDyAqN9idatDTpOaMTt4+KErLLe1iGFZcdpF6GT0P4t/G/Scco0Ki6Sbkx94bK6RaFIYWUPCtdRuz2T3n5G0u6Ts7nTQfEOjzM1Ju2/zIyNSaqT76JTSGz0914672HMIltWok51v/ZyOQkGRu6e41I5z73Tu8UYaBjqZBIIhUOoTaRP2uuPsOjmOFEtqQzCyWXkPywhpHlTdn9UlnXuO5G6zobRNMK2UoZ269nK2GgYLuT58MaZo+IeAhdhVqHZlhgxb2ZYK9ScM+wMSwhz3hSR1HEoOYvXMAwjr2HE0c1otiiHd6+x++Mc+1+0+clVUAyTdtQPP5iT89tOQGjebQ0kqrFMUR/bQI0yMfIaRoUm01ZDCzv+rKGIYafg8sDFTayL0y5WmRmIrbZszvOeZgrH0Kmjdzn/uHQxafsmH2s40790q11kzvk0DBFSPqy2xcgLjChJo8HoSL3Tg5642L2jEEpytA/TaHWQdErp4kJ4rbMKbdd7nCX1fVnoRlBknuXuMP/CU07GTmAkEW30cWk7OoW9hr/l0RGExxoVNTxc4rSTrySvtCdl7IyzMkz5pIqgNOfuo6RajLwPI0zc14m4EVJe/oGouWUUOjNPuumr7KaoIjrjIsyr9nUckxTnpWbkBUZIt+aLqNDo9UErs7AokzZTmtFlBJf7N4ymqG7pKR9Z6PieJdWXEV29sO+EPgyX14gzNgIDkoVGKBRWTUrBXsoqE6PSMZVqElcHyq5ZpNHJXJhH6LVPMJiMiJwnIneIyEPmfXvCfteYfR4SkWtifj8gIvdb339MRP5KRP5GRD4nIuea7XtFZE1E7jOvD0fLijLyAsNODQJuHX0WoZFFcPTSgaeN5Iqe5JRXh53XXI+ta0fMlGIeyTALi15xmhxrO9SHKRo89GG4vHrjbcAXVHUf8AXzvQ0ROY9gedUrgMuBG2zBIiL/OKYmvw+8TVWfA/wJ8KvWbw+r6mXm9WY6MPICAzotoLSpXbgSFRKuYZpZCU1EmynasyzSNJjJZnlrNWUyTWVZabHbsoYdJ/PRdPrPaWWPOFcDHzWfPwq8MmaflwJ3qOpJVT1FsGb3VQAiMgf8CvCbkf88E/iS+XwHELugkguFCgwRuUpEviUih0QkTlr+iog8KCJfF5EviMgPF1WXojuerNoGdNdpDIMpDPKZVFfEuYbtoEyCaBgoZIKobZ6aDjSQ5OV7x0J7W7DW1P4esBCzzwXAd63vR8w2gJuA98OWxv0AgTACeA3wNOu3C0XkXhH5SxH5qU4VLExgiMgE8CHgZcAlwOtF5JLIbvcC+1X1R4FPA+8tqj5phNqF3YEXbeYJNYD4dCG9dZSjOnqNY7XtnuVz3qOWCqTX9tSNsIh28Ikmw4jDO06LHnh0VDan904ROWi9rrOLEpHPi8j9Ma+r7f3M8qnqWkURuQy4SFX/JObnXwL+mYjcA5wDrQZxDHi6qj6XQDP5eOjfSKLIeRiXA4dU9REAEbmVQMo9GO6gqnda+38V+Lm8KyEO19yeadxr7HuV9UwddjdqtusMZE9+NFPGVmUU0HaHHdZPIv48F5KERY01lpkHis1FNsMap8xxAsGxrZDj5MgTqro/6UdVfXHSbyJyXER2qeoxEdkFPB6z22PAovV9D7AE/ASwX0QOE/TrTxWRJVVdVNVvAi8xx3gm8PdNXeqYKZSqeo+IPExgvjqYWMdAkOWPiLwauEpVrzXffx64QlWvT9j/g8D3VDVqf8NI6esAFhYWnn/rrbc61+P7K3/HtrnHW+sZhA++IjSp0LS2h7/ZjvJgq5o9N9/TOMtEW/l22cGxg89Ck0kaieWH9VhfWWB67lirHEU4y0Rs+Wo+t//Sfg4TnG1tDwn/H5Yfnkd4jAaTrXqHhB1QhSaTpsyw/Oh1rK8sUJ073jpG3DVqvz+VxPqHZUevU/Teatu9bb/PFavum/daW9/F+gywsXI+E3Mn2s4/2qaKwK5PtL429rmH3+0WoFTYtjJLY+4HrXLCXyY422oTEzRaZUbvd3jfzjJBgwk2mOIsE7HHn6TBBA2m2GAbG61/VbRJpUEwdm4QjN4rwDZobKu0ytxg0vq8rXW8C1aEubk55+t35ZVX3pPWgbsg5+9XXpnYh7bz+9L18UTkt4ETqvpuY8I/T1V/LbLPecA9wPPMpr8Gnq+qJ6199gJ/qqqXmu9PVdXHRaQC/AGwpKq3iMj5wElVPSsizwD+J/Acu6wopZjpLSI/B+wH/l7c76p6M3AzwP79+3VxcdG57D9b+hAXLP5Oa0S+mUV2ijVqNCynd9z6FzXWqFJnmlWqrDNj3kPVOc4Mssx8W/nRssO6VFlnBydiyw+OHRzj0aW3csniTawxwyo16kyxzHxs+eFxZ6zyoucwzzI186+QzbTStVb97GOcYMcWrcae+b6d5bby7foDPLz0a1y0+N7WMeKuUfT+JNU/PGb0Oq1GroF9z6P3OS4tSHiM8NxsTfP40ls4d/G/tp1/tE0VgV0fiPe9RNvWGjUE2tpGnSl2L/0EJxb/slVOeF3PZbnVJsJ7F6dZrDHDKebN3ts5yQ6OGzN72H7C/y1wnHmW2c1Rzuco282/ZuqrzJ5sBuabk8BpApPUbnhi1xxH2c0y8xxngWPsYpntHGUXy8xzlN3ctLSNLM//kPFu4JMi8kbg28BrAURkP/BmVb1WVU+KyE3A3eY/N6Z18IbXi8hbzOc/BsKG/NPAjSKyQSC639yprCIFxmO0O1f2mG1tiMiLgXcAf8+oSLmSNCKziXboWYhLO55mMopLSjiqDr1Van2fDFiEqa5MJqei0oXUmaLGai7O7a3+ixrbjSCCYC7G5Bk2Q2vLHmLbpC+5r1T1BPCimO0HgWut77cAt6SUcxi41Pr+H4H/GLPf/wD+R5Y6FhkldTewT0QuFJEp4HXAAXsHEXku8F+AV6hqnL0uN9zSgxTjFyhTh+OJH6V3Wr53lMhT4ITXLdRW7euY5ThpE/pCLXAMwmpLT2ECQ1UbwPXA7cA3gE+q6gMicqOIvMLs9tvAHPApM9PwQEJxpabIUXTShL1hCa/NG1uol8Xx70N03ciqvdhtfOCpQfozca/0FOrDUNXbgNsi295pfU6MGMgT22zkmk02TfXvVkCUpYNLoogFiQZhlsqTUdEyBjHAiJqi2pgm8F94hopSOL3LRHSdBVcfQ5FLqJaRXjqgsgtOT3dEw2s7al6zkfcY7GdvYL6+s8APBnPosjEWqUE8xVJMWmt3gbRK8gzhohhFoZd2DdPmWcR15IkLjPl1woeakRcYLlFSWUjryIbZ9NILnWbFl1XzGiYn6iAFlB1y7UKnlOf22t1t2xN8HAOPIlSCKCmX14gz8gLD0x1R230Wx25a59YP4RHndxh4p9MHXIRKlvuYJQtwNFoqSvS+NyLmKFuIxJ3HFHUfXFACvMDoE2U2YWRN69CN/8J1NrTvFMqBa5vo6X5NR94p93PiGTOnd9p60fYM6WGn0zmEk7TyYphMO552om2lyHVF1joEkJRhTZNYzjIWIbMueA0jBjfVvlyd5DAIujzNUXFmp3EcnfYa9pv1/3Hpc0JczH7dziQf+DKtHmCMBMa4OqST6Lbzjpqj8hJU3XYGWYVEHrOGBy2YOnXy0XsSfs87AKRb1qq1TZ+FZY6KDsJmWosmD1hQKH5Nb8PYCIy86YfdP+04eXRa/TqHbhmk1jRooVA0eY7W7ftUpe4cYBA6vu20IOOawWBYGCsfRlmpU829cxzmB891Nr6nM/ZaL3G4truio9vWqrXWACau7VapD24hJe/DaOEFRgkYZMhnNMZ+1EfW40q3AxL3uRftQt51wBJNOujbX7nxAmMESBpFDtqkMyxaThaBXaYOLUkLy6KdRfdNW+cl7tztyMOo0Egye9WpmpTmq1TrzS0T+YK2U2+16Sr1wUZQKQzajVIWvA8jR8o4o7nIyBKX8N1+EBgr3I81LNE2ade3F5Nd2vnnkWbFrnf4uc6UWbIpySdXTf0Ow3PfukVEzhORO0TkIfO+PWG/a8w+D4nINdb2KRG5WUT+VkS+KSKvsn57rYg8KCIPiMjHO5WVhBcYMRQ1Mk4qt5tQw2EZvXfbkcetiBclrtNcG2HTWlnOKXrd7baYVau1tYtVEzwblFmimflnCTLrurx6423AF1R1H/AF870Ns0TrDcAVwOXADZZgeQfwuKo+E7gE+Evzn33A24EXquqPAP/KoaxYvMAwDLIDLtXD4UheqUKGiX6fR9GO/yLbXdg+ks6hTrWViNBOSJjUrgYeWtsfrgY+aj5/FHhlzD4vBe5Q1ZOqegq4A7jK/PZLwL8DUNWmqj5htr8J+JDZH2uxurSyYvECw8KlE0zqNNLU+PawQ/eV/8Iym1Ta1vO216uOUlbNQxFgdIRH2XC9rnmYdeJXLHRvd3FmqSRTlV3uMA6sMrKgqsfM5++BWTC9nQuA71rfjwAXiMi8+X6TiPy1iHxKRML/PxN4poh8WUS+KiJXpZWVVsGxERhl8i/k2ann8RBljZDq1pnuhUV/CO9P2DZCIdHLxL2s985VOwq1izQNYuBZDLJN3NspIget13V2USLyeRG5P+Z1ddshVdUc2ZVJYA/wFVV9HvBXwPus3/YBi8Drgd+zBEwmfJRUF0RXkYsTRlXWUx+aIjSBMErFteyk1fDS6p3Hw9urqWUQEVihhhRHP+eMxJ17L4I47X4mlRtND7Lpd2iPmLLLCb93uwLjwCOl3HlCVfcn/Zi2yqiIHBeRXap6TER2AY/H7PYYQccfsgdYAk4Aq8Afm+2fAt5oPh8B7lLVDeBREflbAgGSVFYiY6NhgNuDFT6MLk5X6E1zmTFuvjiiZqk8sU1aWcp3FRZZO1BbSxr1SJhB4Xpdw4iztCSdaWVWWXcW5mGwR52qkzAYqB9DHV+9cQAII5WuAT4bs8/twEtEZLtxUL8EuN1oJJ9jUwC8CHjQfP5MuF1EdhKYqB5JKiutgmMlMPpFmo+hX2SOVulQ36QOp8gOPiw7PcNpLfZzHHHluCXMK68prZ91a5+Yt3ndXNuaXddQQKRFCI7h4OHdwM+KyEPAi813RGS/iPw+gKqeBG4C7javG802gF8H3iUiXwd+HvjXZvvtwAkReRC4E/hVVT3RoaxYRt4k5boOQze4Tm6Cwaa7GDZnYad0Fv2iSNOXS3tI6ojzrJed0t8lvX943LgFttLOxy47zixlB3REyx08Tfoxc09VTxBoBtHtB4Frre+3ALfE7Pdt4KdjtivwK+YV/S22rCTGTsPIq9PuxlTk0vjj6tek0tXxih6hxZUfCsxhyAU1KO0ibAdp7SGvjjLpHIsYRNjnVWONqlklL0m4hVrGkPgmPIyBhgGdO/dox5dHFFD4kERV7qI0jXBU3k3d200FbnVzEUa9LEjVqXx7lD0MwimJbttDL4IsTlikaS1Z6ucy+98+TlRYlNP81x8NYxgYC4HRLVlG6NGGHn4PH07bxBL3UNmRJnYZ0e82vQqftIezXfjV2wRflusS1i80DQ5z594v8s9cvHn/OmkWne5PtM24mA/jhJFtlrLNUUmrYpZ1ftG4MXYmqTxIEg5Ruh2Z2f+Llp1WZq8mqE71TVr1zNW8kXZeeZpIyjlKTWbrMqnFCNVKDmE8NtF5Hq5kidCrmSmrg6UJfN/xNdqMvMAIR7Z2J5LWoWRNedGpc+p2SUobRWKPk5Z3JynCqMw+hn4458NjlC0QYHN1uWLmuSSdb54rJsYJjqQotqxh3Wm+EE//GHmBYdNtVEocWbWK8IGyH6qsifXSjm2P9lzCUV2PF501XDS9Hsdtrk25hEWUYV5Aym5/cYOlOKERHcyVLwFh6MNweY02YyEwujFRJHXmnUIHo8dLGv1Hy0/LvOpy7G5Ys8SYTZbrZZ+fa6bYTr/bZZan0+gvgxAaWe6by+DKvndJgRVxGu/gTVCeJMZCYKQRZ4e1P8c1+riOvNuHO6sTsmj7fLfCAopx1qbh6ksqE1muUaeMr0Vgz/SOvmw6aQHdONeT7l/4PHpBMnhGPkoqLQdQHK4OvCwPcTTKyN4eYi80E7XVBtlqOx/PNRomKYQyzU/SqUyXstK2R3E91jCt7NctcdqGyxyOfgmarX6yeL/d1pDaWkdNKmzTg53MeZZxcGi7MPICI8TFXJKkWXRLe2K25PKiD/9mSG72jrBTGo0kwVT06DzJcZ8Hw6BZ5E0nn1P08xo1KjSZTojGy5MsgxUXU6wtNDyDpVCTlIhcJSLfEpFDIhK3elRVRD5hfr9LRPYWUY+sq7B1KyyyLhUK2bKFdjPBLo1OieaG1fHq2UpcOxuUiSeuzXWK3husL8s7vUMKExgiMgF8CHgZwXKBrxeRSyK7vRE4paoXAx8A3pN3PeLCaqNUqbe94rCFjouN1wXXBZuio/Os+XaS5njkST86Hy/ARovos9NN8khPfynSJHU5cEhVHwEQkVsJliB80NrnauBd5vOngQ+KiJhkWbmRh8mi2w6xqGiXaH1chUbooO+0fxmjVrqpR55pLYaBXtKxhP+PI2t764ZOz8oruJ2l9OUaCqIJ/GAAxy0fRQqMuOX/rkjaR1UbIvIksAN4wt7JrFp1HcDCwgJLS0vutVjZw7alm2J/2uZeSk/0epz6ykrbOfRSnut/87420XMo6jhFlZ9U/zyPkUYex0g7hzyP0wtpx19iiZWVlWzPvydXhsLprao3AzcD7N+/XxcXF53/u7S0RJb9y4g/h8Ez7PUHfw7d46OkQop0ej8GPM36vsdsi91HRCaBpxAsNejxeDxjhYicJyJ3iMhD5n17wn7XmH0eEpFrrO2vF5G/EZGvi8ifm9X1EJHfFpFvmu1/Eq7nLSJ7RWRNRO4zrw93qmORAuNuYJ+IXCgiU8DrCJYgtLGXJHw18MW8/Rcej8fTG32Lknob8AVV3Qd8wXxvQ0TOA24gMO9fDtxgllidBP4jcKWq/ijwdeB687c7gEvN9r8F3m4V+bCqXmZeb+5UwcIEhqo2CCp8O/AN4JOq+oCI3CgirzC7fQTYISKHCFaD2nKBPB6PZ0y4Gvio+fxR4JUx+7wUuENVT6rqKQJhcBUg5jUrIgKcCxwFUNW/MP0xwFcJrD1dUagPQ1VvA26LbHun9fkM8Joi6+DxeDy9kcmHsVNEDlrfbzY+WBcWVPWY+fw9YCFmn7hgogtUdUNEfhn4G+A08BDwlpj//xLwCev7hSJyL8EJ/oaq/s+0Cg6F09vj8XiGhCdUdX/SjyLyeeCHYn56h/1FVVVEnM3zIrIN+GXgucAjwH8iMD39prXPO4AG8Edm0zHg6ap6QkSeD3xGRH5EVROloxcYHo/H0ydU9cVJv4nIcRHZparHRGQX8HjMbo8Bi9b3PcAScJkp/2FT1iexTPwi8gbgHwAvCv3EqlqHYDakqt4jIg8DzwRsDamNsc9W6/F4POn0zeltBwFdA3w2Zp/bgZcYR/d24CVm22PAJSJyvtnvZwl8x4jIVcCvAa9Q1daMSxE532TkQESeAewj0E4S8RqGx+PxlIN3A58UkTcC3wZeCyAi+4E3q+q1qnpSRG4iiEIFuFFVT5r9/g3wJRHZMP9/g9nng0AVuCPwh/NVExH108CNZv+mOcbJtArKsEWxisjfEVwMV3YSmTk+hPhzGDzDXn8Yz3P4YVU9v/NuyYjIn5vjuvCEql7Vy/HKzNAJjKyIyME0J9Qw4M9h8Ax7/cGfg6d3vA/D4/F4PE54geHxeDweJ8ZBYLhOmikz/hwGz7DXH/w5eHpk5H0YHo/H48mHcdAwPB6Px5MDXmB4PB6Px4mRERgicpWIfEtEDolIXFrgqoh8wvx+l4jsHUA1U3E4h18RkQdNXvsviMgPD6KeSXSqv7Xfq0REzYSkUuFyDiLyWnMfHhCRj/e7jp1waEdPF5E7ReRe05ZePoh6JiEit4jI4yJyf8LvIiK/Y87v6yLyvH7XcWxR1aF/ARPAw8AzgCnga8AlkX3+GfBh8/l1wCcGXe8uzuFKoGY+/3KZzsGl/ma/c4AvEaRZ3j/oendxD/YB9wLbzfenDrreXZzDzcAvm8+XAIcHXe9I/X4aeB5wf8LvLwf+jCCd9wuAuwZd53F5jYqGcTlwSFUfUdV14FaC3PI2dq75TwMvMnnjy0LHc1DVO3UzF0xPee0LwOUeANwEvAc408/KOeJyDm8CPqTBWgSoalyCuEHicg5KsF4CBKtcHu1j/Tqiql8C0lJUXA38oQZ8FZg3yfo8BTMqAiM2R3zSPhosJvIksKMvtXPD5Rxs3kgwyioLHetvTAdPU9X/r58Vy4DLPXgm8EwR+bKIfNUkdisTLufwLuDnROQIwXo1/7w/VcuNrM+KJyd88sEhRER+DtgP/L1B18UVEakA/57NhGjDyiSBWWqRQMP7kog8R1WXB1mpjLwe+ANVfb+I/ATwMRG5VFWbg66Yp9yMiobxGPA06/sesy12H7P+7VOAE32pnRsu54CIvJhgsZVXaJDPvix0qv85wKXAkogcJrA9HyiZ49vlHhwBDqjqhqo+SrBG8r4+1c8Fl3N4I/BJAFX9K2Aa9+R6ZcDpWfHkz6gIjLuBfSJyoYhMETi1D0T2sXPNvxr4ohoPWknoeA4i8lzgvxAIi7LZzlPrr6pPqupOVd2rqnsJfDCvUNXExVoGgEs7+gxmARsR2UlgokpdQ6DPuJzDd4AXAYjIswkExt/1tZa9cQD4BRMt9QLgSd1c2tRTICNhklLVhohcT7CQyARwi6o+ICI3AgdV9QDwEQLV+xCBQ+11g6vxVhzP4beBOeBTxl//HVV9xcAqbeFY/1LjeA7hAjYPEiz2/KuqWhpN1fEc/jXweyLy/xA4wN9QpsGTiPx3AqG80/hZbgC2Aajqhwn8Li8HDgGrwC8Opqbjh08N4vF4PB4nRsUk5fF4PJ6C8QLD4/F4PE54geHxeDweJ7zA8Hg8Ho8TXmB4PB6PxwkvMDwej8fjhBcYHo/H43HCCwzP0CIiP27WQ5gWkVmzPsWlg66XxzOq+Il7nqFGRH6TILXFDHBEVf/dgKvk8YwsXmB4hhqTL+lugvU1flJVzw64Sh7PyOJNUp5hZwdBfq1zCDQNj8dTEF7D8Aw1InKAYFW5C4Fdqnr9gKvk8YwsI5Gt1jOeiMgvABuq+nERmQC+IiI/o6pfHHTdPJ5RxGsYHo/H43HC+zA8Ho/H44QXGB6Px+NxwgsMj8fj8TjhBYbH4/F4nPACw+PxeDxOeIHh8Xg8Hie8wPB4PB6PE/8/sGtMDKvjUKMAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=2000)\n", + "fig = tp.utils.plot(model, lambda u,x,y: constrain_fn(u,x)-torch.cos(20*math.pi*x)*y, plot_sampler, plot_type='contour_surface')\n", + "plt.title('Error')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/backup/BackUp_Sol_2.ipynb b/examples/backup/BackUp_Sol_2.ipynb new file mode 100644 index 00000000..a42418a3 --- /dev/null +++ b/examples/backup/BackUp_Sol_2.ipynb @@ -0,0 +1,384 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Backup 2: The DeepRitz-Method\n", + "\n", + "While PINNs usually utilize the strong formulation of the PDE, there are other concepts that use different formulations of the PDE for training the network, one of them is the DeepRitz method. There, the energy formulation\n", + "of the problem is used.\n", + "\n", + "Let us considere the following simple Laplace equation with a singularity at (0, 0):\n", + "\\begin{align*}\n", + " -\\Delta u &= 1 \\text{ in } \\Omega, \\\\\n", + " u &= 0 \\text{ on } \\partial \\Omega,\n", + "\\end{align*} \n", + "\n", + "with $\\Omega=([-1, 1] \\times [-1, 1]) \\setminus ([0, 1] \\times \\{0\\})$.\n", + "\n", + "Then the energy functional for this problem is given by:\n", + "\\begin{equation}\n", + " E(v) = \\int_\\Omega \\frac{1}{2}\\|\\nabla v\\|^2 \\text{d}x\n", + "\\end{equation}\n", + "The solution $u$ of the strong formulation minimizes the energy functional, namely $E(u) \\leq E(v)$ for all $v$ in the corresponding function space.\n", + "\n", + "The DeepRitz method still tries to learn the solution $u$, but now minimizes $E$ in the training instead of using the strong formulation. To include the boundary condition, the functional also is extended:\n", + "\\begin{equation}\n", + " E(v) = \\int_\\Omega \\frac{1}{2}\\|\\nabla v\\|^2 \\text{d}x + \\int_{\\partial\\Omega} \\frac{1}{2}\\|v\\|^2 \\text{d}o\n", + "\\end{equation}\n", + "\n", + "The following cells, show the usage of DeepRitz in TorchPhysics." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import torchphysics as tp \n", + "import torch\n", + "import pytorch_lightning as pl\n", + "\n", + "X = tp.spaces.R1('x') \n", + "Y = tp.spaces.R1('y')\n", + "U = tp.spaces.R1('u')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the square [-1, 1] x [-1, 1] \n", + "square = tp.domains.Parallelogram(X*Y, [-1, -1], [1, -1], [-1, 1])\n", + "line = tp.domains.Interval(X, 0, 1) * tp.domains.Point(Y, 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Here we create the sampler. For DeepRitz we need to approximate the integral, therefore one usually needs more points\n", + "# then in the PINN approach to get a good estimate.\n", + "# But since in the energy functional the derivatives are of lower order, this generally does not lead to memory problems.\n", + "inner_sampler = tp.samplers.RandomUniformSampler(square, n_points=100000) \n", + "\n", + "bound_sampler = tp.samplers.RandomUniformSampler(square.boundary, n_points=40000)\n", + "bound_sampler += tp.samplers.RandomUniformSampler(line, n_points=10000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The classic DeepRitz method uses a ResNet-architecture instead of a FCN. This is also implemented and used here: " + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Add the input and output space\n", + "model = tp.models.DeepRitzNet(input_space=X*Y, output_space=U, width=20, depth=4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The transformation of the mathematical equations is handled similar to the PINN approach. For each integral in the energy functional, we define a condition.\n", + "\n", + "Instead of a *PINNCondition*, we now use a *DeepRitzCondition*. While the *PINNCondition* compute the mean squared error over the output of the residual function, the *DeepRitzCondition* only sums up the output to approximate the interval." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# The integral for the boundary\n", + "def bound_residual(u):\n", + " return u**2\n", + "\n", + "bound_cond = tp.conditions.DeepRitzCondition(module=model, sampler=bound_sampler, \n", + " integrand_fn=bound_residual, weight=100)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# The integral for the inner part.\n", + "# TODO: Following the implementation in the above cell, complete the condition below:\n", + "# Hint: to compute the norm over a batch of vectors called v, the call\n", + "# torch.sum(v, dim=1, keepdim=True) is useful.\n", + "def energy_residual(u, x, y):\n", + " grad_term = torch.sum(tp.utils.grad(u, x, y)**2, dim=1, keepdim=True)\n", + " return 0.5*grad_term - u\n", + "\n", + "pde_cond = tp.conditions.DeepRitzCondition(module=model, sampler=inner_sampler, \n", + " integrand_fn=energy_residual, weight=1.0)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 3.4 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "3.4 K Trainable params\n", + "0 Non-trainable params\n", + "3.4 K Total params\n", + "0.014 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0df36ef876cb4728ae2fe7a55a0895c1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 20 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f1b2f181ee7047a8966f5ce0be602497", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "01ed1b7d5f8f43c9810c6a1a6cce041c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.001)\n", + "solver = tp.solver.Solver(train_conditions=[bound_cond, pde_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1, # or None if CPU is used\n", + " max_steps=4000, # number of training steps\n", + " logger=False,\n", + " benchmark=True,\n", + " enable_checkpointing=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also use different optimizer algorithms, like LBFGS to may get better convergence.\n", + "\n", + "One point we have to keep in mind, is to fix the inputs of the neural network for LBFGS to work." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 3.4 K \n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "3.4 K Trainable params\n", + "0 Non-trainable params\n", + "3.4 K Total params\n", + "0.014 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "abdf252e6a5748958e99c3fc709cb674", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "065a0ddcf6f642d19e3bfd6d616011c4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "29878664f043434a85f42f7560e52485", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.LBFGS, lr=0.05, \n", + " optimizer_args={'max_iter': 2, 'history_size': 100})\n", + "\n", + "pde_cond.sampler = pde_cond.sampler.make_static() \n", + "bound_cond.sampler = bound_cond.sampler.make_static() \n", + "solver = tp.solver.Solver(train_conditions=[bound_cond, pde_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=2000, # number of training steps\n", + " logger=False,\n", + " benchmark=True,\n", + " enable_checkpointing=False)\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.)\n", + " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/problem/domains/domain2D/parallelogram.py:134: UserWarning: The use of `x.T` on tensors of dimension other than 2 to reverse their shape is deprecated and it will throw an error in a future release. Consider `x.mT` to transpose batches of matricesor `x.permute(*torch.arange(x.ndim - 1, -1, -1))` to reverse the dimensions of a tensor. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2985.)\n", + " bary_coords = torch.stack(torch.meshgrid((x, y))).T.reshape(-1, 2)\n", + "/home/tomfre/Desktop/torchphysics/src/torchphysics/utils/plotting/plot_functions.py:416: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:204.)\n", + " embed_point = Points(torch.tensor([center]), domain.space)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_sampler = tp.samplers.PlotSampler(plot_domain=square, n_points=640, device='cuda')\n", + "fig = tp.utils.plot(model, lambda u : u, plot_sampler, plot_type='contour_surface')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/new_examples/DrillingData/coordinates.npy b/examples/new_examples/DrillingData/coordinates.npy new file mode 100644 index 00000000..ea187796 Binary files /dev/null and b/examples/new_examples/DrillingData/coordinates.npy differ diff --git a/examples/new_examples/DrillingData/model_drilling.pt b/examples/new_examples/DrillingData/model_drilling.pt new file mode 100644 index 00000000..a8d737e3 Binary files /dev/null and b/examples/new_examples/DrillingData/model_drilling.pt differ diff --git a/examples/new_examples/DrillingData/solution.npy b/examples/new_examples/DrillingData/solution.npy new file mode 100644 index 00000000..f5ae2c95 Binary files /dev/null and b/examples/new_examples/DrillingData/solution.npy differ diff --git a/examples/new_examples/DrillingData/time_points.npy b/examples/new_examples/DrillingData/time_points.npy new file mode 100644 index 00000000..52ea5815 Binary files /dev/null and b/examples/new_examples/DrillingData/time_points.npy differ diff --git a/examples/new_examples/Exercise_2.ipynb b/examples/new_examples/Exercise_2.ipynb index ec43cbac..eb8e8204 100644 --- a/examples/new_examples/Exercise_2.ipynb +++ b/examples/new_examples/Exercise_2.ipynb @@ -69,7 +69,7 @@ "import torchphysics as tp\n", "X = tp.spaces.R2('x')\n", "U = tp.spaces.R1('u')\n", - "T = tp.spaces. # <- Add the time variable \"t\" of dimension 1 (e.g. R1)" + "T = tp.spaces. # TODO: Add the time variable \"t\" of dimension 1 (e.g. R1)" ] }, { @@ -91,8 +91,8 @@ "outputs": [], "source": [ "omega = tp.domains.Parallelogram(X, [0,0], [1,0], [0,1])\n", - "time_interval = tp.domains.Interval(T, ) # <-add the bounds of the Interval (0, 2)\n", - "product_domain = time_interval # <- products are define with: * omega" + "time_interval = tp.domains.Interval(T, ) # TODO: Add the bounds of the Interval (0, 2)\n", + "product_domain = time_interval # TODO: Create the product domain. Products are define with: * omega" ] }, { @@ -113,13 +113,13 @@ }, "outputs": [], "source": [ - "# Add the product domain of time and space:\n", + "# TODO: Add the product domain of time and space:\n", "inner_sampler = tp.samplers.RandomUniformSampler(, n_points=25000) \n", "\n", "# The boundary sampler is done already.\n", "bound_sampler = tp.samplers.RandomUniformSampler(time_interval*omega.boundary, n_points=10000)\n", "\n", - "# Currently only the left interval side {0} is passed in the initial sampler, create the product domain with omega:\n", + "# Currently only the left interval side {0} is passed in the initial sampler. TODO: Create the product domain with omega:\n", "initial_sampler = tp.samplers.RandomUniformSampler(time_interval.boundary_left, n_points=5000)" ] }, @@ -143,6 +143,7 @@ }, "outputs": [], "source": [ + "# TODO: Add spaces\n", "model = tp.models.FCN(input_space=, output_space=, hidden=(30,30,30))" ] }, @@ -167,7 +168,7 @@ "outputs": [], "source": [ "def pde_residual(u, x, t):\n", - " # in the differential operators you have to pass in the correct variables \n", + " # TODO: Pass in the correct variables \n", " # for the derivative computation as the second argument:\n", " return tp.utils.grad(u, ) - 0.1*tp.utils.laplacian(u, ) - 1.0\n", "\n", @@ -212,11 +213,11 @@ "metadata": {}, "outputs": [], "source": [ - "# Implement the residual for the initial condition:\n", + "# TODO: Implement the residual for the initial condition:\n", "def initial_residual(u):\n", " return \n", "\n", - "initial_cond = tp.conditions.PINNCondition() # add the model, sampler and residual" + "initial_cond = tp.conditions.PINNCondition() # TODO: Add the model, sampler and residual" ] }, { @@ -238,7 +239,7 @@ "outputs": [], "source": [ "optim = tp.OptimizerSetting(torch.optim.Adam, lr=0.005)\n", - "solver = tp.solver.Solver([.,.], optimizer_setting=optim)" + "solver = tp.solver.Solver([.,.], optimizer_setting=optim) # TODO: Collect all conditions" ] }, { @@ -282,7 +283,7 @@ "metadata": {}, "outputs": [], "source": [ - "plot_sampler = tp.samplers.PlotSampler(plot_domain=omega, n_points=2000, data_for_other_variables={\"t\": 0.0})\n", + "plot_sampler = tp.samplers.PlotSampler(plot_domain=omega, n_points=2000, data_for_other_variables={\"t\": 0.1})\n", "fig = tp.utils.plot(model, lambda u : u, plot_sampler)\n", "\n", "\n", diff --git a/examples/new_examples/Exercise_5.ipynb b/examples/new_examples/Exercise_5.ipynb new file mode 100644 index 00000000..aa40fc1b --- /dev/null +++ b/examples/new_examples/Exercise_5.ipynb @@ -0,0 +1,556 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Heat equation on a time-dependent domain: Example 5\n", + "\n", + "With the knowledge gained from the previous examples, we can now solve the drilling problem. Here, we consider\n", + "the heat equation on a time-dependent domain. For the PDE we consider, for $t\\in[0, 5]$,\n", + "\\begin{align*}\n", + " \\partial_t u(x, t) -0.1\\Delta u(x, t) &= 0.0, && \\text{ in } \\Omega(t), \\\\\n", + " u(x, 0) &= 0 , && \\text{ in } \\Omega(0), \\\\\n", + " u(x, t) &= 0 , &&\\text{ for } x_2=0, \\\\\n", + " -\\kappa \\nabla u(x, t)\\cdot n &= 0 , &&\\text{ on } \\Gamma_N(t), \\\\\n", + " -\\kappa \\nabla u(x, t)\\cdot n &= f , &&\\text{ on } \\Gamma_H(t).\n", + "\\end{align*}\n", + "\n", + "Here, $\\Omega(t) = ([0, 1] \\times [0, 1]) \\setminus D(t)$ and $D(t) = [0.2, 0.4] \\times [h(t), 1.0]$, with\n", + "\\begin{align*}\n", + " h(t) = 1.0 - v_\\text{drill} * t,\n", + "\\end{align*}\n", + "such that $h(t)$ describes the depth of the drill at point $t$ and we remove a rectangular part from our domain.\n", + "\n", + "The boundary parts are given by\n", + "\\begin{align*}\n", + " \\Gamma_H(t) &= [0.2, 0.4] \\times \\{h(t)\\}, \\\\\n", + " \\Gamma_N(t) &= \\partial ([0, 1] \\times [0, 1]) \\setminus (\\{x_2=0\\} \\cup \\Gamma_H(t)),\n", + "\\end{align*}\n", + "e.g. at the bottom boundary we have a fixed temperature $u=0$, at the bottom of the drill part a heat source and \n", + "everywhere else homogeneous Neumann conditions.\n", + "\n", + "First we have to install the library:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torchphysics as tp\n", + "import pytorch_lightning as pl\n", + "import math \n", + "\n", + "# Here all parameters are defined:\n", + "t_min, t_max = 0.0, 5.0\n", + "t_prod_end = 5.0\n", + "prod_speed = 1.0 # speed of heating \n", + "\n", + "size_x, size_y = 1.0, 1.0\n", + "x_start, x_end = 0.2, 0.4 # x-size of drill hole\n", + "y_end = 0.4 # end height of drill hole\n", + "\n", + "drill_speed = (size_y - y_end) / (t_prod_end)\n", + "\n", + "kappa = 0.1 # heat diffusion\n", + "\n", + "# Function for heat source\n", + "def f(t, x):\n", + " heat_source = 80 * (x[:, :1] - x_start) * (x_end - x[:, :1])\n", + " heat_source *= (1.0 - torch.exp(-prod_speed*t))\n", + " return heat_source\n", + "\n", + "# Movement of drill (returns the y position of the bottom of the drill head)\n", + "def drill_height(t):\n", + " height = size_y - drill_speed * t\n", + " return height" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# First we have to implement the spaces that appear:\n", + "X = tp.spaces.R2('x')\n", + "T = tp.spaces.R1('t')\n", + "U = tp.spaces.R1('u')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we handle the time dependent domain. The basic domain creation is like we have seen before.\n", + "Special here is now, that we use Pyhton-functions to describe the corners of our drill hole.\n", + "\n", + "To create our domain, we define first the square $[0, 1] \\times [0, 1]$ and then substract the drill hole (a \n", + "time dependent square) from it." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the unit square \n", + "box = ...\n", + "\n", + "# This is the lower left corner of our drill hole. At a given input t, we have to return \n", + "# the correct coordinate of the left lower corner.\n", + "def left_corner(t):\n", + " # First construct a tensor, where we can input the correct corrdinates.\n", + " # The x-coordinate is \n", + " coordinate = x_start * torch.ones((len(t), 2), device=t.device)\n", + " coordinate[:, 1:] = drill_height(t)\n", + " return coordinate\n", + "\n", + "# TODO: Implement the lower right corner:\n", + "def right_corner(t):\n", + " pass\n", + "\n", + "# Now we can use the above functions as input arguments in the Parallelogram.\n", + "# The top left corner is fixed (outside our square for numerical reasons), such that we obtain \n", + "# a rectangle that grows in the negative y direction in time.\n", + "drill_hole = tp.domains.Parallelogram(X, left_corner, right_corner, [x_start, size_y+0.1])\n", + "\n", + "# TODO: Construct the difference of the \"box\" and \"drill_hole\"\n", + "omega = ...\n", + "\n", + "# TODO: Implement the time interval\n", + "I_t = ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The defined domain $\\Omega$ is now dependent on time, since the *drill_hole* depends on time.\n", + "This we have to keep in mind when we want to create points inside this domain. To sample points we\n", + "we have to say what time point $t$ we are considering, e.g. we can only sample in $\\Omega \\times [0, T]$.\n", + "\n", + "This order is also important for the *Samplers* in TorchPhysics. If we input the Cartesian Product *omega \\* I_t*, the sampler will create points from right to left, first points in the time interval and then pass them to the space domain to create valid points. \n", + "\n", + "The combination *I_t \\* omega* does **not** work. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Experiment a bit with different Samplers and number of points to get a feeling of the\n", + "# time dependent domain.\n", + "\n", + "inner_sampler = tp.samplers.RandomUniformSampler(omega * I_t, 5000)\n", + "bc_sampler = tp.samplers.RandomUniformSampler(box.boundary*I_t, 2000)\n", + "\n", + "# One can also multiply (create the Cartesian product) of the samplers, which allows for \n", + "# grid sampling. \n", + "time_sampler = tp.samplers.GridSampler(I_t, 10)\n", + "drill_sampler = tp.samplers.RandomUniformSampler(drill_hole.boundary, 50) * time_sampler\n", + "\n", + "# With scatter we can visualize one example batch of points.\n", + "# First argument: The space over which we want to plot (here either: X, T or X*T)\n", + "# Later arguments all sampler we want to visualize.\n", + "# Note: The points in the plot not always have the correct three-dimensional \"depth\", \n", + "# they may incorrectly appear behind or in front of each other.\n", + "fig = tp.utils.scatter(X, drill_sampler, bc_sampler)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For training we use the following sampler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# When making a sampler static (e.g. fixing the points it creates) we can also pass an \n", + "# after how many training iterations it will create new points.\n", + "# We do this here to speed up the training process, since sampling in time dependent domains\n", + "# is a little bit slower than in normal domains. \n", + "inner_sampler = tp.samplers.RandomUniformSampler(omega * I_t, 75000).make_static(resample_interval=250)\n", + "bc_sampler = tp.samplers.RandomUniformSampler(box.boundary*I_t, 25000)\n", + "\n", + "time_sampler = tp.samplers.GridSampler(I_t, 120).make_static()\n", + "drill_sampler = tp.samplers.RandomUniformSampler(drill_hole.boundary, 2000) * time_sampler" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Next the neural network:\n", + "model = tp.models.FCN(input_space=X*T, output_space=U, \n", + " hidden=(80, 80, 80, 80, 80, 80, 80))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To simplify the training procedure, we implement some conditions into the network architecture by using the so called *hard constrains*.\n", + "These include the initial condition $u(\\cdot, 0) = 0$ and the Dirichlet condition at the lower boundary. \n", + "A simple way to achieve this, is to multiply the output of the neural network by some factors such that the conditions are fulfilled.\n", + "\n", + "In our case this is possible with\n", + "\\begin{align*}\n", + " u \\cdot (1.0 - e^{-t}) \\cdot x_2,\n", + "\\end{align*}\n", + "where $u$ is the output of the neural network." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the hard constrains\n", + "def constrain_fn(u, x, t):\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we implement the PDE via the *PINNCondition* as we did before." + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "# Start we the heat equation\n", + "def pde_residual(u, x, t):\n", + " u = constrain_fn(u, x, t) # here remember to apply our constrain \n", + " return kappa * tp.utils.laplacian(u, x) - tp.utils.grad(u, t)\n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition', weight=50)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Next the boundary conditions at the drill hole:\n", + "tol = 0.0001 # small tolerance for filtering points\n", + "\n", + "def drill_residual(u, x, t):\n", + " u = constrain_fn(u, x, t)\n", + "\n", + " resiudal = torch.zeros_like(u) # a tensor to write the residual into\n", + " normal_vectors = -drill_hole.boundary.normal(x, {\"t\": t})\n", + " u_n = tp.utils.normal_derivative(u, normal_vectors, x)\n", + " \n", + " # Evaluate heat source everywhere (filter out correct points later)\n", + " heat_source = f(t, x) \n", + " # The upper boundary of our drill hole rectangle is not inside the domain\n", + " # -> filter out the correct points\n", + " point_in_domain = (x[:, 1:] <= size_y)\n", + "\n", + " # Homogeneous Neumann condition on drill hole\n", + " resiudal[point_in_domain] = u_n[point_in_domain]\n", + " \n", + " # On the bottom side on the hole we have a heat source.\n", + " # First filter the points: \n", + " drill_section_x = torch.logical_and(x[:, :1] > x_start + tol, x[:, :1] < x_end - tol)\n", + " drill_section = torch.logical_and(point_in_domain, drill_section_x)\n", + " # Then construct residual:\n", + " resiudal[drill_section] = (u_n - heat_source/kappa)[drill_section]\n", + "\n", + " return resiudal\n", + "\n", + "drill_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=drill_sampler,\n", + " residual_fn=drill_residual,\n", + " name='drill_condition', weight=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the condition for the outer boundary (not on the drill hole)\n", + "\n", + "def bc_residual(u, x, t):\n", + " # Apply constrains:\n", + " \n", + " # Compute normal vectors and derivative:\n", + "\n", + " # Construct residual:\n", + "\n", + " return \n", + "\n", + "bc_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=bc_sampler,\n", + " residual_fn=bc_residual,\n", + " name='bc_condition', weight=100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we can start the training of the neural network. \n", + "In our testing we found that first only training the boundary condition on the drill part is helpful:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=1.e-4)\n", + "solver = tp.solver.Solver([drill_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=2500, \n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we combine all loss terms in the training process. Here, we only train for a short time frame. Because we need a rather large network and the GPUs on Google Colab at not that fast, the training is slow. \n", + "\n", + "But we can still obtain a good first approximation and in the later cells also load a pretrained network, that we trained for roughly 25 minutes on a RTX 2080 beforehand." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=1.e-3) \n", + "solver = tp.solver.Solver([pde_condition, drill_condition, bc_condition],\n", + " optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=1500,\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we can have a look on the learned solution:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "anim_sampler = tp.samplers.AnimationSampler(omega, I_t, 100, n_points=1000)\n", + "fig, anim = tp.utils.animate(model, lambda u, t, x: constrain_fn(u, x, t), \n", + " anim_sampler, ani_speed=10, ani_type='contour_surface')\n", + "anim.save('moving-heat-eq.gif')\n", + "# On Google colab you have at the left side a tab with a folder. There you can find the gif and can watch it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We also prepared a FEM-solution for comparision. First, we download the data from GitHub and then read it with\n", + "numpy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/time_points.npy\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/coordinates.npy\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/solution.npy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "time_points = np.load(\"time_points.npy\")\n", + "coords = np.load(\"coordinates.npy\")\n", + "fem_sol = np.load(\"solution.npy\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Now evaluate the PINN solution at the FEM-points and compare the solution.\n", + "pinn_sol = torch.zeros((len(time_points), len(coords[0])))\n", + "\n", + "for i in range(len(time_points)):\n", + " input_points = torch.zeros((len(coords[i]), 3))\n", + " input_points[:, :2] = torch.tensor(coords[i], dtype=torch.float32)\n", + " input_points[:, 2] = time_points[i]\n", + " model_out = model(tp.spaces.Points(input_points, X*T)).as_tensor\n", + " pinn_sol[i, :] = constrain_fn(model_out, input_points[:, :2], input_points[:, 2:]).flatten()\n", + "\n", + "print(\"Difference to FEM in Sup-norm:\")\n", + "difference_sup = np.max(np.abs(fem_sol - pinn_sol.detach().numpy()))\n", + "print(\"Absolute:\", difference_sup)\n", + "print(\"Relative:\", difference_sup / np.max(fem_sol))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since we only trained for a short time frame, the relative error is still large.\n", + "Therefore, we also prepared a neural network that has been trained a bit longer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get the network from Github\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/model_drilling.pt" + ] + }, + { + "cell_type": "code", + "execution_count": 175, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 175, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The following lines show how one can save and load a neural network\n", + "torch.save(model.state_dict(), 'model_drilling_short_training.pt')\n", + "\n", + "model.load_state_dict(torch.load('model_drilling.pt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We evaluate the new model and obtain a relative error of around 9%." + ] + }, + { + "cell_type": "code", + "execution_count": 176, + "metadata": {}, + "outputs": [], + "source": [ + "pinn_sol = torch.zeros((len(time_points), len(coords[0])))\n", + "\n", + "for i in range(len(time_points)):\n", + " input_points = torch.zeros((len(coords[i]), 3))\n", + " input_points[:, :2] = torch.tensor(coords[i], dtype=torch.float32)\n", + " input_points[:, 2] = time_points[i]\n", + " model_out = model(tp.spaces.Points(input_points, X*T)).as_tensor\n", + " pinn_sol[i, :] = constrain_fn(model_out, input_points[:, :2], input_points[:, 2:]).flatten()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Difference to FEM in Sup-norm:\")\n", + "difference_sup = np.max(np.abs(fem_sol - pinn_sol.detach().numpy()))\n", + "print(\"Absolute:\", difference_sup)\n", + "print(\"Relative:\", difference_sup / np.max(fem_sol))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/new_examples/Exercise_9.ipynb b/examples/new_examples/Exercise_9.ipynb new file mode 100644 index 00000000..40da666b --- /dev/null +++ b/examples/new_examples/Exercise_9.ipynb @@ -0,0 +1,1466 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "LWURJEwMXGB6" + }, + "source": [ + "# Physics-informed-DeepONet: Example 9\n", + "\n", + "Now we want to train the PI-DeepONet variant, where no solution data is needed. On Google colab this approach is not feasible for problems with multiple higher order derivatives, because it becomes too memory and computational expensive. Because of this, we switch to a simple ODE:\n", + "\n", + "\\begin{align*}\n", + " \\partial_t u(t) &= f(t), \\text{ in } [0, 1] \\\\\n", + " u(0) &= 0\n", + "\\end{align*}\n", + "\n", + "This ODE will guide us through the implementation and gives a simple introduction to PI-DeepONets. Our goal is to learn the integral operator for different $f$.\n", + "\n", + "First, we have to again install the library:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "jmBQTvy8XDMz", + "outputId": "d825df37-9504-4525-a5d8-df01d760dcc8" + }, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics\n", + "\n", + "import torch\n", + "import torchphysics as tp\n", + "import pytorch_lightning as pl" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xJMAXc6zYKjq", + "outputId": "57815226-0b7a-49ff-fe88-4b4f60dd3b55" + }, + "outputs": [], + "source": [ + "# Spaces \n", + "T = tp.spaces.R1('t') # input variable\n", + "U = tp.spaces.R1('u') # output variable\n", + "K = tp.spaces.R1('k') # parameter\n", + "F = tp.spaces.R1('f') # function output space name\n", + "# Domains\n", + "T_int = tp.domains.Interval(T, 0, 1)\n", + "K_int = tp.domains.Interval(K, 0, 6) # Parameters to sample f will be scalar values\n", + "# Defining the FunctionSpace\n", + "Fn_space = tp.spaces.FunctionSpace(T_int, F)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will consider three different types of function types for $f$. These are:\n", + "\\begin{align*}\n", + " f_1(t) &= k t\\\\\n", + " f_2(t) &= k t^2\\\\\n", + " f_3(t) &= k \\cos{(k t)}\n", + "\\end{align*}\n", + "Here, $k$ is a random parameter that lead to different slopes and amplitude." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement f2 und f3\n", + "def f1(k, t):\n", + " return k*t\n", + "\n", + "def f2(k, t):\n", + " return \n", + "\n", + "def f3(k, t):\n", + " return \n", + "\n", + "param_sampler = tp.samplers.RandomUniformSampler(K_int, n_points=80)\n", + "\n", + "# Each function f gives a FunctionSet, where we can sample functions for the right hand side from:\n", + "Fn_set_1 = tp.domains.CustomFunctionSet(Fn_space, param_sampler, f1)\n", + "# TODO: Complete the FunctionSet for f2 and f3 using the same param_sampler\n", + "Fn_set_2 = tp.domains.CustomFunctionSet() \n", + "Fn_set_3 = tp.domains.CustomFunctionSet()\n", + "\n", + "# With \"+\" we can construct the Union of these sets (this is not the sum of f1+f2+f3, but just the set union)\n", + "Fn_set = Fn_set_1 + Fn_set_2 + Fn_set_3 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next is the DeepONet itself, the definition is the same as in the data driven case. Since our problem is now alot simpler, we can use a smaller network" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Since our input functions are now created on the fly and not given by data, we can\n", + "# use an arbitrary sampler to discretize them.\n", + "dis_sampler = tp.samplers.GridSampler(T_int, 50).make_static()\n", + "\n", + "# TODO: Implement the a fully connected Trunk and Branchnet. The Trunk should have two hidden layers with\n", + "# 30 neurons each and the Branch two hidden layers with 50 neurons.\n", + "trunk_net = tp.models.FCTrunkNet(...)\n", + "branch_net = tp.models.FCBranchNet(...)\n", + "model = tp.models.DeepONet(trunk_net, branch_net, U, output_neurons=50)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement a time sampler (sampling 5000 points) for the ODE condition \n", + "# and the ODE residual (same as for PINNS)\n", + "ode_sampler = ...\n", + "\n", + "def ode_residual(u, t, f): \n", + " # The f is the function that was inputed in the Branch, but now evaluated\n", + " # at the time points that are used in this condition.\n", + " return\n", + "\n", + "# Here we now use the \"PIDeepONetCondition\" instead of the \"PINNCondition\", since\n", + "# we also have to handle the Branch-inputs.\n", + "ode_cond = tp.conditions.PIDeepONetCondition(deeponet_model=model, \n", + " function_set=Fn_set, \n", + " input_sampler=ode_sampler, \n", + " name='ode_condition',\n", + " residual_fn=ode_residual)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# The initial condition is also the same as in PINNs:\n", + "left_sampler = tp.samplers.RandomUniformSampler(T_int.boundary_left, 1000)\n", + "\n", + "def initial_residual(u):\n", + " return u\n", + "\n", + "# TODO: Complete the \"PIDeepONetCondition\"\n", + "initial_cond = tp.conditions.PIDeepONetCondition(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This already finishes the PI-DeepONet implementation and we can start the training." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3,4,5,6,7]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 10.2 K\n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "10.2 K Trainable params\n", + "0 Non-trainable params\n", + "10.2 K Total params\n", + "0.041 Total estimated model params size (MB)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 32 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 32 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ca08676ffe6e401c85ac39bb25935532", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f4c98852fddd40dc851015908c8f9e44", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.0001)\n", + "\n", + "solver = tp.solver.Solver([ode_cond, initial_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=4000,\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Switching to LBFGS, to further tune the network, is helpful in this problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3,4,5,6,7]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 10.2 K\n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "10.2 K Trainable params\n", + "0 Non-trainable params\n", + "10.2 K Total params\n", + "0.041 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d0589d1db0e4485ba6a39a04d41ce5f2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "704c72532358493b987f72ec4addfcb3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "28cbd027f8e94e3da6d608009ecdd61c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.LBFGS, lr=0.4, \n", + " optimizer_args={'max_iter':2, 'history_size': 100})\n", + "\n", + "# Here, use grid of points, since LBFGS needs fixed inputs:\n", + "ode_cond.input_sampler = tp.samplers.GridSampler(T_int, n_points=4000).make_static()\n", + "initial_cond.input_sampler = initial_cond.input_sampler.make_static()\n", + "# Also fix parameters for input functions of the Branch:\n", + "Fn_set_1.parameter_sampler = Fn_set_1.parameter_sampler.make_static()\n", + "Fn_set_2.parameter_sampler = Fn_set_2.parameter_sampler.make_static()\n", + "Fn_set_3.parameter_sampler = Fn_set_3.parameter_sampler.make_static()\n", + "\n", + "\n", + "solver = tp.solver.Solver(train_conditions=[ode_cond, initial_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=3000, \n", + " benchmark=True,\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check the accuracy of the learned integrator:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def F1(k, t):\n", + " return k/2.0 * t**2\n", + "\n", + "def F2(k, t):\n", + " return k/3.0 * t**3\n", + "\n", + "def F3(k, t):\n", + " return torch.sin(k*t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "k_test = 5.16\n", + "\n", + "print(\"Plot one example for each f:\")\n", + "plt.figure(figsize=(10, 4))\n", + "\n", + "\n", + "f = [f1, f2, f3]\n", + "F = [F1, F2, F3]\n", + "\n", + "grid_sampler = tp.samplers.GridSampler(T_int, 500)\n", + "grid_points = grid_sampler.sample_points().as_tensor\n", + "\n", + "for j in range(3):\n", + " def f_helper(t):\n", + " return f[j](k_test, t)\n", + " \n", + " plt.subplot(1, 3, j+1)\n", + " plt.plot(grid_points, F[j](k_test, grid_points)) # plot the expected solution\n", + "\n", + " model.fix_branch_input(f_helper)\n", + " out = model(tp.spaces.Points(grid_points, T)).as_tensor.detach()[0]\n", + " plt.plot(grid_points, out, linestyle=\"--\") # plot network output\n", + " plt.grid()\n", + " plt.legend([\"Solution u\", \"Network output\"])\n", + "\n", + "plt.tight_layout()" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.15" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "0596c4022b754db396349c408529b39a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": "100%" + } + }, + "06a43d890f32453eb7b8e7da71f5d4bb": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0eb7d129999f4abc890134f28551781a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5fb4cf6e97d1403ea1ac9506c05ccc03", + "placeholder": "​", + "style": "IPY_MODEL_6451ed0ec3ee4d418f03b658c60a48d9", + "value": "Validation DataLoader 0: 100%" + } + }, + "103def06d6434f4a8dcdcf84a48c4e08": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7da5216ed5574efe879eb4391b23f900", + "placeholder": "​", + "style": "IPY_MODEL_06a43d890f32453eb7b8e7da71f5d4bb", + "value": " 3001/3001 [00:43<00:00, 69.73it/s, loss=0.000255]" + } + }, + "122cd23c57044fb9bb9503b7aac6cd34": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "1cb0e2237ddc4857a1b2f8f8cf6d366d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5e3287ced6f04769a756ae031eb84bed", + "max": 3001, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7449c75be87d4b8ca841693e020a99d6", + "value": 3001 + } + }, + "2a3f4039db554fbba6849de46c9feb7d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2d1571180c6c49b89e38c5bb38556704": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "41cc5db22b414e1997fe88c9153e6888": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "100%" + } + }, + "505ef0a22f514bb8a810ebf667f0499c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "53b8ebb34f744673b6d220857ad9cc93": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_505ef0a22f514bb8a810ebf667f0499c", + "placeholder": "​", + "style": "IPY_MODEL_a6fa22463e014fe0af71869a90e33c5f", + "value": " 1/1 [00:00<00:00, 237.75it/s]" + } + }, + "5e3287ced6f04769a756ae031eb84bed": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5e7bfcbd4dce41199186c5dae97afb0e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": "100%" + } + }, + "5f50e606f182489cae643b52a8bc5fd5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "5fb4cf6e97d1403ea1ac9506c05ccc03": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6451ed0ec3ee4d418f03b658c60a48d9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "717b98e49cbb4831bcccb5bfcd2d79a5": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7449c75be87d4b8ca841693e020a99d6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "7da5216ed5574efe879eb4391b23f900": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7ea917bfb0594836b7729ccda3e368fd": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_af105b53fd3544989dac937f13abceb7", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5f50e606f182489cae643b52a8bc5fd5", + "value": 1 + } + }, + "8f9a02cd7be043bf89768ca4f96a084d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_0eb7d129999f4abc890134f28551781a", + "IPY_MODEL_7ea917bfb0594836b7729ccda3e368fd", + "IPY_MODEL_53b8ebb34f744673b6d220857ad9cc93" + ], + "layout": "IPY_MODEL_5e7bfcbd4dce41199186c5dae97afb0e" + } + }, + "a3258c3e45414be9889540ea399dc78b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_b75c806f29f24ddbbb2b76482ca46991", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_d103b7a673bb4fe295b118c48ab84275", + "value": 1 + } + }, + "a6fa22463e014fe0af71869a90e33c5f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "af105b53fd3544989dac937f13abceb7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b75c806f29f24ddbbb2b76482ca46991": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c8d8a13e6371478887b93bc7e39c61f1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d02dea15914b4c1581cfccd5f9e397f8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_f59a409bd70c4af8847679adcca05c01", + "IPY_MODEL_1cb0e2237ddc4857a1b2f8f8cf6d366d", + "IPY_MODEL_103def06d6434f4a8dcdcf84a48c4e08" + ], + "layout": "IPY_MODEL_41cc5db22b414e1997fe88c9153e6888" + } + }, + "d103b7a673bb4fe295b118c48ab84275": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "d7ef3e58242b45cfb4b2b76f667dbe22": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_717b98e49cbb4831bcccb5bfcd2d79a5", + "placeholder": "​", + "style": "IPY_MODEL_2a3f4039db554fbba6849de46c9feb7d", + "value": "Sanity Checking DataLoader 0: 100%" + } + }, + "da03fd37a5844453ab54ce1bc726e951": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c8d8a13e6371478887b93bc7e39c61f1", + "placeholder": "​", + "style": "IPY_MODEL_122cd23c57044fb9bb9503b7aac6cd34", + "value": " 1/1 [00:00<00:00, 404.00it/s]" + } + }, + "e6970710f4db45d6b4f744de34a09ff2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "f4894f8957534adc85f76915adb831e9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_d7ef3e58242b45cfb4b2b76f667dbe22", + "IPY_MODEL_a3258c3e45414be9889540ea399dc78b", + "IPY_MODEL_da03fd37a5844453ab54ce1bc726e951" + ], + "layout": "IPY_MODEL_0596c4022b754db396349c408529b39a" + } + }, + "f59a409bd70c4af8847679adcca05c01": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_2d1571180c6c49b89e38c5bb38556704", + "placeholder": "​", + "style": "IPY_MODEL_e6970710f4db45d6b4f744de34a09ff2", + "value": "Epoch 0: 100%" + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/new_examples/Sol_5.ipynb b/examples/new_examples/Sol_5.ipynb new file mode 100644 index 00000000..2d742cdc --- /dev/null +++ b/examples/new_examples/Sol_5.ipynb @@ -0,0 +1,582 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Heat equation on a time-dependent domain: Example 5\n", + "\n", + "With the knowledge gained from the previous examples, we can now solve the drilling problem. Here, we consider\n", + "the heat equation on a time-dependent domain. For the PDE we consider, for $t\\in[0, 5]$,\n", + "\\begin{align*}\n", + " \\partial_t u(x, t) -0.1\\Delta u(x, t) &= 0.0, && \\text{ in } \\Omega(t), \\\\\n", + " u(x, 0) &= 0 , && \\text{ in } \\Omega(0), \\\\\n", + " u(x, t) &= 0 , &&\\text{ for } x_2=0, \\\\\n", + " -\\kappa \\nabla u(x, t)\\cdot n &= 0 , &&\\text{ on } \\Gamma_N(t), \\\\\n", + " -\\kappa \\nabla u(x, t)\\cdot n &= f , &&\\text{ on } \\Gamma_H(t).\n", + "\\end{align*}\n", + "\n", + "Here, $\\Omega(t) = ([0, 1] \\times [0, 1]) \\setminus D(t)$ and $D(t) = [0.2, 0.4] \\times [h(t), 1.0]$, with\n", + "\\begin{align*}\n", + " h(t) = 1.0 - v_\\text{drill} * t,\n", + "\\end{align*}\n", + "such that $h(t)$ describes the depth of the drill at point $t$ and we remove a rectangular part from our domain.\n", + "\n", + "The boundary parts are given by\n", + "\\begin{align*}\n", + " \\Gamma_H(t) &= [0.2, 0.4] \\times \\{h(t)\\}, \\\\\n", + " \\Gamma_N(t) &= \\partial ([0, 1] \\times [0, 1]) \\setminus (\\{x_2=0\\} \\cup \\Gamma_H(t)),\n", + "\\end{align*}\n", + "e.g. at the bottom boundary we have a fixed temperature $u=0$, at the bottom of the drill part a heat source and \n", + "everywhere else homogeneous Neumann conditions.\n", + "\n", + "First we have to install the library:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torchphysics as tp\n", + "import pytorch_lightning as pl\n", + "import math \n", + "\n", + "# Here all parameters are defined:\n", + "t_min, t_max = 0.0, 5.0\n", + "t_prod_end = 5.0\n", + "prod_speed = 1.0 # speed of heating \n", + "\n", + "size_x, size_y = 1.0, 1.0\n", + "x_start, x_end = 0.2, 0.4 # x-size of drill hole\n", + "y_end = 0.4 # end height of drill hole\n", + "\n", + "drill_speed = (size_y - y_end) / (t_prod_end)\n", + "\n", + "kappa = 0.1 # heat diffusion\n", + "\n", + "# Function for heat source\n", + "def f(t, x):\n", + " heat_source = 80 * (x[:, :1] - x_start) * (x_end - x[:, :1])\n", + " heat_source *= (1.0 - torch.exp(-prod_speed*t))\n", + " return heat_source\n", + "\n", + "# Movement of drill (returns the y position of the bottom of the drill head)\n", + "def drill_height(t):\n", + " height = size_y - drill_speed * t\n", + " return height" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# First we have to implement the spaces that appear:\n", + "X = tp.spaces.R2('x')\n", + "T = tp.spaces.R1('t')\n", + "U = tp.spaces.R1('u')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we handle the time dependent domain. The basic domain creation is like we have seen before.\n", + "Special here is now, that we use Pyhton-functions to describe the corners of our drill hole.\n", + "\n", + "To create our domain, we define first the square $[0, 1] \\times [0, 1]$ and then substract the drill hole (a \n", + "time dependent square) from it." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the unit square \n", + "box = tp.domains.Parallelogram(X, [0.0, 0.0], [size_x, 0.0], [0.0, size_y])\n", + "\n", + "# This is the lower left corner of our drill hole. At a given input t, we have to return \n", + "# the correct coordinate of the left lower corner.\n", + "def left_corner(t):\n", + " # First construct a tensor, where we can input the correct corrdinates.\n", + " # The x-coordinate is \n", + " coordinate = x_start * torch.ones((len(t), 2), device=t.device)\n", + " coordinate[:, 1:] = drill_height(t)\n", + " return coordinate\n", + "\n", + "# TODO: Implement the lower right corner:\n", + "def right_corner(t):\n", + " coordinate = x_end * torch.ones((len(t), 2), device=t.device)\n", + " coordinate[:, 1:] = drill_height(t)\n", + " return coordinate\n", + "\n", + "# Now we can use the above functions as input arguments in the Parallelogram.\n", + "# The top left corner is fixed (outside our square for numerical reasons), such that we obtain \n", + "# a rectangle that grows in the negative y direction in time.\n", + "drill_hole = tp.domains.Parallelogram(X, left_corner, right_corner, [x_start, size_y+0.1])\n", + "\n", + "# TODO: Construct the difference of the \"box\" and \"drill_hole\"\n", + "omega = (box - drill_hole)\n", + "\n", + "# TODO: Implement the time interval\n", + "I_t = tp.domains.Interval(T, t_min, t_max)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The defined domain $\\Omega$ is now dependent on time, since the *drill_hole* depends on time.\n", + "This we have to keep in mind when we want to create points inside this domain. To sample points we\n", + "we have to say what time point $t$ we are considering, e.g. we can only sample in $\\Omega \\times [0, T]$.\n", + "\n", + "This order is also important for the *Samplers* in TorchPhysics. If we input the Cartesian Product *omega \\* I_t*, the sampler will create points from right to left, first points in the time interval and then pass them to the space domain to create valid points. \n", + "\n", + "The combination *I_t \\* omega* does **not** work. " + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# TODO: Experiment a bit with different Samplers and number of points to get a feeling of the\n", + "# time dependent domain.\n", + "\n", + "inner_sampler = tp.samplers.RandomUniformSampler(omega * I_t, 5000)\n", + "bc_sampler = tp.samplers.RandomUniformSampler(box.boundary*I_t, 2000)\n", + "\n", + "# One can also multiply (create the Cartesian product) of the samplers, which allows for \n", + "# grid sampling. \n", + "time_sampler = tp.samplers.GridSampler(I_t, 10)\n", + "drill_sampler = tp.samplers.RandomUniformSampler(drill_hole.boundary, 50) * time_sampler\n", + "\n", + "# With scatter we can visualize one example batch of points.\n", + "# First argument: The space over which we want to plot (here either: X, T or X*T)\n", + "# Later arguments all sampler we want to visualize.\n", + "# Note: The points in the plot not always have the correct three-dimensional \"depth\", \n", + "# they may incorrectly appear behind or in front of each other.\n", + "fig = tp.utils.scatter(X, drill_sampler, bc_sampler)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For training we use the following sampler:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# When making a sampler static (e.g. fixing the points it creates) we can also pass an \n", + "# after how many training iterations it will create new points.\n", + "# We do this here to speed up the training process, since sampling in time dependent domains\n", + "# is a little bit slower than in normal domains. \n", + "inner_sampler = tp.samplers.RandomUniformSampler(omega * I_t, 75000).make_static(resample_interval=250)\n", + "bc_sampler = tp.samplers.RandomUniformSampler(box.boundary*I_t, 25000)\n", + "\n", + "time_sampler = tp.samplers.GridSampler(I_t, 120).make_static()\n", + "drill_sampler = tp.samplers.RandomUniformSampler(drill_hole.boundary, 2000) * time_sampler" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Next the neural network:\n", + "model = tp.models.FCN(input_space=X*T, output_space=U, \n", + " hidden=(80, 80, 80, 80, 80, 80, 80))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To simplify the training procedure, we implement some conditions into the network architecture by using the so called *hard constrains*.\n", + "These include the initial condition $u(\\cdot, 0) = 0$ and the Dirichlet condition at the lower boundary. \n", + "A simple way to achieve this, is to multiply the output of the neural network by some factors such that the conditions are fulfilled.\n", + "\n", + "In our case this is possible with\n", + "\\begin{align*}\n", + " u \\cdot (1.0 - e^{-t}) \\cdot x_2,\n", + "\\end{align*}\n", + "where $u$ is the output of the neural network." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the hard constrains\n", + "def constrain_fn(u, x, t):\n", + " return u * (1.0-torch.exp(-t)) * x[:, 1:]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we implement the PDE via the *PINNCondition* as we did before." + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "# Start we the heat equation\n", + "def pde_residual(u, x, t):\n", + " u = constrain_fn(u, x, t) # here remember to apply our constrain \n", + " return kappa * tp.utils.laplacian(u, x) - tp.utils.grad(u, t)\n", + "\n", + "pde_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=inner_sampler,\n", + " residual_fn=pde_residual,\n", + " name='pde_condition', weight=50)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Next the boundary conditions at the drill hole:\n", + "tol = 0.0001 # small tolerance for filtering points\n", + "\n", + "def drill_residual(u, x, t):\n", + " u = constrain_fn(u, x, t)\n", + "\n", + " resiudal = torch.zeros_like(u) # a tensor to write the residual into\n", + " normal_vectors = -drill_hole.boundary.normal(x, {\"t\": t})\n", + " u_n = tp.utils.normal_derivative(u, normal_vectors, x)\n", + " \n", + " # Evaluate heat source everywhere (filter out correct points later)\n", + " heat_source = f(t, x) \n", + " # The upper boundary of our drill hole rectangle is not inside the domain\n", + " # -> filter out the correct points\n", + " point_in_domain = (x[:, 1:] <= size_y)\n", + "\n", + " # Homogeneous Neumann condition on drill hole\n", + " resiudal[point_in_domain] = u_n[point_in_domain]\n", + " \n", + " # On the bottom side on the hole we have a heat source.\n", + " # First filter the points: \n", + " drill_section_x = torch.logical_and(x[:, :1] > x_start + tol, x[:, :1] < x_end - tol)\n", + " drill_section = torch.logical_and(point_in_domain, drill_section_x)\n", + " # Then construct residual:\n", + " resiudal[drill_section] = (u_n - heat_source/kappa)[drill_section]\n", + "\n", + " return resiudal\n", + "\n", + "drill_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=drill_sampler,\n", + " residual_fn=drill_residual,\n", + " name='drill_condition', weight=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement the condition for the outer boundary (not on the drill hole)\n", + "\n", + "def bc_residual(u, x, t):\n", + " # Apply constrains:\n", + " u = constrain_fn(u, x, t)\n", + " \n", + " # Compute normal vectors and derivative:\n", + " resiudal = torch.zeros_like(u)\n", + " normals = box.boundary.normal(x)\n", + " u_n = tp.utils.normal_derivative(u, normals, x)\n", + "\n", + " # Construct residual:\n", + " resiudal = u_n\n", + "\n", + " lower_boundary = x[:, 1:] < tol # small tolerance for lower boundary\n", + " resiudal[lower_boundary] = u[lower_boundary] # = 0.0 (for fixed temperature)\n", + "\n", + " return resiudal\n", + "\n", + "bc_condition = tp.conditions.PINNCondition(module=model,\n", + " sampler=bc_sampler,\n", + " residual_fn=bc_residual,\n", + " name='bc_condition', weight=100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we can start the training of the neural network. \n", + "In our testing we found that first only training the boundary condition on the drill part is helpful:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=1.e-4)\n", + "solver = tp.solver.Solver([drill_condition], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=2500, \n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we combine all loss terms in the training process. Here, we only train for a short time frame. Because we need a rather large network and the GPUs on Google Colab at not that fast, the training is slow. \n", + "\n", + "But we can still obtain a good first approximation and in the later cells also load a pretrained network, that we trained for roughly 25 minutes on a RTX 2080 beforehand." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "learning_rates = [1.e-3, 2.e-4, 1e-4, 5e-5, 2.5e-5]\n", + "iterations = [1500, 2500, 4000, 1000, 2000]\n", + "for i in range(len(learning_rates)):\n", + " optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=learning_rates[i]) \n", + " solver = tp.solver.Solver([pde_condition, drill_condition, bc_condition],\n", + " optimizer_setting=optim)\n", + "\n", + " trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=iterations[i],\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + " trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we can have a look on the learned solution:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "anim_sampler = tp.samplers.AnimationSampler(omega, I_t, 100, n_points=1000)\n", + "fig, anim = tp.utils.animate(model, lambda u, t, x: constrain_fn(u, x, t), \n", + " anim_sampler, ani_speed=10, ani_type='contour_surface')\n", + "anim.save('moving-heat-eq.gif')\n", + "# On Google colab you have at the left side a tab with a folder. There you can find the gif and can watch it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We also prepared a FEM-solution for comparision. First, we download the data from GitHub and then read it with\n", + "numpy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/time_points.npy\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/coordinates.npy\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/solution.npy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "time_points = np.load(\"time_points.npy\")\n", + "coords = np.load(\"coordinates.npy\")\n", + "fem_sol = np.load(\"solution.npy\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Now evaluate the PINN solution at the FEM-points and compare the solution.\n", + "pinn_sol = torch.zeros((len(time_points), len(coords[0])))\n", + "\n", + "for i in range(len(time_points)):\n", + " input_points = torch.zeros((len(coords[i]), 3))\n", + " input_points[:, :2] = torch.tensor(coords[i], dtype=torch.float32)\n", + " input_points[:, 2] = time_points[i]\n", + " model_out = model(tp.spaces.Points(input_points, X*T)).as_tensor\n", + " pinn_sol[i, :] = constrain_fn(model_out, input_points[:, :2], input_points[:, 2:]).flatten()\n", + "\n", + "print(\"Difference to FEM in Sup-norm:\")\n", + "difference_sup = np.max(np.abs(fem_sol - pinn_sol.detach().numpy()))\n", + "print(\"Absolute:\", difference_sup)\n", + "print(\"Relative:\", difference_sup / np.max(fem_sol))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since we only trained for a short time frame, the relative error is still large.\n", + "Therefore, we also prepared a neural network that has been trained a bit longer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get the network from Github\n", + "!wget https://github.com/TomF98/torchphysics/raw/main/examples/workshop/FEMData/DrillingData/model_drilling.pt" + ] + }, + { + "cell_type": "code", + "execution_count": 175, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 175, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# The following lines show how one can save and load a neural network\n", + "torch.save(model.state_dict(), 'model_drilling_short_training.pt')\n", + "\n", + "model.load_state_dict(torch.load('model_drilling.pt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We evaluate the new model and obtain a relative error of around 9%." + ] + }, + { + "cell_type": "code", + "execution_count": 176, + "metadata": {}, + "outputs": [], + "source": [ + "pinn_sol = torch.zeros((len(time_points), len(coords[0])))\n", + "\n", + "for i in range(len(time_points)):\n", + " input_points = torch.zeros((len(coords[i]), 3))\n", + " input_points[:, :2] = torch.tensor(coords[i], dtype=torch.float32)\n", + " input_points[:, 2] = time_points[i]\n", + " model_out = model(tp.spaces.Points(input_points, X*T)).as_tensor\n", + " pinn_sol[i, :] = constrain_fn(model_out, input_points[:, :2], input_points[:, 2:]).flatten()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Difference to FEM in Sup-norm:\")\n", + "difference_sup = np.max(np.abs(fem_sol - pinn_sol.detach().numpy()))\n", + "print(\"Absolute:\", difference_sup)\n", + "print(\"Relative:\", difference_sup / np.max(fem_sol))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "bosch", + "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.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/new_examples/Sol_9.ipynb b/examples/new_examples/Sol_9.ipynb new file mode 100644 index 00000000..92bcd076 --- /dev/null +++ b/examples/new_examples/Sol_9.ipynb @@ -0,0 +1,1470 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "LWURJEwMXGB6" + }, + "source": [ + "# Physics-informed-DeepONet: Example 9\n", + "\n", + "Now we want to train the PI-DeepONet variant, where no solution data is needed. On Google colab this approach is not feasible for problems with multiple higher order derivatives, because it becomes too memory and computational expensive. Because of this, we switch to a simple ODE:\n", + "\n", + "\\begin{align*}\n", + " \\partial_t u(t) &= f(t), \\text{ in } [0, 1] \\\\\n", + " u(0) &= 0\n", + "\\end{align*}\n", + "\n", + "This ODE will guide us through the implementation and gives a simple introduction to PI-DeepONets. Our goal is to learn the integral operator for different $f$.\n", + "\n", + "First, we have to again install the library:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "jmBQTvy8XDMz", + "outputId": "d825df37-9504-4525-a5d8-df01d760dcc8" + }, + "outputs": [], + "source": [ + "!pip install torchaudio==0.13.0\n", + "!pip install torchphysics\n", + "\n", + "import torch\n", + "import torchphysics as tp\n", + "import pytorch_lightning as pl" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xJMAXc6zYKjq", + "outputId": "57815226-0b7a-49ff-fe88-4b4f60dd3b55" + }, + "outputs": [], + "source": [ + "# Spaces \n", + "T = tp.spaces.R1('t') # input variable\n", + "U = tp.spaces.R1('u') # output variable\n", + "K = tp.spaces.R1('k') # parameter\n", + "F = tp.spaces.R1('f') # function output space name\n", + "# Domains\n", + "T_int = tp.domains.Interval(T, 0, 1)\n", + "K_int = tp.domains.Interval(K, 0, 6) # Parameters to sample f will be scalar values\n", + "# Defining the FunctionSpace\n", + "Fn_space = tp.spaces.FunctionSpace(T_int, F)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will consider three different types of function types for $f$. These are:\n", + "\\begin{align*}\n", + " f_1(t) &= k t\\\\\n", + " f_2(t) &= k t^2\\\\\n", + " f_3(t) &= k \\cos{(k t)}\n", + "\\end{align*}\n", + "Here, $k$ is a random parameter that lead to different slopes and amplitude." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def f1(k, t):\n", + " return k*t\n", + "\n", + "def f2(k, t):\n", + " return k*t**2\n", + "\n", + "def f3(k, t):\n", + " return k*torch.cos(k*t)\n", + "\n", + "param_sampler = tp.samplers.RandomUniformSampler(K_int, n_points=80)\n", + "\n", + "# Each function f gives a FunctionSet, where we can sample functions for the right hand side from:\n", + "Fn_set_1 = tp.domains.CustomFunctionSet(Fn_space, param_sampler, f1)\n", + "# TODO: Complete the FunctionSet for f2 and f3\n", + "Fn_set_2 = tp.domains.CustomFunctionSet(Fn_space, param_sampler, f2) \n", + "Fn_set_3 = tp.domains.CustomFunctionSet(Fn_space, param_sampler, f3)\n", + "\n", + "# With \"+\" we can construct the Union of these sets (this is not the sum of f1+f2+f3, but just the set union)\n", + "Fn_set = Fn_set_1 + Fn_set_2 + Fn_set_3 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next is the DeepONet itself, the definition is the same as in the data driven case. Since our problem is now alot simpler, we can use a smaller network" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Since our input functions are now created on the fly and not given by data, we can\n", + "# use an arbitrary sampler to discretize them.\n", + "dis_sampler = tp.samplers.GridSampler(T_int, 50).make_static()\n", + "\n", + "# TODO: Implement the a fully connected Trunk and Branchnet. The Trunk should have two hidden layers with\n", + "# 30 neurons each and the Branch two hidden layers with 50 neurons.\n", + "trunk_net = tp.models.FCTrunkNet(T, hidden=(30, 30))\n", + "branch_net = tp.models.FCBranchNet(Fn_space, hidden=(50, 50), \n", + " discretization_sampler=dis_sampler)\n", + "model = tp.models.DeepONet(trunk_net, branch_net, U, output_neurons=50)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Implement a time sampler for the ODE condition and the ODE residual (same as for PINNS)\n", + "ode_sampler = tp.samplers.RandomUniformSampler(T_int, 6000)\n", + "\n", + "def ode_residual(u, t, f): \n", + " # The f is the function that was inputed in the Branch, but now evaluated\n", + " # at the time points that are used in this condition.\n", + " return tp.utils.grad(u, t) - f\n", + "\n", + "# Here we now use the \"PIDeepONetCondition\" instead of the \"PINNCondition\", since\n", + "# we also have to handle the Branch-inputs.\n", + "ode_cond = tp.conditions.PIDeepONetCondition(deeponet_model=model, \n", + " function_set=Fn_set, \n", + " input_sampler=ode_sampler, \n", + " name='ode_condition',\n", + " residual_fn=ode_residual)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# The initial condition is also the same as in PINNs:\n", + "left_sampler = tp.samplers.RandomUniformSampler(T_int.boundary_left, 1000)\n", + "\n", + "def initial_residual(u):\n", + " return u\n", + "\n", + "# TODO: Complete the \"PIDeepONetCondition\"\n", + "initial_cond = tp.conditions.PIDeepONetCondition(deeponet_model=model, \n", + " function_set=Fn_set, \n", + " input_sampler=left_sampler, \n", + " name='initial_condition',\n", + " residual_fn=initial_residual)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This already finishes the PI-DeepONet implementation and we can start the training." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3,4,5,6,7]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 10.2 K\n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "10.2 K Trainable params\n", + "0 Non-trainable params\n", + "10.2 K Total params\n", + "0.041 Total estimated model params size (MB)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, train dataloader, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 32 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n", + "/home/tomfre/miniconda3/envs/bosch/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.py:69: UserWarning: The dataloader, val dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 32 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n", + " warnings.warn(*args, **kwargs)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ca08676ffe6e401c85ac39bb25935532", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f4c98852fddd40dc851015908c8f9e44", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.Adam, lr=0.0001)\n", + "\n", + "solver = tp.solver.Solver([ode_cond, initial_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " num_sanity_val_steps=0,\n", + " benchmark=True,\n", + " max_steps=4000,\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + "\n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Switching to LBFGS, to further tune the network, is helpful in this problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "GPU available: True, used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3,4,5,6,7]\n", + "\n", + " | Name | Type | Params\n", + "------------------------------------------------\n", + "0 | train_conditions | ModuleList | 10.2 K\n", + "1 | val_conditions | ModuleList | 0 \n", + "------------------------------------------------\n", + "10.2 K Trainable params\n", + "0 Non-trainable params\n", + "10.2 K Total params\n", + "0.041 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d0589d1db0e4485ba6a39a04d41ce5f2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validation sanity check: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "704c72532358493b987f72ec4addfcb3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Training: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "28cbd027f8e94e3da6d608009ecdd61c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Validating: 0it [00:00, ?it/s]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "optim = tp.OptimizerSetting(optimizer_class=torch.optim.LBFGS, lr=0.4, \n", + " optimizer_args={'max_iter':2, 'history_size': 100})\n", + "\n", + "# Here, use grid of points, since LBFGS needs fixed inputs:\n", + "ode_cond.input_sampler = tp.samplers.GridSampler(T_int, n_points=4000).make_static()\n", + "initial_cond.input_sampler = initial_cond.input_sampler.make_static()\n", + "# Also fix parameters for input functions of the Branch:\n", + "Fn_set_1.parameter_sampler = Fn_set_1.parameter_sampler.make_static()\n", + "Fn_set_2.parameter_sampler = Fn_set_2.parameter_sampler.make_static()\n", + "Fn_set_3.parameter_sampler = Fn_set_3.parameter_sampler.make_static()\n", + "\n", + "\n", + "solver = tp.solver.Solver(train_conditions=[ode_cond, initial_cond], optimizer_setting=optim)\n", + "\n", + "trainer = pl.Trainer(gpus=1,\n", + " max_steps=3000, \n", + " benchmark=True,\n", + " logger=False, \n", + " enable_checkpointing=False\n", + " )\n", + " \n", + "trainer.fit(solver)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check the accuracy of the learned integrator:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def F1(k, t):\n", + " return k/2.0 * t**2\n", + "\n", + "def F2(k, t):\n", + " return k/3.0 * t**3\n", + "\n", + "def F3(k, t):\n", + " return torch.sin(k*t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "k_test = 5.16\n", + "\n", + "print(\"Plot one example for each f:\")\n", + "plt.figure(figsize=(10, 4))\n", + "\n", + "\n", + "f = [f1, f2, f3]\n", + "F = [F1, F2, F3]\n", + "\n", + "grid_sampler = tp.samplers.GridSampler(T_int, 500)\n", + "grid_points = grid_sampler.sample_points().as_tensor\n", + "\n", + "for j in range(3):\n", + " def f_helper(t):\n", + " return f[j](k_test, t)\n", + " \n", + " plt.subplot(1, 3, j+1)\n", + " plt.plot(grid_points, F[j](k_test, grid_points)) # plot the expected solution\n", + "\n", + " model.fix_branch_input(f_helper)\n", + " out = model(tp.spaces.Points(grid_points, T)).as_tensor.detach()[0]\n", + " plt.plot(grid_points, out, linestyle=\"--\") # plot network output\n", + " plt.grid()\n", + " plt.legend([\"Solution u\", \"Network output\"])\n", + "\n", + "plt.tight_layout()" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.15" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "0596c4022b754db396349c408529b39a": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": "100%" + } + }, + "06a43d890f32453eb7b8e7da71f5d4bb": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0eb7d129999f4abc890134f28551781a": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5fb4cf6e97d1403ea1ac9506c05ccc03", + "placeholder": "​", + "style": "IPY_MODEL_6451ed0ec3ee4d418f03b658c60a48d9", + "value": "Validation DataLoader 0: 100%" + } + }, + "103def06d6434f4a8dcdcf84a48c4e08": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7da5216ed5574efe879eb4391b23f900", + "placeholder": "​", + "style": "IPY_MODEL_06a43d890f32453eb7b8e7da71f5d4bb", + "value": " 3001/3001 [00:43<00:00, 69.73it/s, loss=0.000255]" + } + }, + "122cd23c57044fb9bb9503b7aac6cd34": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "1cb0e2237ddc4857a1b2f8f8cf6d366d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5e3287ced6f04769a756ae031eb84bed", + "max": 3001, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7449c75be87d4b8ca841693e020a99d6", + "value": 3001 + } + }, + "2a3f4039db554fbba6849de46c9feb7d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2d1571180c6c49b89e38c5bb38556704": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "41cc5db22b414e1997fe88c9153e6888": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "100%" + } + }, + "505ef0a22f514bb8a810ebf667f0499c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "53b8ebb34f744673b6d220857ad9cc93": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_505ef0a22f514bb8a810ebf667f0499c", + "placeholder": "​", + "style": "IPY_MODEL_a6fa22463e014fe0af71869a90e33c5f", + "value": " 1/1 [00:00<00:00, 237.75it/s]" + } + }, + "5e3287ced6f04769a756ae031eb84bed": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5e7bfcbd4dce41199186c5dae97afb0e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": "inline-flex", + "flex": null, + "flex_flow": "row wrap", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": "hidden", + "width": "100%" + } + }, + "5f50e606f182489cae643b52a8bc5fd5": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "5fb4cf6e97d1403ea1ac9506c05ccc03": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6451ed0ec3ee4d418f03b658c60a48d9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "717b98e49cbb4831bcccb5bfcd2d79a5": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7449c75be87d4b8ca841693e020a99d6": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "7da5216ed5574efe879eb4391b23f900": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7ea917bfb0594836b7729ccda3e368fd": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_af105b53fd3544989dac937f13abceb7", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5f50e606f182489cae643b52a8bc5fd5", + "value": 1 + } + }, + "8f9a02cd7be043bf89768ca4f96a084d": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_0eb7d129999f4abc890134f28551781a", + "IPY_MODEL_7ea917bfb0594836b7729ccda3e368fd", + "IPY_MODEL_53b8ebb34f744673b6d220857ad9cc93" + ], + "layout": "IPY_MODEL_5e7bfcbd4dce41199186c5dae97afb0e" + } + }, + "a3258c3e45414be9889540ea399dc78b": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "FloatProgressModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_b75c806f29f24ddbbb2b76482ca46991", + "max": 1, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_d103b7a673bb4fe295b118c48ab84275", + "value": 1 + } + }, + "a6fa22463e014fe0af71869a90e33c5f": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "af105b53fd3544989dac937f13abceb7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b75c806f29f24ddbbb2b76482ca46991": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": "2", + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c8d8a13e6371478887b93bc7e39c61f1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "1.2.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d02dea15914b4c1581cfccd5f9e397f8": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_f59a409bd70c4af8847679adcca05c01", + "IPY_MODEL_1cb0e2237ddc4857a1b2f8f8cf6d366d", + "IPY_MODEL_103def06d6434f4a8dcdcf84a48c4e08" + ], + "layout": "IPY_MODEL_41cc5db22b414e1997fe88c9153e6888" + } + }, + "d103b7a673bb4fe295b118c48ab84275": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "ProgressStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "d7ef3e58242b45cfb4b2b76f667dbe22": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_717b98e49cbb4831bcccb5bfcd2d79a5", + "placeholder": "​", + "style": "IPY_MODEL_2a3f4039db554fbba6849de46c9feb7d", + "value": "Sanity Checking DataLoader 0: 100%" + } + }, + "da03fd37a5844453ab54ce1bc726e951": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_c8d8a13e6371478887b93bc7e39c61f1", + "placeholder": "​", + "style": "IPY_MODEL_122cd23c57044fb9bb9503b7aac6cd34", + "value": " 1/1 [00:00<00:00, 404.00it/s]" + } + }, + "e6970710f4db45d6b4f744de34a09ff2": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "DescriptionStyleModel", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "f4894f8957534adc85f76915adb831e9": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HBoxModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_d7ef3e58242b45cfb4b2b76f667dbe22", + "IPY_MODEL_a3258c3e45414be9889540ea399dc78b", + "IPY_MODEL_da03fd37a5844453ab54ce1bc726e951" + ], + "layout": "IPY_MODEL_0596c4022b754db396349c408529b39a" + } + }, + "f59a409bd70c4af8847679adcca05c01": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "1.5.0", + "model_name": "HTMLModel", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_2d1571180c6c49b89e38c5bb38556704", + "placeholder": "​", + "style": "IPY_MODEL_e6970710f4db45d6b4f744de34a09ff2", + "value": "Epoch 0: 100%" + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}