* clean `condition` module
* add docs
This commit is contained in:
Nicola Demo
2023-04-18 15:00:26 +02:00
committed by GitHub
parent 736c78fd64
commit 2ca08b5236
18 changed files with 198 additions and 158 deletions

View File

@@ -1,5 +1,5 @@
AbstractProblem
===========
===============
.. currentmodule:: pina.problem.abstract_problem
.. automodule:: pina.problem.abstract_problem
@@ -9,4 +9,3 @@ AbstractProblem
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -7,14 +7,36 @@ Code Documentation
PINN <pinn.rst>
LabelTensor <label_tensor.rst>
Span <span.rst>
Operators <operators.rst>
Plotter <plotter.rst>
Condition <condition.rst>
Location <location.rst>
Model
-----
.. toctree::
:maxdepth: 3
FeedForward <fnn.rst>
DeepONet <deeponet.rst>
ContinuousConv <convolution.rst>
MultiFeedForward <multifeedforward.rst>
Layers
------
.. toctree::
:maxdepth: 3
ContinuousConv <convolution.rst>
Problem
-------
.. toctree::
:maxdepth: 3
AbstractProblem <abstractproblem.rst>
SpatialProblem <spatialproblem.rst>
TimeDependentProblem <timedepproblem.rst>
Operators <operators.rst>
Plotter <plotter.rst>
PINN <pinn.rst>
Condition <condition.rst>
ParametricProblem <parametricproblem.rst>

View File

@@ -7,6 +7,4 @@ Condition
.. autoclass:: Condition
:members:
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -0,0 +1,10 @@
Location
=========
.. currentmodule:: pina.location
.. automodule:: pina.location
.. autoclass:: Location
:members:
:private-members:
:show-inheritance:

View File

@@ -1,5 +1,5 @@
MultiFeedForward
===========
================
.. currentmodule:: pina.model.multi_feed_forward
.. automodule:: pina.model.multi_feed_forward
@@ -7,6 +7,4 @@ MultiFeedForward
.. autoclass:: MultiFeedForward
:members:
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -1,5 +1,5 @@
ParametricProblem
===========
=================
.. currentmodule:: pina.problem.parametric_problem
.. automodule:: pina.problem.parametric_problem
@@ -7,6 +7,4 @@ ParametricProblem
.. autoclass:: ParametricProblem
:members:
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -1,5 +1,5 @@
SpatialProblem
===========
==============
.. currentmodule:: pina.problem.spatial_problem
.. automodule:: pina.problem.spatial_problem
@@ -9,4 +9,3 @@ SpatialProblem
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -1,5 +1,5 @@
TimeDependentProblem
===========
====================
.. currentmodule:: pina.problem.timedep_problem
.. automodule:: pina.problem.timedep_problem
@@ -9,4 +9,3 @@ TimeDependentProblem
:private-members:
:undoc-members:
:show-inheritance:
:noindex:

View File

@@ -82,5 +82,13 @@ class Condition:
if not self._dictvalue_isinstance(kwargs, 'location', Location):
raise TypeError('`location` must be a Location.')
if 'function' in kwargs:
kwargs['function'] = [kwargs['function']]
for i, func in enumerate(kwargs['function']):
if not callable(func):
raise TypeError(
f'`function[{i}]` must be a callable function.')
for key, value in kwargs.items():
setattr(self, key, value)

View File

@@ -6,16 +6,17 @@ from .feed_forward import FeedForward
class MultiFeedForward(torch.nn.Module):
"""
This model allows to create a network with multiple FeedForward combined
together. The user has to define the `forward` method choosing how to
combine the different FeedForward networks.
:param dict dff_dict: dictionary of FeedForward networks.
"""
def __init__(self, dff_dict):
'''
dff_dict: dict of FeedForward objects
'''
def __init__(self, ffn_dict):
super().__init__()
if not isinstance(dff_dict, dict):
if not isinstance(ffn_dict, dict):
raise TypeError
for name, constructor_args in dff_dict.items():
for name, constructor_args in ffn_dict.items():
setattr(self, name, FeedForward(**constructor_args))

