Download Latest Version v2.1.1 source code.zip (164.3 MB)
Email in envelope

Get an email when there's a new version of NVIDIA PhysicsNeMo

Home / v2.1.0
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-05-26 19.4 kB
v2.1.0 source code.tar.gz 2026-05-26 161.1 MB
v2.1.0 source code.zip 2026-05-26 164.3 MB
Totals: 3 Items   325.4 MB 2

PhysicsNeMo General Release v2.1.0

Added

  • Adds GLOBE model (physicsnemo.experimental.models.globe.model.GLOBE), including new variant that uses a dual tree traversal algorithm to reduce the complexity of the kernel evaluations from O(N^2) to O(N).
  • Adds GLOBE AirFRANS example case (examples/cfd/external_aerodynamics/globe/airfrans)
  • Adds GLOBE DrivAerML example case (examples/cfd/external_aerodynamics/globe/drivaer)
  • Adds drop-test dynamics recipe.
  • Adds concrete dropout uncertainty quantification for GeoTransolver. Learnable per-layer dropout rates enable MC-Dropout inference for uncertainty estimates. Disabled by default (concrete_dropout: false).
  • Adds automatic support for FSDP and/or ShardTensor models in checkpoint save/load functionality
  • PhysicsNeMo-Mesh now supports conversion from PyVista/VTK/VTU meshes that may contain polyhedral cells.
  • In PhysicsNeMo-Mesh, adds Mesh.to_point_cloud(), .to_edge_graph(), and .to_dual_graph() methods. These allow Mesh conversion to 0D point clouds, 1D edge graphs, and 1D dual graphs, respectively, when connectivity information is not needed.
  • Adds physicsnemo.mesh.generate subpackage with marching_cubes for isosurface extraction from 3D scalar fields, returning a Mesh object. Supports the NVIDIA Warp backend.
  • Adds a type system to PhysicsNeMo-Mesh, allowing annotation of Mesh dimensions using notation like Mesh[2, 3] for a 2D manifold in 3D space.
  • Adds adjacency caching to PhysicsNeMo-Mesh Mesh objects, allowing efficient reuse of neighbor information.
  • Adds DomainMesh class for grouping an interior mesh with named boundary meshes and domain-level metadata, with passthrough geometric transforms (translate, rotate, scale, transform) and data operations.
  • Allows selective per-field transformation of Mesh objects: transform_point_data, transform_cell_data, and transform_global_data now accept bool | TensorDict (or plain dict for convenience).
  • Adds physicsnemo.mesh.remeshing subpackage with partition_cells() for creating Voronoi regions around seed points. BVH-accelerated.
  • Added support for 1D, 2D, and 3D neighborhood attention (natten) via physicsnemo.nn.functional interface, with full ShardTensor support.
  • Added derivative functionals in physicsnemo.nn.functional for uniform_grid_gradient, rectilinear_grid_gradient, spectral_grid_gradient, meshless_fd_derivatives, mesh_lsq_gradient, and mesh_green_gauss_gradient.
  • Adds physicsnemo.sym module for symbolic PDE residual computation (PhysicsInformer). Users define PDEs via SymPy and select a gradient method (autodiff, finite_difference, spectral, meshless_finite_difference, least_squares); spatial derivatives are computed automatically using the nn.functional.derivatives functionals.
  • Ports all physics-informed examples (LDC PINNs, Darcy, Stokes MGN, DoMINO, datacenter, xaeronet, MHD/SWE PINO) to the new physicsnemo.sym interface, replacing the separate physicsnemo-sym package dependency. Geometry is now handled via physicsnemo.mesh and PyVista.
  • Added geometry functionals in physicsnemo.nn.functional for mesh_poisson_disk_sample, mesh_to_voxel_fraction, and signed_distance_field.
  • Adds embedded OOD guardrail OODGuard at physicsnemo.experimental.guardrails.embedded, optionally wired into GeoTransolver via a new guard_config constructor argument. The guard calibrates per-channel global bounds and a geometry-latent kNN threshold during training, and emits warnings on out-of-distribution inputs at inference.
  • In PhysicsNeMo-Mesh, physicsnemo.mesh.geometry now publicly exposes stable_angle_between_vectors and compute_triangle_angles (previously only available via the private physicsnemo.mesh.curvature._utils).
  • PhysicsNeMo Datapipes enables reproducability through torch.generator utilities.
  • PhysicsNeMo Datapipes now supports physicsnemo.mesh.Mesh and physicsnemo.mesh.DomainMesh objects for deserialization, with transformations and utilities for mesh-based datasets.
  • PhysicsNeMo Datapipes now support MultiDataset construction, allowing on-the-fly construction of multi-source composite datasets that can be sampled and processed efficiently and coherently as one dataset.
  • PhysicsNeMo Datapipes also support random augmentations for mesh-based datapipes, leveraging torch.distributions for broad random distribution support. Mesh and DomainMesh datasets allow random translation, scaling, and rotation of mesh data in coherent ways, compatible with reproducability features of physicsnemo datapipes.
  • Adds a new unified training recipe for external aerodynamics that supports training on multiple datasets (DrivaerML, ShiftSUV, HighLiftAeroML, or more, bring your own, mix and match), supports training several different models (Domino, Transolver, GeoTransolver, Flare, GeoTransolver with Flare-attention, bring your own!). Leverages mesh datasets and non-dimensionalization to enable dataset mixing and matching at runtime. Train with surface or volume data.
  • Adds a new physicsnemo.diffusion.multi_diffusion subpackage that scales 2D diffusion models to large domains via patch-based training and inference. Provides MultiDiffusionModel2D (wraps a base model and handles state patching, conditioning preprocessing, positional-embedding injection, and per-patch output fusion), the MultiDiffusionMSEDSMLoss / MultiDiffusionWeightedMSEDSMLoss losses for patch-based DSM training, and MultiDiffusionPredictor for sampling (plugs straight into sample() / get_denoiser() and the standard solvers). Patching primitives (BasePatching2D, GridPatching2D, RandomPatching2D) are exposed under the same subpackage and are torch.compile-friendly with fullgraph=True. MultiDiffusionPredictor supports memory-efficient inference on large domains via chunk_size and use_checkpointing. The subpackage also ships patch-local DPS guidance: MultiDiffusionDPSScorePredictor (drop-in score predictor that plugs into the standard sampling stack), MultiDiffusionDataConsistencyDPSGuidance for inpainting and sparse data assimilation, and MultiDiffusionModelConsistencyDPSGuidance for generic patch-local observation operators. Use these instead of the global DPSScorePredictor to run guided sampling on domains that would otherwise OOM.
  • Adds "epsilon" as a supported prediction type throughout the diffusion framework, alongside the existing "x0" and "score" modes. A new PredictorType = Literal["x0", "score", "epsilon"] alias in physicsnemo.diffusion.base is wired through losses (MSEDSMLoss, WeightedMSEDSMLoss, and the multi-diffusion losses), preconditioners, samplers / solvers, DPS guidance, and noise schedulers, enabling end-to-end training and sampling of epsilon-parameterized models. Losses gain an epsilon_to_x0_fn kwarg used for the epsilon-to-x0 conversion required during DSM training.
  • Adds DiffusionUNet3D 3D U-Net diffusion backbone for volumetric data at physicsnemo.experimental.models.diffusion_unets. Implements the DiffusionModel protocol. Exposes reusable 3D building blocks (Conv3D, GroupNorm3D, UNetAttention3D, UNetBlock3D) at physicsnemo.experimental.nn.
  • Added support for Batched radius search, which enables Domino and GeoTransolver with local features and batch size > 1.
  • Added the underfill recipe.

