v2.1.0
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
FSDPand/orShardTensormodels 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.generatesubpackage withmarching_cubesfor
isosurface extraction from 3D scalar fields, returning aMeshobject.
Supports the NVIDIA Warp backend. - Adds a type system to PhysicsNeMo-Mesh, allowing annotation of Mesh dimensions
using notation likeMesh[2, 3]for a 2D manifold in 3D space. - Adds adjacency caching to PhysicsNeMo-Mesh
Meshobjects, allowing efficient
reuse of neighbor information. - Adds
DomainMeshclass 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
Meshobjects:transform_point_data,
transform_cell_data, andtransform_global_datanow acceptbool | TensorDict
(or plaindictfor convenience). - Adds
physicsnemo.mesh.remeshingsubpackage withpartition_cells()for
creating Voronoi regions around seed points. BVH-accelerated. - Added support for 1D, 2D, and 3D neighborhood attention (natten) via
physicsnemo.nn.functionalinterface, with fullShardTensorsupport. - Added derivative functionals in
physicsnemo.nn.functionalfor
uniform_grid_gradient,rectilinear_grid_gradient,
spectral_grid_gradient,meshless_fd_derivatives,mesh_lsq_gradient,
andmesh_green_gauss_gradient. - Adds
physicsnemo.symmodule 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.derivativesfunctionals. - Ports all physics-informed examples (LDC PINNs, Darcy, Stokes MGN, DoMINO,
datacenter, xaeronet, MHD/SWE PINO) to the newphysicsnemo.syminterface,
replacing the separatephysicsnemo-sympackage dependency. Geometry is now
handled viaphysicsnemo.meshand PyVista. - Added geometry functionals in
physicsnemo.nn.functionalfor
mesh_poisson_disk_sample,mesh_to_voxel_fraction, and
signed_distance_field. - Adds embedded OOD guardrail
OODGuardat
physicsnemo.experimental.guardrails.embedded, optionally
wired intoGeoTransolvervia a newguard_configconstructor 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.geometrynow publicly exposes
stable_angle_between_vectorsandcompute_triangle_angles(previously
only available via the privatephysicsnemo.mesh.curvature._utils). - PhysicsNeMo Datapipes enables reproducability through
torch.generator
utilities. - PhysicsNeMo Datapipes now supports
physicsnemo.mesh.Meshand
physicsnemo.mesh.DomainMeshobjects for deserialization, with
transformations and utilities for mesh-based datasets. - PhysicsNeMo Datapipes now support
MultiDatasetconstruction,
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, leveragingtorch.distributionsfor
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_diffusionsubpackage that
scales 2D diffusion models to large domains via patch-based training
and inference. ProvidesMultiDiffusionModel2D(wraps a base model and
handles state patching, conditioning preprocessing, positional-embedding
injection, and per-patch output fusion), the
MultiDiffusionMSEDSMLoss/MultiDiffusionWeightedMSEDSMLosslosses
for patch-based DSM training, andMultiDiffusionPredictorfor
sampling (plugs straight intosample()/get_denoiser()and the
standard solvers). Patching primitives (BasePatching2D,
GridPatching2D,RandomPatching2D) are exposed under the same
subpackage and aretorch.compile-friendly withfullgraph=True.
MultiDiffusionPredictorsupports memory-efficient inference on
large domains viachunk_sizeanduse_checkpointing. The
subpackage also ships patch-local DPS guidance:
MultiDiffusionDPSScorePredictor(drop-in score predictor that plugs
into the standard sampling stack),
MultiDiffusionDataConsistencyDPSGuidancefor inpainting and sparse
data assimilation, andMultiDiffusionModelConsistencyDPSGuidancefor
generic patch-local observation operators. Use these instead of the
globalDPSScorePredictorto 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.baseis 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 anepsilon_to_x0_fnkwarg used for the epsilon-to-x0
conversion required during DSM training. - Adds
DiffusionUNet3D3D U-Net diffusion backbone for volumetric data at
physicsnemo.experimental.models.diffusion_unets. Implements the
DiffusionModelprotocol. 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_cellsuses a KNN-backed
implementation, and no longer accepts thebvh=,chunk_size=,
max_rounds=, ormax_candidates_per_point=parameters.⚠️ BC-impact (deep imports): internalphysicsnemo.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.knnor
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_circumcentersis up to
~10000x faster (e.g. 11 s -> ~1 ms on a 360 K-triangle AirFRANS mesh,
RTX 4090) by replacing batchedtorch.linalg.lstsqover (2, 3) systems
with a closed-form cross product, andcompute_vertex_anglesis up to
~15x faster on the same meshes by replacing the dimension-agnostic
Gram-determinant formula with anatan2(||cross||, dot)formulation.
Anything that depends on these (Gaussian curvature, FEM Laplacian,
cotangent weights, Voronoi areas, smoothing) inherits the speedup. See
perf.mdfor the full audit. - In PhysicsNeMo-Mesh, BVH construction is faster on GPU.
_compute_morton_codeshas a CUDA-specific fused-bits path that
eliminates then_bitssequential kernel launches of the previous
bit-loop (5-8x speedup on small / medium meshes), andBVH.from_mesh
reuses the cachedMesh.cell_centroidsinstead of recomputing.
End-to-endBVH.from_meshis ~2x faster on a 162 K-tetcube_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_targetsparameters. When the caller passes a strict
upper bound (typicallymesh.n_pointsormesh.n_cells), the implicit
tensor.max().item()GPU sync is avoided and the dedup uses a packed
int64 unique (via the new internalunique_index_tuples) and a single
composite-key argsort. End-to-endget_boundary_edgesand
cell_to_cells_adjacencyare ~2x faster on practical-size unstructured
meshes (e.g. 360 K-triangle AirFRANS). ⚠️ BC-impact (deep imports): in PhysicsNeMo-Mesh,
stable_angle_between_vectorsandcompute_triangle_anglesmoved from
physicsnemo.mesh.curvature._utilstophysicsnemo.mesh.geometry._angles.
The old private path is no longer available; use the
physicsnemo.mesh.geometryre-export instead.⚠️ BC-impact (pre-release rename): in PhysicsNeMo-Mesh,
DomainMesh.applywas renamed toDomainMesh.apply_to_meshes. The
original name shadowed the recursiveTensor -> Tensorapplymethod
that@tensorclassauto-injects, breaking duck-type symmetry with
Mesh.applyfor any code that handled both classes. After the rename,
dm.apply(tensor_fn)works as expected (recurses through every leaf
tensor ininterior,boundaries, andglobal_data); the original
Mesh-to-Mesh broadcast is nowdm.apply_to_meshes(mesh_fn). Early
adopters of the unreleasedDomainMeshAPI 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 andtorch.compile-friendly (e.g.
fullgraph=True,error_on_recompile=True). - Refactored the
examples/geophysics/diffusion_fwifull-waveform
inversion example to use the consolidatedphysicsnemo.diffusionAPI
(preconditioners, samplers, losses, DPS guidance) and removed the
recipe-local copies of these utilities underutils/. - Refactored the
examples/generative/topodiffrecipe to use the
consolidatedphysicsnemo.diffusionAPI (MSEDSMLosswith
prediction_type="epsilon",sample(),DPSScorePredictor) plus a
recipe-local DDPM scheduler, solver, and classifier guidance. Removed
the now-unusedDiffusion,DatasetTopoDiff, andload_data_topodiff
abstractions fromphysicsnemo.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 withfullgraph=Trueanderror_on_recompileto catch
torch.compileregressions. - Internal weight initialization in the distributed AFNO layers and the
EarthAttentionblocks ofphysicsnemo.nn.module.attention_layersnow
dispatches totorch.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 reimplementedtrunc_normal_as a
rejection-sampling loop on top ofnormal_()(see
pytorch/pytorch#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 forAFNO,ModAFNO,Transolver,FLARE, andPanguwere
regenerated against the new algorithm. Rather than wiring per-model
skips,test.common.validate_forward_accuracynow uniformly skips on
torch < 2.12(the reference data is locked to that floor via a single
_REFERENCE_DATA_MIN_TORCHconstant; bump it when a PyTorch
release next changes an init/RNG algorithm any forward-accuracy model
depends on, and regenerate the.pthfiles at the same time).
Deprecated
physicsnemo.utils.meshis deprecated and will be removed in v2.2.0. For
isosurface extraction, usephysicsnemo.mesh.generate.marching_cubesinstead
ofsdf_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 aDeprecationWarningon
call, replacing the frozen in-tree copy of the legacy inverse-CDF
implementation. Usetorch.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 usetorch.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
FunctionSpecdispatch (max(key=)is not supported bytorch.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 whentensordict >= 0.12reordered leaves during
TensorDict construction from dict literals mixing plain and nested keys. - In PhysicsNeMo-Mesh,
from_pyvistanow correctly handles
UnstructuredGridinputs in newerpyvistaversions, looking up
cell-type buckets incells_dictwithnp.uint8(pv.CellType.X)keys
rather than theIntEnumvalue, and skipping non-numeric VTK arrays
(strings, objects) when copying point / cell / field data into the
MeshTensorDicts instead of failing the conversion. - In PhysicsNeMo-Mesh, the
Meshconstructor now preserves data when
point_data/cell_data/global_dataare passed as a non-dict
Mapping(notably PyVista'sDataSetAttributes). Previously, with
tensordict >= 0.12, the@tensorclass(tensor_only=True)auto-init
silently wrapped such Mappings asNonTensorDataand 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 toTensorDict. Thetensor_only
fast path is preserved, so internal Mesh constructions (slicing,
transforms,from_pyvista) keep their full speed. Backed by new direct-
construction regression tests, acell_data/global_datamemmap
round-trip test, and a committed.pmshgolden 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
previoustiny ** 0.25floor exceeded machine epsilon and could
corrupt fp16 mesh quantities. Ad-hoc+ 1e-10denominators in
smooth_laplacianandcompute_quality_metricshave 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 withuse_orig_params=Falseand channels last
memory format. - Fixed issues with physicsnemo.nn.functional's
radius_searchthat
caused crashes when used with torch.compile. - Fixed the sinusoidal positional embeddings formula in
SongUNetand
MultiDiffusionModel2Dso it now follows the standardsin / cos
convention. Affected reference data was regenerated. - Constructing a
Mesh(orDomainMesh) inside atorch.compile-traced
function no longer raisesAttributeError/KeyErroror silently
produces wrong output. The breakage came from two regressions in
tensordict >= 0.12.0(PRpytorch/tensordict#1552), where the
@tensorclassinit wrapper's bypass branch silently skipped both
field-default normalization and__post_init__under
torch.compile. We pintensordict < 0.12until the upstream fix
(pytorch/tensordict#1708,pytorch/tensordict#1709) ships, and add
a regression test (test/mesh/mesh/test_compile.py) that constructs
aMeshinsidetorch.compileand 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.0to support FSDP better - Upper-bounds
tensordict < 0.12to avoid thetorch.compileregressions
intensordict >= 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 ❤️ — we truly appreciate your contributions and hope to see more from you in the future!