PhysicsNeMo Sym#

Symbolic PDE residual computation for physics-informed training.

class physicsnemo.sym.eq.pde.PDE[source]#

Bases: object

base class for all partial differential equations

make_nodes(
create_instances: int = 1,
freeze_terms: Dict[str, List[int]] = None,
detach_names: list[str] = None,
return_as_dict: bool = False,
)[source]#

Make a list of nodes from PDE.

Parameters:
  • create_instances (int) – This will create various instances of the same equations

  • freeze_terms (Dict[str, List[int]]) – This will freeze the terms in appropiate equation

  • detach_names (List[str]) – This will detach the inputs of the resulting node.

  • return_as_dict (bool) – If True, return nodes as a dictionary with equation names as keys. If False, return nodes as a list (default behavior).

Returns:

nodes – Makes a separate node for every equation. Returns list of nodes if return_as_dict=False, dictionary if return_as_dict=True.

Return type:

list[Node] | dict[str, Node]

pprint(print_latex=False)[source]#

Print differential equation.

Parameters:

print_latex (bool) – If True print the equations in Latex. Else, just print as text.

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] = [6.283185307179586, 6.283185307179586, 6.283185307179586],
compute_connectivity: bool = True,
device: str | None = None,
)[source]#

Bases: object

A utility to compute the residual of a Partial Differential Equation (PDE). Given the equations and required_outputs, this utility constructs the computational graph, including computing of the derivatives to output the residuals.

This utility computes the spatial grads automatically. Currently the spatial grads are computed using “autodiff”, “meshless_finite_difference”, “finite_difference”, “spectral”, and “least_squares” methods. All the other gradients (such as gradients w.r.t. time) will have to be manually included in the input_dict to the forward call.

Parameters:
  • required_outputs (List[str]) – Required keys in the output dictionary. To find the available outputs of a PDE, you can use the .pprint() method.

  • equations (PDE) – Equation to use for computing the residual. The equation must be in the form of PhysicsNeMo Sym’s PDE. For more details, refer: https://docs.nvidia.com/deeplearning/physicsnemo/physicsnemo-sym/user_guide/features/nodes.html#equations. Custom PDEs are also supported. For details refer: https://docs.nvidia.com/deeplearning/physicsnemo/physicsnemo-sym/user_guide/features/nodes.html#custom-pdes

  • grad_method (str) –

    Gradient method to use. Currently below methods are supported, which can be selected based on the model output format:

    • autodiff: The spatial gradients are computed using automatic differentiation. Ideal for networks dealing with point-clouds and fully-differentiable networks. The .forward call requires input dict with the relevant variables in [N, 1] shape along with entry for “coordinates” in [N, m] shape where m is the dimensionality of the input (1/2/3 based on 1D, 2D and 3D). Note: the coordinates tensor must have requires_grad set to True and the model outputs need to be connected to the coordinates in the computational graph.

    • meshless_finite_difference: The spatial gradients are computed using meshless finite difference. Ideal for use with point-clouds. For details refer: https://docs.nvidia.com/deeplearning/physicsnemo/physicsnemo-sym/user_guide/features/performance.html#meshless-finite-derivatives. The .forward call requires input dict with the relevant variables in [N, 1] shape along with the same variables executed at the stencil points. Stencil points are defined by the following convention:

      ”u>>x::1”: u(i+1, j) “u>>x::-1”: u(i-1, j) “u>>x::1&&y::1”: u(i+1, j+1) “u>>x::-1&&y::-1”: u(i-1, j-1) etc.

    • finite_difference: The spatial gradients are computed using finite difference assuming regular grid. Ideal for use with regular grids / images. The .forward call requires input dict with the relevant variables in [N, 1, H, W, D] for 3D, [N, 1, H, W] for 2D and [N, 1, H] for 1D.

    • spectral: The spatial gradients are computed using FFTs. Note: this can lead to boundary artifacts for non-periodic signals. Ideal for use with regular grids / images. The .forward call requires input dict with the relevant variables in [N, 1, H, W, D] for 3D, [N, 1, H, W] for 2D and [N, 1, H] for 1D.

    • least_squares: The spatial gradients are computed using Least Squares technique. Ideal for use with mesh based representations (i.e. unstructured grids). All values are computed at the nodes. The .forward call requires input dict with the relevant variables in [N, 1] shape along with entry for “coordinates” in [N, m] shape where m is the dimensionality of the input (1/2/3 based on 1D, 2D and 3D), “node_ids”, “edges” and “connectivity_tensor”. The “node_ids” and “edges” can directly derived from the graph representation (for example for dgl graph, by running graph.nodes() and graph.edges()). For computing connectivity tensor, refer: physicsnemo.sym.eq.spatial_grads.spatial_grads.compute_connectivity_tensor

  • fd_dx (Union[float, List[float]], optional) – dx to be used for meshless finite difference and regular finite difference calculation. If float, the same value is used across all dimensions, by default 0.001

  • bounds (List[float], optional) – bounds to be used for spectral derivatives, by default [2 * np.pi, 2 * np.pi, 2 * np.pi]

  • compute_connectivity (bool, optional) – Whether to compute the connectivity tensor during forward pass (only applies for least squares method), by default True. Set to false if this can be computed as a part of the dataloader.

  • device (Optional[str], optional) – The device to use for computation. Options are “cuda” or “cpu”. If not specified, the computation defaults to “cpu”.

Examples

>>> import torch
>>> from physicsnemo.sym.eq.pdes.navier_stokes import NavierStokes
>>> from physicsnemo.sym.eq.phy_informer import PhysicsInformer
>>> ns = NavierStokes(nu=0.1, rho=1.0, dim=2, time=True)
>>> phy_inf = PhysicsInformer(
... required_outputs=["continuity", "momentum_x"],
... equations=ns,
... grad_method="finite_difference"
... )
>>> tensor = torch.rand(1, 1, 10, 10)   # [N, 1, H, W]
>>> sorted(phy_inf.required_inputs)
...
['p', 'u', 'u__t', 'v']
>>> out_dict = phy_inf.forward({"u": tensor, "v": tensor, "u__t": tensor, "p": tensor})
>>> out_dict.keys()
dict_keys(['continuity', 'momentum_x'])
>>> out_dict["continuity"].shape
torch.Size([1, 1, 10, 10])
forward(inputs)[source]#

Forward pass

property required_inputs#

Find the required inputs

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)
compute_gradients(
input_dict,
method_name=None,
invar=None,
**kwargs,
)[source]#

Compute gradients in one shot (convenience wrapper).

get_gradient_module(
method_name: str,
invar: str,
**kwargs,
)[source]#

Return a gradient torch.nn.Module for the given method and variable.

physicsnemo.sym.eq.gradients.compute_connectivity_tensor(
nodes: Tensor,
edges: Tensor,
max_neighbors: int | None = None,
) tuple[Tensor, Tensor, Tensor][source]#

Build CSR adjacency from node/edge lists.

Uses vectorized PyTorch ops (argsort + bincount) via the physicsnemo.mesh.neighbors utilities.

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]