View File

@@ -6,36 +6,39 @@ from pina.label_tensor import LabelTensor
def grad(output_, input_, components=None, d=None):
"""
Perform gradient operation. The operator works for
vectorial and scalar functions, with multiple input
coordinates.
Perform gradient operation. The operator works for vectorial and scalar
functions, with multiple input coordinates.
:param output_: output of the PINN, i.e. function values.
:type output_: LabelTensor
:param input_: input of the PINN, i.e. function coordinates.
:type input_: LabelTensor
:param components: function components to apply the operator,
defaults to None.
:type components: list(str), optional
:param d: coordinates of function components to be differentiated,
defaults to None.
:type d: list(str), optional
:param LabelTensor output_: the output tensor onto which computing the
gradient.
:param LabelTensor input_: the input tensor with respect to which computing
the gradient.
:param list(str) components: the name of the output variables to calculate
the gradient for. It should be a subset of the output labels. If None,
all the output variables are considered. Default is None.
:param list(str) d: the name of the input variables on which the gradient is
calculated. d should be a subset of the input labels. If None, all the
input variables are considered. Default is None.
:return: the gradient tensor.
:rtype: LabelTensor
"""
def grad_scalar_output(output_, input_, d):
"""
Perform gradient operation for a scalar function.
Perform gradient operation for a scalar output.
:param LabelTensor output_: the output tensor onto which computing the
gradient. It has to be a column tensor.
:param LabelTensor input_: the input tensor with respect to which
computing the gradient.
:param list(str) d: the name of the input variables on which the
gradient is calculated. d should be a subset of the input labels. If
None, all the input variables are considered. Default is None.
:param output_: output of the PINN, i.e. function values.
:type output_: LabelTensor
:param input_: input of the PINN, i.e. function coordinates.
:type input_: LabelTensor
:param d: coordinates of function components to be differentiated,
defaults to None.
:type d: list(str), optional
:raises RuntimeError: a vectorial function is passed.
:raises RuntimeError: missing derivative labels.
:return: function gradients.
:return: the gradient tensor.
:rtype: LabelTensor
"""
@@ -93,24 +96,25 @@ def grad(output_, input_, components=None, d=None):
def div(output_, input_, components=None, d=None):
"""
Perform divergence operation. The operator works for
vectorial functions, with multiple input coordinates.
Perform divergence operation. The operator works for vectorial functions,
with multiple input coordinates.
:param LabelTensor output_: the output tensor onto which computing the
divergence.
:param LabelTensor input_: the input tensor with respect to which computing
the divergence.
:param list(str) components: the name of the output variables to calculate
the divergence for. It should be a subset of the output labels. If None,
all the output variables are considered. Default is None.
:param list(str) d: the name of the input variables on which the divergence
is calculated. d should be a subset of the input labels. If None, all
the input variables are considered. Default is None.
:param output_: output of the PINN, i.e. function values.
:type output_: LabelTensor
:param input_: input of the PINN, i.e. function coordinates.
:type input_: LabelTensor
:param components: function components to apply the operator,
defaults to None.
:type components: list(str), optional
:param d: coordinates of function components to be differentiated,
defaults to None.
:type d: list(str), optional
:raises TypeError: div operator works only for LabelTensor.
:raises ValueError: div operator works only for vector fields.
:raises ValueError: div operator must derive all components with
respect to all coordinates.
:return: Function divergence.
:return: the divergenge tensor.
:rtype: LabelTensor
"""
if not isinstance(input_, LabelTensor):
@@ -143,27 +147,24 @@ def div(output_, input_, components=None, d=None):
def nabla(output_, input_, components=None, d=None, method='std'):
"""
Perform nabla (laplace) operation. The operator works for
vectorial and scalar functions, with multiple input
coordinates.
Perform nabla (laplace) operator. The operator works for vectorial and
scalar functions, with multiple input coordinates.
:param output_: output of the PINN, i.e. function values.
:type output_: LabelTensor
:param input_: input of the PINN, i.e. function coordinates.
:type input_: LabelTensor
:param components: function components to apply the operator,
defaults to None.
:type components: list(str), optional
:param d: coordinates of function components to be differentiated,
defaults to None.
:type d: list(str), optional
:param method: used method to calculate nabla, defaults to 'std'.
:type method: str, optional including 'divgrad' where first gradient
and later divergece operator are applied.
:param LabelTensor output_: the output tensor onto which computing the
nabla.
:param LabelTensor input_: the input tensor with respect to which computing
the nabla.
:param list(str) components: the name of the output variables to calculate
the nabla for. It should be a subset of the output labels. If None,
all the output variables are considered. Default is None.
:param list(str) d: the name of the input variables on which the nabla
is calculated. d should be a subset of the input labels. If None, all
the input variables are considered. Default is None.
:param str method: used method to calculate nabla, defaults to 'std'.
:raises ValueError: for vectorial field derivative with respect to
all coordinates must be performed.
:raises NotImplementedError: 'divgrad' not implemented as method.
:return: Function nabla.
:return: The tensor containing the result of the nabla operator.
:rtype: LabelTensor
"""
if d is None:
@@ -212,22 +213,22 @@ def nabla(output_, input_, components=None, d=None, method='std'):
def advection(output_, input_, velocity_field, components=None, d=None):
"""
Perform advection operation. The operator works for
vectorial functions, with multiple input coordinates.
Perform advection operation. The operator works for vectorial functions,
with multiple input coordinates.
:param output_: output of the PINN, i.e. function values.
:type output_: LabelTensor
:param input_: input of the PINN, i.e. function coordinates.
:type input_: LabelTensor
:param velocity_field: field used for multiplying the gradient.
:type velocity_field: str
:param components: function components to apply the operator,
defaults to None.
:type components: list(str), optional
:param d: coordinates of function components to be differentiated,
defaults to None.
:type d: list(str), optional
:return: Function advection.
:param LabelTensor output_: the output tensor onto which computing the
nabla.
:param LabelTensor input_: the input tensor with respect to which computing
the nabla.
:param str velocity_field: the name of the output variables which is used
as velocity field. It should be a subset of the output labels.
:param list(str) components: the name of the output variables to calculate
the nabla for. It should be a subset of the output labels. If None,
all the output variables are considered. Default is None.
:param list(str) d: the name of the input variables on which the nabla
is calculated. d should be a subset of the input labels. If None, all
the input variables are considered. Default is None.
:return: the tensor containing the result of the advection operator.
:rtype: LabelTensor
"""
if d is None:

