Source code for nvalchemiops.interactions.switching
# SPDX-FileCopyrightText: Copyright (c) 2025 - 2026 NVIDIA CORPORATION & AFFILIATES. 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.
"""
Switching functions for smooth cutoffs.
These utilities are designed to be callable from Warp kernels (``@wp.func``).
We provide a C2-continuous quintic switching function commonly used in MD:
Let :math:`x = (r - r_{on}) / (r_{cut} - r_{on})` in [0, 1]. Then:
.. math::
s(x) = 1 - 10x^3 + 15x^4 - 6x^5
This yields:
- s = 1 at r = r_on
- s = 0 at r = r_cut
- s', s'' continuous at both endpoints (C2)
"""
from __future__ import annotations
import warp as wp
__all__ = [
"switch_c2",
]
[docs]
@wp.func
def switch_c2(
r: wp.float64, r_on: wp.float64, r_cut: wp.float64
) -> tuple[wp.float64, wp.float64]:
"""C2 switching function and derivative.
Parameters
----------
r : wp.float64
Distance.
r_on : wp.float64
Switch-on radius. For r <= r_on, s=1.
r_cut : wp.float64
Cutoff radius. For r >= r_cut, s=0.
Returns
-------
wp.vec2d
(s, ds_dr)
"""
if r <= r_on:
return wp.float64(1.0), wp.float64(0.0)
if r >= r_cut:
return wp.float64(0.0), wp.float64(0.0)
denom = r_cut - r_on
# Defensive: if denom is ~0, behave like a hard cutoff
if denom <= wp.float64(1e-12):
return wp.float64(0.0), wp.float64(0.0)
x = (r - r_on) / denom # in (0,1)
x2 = x * x
x3 = x2 * x
x4 = x2 * x2
x5 = x4 * x
s = (
wp.float64(1.0)
- wp.float64(10.0) * x3
+ wp.float64(15.0) * x4
- wp.float64(6.0) * x5
)
# ds/dx = -30 x^2 + 60 x^3 - 30 x^4
ds_dx = -wp.float64(30.0) * x2 + wp.float64(60.0) * x3 - wp.float64(30.0) * x4
ds_dr = ds_dx / denom
return s, ds_dr