Source code for pina._src.equation.zoo.burgers_equation

"""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


[docs] 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 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)