Source code for pina._src.problem.zoo.burgers_problem

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


[docs] class BurgersProblem(TimeDependentProblem, SpatialProblem): r""" Implementation of the one-dimensional Burgers' problem on the space-time domain :math:`\Omega\times T = [-1, 1] \times [0, 1]`. The problem is governed by the Burgers' equation .. math:: \frac{\partial u}{\partial t} + u \frac{\partial u}{\partial x} = \nu \frac{\partial^2 u}{\partial x^2}, where :math:`u = u(x, t)` is the solution field and :math:`\nu \geq 0` is the viscosity coefficient. For :math:`\nu = 0`, the equation reduces to the inviscid Burgers' equation. Homogeneous Dirichlet boundary conditions are imposed at the spatial boundaries: .. math:: u(-1, t) = u(1, t) = 0, \qquad t \in [0, 1]. The initial condition is prescribed as .. math:: u(x, 0) = -\sin(\pi x), \qquad x \in [-1, 1]. .. 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) )