Operator Models#

class physicsnemo.models.domino.model.DoMINO(
input_features: int,
output_features_vol: int | None = None,
output_features_surf: int | None = None,
global_features: int = 2,
model_parameters=None,
)[source]#

Bases: Module

DoMINO model architecture for predicting both surface and volume quantities.

The DoMINO (Deep Operational Modal Identification and Nonlinear Optimization) model is designed to model both surface and volume physical quantities in aerodynamic simulations. It can operate in three modes: 1. Surface-only: Predicting only surface quantities 2. Volume-only: Predicting only volume quantities 3. Combined: Predicting both surface and volume quantities

The model uses a combination of: - Geometry representation modules - Neural network basis functions - Parameter encoding - Local and global geometry processing - Aggregation models for final prediction

Parameters:
  • input_features (int) – Number of point input features

  • output_features_vol (int, optional) – Number of output features in volume

  • output_features_surf (int, optional) – Number of output features on surface

  • model_parameters – Model parameters controlled by config.yaml

Example

>>> from physicsnemo.models.domino.model import DoMINO
>>> import torch, os
>>> from hydra import compose, initialize
>>> from omegaconf import OmegaConf
>>> device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
>>> cfg = OmegaConf.register_new_resolver("eval", eval)
>>> with initialize(version_base="1.3", config_path="examples/cfd/external_aerodynamics/domino/src/conf"):
...    cfg = compose(config_name="config")
>>> cfg.model.model_type = "combined"
>>> model = DoMINO(
...         input_features=3,
...         output_features_vol=5,
...         output_features_surf=4,
...         model_parameters=cfg.model
...     ).to(device)

Warp … >>> bsize = 1 >>> nx, ny, nz = cfg.model.interp_res >>> num_neigh = 7 >>> global_features = 2 >>> pos_normals_closest_vol = torch.randn(bsize, 100, 3).to(device) >>> pos_normals_com_vol = torch.randn(bsize, 100, 3).to(device) >>> pos_normals_com_surface = torch.randn(bsize, 100, 3).to(device) >>> geom_centers = torch.randn(bsize, 100, 3).to(device) >>> grid = torch.randn(bsize, nx, ny, nz, 3).to(device) >>> surf_grid = torch.randn(bsize, nx, ny, nz, 3).to(device) >>> sdf_grid = torch.randn(bsize, nx, ny, nz).to(device) >>> sdf_surf_grid = torch.randn(bsize, nx, ny, nz).to(device) >>> sdf_nodes = torch.randn(bsize, 100, 1).to(device) >>> surface_coordinates = torch.randn(bsize, 100, 3).to(device) >>> surface_neighbors = torch.randn(bsize, 100, num_neigh, 3).to(device) >>> surface_normals = torch.randn(bsize, 100, 3).to(device) >>> surface_neighbors_normals = torch.randn(bsize, 100, num_neigh, 3).to(device) >>> surface_sizes = torch.rand(bsize, 100).to(device) + 1e-6 # Note this needs to be > 0.0 >>> surface_neighbors_areas = torch.rand(bsize, 100, num_neigh).to(device) + 1e-6 >>> volume_coordinates = torch.randn(bsize, 100, 3).to(device) >>> vol_grid_max_min = torch.randn(bsize, 2, 3).to(device) >>> surf_grid_max_min = torch.randn(bsize, 2, 3).to(device) >>> global_params_values = torch.randn(bsize, global_features, 1).to(device) >>> global_params_reference = torch.randn(bsize, global_features, 1).to(device) >>> input_dict = { … “pos_volume_closest”: pos_normals_closest_vol, … “pos_volume_center_of_mass”: pos_normals_com_vol, … “pos_surface_center_of_mass”: pos_normals_com_surface, … “geometry_coordinates”: geom_centers, … “grid”: grid, … “surf_grid”: surf_grid, … “sdf_grid”: sdf_grid, … “sdf_surf_grid”: sdf_surf_grid, … “sdf_nodes”: sdf_nodes, … “surface_mesh_centers”: surface_coordinates, … “surface_mesh_neighbors”: surface_neighbors, … “surface_normals”: surface_normals, … “surface_neighbors_normals”: surface_neighbors_normals, … “surface_areas”: surface_sizes, … “surface_neighbors_areas”: surface_neighbors_areas, … “volume_mesh_centers”: volume_coordinates, … “volume_min_max”: vol_grid_max_min, … “surface_min_max”: surf_grid_max_min, … “global_params_reference”: global_params_values, … “global_params_values”: global_params_reference, … } >>> output = model(input_dict) >>> print(f”{output[0].shape}, {output[1].shape}”) torch.Size([1, 100, 5]), torch.Size([1, 100, 4])

calculate_solution(
volume_mesh_centers,
encoding_g,
encoding_node,
global_params_values,
global_params_reference,
eval_mode,
num_sample_points=20,
noise_intensity=50,
return_volume_neighbors=False,
)[source]#

Function to approximate solution sampling the neighborhood information

calculate_solution_with_neighbors(
surface_mesh_centers,
encoding_g,
encoding_node,
surface_mesh_neighbors,
surface_normals,
surface_neighbors_normals,
surface_areas,
surface_neighbors_areas,
global_params_values,
global_params_reference,
num_sample_points=7,
)[source]#

Function to approximate solution given the neighborhood information

geo_encoding_local(
encoding_g,
volume_mesh_centers,
p_grid,
mode='volume',
)[source]#

Function to calculate local geometry encoding from global encoding

position_encoder(
encoding_node: Tensor,
eval_mode: Literal['surface', 'volume'] = 'volume',
) Tensor[source]#

Compute positional encoding for input points.

Parameters:
  • encoding_node – Tensor containing node position information

  • eval_mode – Mode of evaluation, either “volume” or “surface”

Returns:

Tensor containing positional encoding features

sample_sphere(center, r, num_points)[source]#

Uniformly sample points in a 3D sphere around the center.

This method generates random points within a sphere of radius r centered at each point in the input tensor. The sampling is uniform in volume, meaning points are more likely to be sampled in the outer regions of the sphere.

Parameters:
  • center – Tensor of shape (batch_size, num_points, 3) containing center coordinates

  • r – Radius of the sphere for sampling

  • num_points – Number of points to sample per center

Returns:

Tensor of shape (batch_size, num_points, num_samples, 3) containing the sampled points around each center

sample_sphere_shell(center, r_inner, r_outer, num_points)[source]#

Uniformly sample points in a 3D spherical shell around a center.

This method generates random points within a spherical shell (annulus) between inner radius r_inner and outer radius r_outer centered at each point in the input tensor. The sampling is uniform in volume within the shell.

Parameters:
  • center – Tensor of shape (batch_size, num_points, 3) containing center coordinates

  • r_inner – Inner radius of the spherical shell

  • r_outer – Outer radius of the spherical shell

  • num_points – Number of points to sample per center

Returns:

Tensor of shape (batch_size, num_points, num_samples, 3) containing the sampled points within the spherical shell around each center