Update Tutorials 0.2 (#490)
This commit is contained in:
committed by
Nicola Demo
parent
beee4cdc0b
commit
6ce0bafc2b
100
tutorials/tutorial12/tutorial.ipynb
vendored
100
tutorials/tutorial12/tutorial.ipynb
vendored
@@ -63,11 +63,11 @@
|
||||
"import torch\n",
|
||||
"\n",
|
||||
"#useful imports\n",
|
||||
"from pina import Condition\n",
|
||||
"from pina.problem import SpatialProblem, TimeDependentProblem\n",
|
||||
"from pina.equation import Equation, FixedValue\n",
|
||||
"from pina.domain import CartesianDomain\n",
|
||||
"from pina.operator import grad, laplacian\n",
|
||||
"from pina import Condition"
|
||||
"from pina.operator import grad, laplacian"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -76,34 +76,50 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# define the burger equation\n",
|
||||
"def burger_equation(input_, output_):\n",
|
||||
" du = grad(output_, input_)\n",
|
||||
" ddu = grad(du, input_, components=[\"dudx\"])\n",
|
||||
" return (\n",
|
||||
" du.extract([\"dudt\"])\n",
|
||||
" + output_.extract([\"u\"]) * du.extract([\"dudx\"])\n",
|
||||
" - (0.01 / torch.pi) * ddu.extract([\"ddudxdx\"])\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# define initial condition\n",
|
||||
"def initial_condition(input_, output_):\n",
|
||||
" u_expected = -torch.sin(torch.pi * input_.extract([\"x\"]))\n",
|
||||
" return output_.extract([\"u\"]) - u_expected\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Burgers1D(TimeDependentProblem, SpatialProblem):\n",
|
||||
"\n",
|
||||
" # define the burger equation\n",
|
||||
" def burger_equation(input_, output_):\n",
|
||||
" du = grad(output_, input_)\n",
|
||||
" ddu = grad(du, input_, components=['dudx'])\n",
|
||||
" return (\n",
|
||||
" du.extract(['dudt']) +\n",
|
||||
" output_.extract(['u'])*du.extract(['dudx']) -\n",
|
||||
" (0.01/torch.pi)*ddu.extract(['ddudxdx'])\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # define initial condition\n",
|
||||
" def initial_condition(input_, output_):\n",
|
||||
" u_expected = -torch.sin(torch.pi*input_.extract(['x']))\n",
|
||||
" return output_.extract(['u']) - u_expected\n",
|
||||
"\n",
|
||||
" # assign output/ spatial and temporal variables\n",
|
||||
" output_variables = ['u']\n",
|
||||
" spatial_domain = CartesianDomain({'x': [-1, 1]})\n",
|
||||
" temporal_domain = CartesianDomain({'t': [0, 1]})\n",
|
||||
" output_variables = [\"u\"]\n",
|
||||
" spatial_domain = CartesianDomain({\"x\": [-1, 1]})\n",
|
||||
" temporal_domain = CartesianDomain({\"t\": [0, 1]})\n",
|
||||
"\n",
|
||||
" domains = {\n",
|
||||
" \"bound_cond1\": CartesianDomain({\"x\": -1, \"t\": [0, 1]}),\n",
|
||||
" \"bound_cond2\": CartesianDomain({\"x\": 1, \"t\": [0, 1]}),\n",
|
||||
" \"time_cond\": CartesianDomain({\"x\": [-1, 1], \"t\": 0}),\n",
|
||||
" \"phys_cond\": CartesianDomain({\"x\": [-1, 1], \"t\": [0, 1]}),\n",
|
||||
" }\n",
|
||||
" # problem condition statement\n",
|
||||
" conditions = {\n",
|
||||
" 'bound_cond1': Condition(domain=CartesianDomain({'x': -1, 't': [0, 1]}), equation=FixedValue(0.)),\n",
|
||||
" 'bound_cond2': Condition(domain=CartesianDomain({'x': 1, 't': [0, 1]}), equation=FixedValue(0.)),\n",
|
||||
" 'time_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': 0}), equation=Equation(initial_condition)),\n",
|
||||
" 'phys_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': [0, 1]}), equation=Equation(burger_equation)),\n",
|
||||
" \"bound_cond1\": Condition(\n",
|
||||
" domain=\"bound_cond1\", equation=FixedValue(0.0)\n",
|
||||
" ),\n",
|
||||
" \"bound_cond2\": Condition(\n",
|
||||
" domain=\"bound_cond2\", equation=FixedValue(0.0)\n",
|
||||
" ),\n",
|
||||
" \"time_cond\": Condition(\n",
|
||||
" domain=\"time_cond\", equation=Equation(initial_condition)\n",
|
||||
" ),\n",
|
||||
" \"phys_cond\": Condition(\n",
|
||||
" domain=\"phys_cond\", equation=Equation(burger_equation)\n",
|
||||
" ),\n",
|
||||
" }"
|
||||
]
|
||||
},
|
||||
@@ -186,20 +202,34 @@
|
||||
"\n",
|
||||
" # define initial condition\n",
|
||||
" def initial_condition(input_, output_):\n",
|
||||
" u_expected = -torch.sin(torch.pi*input_.extract(['x']))\n",
|
||||
" return output_.extract(['u']) - u_expected\n",
|
||||
" u_expected = -torch.sin(torch.pi * input_.extract([\"x\"]))\n",
|
||||
" return output_.extract([\"u\"]) - u_expected\n",
|
||||
"\n",
|
||||
" # assign output/ spatial and temporal variables\n",
|
||||
" output_variables = ['u']\n",
|
||||
" spatial_domain = CartesianDomain({'x': [-1, 1]})\n",
|
||||
" temporal_domain = CartesianDomain({'t': [0, 1]})\n",
|
||||
" output_variables = [\"u\"]\n",
|
||||
" spatial_domain = CartesianDomain({\"x\": [-1, 1]})\n",
|
||||
" temporal_domain = CartesianDomain({\"t\": [0, 1]})\n",
|
||||
"\n",
|
||||
" domains = {\n",
|
||||
" \"bound_cond1\": CartesianDomain({\"x\": -1, \"t\": [0, 1]}),\n",
|
||||
" \"bound_cond2\": CartesianDomain({\"x\": 1, \"t\": [0, 1]}),\n",
|
||||
" \"time_cond\": CartesianDomain({\"x\": [-1, 1], \"t\": 0}),\n",
|
||||
" \"phys_cond\": CartesianDomain({\"x\": [-1, 1], \"t\": [0, 1]}),\n",
|
||||
" }\n",
|
||||
" # problem condition statement\n",
|
||||
" conditions = {\n",
|
||||
" 'bound_cond1': Condition(domain=CartesianDomain({'x': -1, 't': [0, 1]}), equation=FixedValue(0.)),\n",
|
||||
" 'bound_cond2': Condition(domain=CartesianDomain({'x': 1, 't': [0, 1]}), equation=FixedValue(0.)),\n",
|
||||
" 'time_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': 0}), equation=Equation(initial_condition)),\n",
|
||||
" 'phys_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': [0, 1]}), equation=Burgers1DEquation(0.01/torch.pi)),\n",
|
||||
" \"bound_cond1\": Condition(\n",
|
||||
" domain=\"bound_cond1\", equation=FixedValue(0.0)\n",
|
||||
" ),\n",
|
||||
" \"bound_cond2\": Condition(\n",
|
||||
" domain=\"bound_cond2\", equation=FixedValue(0.0)\n",
|
||||
" ),\n",
|
||||
" \"time_cond\": Condition(\n",
|
||||
" domain=\"time_cond\", equation=Equation(initial_condition)\n",
|
||||
" ),\n",
|
||||
" \"phys_cond\": Condition(\n",
|
||||
" domain=\"phys_cond\", equation=Burgers1DEquation(nu=0.01 / torch.pi)\n",
|
||||
" ),\n",
|
||||
" }"
|
||||
]
|
||||
},
|
||||
@@ -223,7 +253,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "pina",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -237,7 +267,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.3"
|
||||
"version": "3.9.21"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
|
||||
156
tutorials/tutorial12/tutorial.py
vendored
156
tutorials/tutorial12/tutorial.py
vendored
@@ -1,156 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# # Tutorial: The `Equation` Class
|
||||
#
|
||||
# [](https://colab.research.google.com/github/mathLab/PINA/blob/master/tutorials/tutorial12/tutorial.ipynb)
|
||||
|
||||
# In this tutorial, we will show how to use the `Equation` Class in PINA. Specifically, we will see how use the Class and its inherited classes to enforce residuals minimization in PINNs.
|
||||
|
||||
# # Example: The Burgers 1D equation
|
||||
|
||||
# We will start implementing the viscous Burgers 1D problem Class, described as follows:
|
||||
#
|
||||
#
|
||||
# $$
|
||||
# \begin{equation}
|
||||
# \begin{cases}
|
||||
# \frac{\partial u}{\partial t} + u \frac{\partial u}{\partial x} &= \nu \frac{\partial^2 u}{ \partial x^2}, \quad x\in(0,1), \quad t>0\\
|
||||
# u(x,0) &= -\sin (\pi x)\\
|
||||
# u(x,t) &= 0 \quad x = \pm 1\\
|
||||
# \end{cases}
|
||||
# \end{equation}
|
||||
# $$
|
||||
#
|
||||
# where we set $ \nu = \frac{0.01}{\pi}$.
|
||||
#
|
||||
# In the class that models this problem we will see in action the `Equation` class and one of its inherited classes, the `FixedValue` class.
|
||||
|
||||
# In[1]:
|
||||
|
||||
|
||||
## routine needed to run the notebook on Google Colab
|
||||
try:
|
||||
import google.colab
|
||||
IN_COLAB = True
|
||||
except:
|
||||
IN_COLAB = False
|
||||
if IN_COLAB:
|
||||
get_ipython().system('pip install "pina-mathlab"')
|
||||
|
||||
import torch
|
||||
|
||||
#useful imports
|
||||
from pina.problem import SpatialProblem, TimeDependentProblem
|
||||
from pina.equation import Equation, FixedValue
|
||||
from pina.domain import CartesianDomain
|
||||
from pina.operator import grad, laplacian
|
||||
from pina import Condition
|
||||
|
||||
|
||||
# In[2]:
|
||||
|
||||
|
||||
class Burgers1D(TimeDependentProblem, SpatialProblem):
|
||||
|
||||
# define the burger equation
|
||||
def burger_equation(input_, output_):
|
||||
du = grad(output_, input_)
|
||||
ddu = grad(du, input_, components=['dudx'])
|
||||
return (
|
||||
du.extract(['dudt']) +
|
||||
output_.extract(['u'])*du.extract(['dudx']) -
|
||||
(0.01/torch.pi)*ddu.extract(['ddudxdx'])
|
||||
)
|
||||
|
||||
# define initial condition
|
||||
def initial_condition(input_, output_):
|
||||
u_expected = -torch.sin(torch.pi*input_.extract(['x']))
|
||||
return output_.extract(['u']) - u_expected
|
||||
|
||||
# assign output/ spatial and temporal variables
|
||||
output_variables = ['u']
|
||||
spatial_domain = CartesianDomain({'x': [-1, 1]})
|
||||
temporal_domain = CartesianDomain({'t': [0, 1]})
|
||||
|
||||
# problem condition statement
|
||||
conditions = {
|
||||
'bound_cond1': Condition(domain=CartesianDomain({'x': -1, 't': [0, 1]}), equation=FixedValue(0.)),
|
||||
'bound_cond2': Condition(domain=CartesianDomain({'x': 1, 't': [0, 1]}), equation=FixedValue(0.)),
|
||||
'time_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': 0}), equation=Equation(initial_condition)),
|
||||
'phys_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': [0, 1]}), equation=Equation(burger_equation)),
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# The `Equation` class takes as input a function (in this case it happens twice, with `initial_condition` and `burger_equation`) which computes a residual of an equation, such as a PDE. In a problem class such as the one above, the `Equation` class with such a given input is passed as a parameter in the specified `Condition`.
|
||||
#
|
||||
# The `FixedValue` class takes as input a value of same dimensions of the output functions; this class can be used to enforce a fixed value for a specific condition, e.g. Dirichlet boundary conditions, as it happens for instance in our example.
|
||||
#
|
||||
# Once the equations are set as above in the problem conditions, the PINN solver will aim to minimize the residuals described in each equation in the training phase.
|
||||
|
||||
# Available classes of equations include also:
|
||||
# - `FixedGradient` and `FixedFlux`: they work analogously to `FixedValue` class, where we can require a constant value to be enforced, respectively, on the gradient of the solution or the divergence of the solution;
|
||||
# - `Laplace`: it can be used to enforce the laplacian of the solution to be zero;
|
||||
# - `SystemEquation`: we can enforce multiple conditions on the same subdomain through this class, passing a list of residual equations defined in the problem.
|
||||
#
|
||||
|
||||
# # Defining a new Equation class
|
||||
|
||||
# `Equation` classes can be also inherited to define a new class. As example, we can see how to rewrite the above problem introducing a new class `Burgers1D`; during the class call, we can pass the viscosity parameter $\nu$:
|
||||
|
||||
# In[3]:
|
||||
|
||||
|
||||
class Burgers1DEquation(Equation):
|
||||
|
||||
def __init__(self, nu = 0.):
|
||||
"""
|
||||
Burgers1D class. This class can be
|
||||
used to enforce the solution u to solve the viscous Burgers 1D Equation.
|
||||
|
||||
:param torch.float32 nu: the viscosity coefficient. Default value is set to 0.
|
||||
"""
|
||||
self.nu = nu
|
||||
|
||||
def equation(input_, output_):
|
||||
return grad(output_, input_, d='t') +\
|
||||
output_*grad(output_, input_, d='x') -\
|
||||
self.nu*laplacian(output_, input_, d='x')
|
||||
|
||||
|
||||
super().__init__(equation)
|
||||
|
||||
|
||||
# Now we can just pass the above class as input for the last condition, setting $\nu= \frac{0.01}{\pi}$:
|
||||
|
||||
# In[4]:
|
||||
|
||||
|
||||
class Burgers1D(TimeDependentProblem, SpatialProblem):
|
||||
|
||||
# define initial condition
|
||||
def initial_condition(input_, output_):
|
||||
u_expected = -torch.sin(torch.pi*input_.extract(['x']))
|
||||
return output_.extract(['u']) - u_expected
|
||||
|
||||
# assign output/ spatial and temporal variables
|
||||
output_variables = ['u']
|
||||
spatial_domain = CartesianDomain({'x': [-1, 1]})
|
||||
temporal_domain = CartesianDomain({'t': [0, 1]})
|
||||
|
||||
# problem condition statement
|
||||
conditions = {
|
||||
'bound_cond1': Condition(domain=CartesianDomain({'x': -1, 't': [0, 1]}), equation=FixedValue(0.)),
|
||||
'bound_cond2': Condition(domain=CartesianDomain({'x': 1, 't': [0, 1]}), equation=FixedValue(0.)),
|
||||
'time_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': 0}), equation=Equation(initial_condition)),
|
||||
'phys_cond': Condition(domain=CartesianDomain({'x': [-1, 1], 't': [0, 1]}), equation=Burgers1DEquation(0.01/torch.pi)),
|
||||
}
|
||||
|
||||
|
||||
# # What's next?
|
||||
|
||||
# Congratulations on completing the `Equation` class tutorial of **PINA**! As we have seen, you can build new classes that inherit `Equation` to store more complex equations, as the Burgers 1D equation, only requiring to pass the characteristic coefficients of the problem.
|
||||
# From now on, you can:
|
||||
# - define additional complex equation classes (e.g. `SchrodingerEquation`, `NavierStokeEquation`..)
|
||||
# - define more `FixedOperator` (e.g. `FixedCurl`)
|
||||
Reference in New Issue
Block a user