Source code for pulse.boundary_conditions
"""This module defines boundary conditions.
Boundary conditions are used to specify the behavior of the solution on the boundary of the domain.
The boundary conditions can be Dirichlet, Neumann, or Robin boundary conditions.
Dirichlet boundary conditions are used to specify the solution on the boundary of the domain.
Neumann boundary conditions are used to specify the traction on the boundary of the domain.
Robin boundary conditions are used to specify a Robin type boundary condition
on the boundary of the domain.
The boundary conditions are collected in a `BoundaryConditions` object.
"""
import logging
import typing
from dataclasses import dataclass
import dolfinx
from .units import Variable
logger = logging.getLogger(__name__)
[docs]
@dataclass(slots=True)
class NeumannBC:
traction: Variable
marker: int
def __post_init__(self):
if not isinstance(self.traction, Variable):
unit = "kPa"
logger.warning("Traction is not a Variable, defaulting to kPa")
self.traction = Variable(self.traction, unit)
logger.debug(f"Created NeumannBC on marker {self.marker} with traction {self.traction}")
[docs]
@dataclass(slots=True)
class RobinBC:
value: Variable
marker: int
damping: bool = False
perpendicular: bool = False
def __post_init__(self):
if not isinstance(self.value, Variable):
unit = "Pa s / m" if self.damping else "Pa / m"
logger.warning(f"Value is not a Variable, defaulting to {unit}")
self.value = Variable(self.value, unit)
logger.debug(
f"Created RobinBC on marker {self.marker} with value {self.value} "
f"({'damping' if self.damping else 'stiffness'})",
)
[docs]
class BoundaryConditions(typing.NamedTuple):
neumann: typing.Sequence[NeumannBC] = ()
dirichlet: typing.Sequence[
typing.Callable[
[dolfinx.fem.FunctionSpace],
typing.Sequence[dolfinx.fem.bcs.DirichletBC],
]
] = ()
robin: typing.Sequence[RobinBC] = ()
body_force: typing.Sequence[float | dolfinx.fem.Constant | dolfinx.fem.Function] = ()