Changed

  • Improved crash recipe with configurable stats directory.
  • physicsnemo.mesh.sampling.find_nearest_cells uses a KNN-backed implementation, and no longer accepts the bvh=, chunk_size=, max_rounds=, or max_candidates_per_point= parameters.
  • ⚠️ BC-impact (deep imports): internal physicsnemo.nn.functional modules were reorganized by category. Public top-level functional imports are unchanged, but code importing internal module paths directly (for example physicsnemo.nn.functional.knn or physicsnemo.nn.functional.radius_search) should migrate to physicsnemo.nn.functional.neighbors.*.
  • Consolidated Warp interpolation kernels for grid-to-point and point-to-grid backends, and added missing kernel/helper docstrings.
  • In PhysicsNeMo-Mesh, dual-mesh primitives gained closed-form fast paths for triangle meshes embedded in 3D. compute_circumcenters is up to ~10000x faster (e.g. 11 s -> ~1 ms on a 360 K-triangle AirFRANS mesh, RTX 4090) by replacing batched torch.linalg.lstsq over (2, 3) systems with a closed-form cross product, and compute_vertex_angles is up to ~15x faster on the same meshes by replacing the dimension-agnostic Gram-determinant formula with an atan2(||cross||, dot) formulation. Anything that depends on these (Gaussian curvature, FEM Laplacian, cotangent weights, Voronoi areas, smoothing) inherits the speedup. See perf.md for the full audit.
  • In PhysicsNeMo-Mesh, BVH construction is faster on GPU. _compute_morton_codes has a CUDA-specific fused-bits path that eliminates the n_bits sequential kernel launches of the previous bit-loop (5-8x speedup on small / medium meshes), and BVH.from_mesh reuses the cached Mesh.cell_centroids instead of recomputing. End-to-end BVH.from_mesh is ~2x faster on a 162 K-tet cube_volume mesh.
  • In PhysicsNeMo-Mesh, the topology-dedup APIs (categorize_facets_by_count, find_edges_in_reference, remove_duplicate_cells, build_adjacency_from_pairs) gained optional index_bound / n_targets parameters. When the caller passes a strict upper bound (typically mesh.n_points or mesh.n_cells), the implicit tensor.max().item() GPU sync is avoided and the dedup uses a packed int64 unique (via the new internal unique_index_tuples) and a single composite-key argsort. End-to-end get_boundary_edges and cell_to_cells_adjacency are ~2x faster on practical-size unstructured meshes (e.g. 360 K-triangle AirFRANS).
  • ⚠️ BC-impact (deep imports): in PhysicsNeMo-Mesh, stable_angle_between_vectors and compute_triangle_angles moved from physicsnemo.mesh.curvature._utils to physicsnemo.mesh.geometry._angles. The old private path is no longer available; use the physicsnemo.mesh.geometry re-export instead.
  • ⚠️ BC-impact (pre-release rename): in PhysicsNeMo-Mesh, DomainMesh.apply was renamed to DomainMesh.apply_to_meshes. The original name shadowed the recursive Tensor -> Tensor apply method that @tensorclass auto-injects, breaking duck-type symmetry with Mesh.apply for any code that handled both classes. After the rename, dm.apply(tensor_fn) works as expected (recurses through every leaf tensor in interior, boundaries, and global_data); the original Mesh-to-Mesh broadcast is now dm.apply_to_meshes(mesh_fn). Early adopters of the unreleased DomainMesh API should rename their .apply(...) callsites to .apply_to_meshes(...).
  • Refactored the patching utilities under physicsnemo.diffusion.multi_diffusion.patching. Patching and fusion operations are now more performant and torch.compile-friendly (e.g. fullgraph=True,error_on_recompile=True).
  • Refactored the examples/geophysics/diffusion_fwi full-waveform inversion example to use the consolidated physicsnemo.diffusion API (preconditioners, samplers, losses, DPS guidance) and removed the recipe-local copies of these utilities under utils/.
  • Refactored the examples/generative/topodiff recipe to use the consolidated physicsnemo.diffusion API (MSEDSMLoss with prediction_type="epsilon", sample(), DPSScorePredictor) plus a recipe-local DDPM scheduler, solver, and classifier guidance. Removed the now-unused Diffusion, DatasetTopoDiff, and load_data_topodiff abstractions from physicsnemo.models.topodiff.
  • Significantly expanded CI test coverage for physicsnemo.diffusion, including new tests for samplers, solvers, preconditioners, losses, DPS guidance, multi-diffusion, and patching utilities, plus combined-workflow and from-checkpoint round-trip tests. Most tests run with fullgraph=True and error_on_recompile to catch torch.compile regressions.
  • Internal weight initialization in the distributed AFNO layers and the EarthAttention blocks of physicsnemo.nn.module.attention_layers now dispatches to torch.nn.init.trunc_normal_ directly instead of going through frozen in-tree copies of the pre-PyTorch-2.12 inverse-CDF implementation. PyTorch 2.12 reimplemented trunc_normal_ as a rejection-sampling loop on top of normal_() (see [pytorch/pytorch#174997](https://github.com/pytorch/pytorch/issues/174997)), so seeded from-scratch initialization consumes the RNG stream differently on 2.12+ vs older versions. Existing trained checkpoints are unaffected (loading bypasses init). Forward-accuracy reference outputs for AFNO, ModAFNO, Transolver, FLARE, and Pangu were regenerated against the new algorithm. Rather than wiring per-model skips, test.common.validate_forward_accuracy now uniformly skips on torch < 2.12 (the reference data is locked to that floor via a single _REFERENCE_DATA_MIN_TORCH constant; bump it when a PyTorch release next changes an init/RNG algorithm any forward-accuracy model depends on, and regenerate the .pth files at the same time).

Deprecated

  • physicsnemo.utils.mesh is deprecated and will be removed in v2.2.0. For isosurface extraction, use physicsnemo.mesh.generate.marching_cubes instead of sdf_to_stl. For VTP/OBJ/STL file conversion (combine_vtp_files, convert_tesselated_files_in_directory), use VTK or PyVista directly.
  • physicsnemo.nn.module.utils.trunc_normal_ (and its submodule path physicsnemo.nn.module.utils.weight_init.trunc_normal_) is deprecated and will be removed in v2.2.0. It is now a thin wrapper around torch.nn.init.trunc_normal_ that emits a DeprecationWarning on call, replacing the frozen in-tree copy of the legacy inverse-CDF implementation. Use torch.nn.init.trunc_normal_ directly.

Removed

  • The legacy in-tree trunc_normal_ implementation that lived in physicsnemo/models/afno/distributed/layers.py (_trunc_normal_ / _no_grad_trunc_normal_) is removed. These names were private; all in-tree call sites now use torch.nn.init.trunc_normal_.

Fixed

  • Fixed functional benchmark plot fallback labeling so unlabeled ASV results use the same key ordering as the benchmark runner.
  • Fixed graph break caused by FunctionSpec dispatch (max(key=) is not supported by torch.compile)
  • Fixed bug in Pangu, FengWu attention window shift for asymmetric longitudes
  • Fixed a bug in mesh.sampling.find_nearest_cells, where a mixup between L2 and L-inf norms could cause slightly incorrect nearest-neighbor assignments in highly skewed meshes.
  • Fixed TensorDict key-ordering bug in GLOBE's Barnes-Hut kernel that caused incorrect results when tensordict >= 0.12 reordered leaves during TensorDict construction from dict literals mixing plain and nested keys.
  • In PhysicsNeMo-Mesh, from_pyvista now correctly handles UnstructuredGrid inputs in newer pyvista versions, looking up cell-type buckets in cells_dict with np.uint8(pv.CellType.X) keys rather than the IntEnum value, and skipping non-numeric VTK arrays (strings, objects) when copying point / cell / field data into the Mesh TensorDicts instead of failing the conversion.
  • In PhysicsNeMo-Mesh, the Mesh constructor now preserves data when point_data / cell_data / global_data are passed as a non-dict Mapping (notably PyVista's DataSetAttributes). Previously, with tensordict >= 0.12, the @tensorclass(tensor_only=True) auto-init silently wrapped such Mappings as NonTensorData and dropped every key, so e.g. Mesh(cell_data=pv_mesh.cell_data, ...) produced an empty cell_data. Mesh.__post_init__ now detects this wrapping and unwraps the original Mapping before coercing to TensorDict. The tensor_only fast path is preserved, so internal Mesh constructions (slicing, transforms, from_pyvista) keep their full speed. Backed by new direct- construction regression tests, a cell_data / global_data memmap round-trip test, and a committed .pmsh golden fixture that locks the on-disk format against silent breakage in future changes.
  • In PhysicsNeMo-Mesh, safe_eps(dtype) is now capped at torch.finfo(dtype).eps, which fixes a float16 corner case where the previous tiny ** 0.25 floor exceeded machine epsilon and could corrupt fp16 mesh quantities. Ad-hoc + 1e-10 denominators in smooth_laplacian and compute_quality_metrics have been replaced with the dtype-aware .clamp(min=safe_eps(dtype)) to avoid silently zeroing fp16 weights.
  • Fixed a silent bug in loading state from checkpoint for FSDP-backed models with use_orig_params=False and channels last memory format.
  • Fixed issues with physicsnemo.nn.functional's radius_search that caused crashes when used with torch.compile.
  • Fixed the sinusoidal positional embeddings formula in SongUNet and MultiDiffusionModel2D so it now follows the standard sin / cos convention. Affected reference data was regenerated.
  • Constructing a Mesh (or DomainMesh) inside a torch.compile-traced function no longer raises AttributeError / KeyError or silently produces wrong output. The breakage came from two regressions in tensordict >= 0.12.0 (PR pytorch/tensordict#1552), where the @tensorclass init wrapper's bypass branch silently skipped both field-default normalization and __post_init__ under torch.compile. We pin tensordict < 0.12 until the upstream fix (pytorch/tensordict#1708, pytorch/tensordict#1709) ships, and add a regression test (test/mesh/mesh/test_compile.py) that constructs a Mesh inside torch.compile and reads cached properties, so the same bug cannot return on a future pin bump unnoticed.

Dependencies

  • Increments minimum viable PyTorch version to torch>=2.5.0 to support FSDP better
  • Upper-bounds tensordict < 0.12 to avoid the torch.compile regressions in tensordict >= 0.12.0 (see corresponding entry under Fixed).

Contributors

We’re grateful to everyone who contributed issues, feature ideas, fixes, and documentation updates — your input is what helps us continuously improve PhysicsNeMo for the whole community! A special shout-out to the authors of the pull requests listed above, in no particular order:

@jleinonen, @Brumbelow, @ghasemiAb, @albertocarpentieri, @dakhare-creator, @manmeet3591,
@nloppi, @nbren12

Thank you :heart: — we truly appreciate your contributions and hope to see more from you in the future!

Source: README.md, updated 2026-05-26