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

"""Formulation of the Helmholtz problem."""

import torch
from pina._src.condition.condition import Condition
from pina._src.equation.zoo.fixed_value import FixedValue
from pina._src.equation.zoo.helmholtz_equation import HelmholtzEquation
from pina._src.problem.spatial_problem import SpatialProblem
from pina._src.core.utils import check_consistency
from pina._src.domain.cartesian_domain import CartesianDomain


[docs] class HelmholtzProblem(SpatialProblem): r""" Implementation of the two-dimensional Helmholtz problem on the square domain :math:`\Omega = [-1, 1] \times [-1, 1]`. The problem is governed by the forced Helmholtz equation .. math:: \Delta u + k u = f(x, y), where :math:`u = u(x, y)` is the solution field, :math:`k` is the squared wavenumber, and :math:`f(x, y)` is a forcing term. Homogeneous Dirichlet boundary conditions are imposed on the boundary of the domain: .. math:: u(x, y) = 0, \qquad (x, y) \in \partial \Omega. The analytical solution is given by .. math:: u(x, y) = \sin(\alpha_x \pi x) \sin(\alpha_y \pi y), with forcing term .. math:: f(x, y) = \left[ k - (\alpha_x^2 + \alpha_y^2)\pi^2 \right] \sin(\alpha_x \pi x) \sin(\alpha_y \pi y). .. seealso:: **Original reference**: Si, Chenhao, et al. *Complex Physics-Informed Neural Network.* arXiv preprint arXiv:2502.04917 (2025). DOI: `arXiv:2502.04917 <https://arxiv.org/abs/2502.04917>`_. :Example: >>> problem = HelmholtzProblem() """ output_variables = ["u"] spatial_domain = CartesianDomain({"x": [-1, 1], "y": [-1, 1]}) domains = { "D": spatial_domain, "boundary": spatial_domain.partial(), } conditions = { "boundary": Condition(domain="boundary", equation=FixedValue(0.0)), } def __init__(self, k=1.0, alpha_x=1, alpha_y=4): """ Initialization of the :class:`HelmholtzProblem` class. :param k: The squared wavenumber. Default is ``1.0``. :type k: float | int :param int alpha_x: The frequency in the x-direction. Default is ``1``. :param int alpha_y: The frequency in the y-direction. Default is ``4``. """ super().__init__() check_consistency(k, (int, float)) check_consistency(alpha_x, int) check_consistency(alpha_y, int) self.k = k self.alpha_x = alpha_x self.alpha_y = alpha_y def forcing_term(input_): """ Implementation of the forcing term. """ x, y, pi = input_["x"], input_["y"], torch.pi factor = (self.alpha_x**2 + self.alpha_y**2) * pi**2 return ( (self.k - factor) * torch.sin(self.alpha_x * pi * x) * torch.sin(self.alpha_y * pi * y) ) self.conditions["D"] = Condition( domain="D", equation=HelmholtzEquation(self.k, forcing_term), )
[docs] def solution(self, pts): """ Implementation of the analytical solution of the Helmholtz problem. :param LabelTensor pts: Points where the solution is evaluated. :return: The analytical solution of the Helmholtz problem. :rtype: LabelTensor """ x, y, pi = pts["x"], pts["y"], torch.pi sol = torch.sin(self.alpha_x * pi * x) * torch.sin( self.alpha_y * pi * y ) sol.labels = self.output_variables return sol