diff --git a/examples/problems/burgers.py b/examples/problems/burgers.py index 53b9244..d06fd4e 100644 --- a/examples/problems/burgers.py +++ b/examples/problems/burgers.py @@ -5,13 +5,26 @@ from pina.operators import grad from pina import Condition from pina.span import Span +# ===================================================== # +# # +# This script implements the one dimensional Burger # +# problem. The Burgers1D class is defined inheriting # +# from TimeDependentProblem, SpatialProblem and we # +# denote: # +# u --> field variable # +# x --> spatial variable # +# t --> temporal variable # +# # +# ===================================================== # class Burgers1D(TimeDependentProblem, SpatialProblem): + # assign output/ spatial and temporal variables output_variables = ['u'] spatial_domain = Span({'x': [-1, 1]}) temporal_domain = Span({'t': [0, 1]}) + # define the burger equation def burger_equation(input_, output_): du = grad(output_, input_) ddu = grad(du, input_, components=['dudx']) @@ -21,17 +34,20 @@ class Burgers1D(TimeDependentProblem, SpatialProblem): (0.01/torch.pi)*ddu.extract(['ddudxdx']) ) + # define nill dirichlet boundary conditions def nil_dirichlet(input_, output_): u_expected = 0.0 return output_.extract(['u']) - u_expected + # define initial condition def initial_condition(input_, output_): u_expected = -torch.sin(torch.pi*input_.extract(['x'])) return output_.extract(['u']) - u_expected + # problem condition statement conditions = { - 'gamma1': Condition(Span({'x': -1, 't': [0, 1]}), nil_dirichlet), - 'gamma2': Condition(Span({'x': 1, 't': [0, 1]}), nil_dirichlet), - 't0': Condition(Span({'x': [-1, 1], 't': 0}), initial_condition), - 'D': Condition(Span({'x': [-1, 1], 't': [0, 1]}), burger_equation), + 'gamma1': Condition(location=Span({'x': -1, 't': [0, 1]}), function=nil_dirichlet), + 'gamma2': Condition(location=Span({'x': 1, 't': [0, 1]}), function=nil_dirichlet), + 't0': Condition(location=Span({'x': [-1, 1], 't': 0}), function=initial_condition), + 'D': Condition(location=Span({'x': [-1, 1], 't': [0, 1]}), function=burger_equation), } diff --git a/examples/problems/elliptic_optimal_control.py b/examples/problems/elliptic_optimal_control.py index db8d056..034b09d 100644 --- a/examples/problems/elliptic_optimal_control.py +++ b/examples/problems/elliptic_optimal_control.py @@ -1,45 +1,47 @@ -import torch -from pina.problem import Problem -from pina.segment import Segment -from pina.cube import Cube -from pina.problem2d import Problem2D +# import torch +# from pina.problem import Problem +# from pina.segment import Segment +# from pina.cube import Cube +# from pina.problem2d import Problem2D -xmin, xmax, ymin, ymax = -1, 1, -1, 1 +# xmin, xmax, ymin, ymax = -1, 1, -1, 1 -class EllipticOptimalControl(Problem2D): +# class EllipticOptimalControl(Problem2D): - def __init__(self, alpha=1): +# def __init__(self, alpha=1): - def term1(input_, output_): - grad_p = self.grad(output_.extract(['p']), input_) - gradgrad_p_x1 = self.grad(grad_p.extract(['x1']), input_) - gradgrad_p_x2 = self.grad(grad_p.extract(['x2']), input_) - yd = 2.0 - return output_.extract(['y']) - yd - (gradgrad_p_x1.extract(['x1']) + gradgrad_p_x2.extract(['x2'])) +# def term1(input_, output_): +# grad_p = self.grad(output_.extract(['p']), input_) +# gradgrad_p_x1 = self.grad(grad_p.extract(['x1']), input_) +# gradgrad_p_x2 = self.grad(grad_p.extract(['x2']), input_) +# yd = 2.0 +# return output_.extract(['y']) - yd - (gradgrad_p_x1.extract(['x1']) + gradgrad_p_x2.extract(['x2'])) - def term2(input_, output_): - grad_y = self.grad(output_.extract(['y']), input_) - gradgrad_y_x1 = self.grad(grad_y.extract(['x1']), input_) - gradgrad_y_x2 = self.grad(grad_y.extract(['x2']), input_) - return - (gradgrad_y_x1.extract(['x1']) + gradgrad_y_x2.extract(['x2'])) - output_.extract(['u']) +# def term2(input_, output_): +# grad_y = self.grad(output_.extract(['y']), input_) +# gradgrad_y_x1 = self.grad(grad_y.extract(['x1']), input_) +# gradgrad_y_x2 = self.grad(grad_y.extract(['x2']), input_) +# return - (gradgrad_y_x1.extract(['x1']) + gradgrad_y_x2.extract(['x2'])) - output_.extract(['u']) - def term3(input_, output_): - return output_.extract(['p']) - output_.extract(['u'])*alpha +# def term3(input_, output_): +# return output_.extract(['p']) - output_.extract(['u'])*alpha - def nil_dirichlet(input_, output_): - y_value = 0.0 - p_value = 0.0 - return torch.abs(output_.extract(['y']) - y_value) + torch.abs(output_.extract(['p']) - p_value) +# def nil_dirichlet(input_, output_): +# y_value = 0.0 +# p_value = 0.0 +# return torch.abs(output_.extract(['y']) - y_value) + torch.abs(output_.extract(['p']) - p_value) - self.conditions = { - 'gamma1': {'location': Segment((xmin, ymin), (xmax, ymin)), 'func': nil_dirichlet}, - 'gamma2': {'location': Segment((xmax, ymin), (xmax, ymax)), 'func': nil_dirichlet}, - 'gamma3': {'location': Segment((xmax, ymax), (xmin, ymax)), 'func': nil_dirichlet}, - 'gamma4': {'location': Segment((xmin, ymax), (xmin, ymin)), 'func': nil_dirichlet}, - 'D1': {'location': Cube([[xmin, xmax], [ymin, ymax]]), 'func': [term1, term2, term3]}, - } +# self.conditions = { +# 'gamma1': {'location': Segment((xmin, ymin), (xmax, ymin)), 'func': nil_dirichlet}, +# 'gamma2': {'location': Segment((xmax, ymin), (xmax, ymax)), 'func': nil_dirichlet}, +# 'gamma3': {'location': Segment((xmax, ymax), (xmin, ymax)), 'func': nil_dirichlet}, +# 'gamma4': {'location': Segment((xmin, ymax), (xmin, ymin)), 'func': nil_dirichlet}, +# 'D1': {'location': Cube([[xmin, xmax], [ymin, ymax]]), 'func': [term1, term2, term3]}, +# } - self.input_variables = ['x1', 'x2'] - self.output_variables = ['u', 'p', 'y'] - self.spatial_domain = Cube([[xmin, xmax], [xmin, xmax]]) +# self.input_variables = ['x1', 'x2'] +# self.output_variables = ['u', 'p', 'y'] +# self.spatial_domain = Cube([[xmin, xmax], [xmin, xmax]]) + +raise NotImplementedError('not available problem at the moment...') \ No newline at end of file diff --git a/examples/problems/first_order_ode.py b/examples/problems/first_order_ode.py new file mode 100644 index 0000000..eb83941 --- /dev/null +++ b/examples/problems/first_order_ode.py @@ -0,0 +1,46 @@ +from pina.problem import SpatialProblem +from pina import Condition, Span +from pina.operators import grad +import torch + +# ===================================================== # +# # +# This script implements a simple first order ode. # +# The FirstOrderODE class is defined inheriting from # +# SpatialProblem. We denote: # +# y --> field variable # +# x --> spatial variable # +# # +# ===================================================== # + +class FirstOrderODE(SpatialProblem): + + # variable domain range + x_rng = [0, 5] + # field variable + output_variables = ['y'] + # create domain + spatial_domain = Span({'x': x_rng}) + + # define the ode + def ode(input_, output_): + y = output_ + x = input_ + return grad(y, x) + y - x + + # define initial conditions + def fixed(input_, output_): + exp_value = 1. + return output_ - exp_value + + # define real solution + def solution(self, input_): + x = input_ + return x - 1.0 + 2*torch.exp(-x) + + # define problem conditions + conditions = { + 'bc': Condition(location=Span({'x': x_rng[0]}), function=fixed), + 'dd': Condition(location=Span({'x': x_rng}), function=ode), + } + truth_solution = solution \ No newline at end of file diff --git a/examples/problems/parametric_elliptic_optimal_control.py b/examples/problems/parametric_elliptic_optimal_control.py index 22c9940..8aa33fd 100644 --- a/examples/problems/parametric_elliptic_optimal_control.py +++ b/examples/problems/parametric_elliptic_optimal_control.py @@ -1,53 +1,53 @@ -import numpy as np -import torch -from pina.problem import Problem -from pina.segment import Segment -from pina.cube import Cube -from pina.problem2d import Problem2D +# import numpy as np +# import torch +# from pina.problem import Problem +# from pina.segment import Segment +# from pina.cube import Cube +# from pina.problem2d import Problem2D -xmin, xmax, ymin, ymax = -1, 1, -1, 1 +# xmin, xmax, ymin, ymax = -1, 1, -1, 1 -class ParametricEllipticOptimalControl(Problem2D): +# class ParametricEllipticOptimalControl(Problem2D): - def __init__(self, alpha=1): +# def __init__(self, alpha=1): - def term1(input_, param_, output_): - grad_p = self.grad(output_['p'], input_) - gradgrad_p_x1 = self.grad(grad_p['x1'], input_) - gradgrad_p_x2 = self.grad(grad_p['x2'], input_) - return output_['y'] - param_ - (gradgrad_p_x1['x1'] + gradgrad_p_x2['x2']) +# def term1(input_, param_, output_): +# grad_p = self.grad(output_['p'], input_) +# gradgrad_p_x1 = self.grad(grad_p['x1'], input_) +# gradgrad_p_x2 = self.grad(grad_p['x2'], input_) +# return output_['y'] - param_ - (gradgrad_p_x1['x1'] + gradgrad_p_x2['x2']) - def term2(input_, param_, output_): - grad_y = self.grad(output_['y'], input_) - gradgrad_y_x1 = self.grad(grad_y['x1'], input_) - gradgrad_y_x2 = self.grad(grad_y['x2'], input_) - return - (gradgrad_y_x1['x1'] + gradgrad_y_x2['x2']) - output_['u_param'] +# def term2(input_, param_, output_): +# grad_y = self.grad(output_['y'], input_) +# gradgrad_y_x1 = self.grad(grad_y['x1'], input_) +# gradgrad_y_x2 = self.grad(grad_y['x2'], input_) +# return - (gradgrad_y_x1['x1'] + gradgrad_y_x2['x2']) - output_['u_param'] - def term3(input_, param_, output_): - return output_['p'] - output_['u_param']*alpha +# def term3(input_, param_, output_): +# return output_['p'] - output_['u_param']*alpha - def term(input_, param_, output_): - return term1( input_, param_, output_) +term2( input_, param_, output_) + term3( input_, param_, output_) +# def term(input_, param_, output_): +# return term1( input_, param_, output_) +term2( input_, param_, output_) + term3( input_, param_, output_) - def nil_dirichlet(input_, param_, output_): - y_value = 0.0 - p_value = 0.0 - return torch.abs(output_['y'] - y_value) + torch.abs(output_['p'] - p_value) +# def nil_dirichlet(input_, param_, output_): +# y_value = 0.0 +# p_value = 0.0 +# return torch.abs(output_['y'] - y_value) + torch.abs(output_['p'] - p_value) - self.conditions = { - 'gamma1': {'location': Segment((xmin, ymin), (xmax, ymin)), 'func': nil_dirichlet}, - 'gamma2': {'location': Segment((xmax, ymin), (xmax, ymax)), 'func': nil_dirichlet}, - 'gamma3': {'location': Segment((xmax, ymax), (xmin, ymax)), 'func': nil_dirichlet}, - 'gamma4': {'location': Segment((xmin, ymax), (xmin, ymin)), 'func': nil_dirichlet}, - 'D1': {'location': Cube([[xmin, xmax], [ymin, ymax]]), 'func': term}, - #'D2': {'location': Cube([[0, 1], [0, 1]]), 'func': term2}, - #'D3': {'location': Cube([[0, 1], [0, 1]]), 'func': term3} - } - - self.input_variables = ['x1', 'x2'] - self.output_variables = ['u', 'p', 'y'] - self.parameters = ['mu'] - self.spatial_domain = Cube([[xmin, xmax], [xmin, xmax]]) - self.parameter_domain = np.array([[0.5, 3]]) +# self.conditions = { +# 'gamma1': {'location': Segment((xmin, ymin), (xmax, ymin)), 'func': nil_dirichlet}, +# 'gamma2': {'location': Segment((xmax, ymin), (xmax, ymax)), 'func': nil_dirichlet}, +# 'gamma3': {'location': Segment((xmax, ymax), (xmin, ymax)), 'func': nil_dirichlet}, +# 'gamma4': {'location': Segment((xmin, ymax), (xmin, ymin)), 'func': nil_dirichlet}, +# 'D1': {'location': Cube([[xmin, xmax], [ymin, ymax]]), 'func': term}, +# #'D2': {'location': Cube([[0, 1], [0, 1]]), 'func': term2}, +# #'D3': {'location': Cube([[0, 1], [0, 1]]), 'func': term3} +# } +# self.input_variables = ['x1', 'x2'] +# self.output_variables = ['u', 'p', 'y'] +# self.parameters = ['mu'] +# self.spatial_domain = Cube([[xmin, xmax], [xmin, xmax]]) +# self.parameter_domain = np.array([[0.5, 3]]) +raise NotImplementedError('not available problem at the moment...') diff --git a/examples/problems/parametric_elliptic_optimal_control_alpha_variable.py b/examples/problems/parametric_elliptic_optimal_control_alpha_variable.py index a0e5eb5..7838e51 100644 --- a/examples/problems/parametric_elliptic_optimal_control_alpha_variable.py +++ b/examples/problems/parametric_elliptic_optimal_control_alpha_variable.py @@ -5,22 +5,42 @@ from pina import Span, Condition from pina.problem import SpatialProblem, ParametricProblem from pina.operators import grad, nabla +# ===================================================== # +# # +# This script implements the two dimensional # +# Parametric Elliptic Optimal Control problem. # +# The ParametricEllipticOptimalControl class is # +# inherited from TimeDependentProblem, SpatialProblem # +# and we denote: # +# u --> field variable # +# p --> field variable # +# y --> field variable # +# x1, x2 --> spatial variables # +# mu, alpha --> problem parameters # +# # +# More info in https://arxiv.org/pdf/2110.13530.pdf # +# Section 4.2 of the article # +# ===================================================== # + class ParametricEllipticOptimalControl(SpatialProblem, ParametricProblem): + # setting spatial variables ranges xmin, xmax, ymin, ymax = -1, 1, -1, 1 + x_range = [xmin, xmax] + y_range = [ymin, ymax] + # setting parameters range amin, amax = 0.0001, 1 mumin, mumax = 0.5, 3 mu_range = [mumin, mumax] a_range = [amin, amax] - x_range = [xmin, xmax] - y_range = [ymin, ymax] - + # setting field variables output_variables = ['u', 'p', 'y'] + # setting spatial and parameter domain spatial_domain = Span({'x1': x_range, 'x2': y_range}) parameter_domain = Span({'mu': mu_range, 'alpha': a_range}) - + # equation terms as in https://arxiv.org/pdf/2110.13530.pdf def term1(input_, output_): laplace_p = nabla(output_, input_, components=['p'], d=['x1', 'x2']) return output_.extract(['y']) - input_.extract(['mu']) - laplace_p @@ -37,21 +57,22 @@ class ParametricEllipticOptimalControl(SpatialProblem, ParametricProblem): p_exp = 0.0 return output_.extract(['p']) - p_exp + # setting problem condition formulation conditions = { 'gamma1': Condition( - Span({'x1': x_range, 'x2': 1, 'mu': mu_range, 'alpha': a_range}), - [state_dirichlet, adj_dirichlet]), + location=Span({'x1': x_range, 'x2': 1, 'mu': mu_range, 'alpha': a_range}), + function=[state_dirichlet, adj_dirichlet]), 'gamma2': Condition( - Span({'x1': x_range, 'x2': -1, 'mu': mu_range, 'alpha': a_range}), - [state_dirichlet, adj_dirichlet]), + location=Span({'x1': x_range, 'x2': -1, 'mu': mu_range, 'alpha': a_range}), + function=[state_dirichlet, adj_dirichlet]), 'gamma3': Condition( - Span({'x1': 1, 'x2': y_range, 'mu': mu_range, 'alpha': a_range}), - [state_dirichlet, adj_dirichlet]), + location=Span({'x1': 1, 'x2': y_range, 'mu': mu_range, 'alpha': a_range}), + function=[state_dirichlet, adj_dirichlet]), 'gamma4': Condition( - Span({'x1': -1, 'x2': y_range, 'mu': mu_range, 'alpha': a_range}), - [state_dirichlet, adj_dirichlet]), + location=Span({'x1': -1, 'x2': y_range, 'mu': mu_range, 'alpha': a_range}), + function=[state_dirichlet, adj_dirichlet]), 'D': Condition( - Span({'x1': x_range, 'x2': y_range, + location=Span({'x1': x_range, 'x2': y_range, 'mu': mu_range, 'alpha': a_range}), - [term1, term2]), - } + function=[term1, term2]), + } \ No newline at end of file diff --git a/examples/problems/parametric_poisson.py b/examples/problems/parametric_poisson.py index fd1e747..6cc1716 100644 --- a/examples/problems/parametric_poisson.py +++ b/examples/problems/parametric_poisson.py @@ -4,37 +4,52 @@ from pina.problem import SpatialProblem, ParametricProblem from pina.operators import nabla from pina import Span, Condition +# ===================================================== # +# # +# This script implements the two dimensional # +# Parametric Poisson problem. The ParametricPoisson # +# class is defined inheriting from SpatialProblem and # +# ParametricProblem. We denote: # +# u --> field variable # +# x,y --> spatial variables # +# mu1, mu2 --> parameter variables # +# # +# ===================================================== # class ParametricPoisson(SpatialProblem, ParametricProblem): + # assign output/ spatial and parameter variables output_variables = ['u'] spatial_domain = Span({'x': [-1, 1], 'y': [-1, 1]}) parameter_domain = Span({'mu1': [-1, 1], 'mu2': [-1, 1]}) + # define the laplace equation def laplace_equation(input_, output_): force_term = torch.exp( - 2*(input_.extract(['x']) - input_.extract(['mu1']))**2 - 2*(input_.extract(['y']) - input_.extract(['mu2']))**2) return nabla(output_.extract(['u']), input_) - force_term + # define nill dirichlet boundary conditions def nil_dirichlet(input_, output_): value = 0.0 return output_.extract(['u']) - value + # problem condition statement conditions = { 'gamma1': Condition( - Span({'x': [-1, 1], 'y': 1, 'mu1': [-1, 1], 'mu2': [-1, 1]}), - nil_dirichlet), + location=Span({'x': [-1, 1], 'y': 1, 'mu1': [-1, 1], 'mu2': [-1, 1]}), + function=nil_dirichlet), 'gamma2': Condition( - Span({'x': [-1, 1], 'y': -1, 'mu1': [-1, 1], 'mu2': [-1, 1]}), - nil_dirichlet), + location=Span({'x': [-1, 1], 'y': -1, 'mu1': [-1, 1], 'mu2': [-1, 1]}), + function=nil_dirichlet), 'gamma3': Condition( - Span({'x': 1, 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), - nil_dirichlet), + location=Span({'x': 1, 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), + function=nil_dirichlet), 'gamma4': Condition( - Span({'x': -1, 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), - nil_dirichlet), + location=Span({'x': -1, 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), + function=nil_dirichlet), 'D': Condition( - Span({'x': [-1, 1], 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), - laplace_equation), + location=Span({'x': [-1, 1], 'y': [-1, 1], 'mu1': [-1, 1], 'mu2': [-1, 1]}), + function=laplace_equation), } diff --git a/examples/problems/poisson.py b/examples/problems/poisson.py index 9f6d6ae..3372bca 100644 --- a/examples/problems/poisson.py +++ b/examples/problems/poisson.py @@ -5,35 +5,49 @@ from pina.problem import SpatialProblem from pina.operators import nabla from pina import Condition, Span +# ===================================================== # +# # +# This script implements the two dimensional # +# Poisson problem. The Poisson class is defined # +# inheriting from SpatialProblem. We denote: # +# u --> field variable # +# x,y --> spatial variables # +# # +# ===================================================== # + class Poisson(SpatialProblem): + # assign output/ spatial variables output_variables = ['u'] spatial_domain = Span({'x': [0, 1], 'y': [0, 1]}) + # define the laplace equation def laplace_equation(input_, output_): force_term = (torch.sin(input_.extract(['x'])*torch.pi) * torch.sin(input_.extract(['y'])*torch.pi)) nabla_u = nabla(output_.extract(['u']), input_) return nabla_u - force_term + # define nill dirichlet boundary conditions def nil_dirichlet(input_, output_): value = 0.0 return output_.extract(['u']) - value + # problem condition statement 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), + '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), } + # real poisson solution def poisson_sol(self, pts): return -( torch.sin(pts.extract(['x'])*torch.pi)* torch.sin(pts.extract(['y'])*torch.pi) )/(2*torch.pi**2) - #return -(np.sin(x*np.pi)*np.sin(y*np.pi))/(2*np.pi**2) truth_solution = poisson_sol diff --git a/examples/problems/stokes.py b/examples/problems/stokes.py index 3918ab5..dd3be33 100644 --- a/examples/problems/stokes.py +++ b/examples/problems/stokes.py @@ -5,36 +5,62 @@ from pina.problem import SpatialProblem from pina.operators import nabla, grad, div from pina import Condition, Span, LabelTensor +# ===================================================== # +# # +# This script implements the two dimensional # +# Stokes problem. The Stokes class is defined # +# inheriting from SpatialProblem. We denote: # +# ux --> field variable velocity along x # +# uy --> field variable velocity along y # +# p --> field variable pressure # +# x,y --> spatial variables # +# # +# ===================================================== # class Stokes(SpatialProblem): + # assign output/ spatial variables output_variables = ['ux', 'uy', 'p'] spatial_domain = Span({'x': [-2, 2], 'y': [-1, 1]}) + # define the momentum equation def momentum(input_, output_): nabla_ = torch.hstack((LabelTensor(nabla(output_.extract(['ux']), input_), ['x']), LabelTensor(nabla(output_.extract(['uy']), input_), ['y']))) return - nabla_ + grad(output_.extract(['p']), input_) - + + # define the continuity equation def continuity(input_, output_): return div(output_.extract(['ux', 'uy']), input_) + # define the inlet velocity def inlet(input_, output_): value = 2 * (1 - input_.extract(['y'])**2) return output_.extract(['ux']) - value - + + # define the outlet pressure def outlet(input_, output_): value = 0.0 return output_.extract(['p']) - value + # define the wall condition def wall(input_, output_): value = 0.0 return output_.extract(['ux', 'uy']) - value + # problem condition statement conditions = { - 'gamma_top': Condition(Span({'x': [-2, 2], 'y': 1}), wall), - 'gamma_bot': Condition(Span({'x': [-2, 2], 'y': -1}), wall), - 'gamma_out': Condition(Span({'x': 2, 'y': [-1, 1]}), outlet), - 'gamma_in': Condition(Span({'x': -2, 'y': [-1, 1]}), inlet), - 'D': Condition(Span({'x': [-2, 2], 'y': [-1, 1]}), [momentum, continuity]), + 'gamma_top': Condition(location=Span({'x': [-2, 2], 'y': 1}), function=wall), + 'gamma_bot': Condition(location=Span({'x': [-2, 2], 'y': -1}), function=wall), + 'gamma_out': Condition(location=Span({'x': 2, 'y': [-1, 1]}), function=outlet), + 'gamma_in': Condition(location=Span({'x': -2, 'y': [-1, 1]}), function=inlet), + 'D1': Condition(location=Span({'x': [-2, 2], 'y': [-1, 1]}), function=momentum), + 'D2': Condition(location=Span({'x': [-2, 2], 'y': [-1, 1]}), function=continuity), } + # conditions = { + # 'gamma_top': Condition(location=Span({'x': [-2, 2], 'y': 1}), function=wall), + # 'gamma_bot': Condition(location=Span({'x': [-2, 2], 'y': -1}), function=wall), + # 'gamma_out': Condition(location=Span({'x': 2, 'y': [-1, 1]}), function=outlet), + # 'gamma_in': Condition(location=Span({'x': -2, 'y': [-1, 1]}), function=inlet), + # 'D': Condition(location=Span({'x': [-2, 2], 'y': [-1, 1]}), function=[momentum, continuity]), + # } diff --git a/examples/first_order_ode.py b/examples/run_first_order_ode.py similarity index 62% rename from examples/first_order_ode.py rename to examples/run_first_order_ode.py index 558547b..f391433 100644 --- a/examples/first_order_ode.py +++ b/examples/run_first_order_ode.py @@ -1,38 +1,10 @@ import argparse -import torch from torch.nn import Softplus -from pina.problem import SpatialProblem -from pina.operators import grad from pina.model import FeedForward -from pina import Condition, Span, Plotter, PINN - - -class FirstOrderODE(SpatialProblem): - - x_rng = [0, 5] - output_variables = ['y'] - spatial_domain = Span({'x': x_rng}) - - def ode(input_, output_): - y = output_ - x = input_ - return grad(y, x) + y - x - - def fixed(input_, output_): - exp_value = 1. - return output_ - exp_value - - def solution(self, input_): - x = input_ - return x - 1.0 + 2*torch.exp(-x) - - conditions = { - 'bc': Condition(Span({'x': x_rng[0]}), fixed), - 'dd': Condition(Span({'x': x_rng}), ode), - } - truth_solution = solution +from pina import Plotter, PINN +from problems.first_order_ode import FirstOrderODE if __name__ == "__main__": @@ -44,6 +16,7 @@ if __name__ == "__main__": parser.add_argument("id_run", help="number of run", type=int) args = parser.parse_args() + # define Problem + Model + PINN problem = FirstOrderODE() model = FeedForward( layers=[4]*2, @@ -51,7 +24,6 @@ if __name__ == "__main__": input_variables=problem.input_variables, func=Softplus, ) - pinn = PINN(problem, model, lr=0.03, error_norm='mse', regularizer=0) if args.s: diff --git a/examples/run_parametric_elliptic_optimal_control_alpha.py b/examples/run_parametric_elliptic_optimal_control_alpha.py index 7e76e83..efe6d62 100644 --- a/examples/run_parametric_elliptic_optimal_control_alpha.py +++ b/examples/run_parametric_elliptic_optimal_control_alpha.py @@ -1,83 +1,84 @@ -import argparse -import numpy as np -import torch -from torch.nn import Softplus +# import argparse +# import numpy as np +# import torch +# from torch.nn import Softplus -from pina import PINN, LabelTensor, Plotter -from pina.model import MultiFeedForward -from problems.parametric_elliptic_optimal_control_alpha_variable import ( - ParametricEllipticOptimalControl) +# from pina import PINN, LabelTensor, Plotter +# from pina.model import MultiFeedForward +# from problems.parametric_elliptic_optimal_control_alpha_variable import ( +# ParametricEllipticOptimalControl) -class myFeature(torch.nn.Module): - """ - Feature: sin(x) - """ +# class myFeature(torch.nn.Module): +# """ +# Feature: sin(x) +# """ - def __init__(self): - super(myFeature, self).__init__() +# def __init__(self): +# super(myFeature, self).__init__() - def forward(self, x): - t = (-x.extract(['x1'])**2+1) * (-x.extract(['x2'])**2+1) - return LabelTensor(t, ['k0']) +# def forward(self, x): +# t = (-x.extract(['x1'])**2+1) * (-x.extract(['x2'])**2+1) +# return LabelTensor(t, ['k0']) -class CustomMultiDFF(MultiFeedForward): +# class CustomMultiDFF(MultiFeedForward): - def __init__(self, dff_dict): - super().__init__(dff_dict) +# def __init__(self, dff_dict): +# super().__init__(dff_dict) - def forward(self, x): - out = self.uu(x) - p = LabelTensor((out.extract(['u_param']) * x.extract(['alpha'])), ['p']) - return out.append(p) +# def forward(self, x): +# out = self.uu(x) +# p = LabelTensor((out.extract(['u_param']) * x.extract(['alpha'])), ['p']) +# return out.append(p) -if __name__ == "__main__": +# if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Run PINA") - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument("-s", "-save", action="store_true") - group.add_argument("-l", "-load", action="store_true") - args = parser.parse_args() +# parser = argparse.ArgumentParser(description="Run PINA") +# group = parser.add_mutually_exclusive_group(required=True) +# group.add_argument("-s", "-save", action="store_true") +# group.add_argument("-l", "-load", action="store_true") +# args = parser.parse_args() - opc = ParametricEllipticOptimalControl() - model = CustomMultiDFF( - { - 'uu': { - 'input_variables': ['x1', 'x2', 'mu', 'alpha'], - 'output_variables': ['u_param', 'y'], - 'layers': [40, 40, 20], - 'func': Softplus, - 'extra_features': [myFeature()], - }, - } - ) +# opc = ParametricEllipticOptimalControl() +# model = CustomMultiDFF( +# { +# 'uu': { +# 'input_variables': ['x1', 'x2', 'mu', 'alpha'], +# 'output_variables': ['u_param', 'y'], +# 'layers': [40, 40, 20], +# 'func': Softplus, +# 'extra_features': [myFeature()], +# }, +# } +# ) - pinn = PINN( - opc, - model, - lr=0.002, - error_norm='mse', - regularizer=1e-8) +# pinn = PINN( +# opc, +# model, +# lr=0.002, +# error_norm='mse', +# regularizer=1e-8) - if args.s: +# if args.s: - pinn.span_pts( - {'variables': ['x1', 'x2'], 'mode': 'random', 'n': 100}, - {'variables': ['mu', 'alpha'], 'mode': 'grid', 'n': 5}, - locations=['D']) - pinn.span_pts( - {'variables': ['x1', 'x2'], 'mode': 'grid', 'n': 20}, - {'variables': ['mu', 'alpha'], 'mode': 'grid', 'n': 5}, - locations=['gamma1', 'gamma2', 'gamma3', 'gamma4']) +# pinn.span_pts( +# {'variables': ['x1', 'x2'], 'mode': 'random', 'n': 100}, +# {'variables': ['mu', 'alpha'], 'mode': 'grid', 'n': 5}, +# locations=['D']) +# pinn.span_pts( +# {'variables': ['x1', 'x2'], 'mode': 'grid', 'n': 20}, +# {'variables': ['mu', 'alpha'], 'mode': 'grid', 'n': 5}, +# locations=['gamma1', 'gamma2', 'gamma3', 'gamma4']) - pinn.train(1000, 20) - pinn.save_state('pina.ocp') +# pinn.train(1000, 20) +# pinn.save_state('pina.ocp') - else: - pinn.load_state('pina.ocp') - plotter = Plotter() - plotter.plot(pinn, components='y', fixed_variables={'alpha': 0.01, 'mu': 1.0}) - plotter.plot(pinn, components='u_param', fixed_variables={'alpha': 0.01, 'mu': 1.0}) - plotter.plot(pinn, components='p', fixed_variables={'alpha': 0.01, 'mu': 1.0}) +# else: +# pinn.load_state('pina.ocp') +# plotter = Plotter() +# plotter.plot(pinn, components='y', fixed_variables={'alpha': 0.01, 'mu': 1.0}) +# plotter.plot(pinn, components='u_param', fixed_variables={'alpha': 0.01, 'mu': 1.0}) +# plotter.plot(pinn, components='p', fixed_variables={'alpha': 0.01, 'mu': 1.0}) +raise NotImplementedError('not available problem at the moment...') \ No newline at end of file diff --git a/examples/run_stokes.py b/examples/run_stokes.py index 9f48fa7..cf3fd41 100644 --- a/examples/run_stokes.py +++ b/examples/run_stokes.py @@ -37,7 +37,9 @@ if __name__ == "__main__": if args.s: pinn.span_pts(200, 'grid', locations=['gamma_top', 'gamma_bot', 'gamma_in', 'gamma_out']) - pinn.span_pts(2000, 'random', locations=['D']) + # pinn.span_pts(2000, 'random', locations=['D']) + pinn.span_pts(2000, 'random', locations=['D1']) + pinn.span_pts(2000, 'random', locations=['D2']) pinn.train(10000, 100) with open('stokes_history_{}.txt'.format(args.id_run), 'w') as file_: for i, losses in pinn.history_loss.items():