Formatting
* Adding black as dev dependency * Formatting pina code * Formatting tests
This commit is contained in:
committed by
Nicola Demo
parent
4c4482b155
commit
42ab1a666b
@@ -1,4 +1,4 @@
|
||||
""" Module for AbstractProblem class """
|
||||
"""Module for AbstractProblem class"""
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from ..utils import check_consistency
|
||||
@@ -60,7 +60,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
elif hasattr(cond, "domain"):
|
||||
to_return[cond_name] = self._discretised_domains[cond.domain]
|
||||
return to_return
|
||||
|
||||
|
||||
@property
|
||||
def discretised_domains(self):
|
||||
return self._discretised_domains
|
||||
@@ -138,11 +138,9 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
"""
|
||||
return self.conditions
|
||||
|
||||
def discretise_domain(self,
|
||||
n=None,
|
||||
mode="random",
|
||||
domains="all",
|
||||
sample_rules=None):
|
||||
def discretise_domain(
|
||||
self, n=None, mode="random", domains="all", sample_rules=None
|
||||
):
|
||||
"""
|
||||
Generate a set of points to span the `Location` of all the conditions of
|
||||
the problem.
|
||||
@@ -193,9 +191,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
"You can't specify both n and sample_rules at the same time."
|
||||
)
|
||||
elif n is None and sample_rules is None:
|
||||
raise RuntimeError(
|
||||
"You have to specify either n or sample_rules."
|
||||
)
|
||||
raise RuntimeError("You have to specify either n or sample_rules.")
|
||||
|
||||
def _apply_default_discretization(self, n, mode, domains):
|
||||
for domain in domains:
|
||||
@@ -213,15 +209,17 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
if not isinstance(self.domains[domain], CartesianDomain):
|
||||
raise RuntimeError(
|
||||
"Custom discretisation can be applied only on Cartesian "
|
||||
"domains")
|
||||
"domains"
|
||||
)
|
||||
discretised_tensor = []
|
||||
for var, rules in sample_rules.items():
|
||||
n, mode = rules['n'], rules['mode']
|
||||
n, mode = rules["n"], rules["mode"]
|
||||
points = self.domains[domain].sample(n, mode, var)
|
||||
discretised_tensor.append(points)
|
||||
|
||||
self.discretised_domains[domain] = merge_tensors(
|
||||
discretised_tensor).sort_labels()
|
||||
discretised_tensor
|
||||
).sort_labels()
|
||||
|
||||
def add_points(self, new_points_dict):
|
||||
"""
|
||||
@@ -232,4 +230,5 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
"""
|
||||
for k, v in new_points_dict.items():
|
||||
self.discretised_domains[k] = LabelTensor.vstack(
|
||||
[self.discretised_domains[k], v])
|
||||
[self.discretised_domains[k], v]
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Module for the ParametricProblem class"""
|
||||
|
||||
import torch
|
||||
from abc import abstractmethod
|
||||
from .abstract_problem import AbstractProblem
|
||||
@@ -51,12 +52,9 @@ class InverseProblem(AbstractProblem):
|
||||
for i, var in enumerate(self.unknown_variables):
|
||||
range_var = self.unknown_parameter_domain.range_[var]
|
||||
tensor_var = (
|
||||
torch.rand(1, requires_grad=True) * range_var[1]
|
||||
+ range_var[0]
|
||||
)
|
||||
self.unknown_parameters[var] = torch.nn.Parameter(
|
||||
tensor_var
|
||||
torch.rand(1, requires_grad=True) * range_var[1] + range_var[0]
|
||||
)
|
||||
self.unknown_parameters[var] = torch.nn.Parameter(tensor_var)
|
||||
|
||||
@abstractmethod
|
||||
def unknown_parameter_domain(self):
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
__all__ = [
|
||||
'Poisson2DSquareProblem',
|
||||
'SupervisedProblem',
|
||||
'InversePoisson2DSquareProblem',
|
||||
'DiffusionReactionProblem',
|
||||
'InverseDiffusionReactionProblem'
|
||||
"Poisson2DSquareProblem",
|
||||
"SupervisedProblem",
|
||||
"InversePoisson2DSquareProblem",
|
||||
"DiffusionReactionProblem",
|
||||
"InverseDiffusionReactionProblem",
|
||||
]
|
||||
|
||||
from .poisson_2d_square import Poisson2DSquareProblem
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" Definition of the diffusion-reaction problem."""
|
||||
"""Definition of the diffusion-reaction problem."""
|
||||
|
||||
import torch
|
||||
from pina import Condition
|
||||
@@ -7,17 +7,22 @@ from pina.equation.equation import Equation
|
||||
from pina.domain import CartesianDomain
|
||||
from pina.operator import grad
|
||||
|
||||
|
||||
def diffusion_reaction(input_, output_):
|
||||
"""
|
||||
Implementation of the diffusion-reaction equation.
|
||||
"""
|
||||
x = input_.extract('x')
|
||||
t = input_.extract('t')
|
||||
u_t = grad(output_, input_, d='t')
|
||||
u_x = grad(output_, input_, d='x')
|
||||
u_xx = grad(u_x, input_, d='x')
|
||||
r = torch.exp(-t) * (1.5 * torch.sin(2*x) + (8/3) * torch.sin(3*x) +
|
||||
(15/4) * torch.sin(4*x) + (63/8) * torch.sin(8*x))
|
||||
x = input_.extract("x")
|
||||
t = input_.extract("t")
|
||||
u_t = grad(output_, input_, d="t")
|
||||
u_x = grad(output_, input_, d="x")
|
||||
u_xx = grad(u_x, input_, d="x")
|
||||
r = torch.exp(-t) * (
|
||||
1.5 * torch.sin(2 * x)
|
||||
+ (8 / 3) * torch.sin(3 * x)
|
||||
+ (15 / 4) * torch.sin(4 * x)
|
||||
+ (63 / 8) * torch.sin(8 * x)
|
||||
)
|
||||
return u_t - u_xx - r
|
||||
|
||||
|
||||
@@ -26,20 +31,25 @@ class DiffusionReactionProblem(TimeDependentProblem, SpatialProblem):
|
||||
Implementation of the diffusion-reaction problem on the spatial interval
|
||||
[-pi, pi] and temporal interval [0,1].
|
||||
"""
|
||||
output_variables = ['u']
|
||||
spatial_domain = CartesianDomain({'x': [-torch.pi, torch.pi]})
|
||||
temporal_domain = CartesianDomain({'t': [0, 1]})
|
||||
|
||||
output_variables = ["u"]
|
||||
spatial_domain = CartesianDomain({"x": [-torch.pi, torch.pi]})
|
||||
temporal_domain = CartesianDomain({"t": [0, 1]})
|
||||
|
||||
conditions = {
|
||||
'D': Condition(
|
||||
domain=CartesianDomain({'x': [-torch.pi, torch.pi], 't': [0, 1]}),
|
||||
equation=Equation(diffusion_reaction))
|
||||
"D": Condition(
|
||||
domain=CartesianDomain({"x": [-torch.pi, torch.pi], "t": [0, 1]}),
|
||||
equation=Equation(diffusion_reaction),
|
||||
)
|
||||
}
|
||||
|
||||
def _solution(self, pts):
|
||||
t = pts.extract('t')
|
||||
x = pts.extract('x')
|
||||
t = pts.extract("t")
|
||||
x = pts.extract("x")
|
||||
return torch.exp(-t) * (
|
||||
torch.sin(x) + (1/2)*torch.sin(2*x) + (1/3)*torch.sin(3*x) +
|
||||
(1/4)*torch.sin(4*x) + (1/8)*torch.sin(8*x)
|
||||
torch.sin(x)
|
||||
+ (1 / 2) * torch.sin(2 * x)
|
||||
+ (1 / 3) * torch.sin(3 * x)
|
||||
+ (1 / 4) * torch.sin(4 * x)
|
||||
+ (1 / 8) * torch.sin(8 * x)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" Definition of the diffusion-reaction problem."""
|
||||
"""Definition of the diffusion-reaction problem."""
|
||||
|
||||
import torch
|
||||
from pina import Condition, LabelTensor
|
||||
@@ -7,45 +7,57 @@ from pina.equation.equation import Equation
|
||||
from pina.domain import CartesianDomain
|
||||
from pina.operator import grad
|
||||
|
||||
|
||||
def diffusion_reaction(input_, output_):
|
||||
"""
|
||||
Implementation of the diffusion-reaction equation.
|
||||
"""
|
||||
x = input_.extract('x')
|
||||
t = input_.extract('t')
|
||||
u_t = grad(output_, input_, d='t')
|
||||
u_x = grad(output_, input_, d='x')
|
||||
u_xx = grad(u_x, input_, d='x')
|
||||
r = torch.exp(-t) * (1.5 * torch.sin(2*x) + (8/3) * torch.sin(3*x) +
|
||||
(15/4) * torch.sin(4*x) + (63/8) * torch.sin(8*x))
|
||||
x = input_.extract("x")
|
||||
t = input_.extract("t")
|
||||
u_t = grad(output_, input_, d="t")
|
||||
u_x = grad(output_, input_, d="x")
|
||||
u_xx = grad(u_x, input_, d="x")
|
||||
r = torch.exp(-t) * (
|
||||
1.5 * torch.sin(2 * x)
|
||||
+ (8 / 3) * torch.sin(3 * x)
|
||||
+ (15 / 4) * torch.sin(4 * x)
|
||||
+ (63 / 8) * torch.sin(8 * x)
|
||||
)
|
||||
return u_t - u_xx - r
|
||||
|
||||
class InverseDiffusionReactionProblem(TimeDependentProblem,
|
||||
SpatialProblem,
|
||||
InverseProblem):
|
||||
|
||||
class InverseDiffusionReactionProblem(
|
||||
TimeDependentProblem, SpatialProblem, InverseProblem
|
||||
):
|
||||
"""
|
||||
Implementation of the diffusion-reaction inverse problem on the spatial
|
||||
interval [-pi, pi] and temporal interval [0,1], with unknown parameters
|
||||
Implementation of the diffusion-reaction inverse problem on the spatial
|
||||
interval [-pi, pi] and temporal interval [0,1], with unknown parameters
|
||||
in the interval [-1,1].
|
||||
"""
|
||||
output_variables = ['u']
|
||||
spatial_domain = CartesianDomain({'x': [-torch.pi, torch.pi]})
|
||||
temporal_domain = CartesianDomain({'t': [0, 1]})
|
||||
unknown_parameter_domain = CartesianDomain({'mu': [-1, 1]})
|
||||
|
||||
output_variables = ["u"]
|
||||
spatial_domain = CartesianDomain({"x": [-torch.pi, torch.pi]})
|
||||
temporal_domain = CartesianDomain({"t": [0, 1]})
|
||||
unknown_parameter_domain = CartesianDomain({"mu": [-1, 1]})
|
||||
|
||||
conditions = {
|
||||
'D': Condition(
|
||||
domain=CartesianDomain({'x': [-torch.pi, torch.pi], 't': [0, 1]}),
|
||||
equation=Equation(diffusion_reaction)),
|
||||
'data' : Condition(
|
||||
input_points=LabelTensor(torch.randn(10, 2), ['x', 't']),
|
||||
output_points=LabelTensor(torch.randn(10, 1), ['u'])),
|
||||
"D": Condition(
|
||||
domain=CartesianDomain({"x": [-torch.pi, torch.pi], "t": [0, 1]}),
|
||||
equation=Equation(diffusion_reaction),
|
||||
),
|
||||
"data": Condition(
|
||||
input_points=LabelTensor(torch.randn(10, 2), ["x", "t"]),
|
||||
output_points=LabelTensor(torch.randn(10, 1), ["u"]),
|
||||
),
|
||||
}
|
||||
|
||||
def _solution(self, pts):
|
||||
t = pts.extract('t')
|
||||
x = pts.extract('x')
|
||||
t = pts.extract("t")
|
||||
x = pts.extract("x")
|
||||
return torch.exp(-t) * (
|
||||
torch.sin(x) + (1/2)*torch.sin(2*x) + (1/3)*torch.sin(3*x) +
|
||||
(1/4)*torch.sin(4*x) + (1/8)*torch.sin(8*x)
|
||||
torch.sin(x)
|
||||
+ (1 / 2) * torch.sin(2 * x)
|
||||
+ (1 / 3) * torch.sin(3 * x)
|
||||
+ (1 / 4) * torch.sin(4 * x)
|
||||
+ (1 / 8) * torch.sin(8 * x)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" Definition of the inverse Poisson problem on a square domain."""
|
||||
"""Definition of the inverse Poisson problem on a square domain."""
|
||||
|
||||
import torch
|
||||
from pina import Condition, LabelTensor
|
||||
@@ -8,43 +8,49 @@ from pina.domain import CartesianDomain
|
||||
from pina.equation.equation import Equation
|
||||
from pina.equation.equation_factory import FixedValue
|
||||
|
||||
|
||||
def laplace_equation(input_, output_, params_):
|
||||
"""
|
||||
Implementation of the laplace equation.
|
||||
"""
|
||||
force_term = torch.exp(- 2*(input_.extract(['x']) - params_['mu1'])**2
|
||||
- 2*(input_.extract(['y']) - params_['mu2'])**2)
|
||||
delta_u = laplacian(output_, input_, components=['u'], d=['x', 'y'])
|
||||
force_term = torch.exp(
|
||||
-2 * (input_.extract(["x"]) - params_["mu1"]) ** 2
|
||||
- 2 * (input_.extract(["y"]) - params_["mu2"]) ** 2
|
||||
)
|
||||
delta_u = laplacian(output_, input_, components=["u"], d=["x", "y"])
|
||||
return delta_u - force_term
|
||||
|
||||
|
||||
class InversePoisson2DSquareProblem(SpatialProblem, InverseProblem):
|
||||
"""
|
||||
Implementation of the inverse 2-dimensional Poisson problem
|
||||
Implementation of the inverse 2-dimensional Poisson problem
|
||||
on a square domain, with parameter domain [-1, 1] x [-1, 1].
|
||||
"""
|
||||
output_variables = ['u']
|
||||
|
||||
output_variables = ["u"]
|
||||
x_min, x_max = -2, 2
|
||||
y_min, y_max = -2, 2
|
||||
data_input = LabelTensor(torch.rand(10, 2), ['x', 'y'])
|
||||
data_output = LabelTensor(torch.rand(10, 1), ['u'])
|
||||
spatial_domain = CartesianDomain({'x': [x_min, x_max], 'y': [y_min, y_max]})
|
||||
unknown_parameter_domain = CartesianDomain({'mu1': [-1, 1], 'mu2': [-1, 1]})
|
||||
data_input = LabelTensor(torch.rand(10, 2), ["x", "y"])
|
||||
data_output = LabelTensor(torch.rand(10, 1), ["u"])
|
||||
spatial_domain = CartesianDomain({"x": [x_min, x_max], "y": [y_min, y_max]})
|
||||
unknown_parameter_domain = CartesianDomain({"mu1": [-1, 1], "mu2": [-1, 1]})
|
||||
|
||||
domains = {
|
||||
'g1': CartesianDomain({'x': [x_min, x_max], 'y': y_max}),
|
||||
'g2': CartesianDomain({'x': [x_min, x_max], 'y': y_min}),
|
||||
'g3': CartesianDomain({'x': x_max, 'y': [y_min, y_max]}),
|
||||
'g4': CartesianDomain({'x': x_min, 'y': [y_min, y_max]}),
|
||||
'D': CartesianDomain({'x': [x_min, x_max], 'y': [y_min, y_max]}),
|
||||
"g1": CartesianDomain({"x": [x_min, x_max], "y": y_max}),
|
||||
"g2": CartesianDomain({"x": [x_min, x_max], "y": y_min}),
|
||||
"g3": CartesianDomain({"x": x_max, "y": [y_min, y_max]}),
|
||||
"g4": CartesianDomain({"x": x_min, "y": [y_min, y_max]}),
|
||||
"D": CartesianDomain({"x": [x_min, x_max], "y": [y_min, y_max]}),
|
||||
}
|
||||
|
||||
conditions = {
|
||||
'nil_g1': Condition(domain='g1', equation=FixedValue(0.0)),
|
||||
'nil_g2': Condition(domain='g2', equation=FixedValue(0.0)),
|
||||
'nil_g3': Condition(domain='g3', equation=FixedValue(0.0)),
|
||||
'nil_g4': Condition(domain='g4', equation=FixedValue(0.0)),
|
||||
'laplace_D': Condition(domain='D', equation=Equation(laplace_equation)),
|
||||
'data': Condition(
|
||||
input_points=data_input.extract(['x', 'y']),
|
||||
output_points=data_output)
|
||||
"nil_g1": Condition(domain="g1", equation=FixedValue(0.0)),
|
||||
"nil_g2": Condition(domain="g2", equation=FixedValue(0.0)),
|
||||
"nil_g3": Condition(domain="g3", equation=FixedValue(0.0)),
|
||||
"nil_g4": Condition(domain="g4", equation=FixedValue(0.0)),
|
||||
"laplace_D": Condition(domain="D", equation=Equation(laplace_equation)),
|
||||
"data": Condition(
|
||||
input_points=data_input.extract(["x", "y"]),
|
||||
output_points=data_output,
|
||||
),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" Definition of the Poisson problem on a square domain."""
|
||||
"""Definition of the Poisson problem on a square domain."""
|
||||
|
||||
from pina.problem import SpatialProblem
|
||||
from pina.operator import laplacian
|
||||
@@ -8,41 +8,47 @@ from pina.equation.equation import Equation
|
||||
from pina.equation.equation_factory import FixedValue
|
||||
import torch
|
||||
|
||||
|
||||
def laplace_equation(input_, output_):
|
||||
"""
|
||||
Implementation of the laplace equation.
|
||||
"""
|
||||
force_term = (torch.sin(input_.extract(['x']) * torch.pi) *
|
||||
torch.sin(input_.extract(['y']) * torch.pi))
|
||||
delta_u = laplacian(output_.extract(['u']), input_)
|
||||
force_term = torch.sin(input_.extract(["x"]) * torch.pi) * torch.sin(
|
||||
input_.extract(["y"]) * torch.pi
|
||||
)
|
||||
delta_u = laplacian(output_.extract(["u"]), input_)
|
||||
return delta_u - force_term
|
||||
|
||||
|
||||
my_laplace = Equation(laplace_equation)
|
||||
|
||||
|
||||
class Poisson2DSquareProblem(SpatialProblem):
|
||||
"""
|
||||
Implementation of the 2-dimensional Poisson problem on a square domain.
|
||||
"""
|
||||
output_variables = ['u']
|
||||
spatial_domain = CartesianDomain({'x': [0, 1], 'y': [0, 1]})
|
||||
|
||||
output_variables = ["u"]
|
||||
spatial_domain = CartesianDomain({"x": [0, 1], "y": [0, 1]})
|
||||
|
||||
domains = {
|
||||
'D': CartesianDomain({'x': [0, 1], 'y': [0, 1]}),
|
||||
'g1': CartesianDomain({'x': [0, 1], 'y': 1}),
|
||||
'g2': CartesianDomain({'x': [0, 1], 'y': 0}),
|
||||
'g3': CartesianDomain({'x': 1, 'y': [0, 1]}),
|
||||
'g4': CartesianDomain({'x': 0, 'y': [0, 1]}),
|
||||
"D": CartesianDomain({"x": [0, 1], "y": [0, 1]}),
|
||||
"g1": CartesianDomain({"x": [0, 1], "y": 1}),
|
||||
"g2": CartesianDomain({"x": [0, 1], "y": 0}),
|
||||
"g3": CartesianDomain({"x": 1, "y": [0, 1]}),
|
||||
"g4": CartesianDomain({"x": 0, "y": [0, 1]}),
|
||||
}
|
||||
|
||||
conditions = {
|
||||
'nil_g1': Condition(domain='g1', equation=FixedValue(0.0)),
|
||||
'nil_g2': Condition(domain='g2', equation=FixedValue(0.0)),
|
||||
'nil_g3': Condition(domain='g3', equation=FixedValue(0.0)),
|
||||
'nil_g4': Condition(domain='g4', equation=FixedValue(0.0)),
|
||||
'laplace_D': Condition(domain='D', equation=my_laplace),
|
||||
"nil_g1": Condition(domain="g1", equation=FixedValue(0.0)),
|
||||
"nil_g2": Condition(domain="g2", equation=FixedValue(0.0)),
|
||||
"nil_g3": Condition(domain="g3", equation=FixedValue(0.0)),
|
||||
"nil_g4": Condition(domain="g4", equation=FixedValue(0.0)),
|
||||
"laplace_D": Condition(domain="D", equation=my_laplace),
|
||||
}
|
||||
|
||||
def poisson_sol(self, pts):
|
||||
return -(torch.sin(pts.extract(['x']) * torch.pi) *
|
||||
torch.sin(pts.extract(['y']) * torch.pi))
|
||||
|
||||
return -(
|
||||
torch.sin(pts.extract(["x"]) * torch.pi)
|
||||
* torch.sin(pts.extract(["y"]) * torch.pi)
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ from pina.problem import AbstractProblem
|
||||
from pina import Condition
|
||||
from pina import Graph
|
||||
|
||||
|
||||
class SupervisedProblem(AbstractProblem):
|
||||
"""
|
||||
A problem definition for supervised learning in PINA.
|
||||
@@ -15,6 +16,7 @@ class SupervisedProblem(AbstractProblem):
|
||||
>>> output_data = torch.rand((100, 10))
|
||||
>>> problem = SupervisedProblem(input_data, output_data)
|
||||
"""
|
||||
|
||||
conditions = dict()
|
||||
output_variables = None
|
||||
|
||||
@@ -29,9 +31,7 @@ class SupervisedProblem(AbstractProblem):
|
||||
"""
|
||||
if isinstance(input_, Graph):
|
||||
input_ = input_.data
|
||||
self.conditions['data'] = Condition(
|
||||
input_points=input_,
|
||||
output_points = output_
|
||||
self.conditions["data"] = Condition(
|
||||
input_points=input_, output_points=output_
|
||||
)
|
||||
super().__init__()
|
||||
|
||||
Reference in New Issue
Block a user