PhysicsNeMo Sym#
Symbolic PDE residual computation for physics-informed training.
PDE Base Class#
- class physicsnemo.sym.eq.pde.PDE[source]#
Bases:
objectBase class for all partial differential equations.
Subclasses must populate
self.equations(adict[str, sympy.Expr]) and setself.dim.Examples
Define a 2-D advection-diffusion equation:
>>> from sympy import Symbol, Function, Number >>> from physicsnemo.sym.eq.pde import PDE >>> >>> class AdvectionDiffusion(PDE): ... def __init__(self, D=0.1): ... self.dim = 2 ... x, y = Symbol("x"), Symbol("y") ... T = Function("T")(x, y) ... u = Function("u")(x, y) ... v = Function("v")(x, y) ... self.equations = { ... "advection_diffusion": ( ... u * T.diff(x) + v * T.diff(y) ... - D * (T.diff(x, 2) + T.diff(y, 2)) ... ), ... } ... >>> pde = AdvectionDiffusion(D=0.01) >>> pde.pprint() advection_diffusion: ...
PhysicsInformer#
- class physicsnemo.sym.eq.phy_informer.PhysicsInformer(
- required_outputs: List[str],
- equations: PDE,
- grad_method: str,
- fd_dx: float | List[float] = 0.001,
- bounds: List[float] | None = None,
- compute_connectivity: bool = True,
- detach_names: List[str] | None = None,
- device: str | None = None,
Bases:
objectCompute the residual of a PDE using automatic spatial derivative computation.
Given a
PDEand a list ofrequired_outputs, this class builds a computational graph that automatically computes spatial derivatives and evaluates equation residuals.- Parameters:
required_outputs (list[str]) – Equation names to compute (e.g.
["continuity", "momentum_x"]).equations (PDE) – The PDE whose
equationsdict defines the symbolic residuals.grad_method (str) – One of
"autodiff","meshless_finite_difference","finite_difference","spectral","least_squares".fd_dx (float or list[float]) – Grid spacing for FD / meshless FD methods.
bounds (list[float]) – Domain lengths for spectral method.
compute_connectivity (bool) – If True and using
"least_squares", build the connectivity tensor on the fly from"nodes"and"edges"in the input dict.detach_names (list[str] or None) – Names of variables (and their derivatives) whose tensors will be detached from the computational graph before the compiled PDE equations are evaluated. When a name appears in this list, its value is passed through
torch.Tensor.detach()inside theSympyToTorchforward call, so no gradient flows through it during back-propagation. This is useful for inverse problems: for example, when inverting for viscositynuthe flow-field variables and their spatial derivatives (["u", "u__x", "u__x__x", ...]) should be detached so that the physics loss updates only the inversion network fornuwhile the flow network is trained solely on data-fitting loss.device (str or torch.device or None) – Target device.
Examples
>>> import torch >>> from sympy import Symbol, Function, Number >>> from physicsnemo.sym.eq.pde import PDE >>> from physicsnemo.sym.eq.phy_informer import PhysicsInformer >>> >>> class Diffusion(PDE): ... def __init__(self, D=0.1): ... self.dim = 2 ... x, y = Symbol("x"), Symbol("y") ... u = Function("u")(x, y) ... self.equations = { ... "diffusion": -D * (u.diff(x, 2) + u.diff(y, 2)), ... } ... >>> pde = Diffusion(D=0.01) >>> pi = PhysicsInformer( ... required_outputs=["diffusion"], ... equations=pde, ... grad_method="finite_difference", ... fd_dx=0.01, ... ) >>> field = torch.rand(1, 1, 32, 32) >>> result = pi.forward({"u": field}) >>> result["diffusion"].shape torch.Size([1, 1, 32, 32])
- property required_inputs: list[str]#
Return the list of tensor names the
forwardcall expects.
Gradient Calculators#
GradientCalculator is the user-facing dispatcher that PhysicsInformer
uses internally based on the grad_method argument. The individual
per-method Gradients* modules are exposed for advanced users that need to
compute spatial derivatives outside of the PhysicsInformer pipeline.
- class physicsnemo.sym.eq.gradients.GradientCalculator(device=None)[source]#
Factory for spatial gradient modules.
- Parameters:
device (str or torch.device or None) – Target device for the created gradient modules.
Examples
>>> import torch >>> from physicsnemo.sym.eq.gradients import GradientCalculator >>> calc = GradientCalculator(device="cpu") >>> module = calc.get_gradient_module("autodiff", invar="u", dim=2, order=1)
- class physicsnemo.sym.eq.gradients.GradientsAutoDiff(
- invar: str,
- dim: int = 3,
- order: int = 1,
- return_mixed_derivs: bool = False,
Bases:
ModuleCompute spatial derivatives via
torch.autograd.grad.- Parameters:
invar (str) – Name of the variable to differentiate (e.g.
"u").dim (int) – Spatial dimensionality (1, 2, or 3).
order (int) – Derivative order (1 or 2).
return_mixed_derivs (bool) – If True and
order=2, include cross-derivatives likeu__x__y.
- forward(
- input_dict: Dict[str, Tensor],
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class physicsnemo.sym.eq.gradients.GradientsFiniteDifference(
- invar: str,
- dx: float | List[float],
- dim: int = 3,
- order: int = 1,
- return_mixed_derivs: bool = False,
Bases:
ModuleCompute spatial derivatives on uniform grids via
UniformGridGradient.- Parameters:
invar (str) – Name of the variable to differentiate (e.g.
"u").dx (float or list[float]) – Uniform grid spacing per axis.
dim (int) – Spatial dimensionality (1, 2, or 3).
order (int) – Derivative order (1 or 2).
return_mixed_derivs (bool) – If True and
order=2, include cross-derivatives likeu__x__y.
- forward(
- input_dict: Dict[str, Tensor],
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class physicsnemo.sym.eq.gradients.GradientsMeshlessFiniteDifference(
- invar: str,
- dx: float | List[float],
- dim: int = 3,
- order: int = 1,
- return_mixed_derivs: bool = False,
Bases:
ModuleCompute spatial derivatives using meshless central differences.
Expects stencil values in the input dict keyed as
u>>x::1,u>>x::-1, etc.- forward(
- input_dict: Dict[str, Tensor],
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class physicsnemo.sym.eq.gradients.GradientsSpectral(
- invar: str,
- ell: float | List[float],
- dim: int = 3,
- order: int = 1,
- return_mixed_derivs: bool = False,
Bases:
ModuleCompute spatial derivatives via
SpectralGridGradient.- forward(
- input_dict: Dict[str, Tensor],
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class physicsnemo.sym.eq.gradients.GradientsLeastSquares(
- invar: str,
- dim: int = 3,
- order: int = 1,
- return_mixed_derivs: bool = False,
Bases:
ModuleCompute spatial derivatives using least-squares gradient reconstruction.
Uses
MeshLSQGradientfor first-order gradients and composes calls for second-order (same approach as the original physicsnemo-sym implementation).- forward(
- input_dict: Dict[str, Tensor],
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Moduleinstance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- physicsnemo.sym.eq.gradients.compute_connectivity_tensor(
- nodes: Tensor,
- edges: Tensor,
- max_neighbors: int | None = None,
Build CSR adjacency from node/edge lists.
Uses vectorized PyTorch ops (argsort + bincount) via the
physicsnemo.mesh.neighborsutilities.- Parameters:
nodes (torch.Tensor) – Node IDs with shape
(N, 1).edges (torch.Tensor) – Edge pairs with shape
(M, 2).max_neighbors (int or None) – Pad neighbor matrix to this width. If None, uses the maximum found.
- Returns:
(offsets, indices, neighbor_matrix)— CSR representation plus a padded(N, max_neighbors)neighbor matrix for batched computation.- Return type:
tuple[torch.Tensor, torch.Tensor, torch.Tensor]