Documentation for v0.1 version (#199)
* Adding Equations, solving typos * improve _code.rst * the team rst and restuctore index.rst * fixing errors --------- Co-authored-by: Dario Coscia <dariocoscia@dhcp-015.eduroam.sissa.it>
This commit is contained in:
committed by
Nicola Demo
parent
3f9305d475
commit
8b7b61b3bd
@@ -27,7 +27,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
|
||||
# put in self.input_pts all the points that we don't need to sample
|
||||
self._span_condition_points()
|
||||
|
||||
|
||||
@property
|
||||
def input_variables(self):
|
||||
"""
|
||||
@@ -55,10 +55,11 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
def domain(self):
|
||||
"""
|
||||
The domain(s) where the conditions of the AbstractProblem are valid.
|
||||
If more than one domain type is passed, a list of Location is
|
||||
retured.
|
||||
|
||||
:return: the domain(s) of self
|
||||
:rtype: list (if more than one domain are defined),
|
||||
`Span` domain (of only one domain is defined)
|
||||
:return: the domain(s) of ``self``
|
||||
:rtype: list[Location]
|
||||
"""
|
||||
domains = [
|
||||
getattr(self, f'{t}_domain')
|
||||
@@ -109,7 +110,11 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
self.input_pts[condition_name] = samples
|
||||
self._have_sampled_points[condition_name] = True
|
||||
|
||||
def discretise_domain(self, n, mode = 'random', variables = 'all', locations = 'all'):
|
||||
def discretise_domain(self,
|
||||
n,
|
||||
mode='random',
|
||||
variables='all',
|
||||
locations='all'):
|
||||
"""
|
||||
Generate a set of points to span the `Location` of all the conditions of
|
||||
the problem.
|
||||
@@ -122,9 +127,9 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
latin hypercube sampling, ``latin`` or ``lh``;
|
||||
chebyshev sampling, ``chebyshev``; grid sampling ``grid``.
|
||||
:param variables: problem's variables to be sampled, defaults to 'all'.
|
||||
:type variables: str or list[str], optional
|
||||
:type variables: str | list[str]
|
||||
:param locations: problem's locations from where to sample, defaults to 'all'.
|
||||
:type locations: str, optional
|
||||
:type locations: str
|
||||
|
||||
:Example:
|
||||
>>> pinn.discretise_domain(n=10, mode='grid')
|
||||
@@ -146,24 +151,24 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
check_consistency(mode, str)
|
||||
if mode not in ['random', 'grid', 'lh', 'chebyshev', 'latin']:
|
||||
raise TypeError(f'mode {mode} not valid.')
|
||||
|
||||
|
||||
# check consistency variables
|
||||
if variables == 'all':
|
||||
variables = self.input_variables
|
||||
else:
|
||||
check_consistency(variables, str)
|
||||
|
||||
if sorted(variables) != sorted(self.input_variables):
|
||||
|
||||
if sorted(variables) != sorted(self.input_variables):
|
||||
TypeError(f'Wrong variables for sampling. Variables ',
|
||||
f'should be in {self.input_variables}.')
|
||||
|
||||
|
||||
# check consistency location
|
||||
if locations == 'all':
|
||||
locations = [condition for condition in self.conditions]
|
||||
else:
|
||||
check_consistency(locations, str)
|
||||
|
||||
if sorted(locations) != sorted(self.conditions):
|
||||
if sorted(locations) != sorted(self.conditions):
|
||||
TypeError(f'Wrong locations for sampling. Location ',
|
||||
f'should be in {self.conditions}.')
|
||||
|
||||
@@ -174,7 +179,7 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
# we try to check if we have already sampled
|
||||
try:
|
||||
already_sampled = [self.input_pts[location]]
|
||||
# if we have not sampled, a key error is thrown
|
||||
# if we have not sampled, a key error is thrown
|
||||
except KeyError:
|
||||
already_sampled = []
|
||||
|
||||
@@ -187,16 +192,15 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
self._have_sampled_points[location] = False
|
||||
|
||||
# build samples
|
||||
samples = [condition.location.sample(
|
||||
n=n,
|
||||
mode=mode,
|
||||
variables=variables)
|
||||
] + already_sampled
|
||||
samples = [
|
||||
condition.location.sample(n=n, mode=mode, variables=variables)
|
||||
] + already_sampled
|
||||
pts = merge_tensors(samples)
|
||||
self.input_pts[location] = pts
|
||||
|
||||
# the condition is sampled if input_pts contains all labels
|
||||
if sorted(self.input_pts[location].labels) == sorted(self.input_variables):
|
||||
if sorted(self.input_pts[location].labels) == sorted(
|
||||
self.input_variables):
|
||||
self._have_sampled_points[location] = True
|
||||
|
||||
def add_points(self, new_points):
|
||||
@@ -207,21 +211,22 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
and values the torch.Tensor points.
|
||||
"""
|
||||
|
||||
if sorted(new_points.keys()) != sorted(self.conditions):
|
||||
if sorted(new_points.keys()) != sorted(self.conditions):
|
||||
TypeError(f'Wrong locations for new points. Location ',
|
||||
f'should be in {self.conditions}.')
|
||||
|
||||
|
||||
for location in new_points.keys():
|
||||
# extract old and new points
|
||||
old_pts = self.input_pts[location]
|
||||
new_pts = new_points[location]
|
||||
|
||||
# if they don't have the same variables error
|
||||
if sorted(old_pts.labels) != sorted(new_pts.labels):
|
||||
if sorted(old_pts.labels) != sorted(new_pts.labels):
|
||||
TypeError(f'Not matching variables for old and new points '
|
||||
f'in condition {location}.')
|
||||
if old_pts.labels != new_pts.labels:
|
||||
new_pts = torch.hstack([new_pts.extract([i]) for i in old_pts.labels])
|
||||
new_pts = torch.hstack(
|
||||
[new_pts.extract([i]) for i in old_pts.labels])
|
||||
new_pts.labels = old_pts.labels
|
||||
|
||||
# merging
|
||||
@@ -233,13 +238,14 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
def have_sampled_points(self):
|
||||
"""
|
||||
Check if all points for
|
||||
``'Location'`` are sampled.
|
||||
"""
|
||||
``Location`` are sampled.
|
||||
"""
|
||||
return all(self._have_sampled_points.values())
|
||||
|
||||
|
||||
@property
|
||||
def not_sampled_points(self):
|
||||
"""Check which points are
|
||||
"""
|
||||
Check which points are
|
||||
not sampled.
|
||||
"""
|
||||
# variables which are not sampled
|
||||
@@ -251,4 +257,3 @@ class AbstractProblem(metaclass=ABCMeta):
|
||||
if not is_sample:
|
||||
not_sampled.append(condition_name)
|
||||
return not_sampled
|
||||
|
||||
|
||||
@@ -16,14 +16,17 @@ class ParametricProblem(AbstractProblem):
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem, ParametricProblem
|
||||
>>> from pina.operators import grad
|
||||
>>> from pina import Condition, Span
|
||||
>>> from pina.equations import Equation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
>>>
|
||||
>>>
|
||||
>>> class ParametricODE(SpatialProblem, ParametricProblem):
|
||||
>>>
|
||||
>>> output_variables = ['u']
|
||||
>>> spatial_domain = Span({'x': [0, 1]})
|
||||
>>> parameter_domain = Span({'alpha': [1, 10]})
|
||||
>>> spatial_domain = CartesianDomain({'x': [0, 1]})
|
||||
>>> parameter_domain = CartesianDomain({'alpha': [1, 10]})
|
||||
>>>
|
||||
>>> def ode_equation(input_, output_):
|
||||
>>> u_x = grad(output_, input_, components=['u'], d=['x'])
|
||||
@@ -31,14 +34,9 @@ class ParametricProblem(AbstractProblem):
|
||||
>>> 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)}
|
||||
>>> 'x0': Condition(CartesianDomain({'x': 0, 'alpha':[1, 10]}), FixedValue(1.)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 1], 'alpha':[1, 10]}), Equation(ode_equation))}
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@@ -14,24 +14,25 @@ class SpatialProblem(AbstractProblem):
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem
|
||||
>>> from pina.operators import grad
|
||||
>>> from pina import Condition, Span
|
||||
>>> from pina.equations import Equation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
>>> class SimpleODE(SpatialProblem):
|
||||
>>>
|
||||
>>>
|
||||
>>> class SpatialODE(SpatialProblem:
|
||||
>>>
|
||||
>>> output_variables = ['u']
|
||||
>>> spatial_domain = Span({'x': [0, 1]})
|
||||
>>> spatial_domain = CartesianDomain({'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)}
|
||||
>>> 'x0': Condition(CartesianDomain({'x': 0, 'alpha':[1, 10]}), FixedValue(1.)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 1], 'alpha':[1, 10]}), Equation(ode_equation))}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -14,14 +14,17 @@ class TimeDependentProblem(AbstractProblem):
|
||||
:Example:
|
||||
>>> from pina.problem import SpatialProblem, TimeDependentProblem
|
||||
>>> from pina.operators import grad, laplacian
|
||||
>>> from pina import Condition, Span
|
||||
>>> from pina.equations import Equation, FixedValue
|
||||
>>> from pina import Condition
|
||||
>>> from pina.geometry import CartesianDomain
|
||||
>>> import torch
|
||||
>>>
|
||||
>>>
|
||||
>>> class Wave(TimeDependentSpatialProblem):
|
||||
>>>
|
||||
>>> output_variables = ['u']
|
||||
>>> spatial_domain = Span({'x': [0, 3]})
|
||||
>>> temporal_domain = Span({'t': [0, 1]})
|
||||
>>> spatial_domain = CartesianDomain({'x': [0, 3]})
|
||||
>>> temporal_domain = CartesianDomain({'t': [0, 1]})
|
||||
>>>
|
||||
>>> def wave_equation(input_, output_):
|
||||
>>> u_t = grad(output_, input_, components=['u'], d=['t'])
|
||||
@@ -29,10 +32,6 @@ class TimeDependentProblem(AbstractProblem):
|
||||
>>> delta_u = laplacian(output_, input_, components=['u'], d=['x'])
|
||||
>>> return delta_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'])))
|
||||
@@ -40,10 +39,10 @@ class TimeDependentProblem(AbstractProblem):
|
||||
>>> 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),
|
||||
>>> 'gamma2': Condition(Span({'x':3, 't':[0, 1]}), nil_dirichlet),
|
||||
>>> 'D': Condition(Span({'x': [0, 3], 't':[0, 1]}), wave_equation)}
|
||||
>>> 't0': Condition(CartesianDomain({'x': [0, 3], 't':0}), Equation(initial_condition)),
|
||||
>>> 'gamma1': Condition(CartesianDomain({'x':0, 't':[0, 1]}), FixedValue(0.)),
|
||||
>>> 'gamma2': Condition(CartesianDomain({'x':3, 't':[0, 1]}), FixedValue(0.)),
|
||||
>>> 'D': Condition(CartesianDomain({'x': [0, 3], 't':[0, 1]}), Equation(wave_equation))}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user