Skip to content

Commit 44d5ec5

Browse files
add burgers equation
1 parent fcaaedc commit 44d5ec5

6 files changed

Lines changed: 132 additions & 0 deletions

File tree

docs/source/_rst/_code.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ Equation Zoo
224224
Acoustic Wave Equation <equation/zoo/acoustic_wave_equation.rst>
225225
Advection Equation <equation/zoo/advection_equation.rst>
226226
Allen-Cahn Equation <equation/zoo/allen_cahn_equation.rst>
227+
Burgers Equation <equation/zoo/burgers_equation.rst>
227228
Diffusion-Reaction Equation <equation/zoo/diffusion_reaction_equation.rst>
228229
Fixed Flux <equation/zoo/fixed_flux.rst>
229230
Fixed Gradient <equation/zoo/fixed_gradient.rst>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Burgers Equation
2+
====================
3+
.. currentmodule:: pina.equation.zoo.burgers_equation
4+
5+
.. automodule:: pina._src.equation.zoo.burgers_equation
6+
:members:
7+
:show-inheritance:
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""Module for defining the Burgers equation."""
2+
3+
from pina._src.core.operator import laplacian, grad
4+
from pina._src.core.utils import check_consistency
5+
from pina._src.equation.equation import Equation
6+
import torch
7+
8+
9+
class BurgersEquation(Equation):
10+
r"""
11+
Implementation of the N-dimensional Burgers equation, defined as follows:
12+
13+
.. math::
14+
15+
\frac{\partial u}{\partial t} + u \cdot \nabla u = \nu \Delta u
16+
17+
Here, :math:`\nu` is the viscosity coefficient.
18+
"""
19+
20+
def __init__(self, nu):
21+
"""
22+
Initialization of the :class:`BurgersEquation` class.
23+
24+
:param nu: The viscosity coefficient.
25+
:type nu: float | int
26+
:raises ValueError: If ``nu`` is not a float or an int.
27+
:raises ValueError: If ``nu`` is negative.
28+
"""
29+
# Check consistency
30+
check_consistency(nu, (float, int))
31+
if nu < 0:
32+
raise ValueError(
33+
"The viscosity ``nu`` must be a positive float or int."
34+
)
35+
36+
# Store viscosity coefficient
37+
self.nu = nu
38+
39+
def equation(input_, output_):
40+
"""
41+
Implementation of the Burgers equation.
42+
43+
:param LabelTensor input_: The input data of the problem.
44+
:param LabelTensor output_: The output data of the problem.
45+
:raises ValueError: If the number of output components does not
46+
match the number of spatial dimensions.
47+
:raises ValueError: If the ``input_`` labels do not contain the time
48+
variable 't'.
49+
:return: The residual of the Burgers equation.
50+
:rtype: LabelTensor
51+
"""
52+
# Store labels
53+
spatial_d = [di for di in input_.labels if di != "t"]
54+
55+
# Ensure consistency between output and spatial dimensions
56+
if len(output_.labels) != len(spatial_d):
57+
raise ValueError(
58+
f"The number of output components must match the number of "
59+
f"spatial dimensions. Got {len(output_.labels)} and "
60+
f"{len(spatial_d)}."
61+
)
62+
63+
# Ensure time is passed as input
64+
if "t" not in input_.labels:
65+
raise ValueError(
66+
"The ``input_`` labels must contain the time 't' variable."
67+
)
68+
69+
# Compute the differential terms
70+
u_t = grad(output_, input_, d=["t"])
71+
u_x = grad(output_, input_, d=spatial_d)
72+
u_xx = laplacian(output_, input_, d=spatial_d)
73+
74+
# Compute the convective term componentwise
75+
convection = torch.zeros_like(output_)
76+
for i, c in enumerate(output_.labels):
77+
convection[:, i] = sum(
78+
output_[output_.labels[j]] * u_x[f"d{c}d{spatial_d[j]}"]
79+
for j in range(len(spatial_d))
80+
).reshape(-1)
81+
82+
return u_t + convection - self.nu * u_xx
83+
84+
super().__init__(equation)

pina/equation/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"AdvectionEquation": ".zoo",
3737
"AllenCahnEquation": ".zoo",
3838
"DiffusionReactionEquation": ".zoo",
39+
"BurgersEquation": ".zoo",
3940
}
4041

4142

pina/equation/zoo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"Laplace",
1313
"PoissonEquation",
1414
"AcousticWaveEquation",
15+
"BurgersEquation",
1516
]
1617

1718
from pina._src.equation.zoo.acoustic_wave_equation import AcousticWaveEquation
@@ -22,6 +23,7 @@
2223
)
2324
from pina._src.equation.zoo.helmholtz_equation import HelmholtzEquation
2425
from pina._src.equation.zoo.poisson_equation import PoissonEquation
26+
from pina._src.equation.zoo.burgers_equation import BurgersEquation
2527
from pina._src.equation.zoo.fixed_value import FixedValue
2628
from pina._src.equation.zoo.fixed_gradient import FixedGradient
2729
from pina._src.equation.zoo.fixed_flux import FixedFlux
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pytest
2+
import torch
3+
from pina import LabelTensor
4+
from pina.equation.zoo import BurgersEquation
5+
6+
7+
# Define input and output values
8+
pts = LabelTensor(torch.rand(10, 3, requires_grad=True), labels=["x", "y", "t"])
9+
u = torch.sin(pts["x", "y"]) * torch.cos(pts["y", "t"])
10+
u.labels = ["u", "v"]
11+
12+
13+
@pytest.mark.parametrize("nu", [0, 1, 2.5])
14+
def test_burgers_equation(nu):
15+
16+
# Constructor
17+
equation = BurgersEquation(nu=nu)
18+
19+
# Should fail if nu is not a float or int
20+
with pytest.raises(ValueError):
21+
BurgersEquation(nu="invalid")
22+
23+
# Should fail if nu is negative
24+
with pytest.raises(ValueError):
25+
BurgersEquation(nu=-1)
26+
27+
# Residual
28+
residual = equation.residual(pts, u)
29+
assert residual.shape == u.shape
30+
31+
# Should fail if the input has no 't' label
32+
with pytest.raises(ValueError):
33+
residual = equation.residual(pts["x", "y"], u)
34+
35+
# Should fail if output and spatial dimensions do not match
36+
with pytest.raises(ValueError):
37+
residual = equation.residual(pts, u["u"])

0 commit comments

Comments
 (0)