Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/source/_rst/_code.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ Equation Zoo
Acoustic Wave Equation <equation/zoo/acoustic_wave_equation.rst>
Advection Equation <equation/zoo/advection_equation.rst>
Allen-Cahn Equation <equation/zoo/allen_cahn_equation.rst>
Burgers Equation <equation/zoo/burgers_equation.rst>
Diffusion-Reaction Equation <equation/zoo/diffusion_reaction_equation.rst>
Fixed Flux <equation/zoo/fixed_flux.rst>
Fixed Gradient <equation/zoo/fixed_gradient.rst>
Expand Down Expand Up @@ -255,6 +256,7 @@ Problem Zoo
AcousticWaveProblem <problem/zoo/acoustic_wave_problem.rst>
AdvectionProblem <problem/zoo/advection_problem.rst>
AllenCahnProblem <problem/zoo/allen_cahn_problem.rst>
BurgersProblem <problem/zoo/burgers_problem.rst>
DiffusionReactionProblem <problem/zoo/diffusion_reaction_problem.rst>
HelmholtzProblem <problem/zoo/helmholtz_problem.rst>
InversePoisson2DSquareProblem <problem/zoo/inverse_poisson_problem.rst>
Expand Down
7 changes: 7 additions & 0 deletions docs/source/_rst/equation/zoo/burgers_equation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Burgers Equation
====================
.. currentmodule:: pina.equation.zoo.burgers_equation

.. automodule:: pina._src.equation.zoo.burgers_equation
:members:
:show-inheritance:
9 changes: 9 additions & 0 deletions docs/source/_rst/problem/zoo/burgers_problem.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Burgers Problem
=====================
.. currentmodule:: pina.problem.zoo.burgers_problem

.. automodule:: pina._src.problem.zoo.burgers_problem

.. autoclass:: pina._src.problem.zoo.burgers_problem.BurgersProblem
:members:
:show-inheritance:
84 changes: 84 additions & 0 deletions pina/_src/equation/zoo/burgers_equation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Module for defining the Burgers equation."""

from pina._src.core.operator import laplacian, grad
from pina._src.core.utils import check_consistency
from pina._src.equation.equation import Equation
import torch


class BurgersEquation(Equation):
r"""
Implementation of the N-dimensional Burgers equation, defined as follows:

.. math::

\frac{\partial u}{\partial t} + u \cdot \nabla u = \nu \Delta u

Here, :math:`\nu` is the viscosity coefficient.
"""

def __init__(self, nu):
"""
Initialization of the :class:`BurgersEquation` class.

:param nu: The viscosity coefficient.
:type nu: float | int
:raises ValueError: If ``nu`` is not a float or an int.
:raises ValueError: If ``nu`` is negative.
"""
# Check consistency
check_consistency(nu, (float, int))
if nu < 0:
raise ValueError(
"The viscosity ``nu`` must be a non-negative float or int."
)

# Store viscosity coefficient
self.nu = nu

def equation(input_, output_):
"""
Implementation of the Burgers equation.

:param LabelTensor input_: The input data of the problem.
:param LabelTensor output_: The output data of the problem.
:raises ValueError: If the number of output components does not
match the number of spatial dimensions.
:raises ValueError: If the ``input_`` labels do not contain the time
variable 't'.
:return: The residual of the Burgers equation.
:rtype: LabelTensor
"""
# Store labels
spatial_d = [di for di in input_.labels if di != "t"]

# Ensure consistency between output and spatial dimensions
if len(output_.labels) != len(spatial_d):
raise ValueError(
f"The number of output components must match the number of "
f"spatial dimensions. Got {len(output_.labels)} and "
f"{len(spatial_d)}."
)

# Ensure time is passed as input
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this types of check we already do in grad. Maybe we can use fast_grad afterwards to speed up a bit?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, grad already checks whether "t" is in the input labels. However, this error message is very explicit and I would keep it.

I can use fast_grad for the temporal derivative. Still, checks must be performed for the differential operators computed on spatial variables.

if "t" not in input_.labels:
raise ValueError(
"The ``input_`` labels must contain the time 't' variable."
)

# Compute the differential terms
u_t = grad(output_, input_, d=["t"])
u_x = grad(output_, input_, d=spatial_d)
u_xx = laplacian(output_, input_, d=spatial_d)

# Compute the convective term componentwise
convection = torch.zeros_like(output_)
for i, c in enumerate(output_.labels):
convection[:, i] = sum(
output_[output_.labels[j]] * u_x[f"d{c}d{spatial_d[j]}"]
for j in range(len(spatial_d))
).reshape(-1)

return u_t + convection - self.nu * u_xx

super().__init__(equation)
79 changes: 79 additions & 0 deletions pina/_src/problem/zoo/burgers_problem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Formulation of the burgers problem."""

import torch
from pina._src.problem.time_dependent_problem import TimeDependentProblem
from pina._src.domain.cartesian_domain import CartesianDomain
from pina._src.problem.spatial_problem import SpatialProblem
from pina._src.condition.condition import Condition
from pina._src.core.utils import check_consistency
from pina._src.equation.equation import Equation
from pina._src.equation.zoo.fixed_value import FixedValue
from pina._src.equation.zoo.burgers_equation import BurgersEquation


def initial_condition(input_, output_):
"""
Definition of the initial condition of the burgers problem.

:param LabelTensor input_: The input data of the problem.
:param LabelTensor output_: The output data of the problem.
:return: The residual of the initial condition.
:rtype: LabelTensor
"""
return output_ + torch.sin(torch.pi * input_["x"])


