Source code for physicsnemo.mesh.transformations.deform.displace

# SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES.
# SPDX-FileCopyrightText: All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Dense displacement for simplicial meshes."""

from typing import TYPE_CHECKING, Literal

import torch

from physicsnemo.mesh.transformations.deform._utils import (
    _mesh_with_deformed_points,
    _resolve_point_field,
)

if TYPE_CHECKING:
    from physicsnemo.mesh.mesh import Mesh


[docs] def displace( mesh: "Mesh", displacement: str | tuple[str, ...] | torch.Tensor, *, point_weights: str | tuple[str, ...] | torch.Tensor | None = None, implementation: Literal["torch"] | None = None, ) -> "Mesh": """Displace every mesh point by a dense vector field. Computes ``points + displacement`` without changing connectivity, optionally multiplying the displacement by ``point_weights[..., None]``. ``displacement`` and ``point_weights`` may be raw tensors or keys (including nested tuple keys) in :attr:`~physicsnemo.mesh.mesh.Mesh.point_data`. Call it as ``displace(mesh, ...)`` or as ``mesh.displace(...)``. The bound method supplies ``mesh`` automatically. Parameters ---------- mesh : Mesh Mesh whose points are displaced. The source mesh is not modified. displacement : str, tuple[str, ...], or torch.Tensor Dense displacement vectors with shape ``(mesh.n_points, mesh.n_spatial_dims)``, or a point-data key resolving to such a tensor. The tensor and ``mesh.points`` must have the same float32 or float64 dtype and device. point_weights : str, tuple[str, ...], torch.Tensor, or None, optional Optional bool or floating-point weights with shape ``(mesh.n_points,)``, or a point-data key resolving to those point weights. Floating-point weights may be signed or greater than one. Default is ``None``. implementation : {"torch"} or None, optional Backend override. ``None`` selects Torch for dense displacement. Returns ------- Mesh New mesh with displaced points and unchanged connectivity and attached fields. Notes ----- Attached fields are treated as Lagrangian data and are not pushed forward. Geometry-dependent caches are invalidated and topology caches are retained. The operation does not detect or repair inverted, degenerate, or self-intersecting cells; call :meth:`~physicsnemo.mesh.mesh.Mesh.validate` explicitly when needed. """ displacement_t = _resolve_point_field( mesh, displacement, argument_name="displacement" ) point_weights_t = ( None if point_weights is None else _resolve_point_field(mesh, point_weights, argument_name="point_weights") ) from physicsnemo.nn.functional.geometry.deform import displace_points points = displace_points( mesh.points, displacement_t, point_weights=point_weights_t, implementation=implementation, ) return _mesh_with_deformed_points(mesh, points)