View File

@@ -26,21 +26,22 @@ class PINN(object):
device='cpu',
error_norm='mse'):
'''
:param Problem problem: the formualation of the problem.
:param AbstractProblem problem: the formualation of the problem.
:param torch.nn.Module model: the neural network model to use.
:param torch.optim optimizer: the neural network optimizer to use;
default is `torch.optim.Adam`.
:param torch.optim.Optimizer optimizer: the neural network optimizer to
use; default is `torch.optim.Adam`.
:param dict optimizer_kwargs: Optimizer constructor keyword args.
:param float lr: the learning rate; default is 0.001.
:param torch.optim.lr_scheduler._LRScheduler lr_scheduler_type: Learning rate scheduler.
:param torch.optim.LRScheduler lr_scheduler_type: Learning
rate scheduler.
:param dict lr_scheduler_kwargs: LR scheduler constructor keyword args.
:param float regularizer: the coefficient for L2 regularizer term.
:param type dtype: the data type to use for the model. Valid option are
`torch.float32` and `torch.float64` (`torch.float16` only on GPU);
default is `torch.float64`.
:param string device: the device used for training; default 'cpu'
:param str device: the device used for training; default 'cpu'
option include 'cuda' if cuda is available.
:param string/int error_norm: the loss function used as minimizer,
:param (str, int) error_norm: the loss function used as minimizer,
default mean square error 'mse'. If string options include mean
error 'me' and mean square error 'mse'. If int, the p-norm is
calculated where p is specifined by the int input.
@@ -161,6 +162,9 @@ class PINN(object):
def span_pts(self, *args, **kwargs):
"""
Generate a set of points to span the `Location` of all the conditions of
the problem.
>>> pinn.span_pts(n=10, mode='grid')
>>> pinn.span_pts(n=10, mode='grid', location=['bound1'])
>>> pinn.span_pts(n=10, mode='grid', variables=['x'])

View File

@@ -1,14 +1,9 @@
""" Module for plotting. """
import matplotlib
# matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
import numpy as np
import torch
from pina import LabelTensor
from pina import PINN
from .problem import SpatialProblem, TimeDependentProblem
#from pina.tdproblem1d import TimeDepProblem1D
class Plotter:
@@ -20,11 +15,14 @@ class Plotter:
"""
Plot a sample of solution.
:param pinn: the PINN object.
:type pinn: PINN
:param variables: pinn variable domains: spatial or temporal,
defaults to None.
:type variables: str, optional
:param PINN pinn: the PINN object.
:param list(str) variables: variables to plot. If None, all variables
are plotted. If 'spatial', only spatial variables are plotted. If
'temporal', only temporal variables are plotted. Defaults to None.
.. todo::
- Add support for 3D plots.
- Fix support for more complex problems.
:Example:
>>> plotter = Plotter()
@@ -136,22 +134,20 @@ class Plotter:
"""
Plot sample of PINN output.
:param pinn: the PINN object.
:type pinn: PINN
:param components: function components to plot, defaults to None.
:type components: list['str'], optional
:param fixed_variables: function variables to be kept fixed during
plotting passed as a dict where the dict-key is the variable
and the dict-value is the value to be kept fixed, defaults to {}.
:type fixed_variables: dict, optional
:param method: matplotlib method to plot the solution,
defaults to 'contourf'.
:type method: str, optional
:param res: number of points used for plotting in each axis,
defaults to 256.
:type res: int, optional
:param filename: file name to save the plot, defaults to None
:type filename: str, optional
:param PINN pinn: the PINN object.
:param list(str) components: the output variable to plot. If None, all
the output variables of the problem are selected. Default value is
None.
:param dict fixed_variables: a dictionary with all the variables that
should be kept fixed during the plot. The keys of the dictionary
are the variables name whereas the values are the corresponding
values of the variables. Defaults is `dict()`.
:param {'contourf', 'pcolor'} method: the matplotlib method to use for
plotting the solution. Default is 'contourf'.
:param int res: the resolution, aka the number of points used for
plotting in each axis. Default is 256.
:param str filename: the file name to save the plot. If None, the plot
is shown using the setted matplotlib frontend. Default is None.
"""
if components is None:
components = [pinn.problem.output_variables]
@@ -194,12 +190,10 @@ class Plotter:
"""
Plot the loss function values during traininig.
:param pinn: the PINN object.
:type pinn: PINN
:param label: matplolib label, defaults to None
:type label: str, optional
:param log_scale: use of log scale in plotting, defaults to True.
:type log_scale: bool, optional
:param PINN pinn: the PINN object.
:param str label: the label to use in the legend, defaults to None.
:param bool log_scale: If True, the y axis is in log scale. Default is
True.
"""
if not label:

View File

@@ -18,24 +18,24 @@ class ParametricProblem(AbstractProblem):
>>> from pina.operators import grad
>>> from pina import Condition, Span
>>> import torch
>>>
>>> class ParametricODE(SpatialProblem, ParametricProblem):
>>>
>>> output_variables = ['u']
>>> spatial_domain = Span({'x': [0, 1]})
>>> parameter_domain = Span({'alpha': {1, 10}})
>>>
>>> def ode_equation(input_, output_):
>>> u_x = grad(output_, input_, components=['u'], d=['x'])
>>> u = output_.extract(['u'])
>>> alpha = input_.extract(['alpha'])
>>> return alpha * u_x - u
>>>
>>> def initial_condition(input_, output_):
>>> value = 1.0
>>> u = output_.extract(['u'])
>>> return u - value
>>>
>>> conditions = {
>>> 'x0': Condition(Span({'x': 0, 'alpha':[1, 10]}), initial_condition),
>>> 'D': Condition(Span({'x': [0, 1], 'alpha':[1, 10]}), ode_equation)}

View File

@@ -16,22 +16,19 @@ class SpatialProblem(AbstractProblem):
>>> from pina.operators import grad
>>> from pina import Condition, Span
>>> import torch
>>> class SimpleODE(SpatialProblem):
>>> output_variables = ['u']
>>> spatial_domain = Span({'x': [0, 1]})
>>> def ode_equation(input_, output_):
>>> u_x = grad(output_, input_, components=['u'], d=['x'])
>>> u = output_.extract(['u'])
>>> return u_x - u
>>>
>>> def initial_condition(input_, output_):
>>> value = 1.0
>>> u = output_.extract(['u'])
>>> return u - value
>>>
>>> conditions = {
>>> 'x0': Condition(Span({'x': 0.}), initial_condition),
>>> 'D': Condition(Span({'x': [0, 1]}), ode_equation)}

View File

@@ -16,29 +16,29 @@ class TimeDependentProblem(AbstractProblem):
>>> from pina.operators import grad, nabla
>>> from pina import Condition, Span
>>> import torch
>>>
>>> class Wave(TimeDependentSpatialProblem):
>>>
>>> output_variables = ['u']
>>> spatial_domain = Span({'x': [0, 3]})
>>> temporal_domain = Span({'t': [0, 1]})
>>>
>>> def wave_equation(input_, output_):
>>> u_t = grad(output_, input_, components=['u'], d=['t'])
>>> u_tt = grad(u_t, input_, components=['dudt'], d=['t'])
>>> nabla_u = nabla(output_, input_, components=['u'], d=['x'])
>>> return nabla_u - u_tt
>>>
>>> def nil_dirichlet(input_, output_):
>>> value = 0.0
>>> return output_.extract(['u']) - value
>>>
>>> def initial_condition(input_, output_):
>>> u_expected = (-3*torch.sin(2*torch.pi*input_.extract(['x']))
>>> + 5*torch.sin(8/3*torch.pi*input_.extract(['x'])))
>>> u = output_.extract(['u'])
>>> return u - u_expected
>>>
>>> conditions = {
>>> 't0': Condition(Span({'x': [0, 3], 't':0}), initial_condition),
>>> 'gamma1': Condition(Span({'x':0, 't':[0, 1]}), nil_dirichlet),

View File

@@ -39,4 +39,4 @@ def test_init_inputfunc():
with pytest.raises(TypeError):
Condition(input_points=3., function='example')
with pytest.raises(TypeError):
Condition(input_points=example_domain, funtion=example_output_pts)
Condition(input_points=example_domain, function=example_output_pts)

View File

@@ -24,12 +24,24 @@ class Poisson(SpatialProblem):
return output_.extract(['u']) - value
conditions = {
'gamma1': Condition(Span({'x': [0, 1], 'y': 1}), nil_dirichlet),
'gamma2': Condition(Span({'x': [0, 1], 'y': 0}), nil_dirichlet),
'gamma3': Condition(Span({'x': 1, 'y': [0, 1]}), nil_dirichlet),
'gamma4': Condition(Span({'x': 0, 'y': [0, 1]}), nil_dirichlet),
'D': Condition(Span({'x': [0, 1], 'y': [0, 1]}), laplace_equation),
'data': Condition(in_, out_)
'gamma1': Condition(
location=Span({'x': [0, 1], 'y': 1}),
function=nil_dirichlet),
'gamma2': Condition(
location=Span({'x': [0, 1], 'y': 0}),
function=nil_dirichlet),
'gamma3': Condition(
location=Span({'x': 1, 'y': [0, 1]}),
function=nil_dirichlet),
'gamma4': Condition(
location=Span({'x': 0, 'y': [0, 1]}),
function=nil_dirichlet),
'D': Condition(
location=Span({'x': [0, 1], 'y': [0, 1]}),
function=laplace_equation),
'data': Condition(
input_points=in_,
output_points=out_)
}
def poisson_sol(self, pts):