class BurgersProblem(TimeDependentProblem, SpatialProblem):
r"""
Implementation of the burgers problem in the spatial interval
:math:`[-1, 1]` and temporal interval :math:`[0, 1]`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe let's add the equation here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have kept the same structure of other problems: the equation is described just in the corresponding class.

Maybe, we can add a more thorough description for all problems in the zoo (domain, boundary and initial conditions, pde, ...).

In such case, I will fix this for the BurgersProblem here and open a new PR for all other zoo members


.. seealso::

**Original reference**: Raissi M., Perdikaris P., Karniadakis G. E.
(2017).
*Physics Informed Deep Learning (Part I): Data-driven Solutions of
Nonlinear Partial Differential Equations*.
DOI: `10.48550 <https://doi.org/10.48550/arXiv.1711.10561>`_.

:Example:

>>> problem = BurgersProblem()
"""

output_variables = ["u"]
spatial_domain = CartesianDomain({"x": [-1, 1]})
temporal_domain = CartesianDomain({"t": [0, 1]})

domains = {
"D": spatial_domain.update(temporal_domain),
"t0": spatial_domain.update(CartesianDomain({"t": 0})),
"boundary": spatial_domain.partial().update(temporal_domain),
}

conditions = {
"boundary": Condition(domain="boundary", equation=FixedValue(0.0)),
"t0": Condition(domain="t0", equation=Equation(initial_condition)),
}

def __init__(self, nu=0):
"""
Initialization of the :class:`BurgersProblem` class.

:param nu: The viscosity coefficient.
:type nu: float | int
:raises ValueError: If ``nu`` is not a float or an int.
:raises ValueError: If ``nu`` is negative.
"""
super().__init__()

# Check consistency
check_consistency(nu, (float, int))
if nu < 0:
raise ValueError(
"The viscosity ``nu`` must be a non-negative float or int."
)

self.conditions["D"] = Condition(
domain="D", equation=BurgersEquation(nu)
)
1 change: 1 addition & 0 deletions pina/equation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"AdvectionEquation": ".zoo",
"AllenCahnEquation": ".zoo",
"DiffusionReactionEquation": ".zoo",
"BurgersEquation": ".zoo",
}


Expand Down
2 changes: 2 additions & 0 deletions pina/equation/zoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"Laplace",
"PoissonEquation",
"AcousticWaveEquation",
"BurgersEquation",
]

from pina._src.equation.zoo.acoustic_wave_equation import AcousticWaveEquation
Expand All @@ -22,6 +23,7 @@
)
from pina._src.equation.zoo.helmholtz_equation import HelmholtzEquation
from pina._src.equation.zoo.poisson_equation import PoissonEquation
from pina._src.equation.zoo.burgers_equation import BurgersEquation
from pina._src.equation.zoo.fixed_value import FixedValue
from pina._src.equation.zoo.fixed_gradient import FixedGradient
from pina._src.equation.zoo.fixed_flux import FixedFlux
Expand Down
2 changes: 2 additions & 0 deletions pina/problem/zoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"DiffusionReactionProblem",
"InversePoisson2DSquareProblem",
"AcousticWaveProblem",
"BurgersProblem",
]

from pina._src.problem.zoo.acoustic_wave_problem import AcousticWaveProblem
Expand All @@ -17,6 +18,7 @@
from pina._src.problem.zoo.advection_problem import AdvectionProblem
from pina._src.problem.zoo.helmholtz_problem import HelmholtzProblem
from pina._src.problem.zoo.poisson_problem import Poisson2DSquareProblem
from pina._src.problem.zoo.burgers_problem import BurgersProblem
from pina._src.problem.zoo.diffusion_reaction_problem import (
DiffusionReactionProblem,
)
Expand Down
37 changes: 37 additions & 0 deletions tests/test_equation_zoo/test_burgers_equation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import pytest
import torch
from pina import LabelTensor
from pina.equation.zoo import BurgersEquation


# Define input and output values
pts = LabelTensor(torch.rand(10, 3, requires_grad=True), labels=["x", "y", "t"])
u = torch.sin(pts["x", "y"]) * torch.cos(pts["y", "t"])
u.labels = ["u", "v"]


@pytest.mark.parametrize("nu", [0, 1, 2.5])
def test_burgers_equation(nu):

# Constructor
equation = BurgersEquation(nu=nu)

# Should fail if nu is not a float or int
with pytest.raises(ValueError):
BurgersEquation(nu="invalid")

# Should fail if nu is negative
with pytest.raises(ValueError):
BurgersEquation(nu=-1)

# Residual
residual = equation.residual(pts, u)
assert residual.shape == u.shape

# Should fail if the input has no 't' label
with pytest.raises(ValueError):
residual = equation.residual(pts["x", "y"], u)

# Should fail if output and spatial dimensions do not match
with pytest.raises(ValueError):
residual = equation.residual(pts, u["u"])
23 changes: 23 additions & 0 deletions tests/test_problem_zoo/test_burgers_problem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
from pina.problem.zoo import BurgersProblem
from pina.problem import SpatialProblem, TimeDependentProblem


@pytest.mark.parametrize("nu", [0.1, 1])
def test_constructor(nu):

problem = BurgersProblem(nu=nu)
problem.discretise_domain(n=10, mode="random", domains=None)
assert problem.are_all_domains_discretised
assert isinstance(problem, SpatialProblem)
assert isinstance(problem, TimeDependentProblem)
assert hasattr(problem, "conditions")
assert isinstance(problem.conditions, dict)

# Should fail if nu is not a float or int
with pytest.raises(ValueError):
BurgersProblem(nu="invalid")

# Should fail if nu is negative
with pytest.raises(ValueError):
BurgersProblem(nu=-0.1)
Loading