nvalchemi-toolkit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nvalchemi/__init__.py +18 -0
- nvalchemi/_optional.py +143 -0
- nvalchemi/_typing.py +248 -0
- nvalchemi/data/__init__.py +35 -0
- nvalchemi/data/atomic_data.py +1170 -0
- nvalchemi/data/batch.py +1666 -0
- nvalchemi/data/buffer_kernels.py +1741 -0
- nvalchemi/data/data.py +419 -0
- nvalchemi/data/datapipes/__init__.py +71 -0
- nvalchemi/data/datapipes/backends/__init__.py +27 -0
- nvalchemi/data/datapipes/backends/base.py +249 -0
- nvalchemi/data/datapipes/backends/zarr.py +1423 -0
- nvalchemi/data/datapipes/dataloader.py +265 -0
- nvalchemi/data/datapipes/dataset.py +473 -0
- nvalchemi/data/io_test.py +634 -0
- nvalchemi/data/level_storage.py +2480 -0
- nvalchemi/dynamics/__init__.py +66 -0
- nvalchemi/dynamics/_ops/__init__.py +42 -0
- nvalchemi/dynamics/_ops/_bridge.py +150 -0
- nvalchemi/dynamics/_ops/cell_align.py +125 -0
- nvalchemi/dynamics/_ops/fire.py +628 -0
- nvalchemi/dynamics/_ops/langevin.py +174 -0
- nvalchemi/dynamics/_ops/neighbor_list_rebuild.py +186 -0
- nvalchemi/dynamics/_ops/nose_hoover.py +304 -0
- nvalchemi/dynamics/_ops/npt_nph.py +825 -0
- nvalchemi/dynamics/_ops/thermostat_utils.py +449 -0
- nvalchemi/dynamics/_ops/velocity_verlet.py +143 -0
- nvalchemi/dynamics/_units.py +31 -0
- nvalchemi/dynamics/base.py +3953 -0
- nvalchemi/dynamics/demo.py +233 -0
- nvalchemi/dynamics/hooks/__init__.py +69 -0
- nvalchemi/dynamics/hooks/_utils.py +290 -0
- nvalchemi/dynamics/hooks/cell_align.py +113 -0
- nvalchemi/dynamics/hooks/freeze.py +184 -0
- nvalchemi/dynamics/hooks/logging.py +411 -0
- nvalchemi/dynamics/hooks/monitors.py +221 -0
- nvalchemi/dynamics/hooks/profiling.py +466 -0
- nvalchemi/dynamics/hooks/safety.py +320 -0
- nvalchemi/dynamics/hooks/snapshot.py +223 -0
- nvalchemi/dynamics/integrators/__init__.py +29 -0
- nvalchemi/dynamics/integrators/nph.py +306 -0
- nvalchemi/dynamics/integrators/npt.py +503 -0
- nvalchemi/dynamics/integrators/nve.py +178 -0
- nvalchemi/dynamics/integrators/nvt_langevin.py +196 -0
- nvalchemi/dynamics/integrators/nvt_nose_hoover.py +274 -0
- nvalchemi/dynamics/optimizers/__init__.py +25 -0
- nvalchemi/dynamics/optimizers/fire.py +528 -0
- nvalchemi/dynamics/optimizers/fire2.py +372 -0
- nvalchemi/dynamics/sampler.py +644 -0
- nvalchemi/dynamics/sinks.py +886 -0
- nvalchemi/hooks/__init__.py +33 -0
- nvalchemi/hooks/_context.py +71 -0
- nvalchemi/hooks/_protocol.py +62 -0
- nvalchemi/hooks/_registry.py +167 -0
- nvalchemi/hooks/bias.py +173 -0
- nvalchemi/hooks/neighbor_list.py +647 -0
- nvalchemi/hooks/periodic.py +218 -0
- nvalchemi/models/__init__.py +92 -0
- nvalchemi/models/_ops/__init__.py +25 -0
- nvalchemi/models/_ops/lj.py +520 -0
- nvalchemi/models/_ops/neighbor_filter.py +430 -0
- nvalchemi/models/_utils.py +225 -0
- nvalchemi/models/aimnet2.py +513 -0
- nvalchemi/models/base.py +657 -0
- nvalchemi/models/demo.py +324 -0
- nvalchemi/models/dftd3.py +760 -0
- nvalchemi/models/ewald.py +492 -0
- nvalchemi/models/lj.py +399 -0
- nvalchemi/models/mace.py +558 -0
- nvalchemi/models/pipeline.py +1035 -0
- nvalchemi/models/pme.py +518 -0
- nvalchemi/neighbors.py +262 -0
- nvalchemi_toolkit-0.1.0.dist-info/METADATA +402 -0
- nvalchemi_toolkit-0.1.0.dist-info/RECORD +77 -0
- nvalchemi_toolkit-0.1.0.dist-info/WHEEL +4 -0
- nvalchemi_toolkit-0.1.0.dist-info/entry_points.txt +2 -0
- nvalchemi_toolkit-0.1.0.dist-info/licenses/LICENSE +202 -0
nvalchemi/__init__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from nvalchemi._optional import OptionalDependency, OptionalDependencyError
|
|
17
|
+
|
|
18
|
+
version = "0.1.0"
|
nvalchemi/_optional.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
"""Utilities for guarding optional dependencies at runtime."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import importlib
|
|
20
|
+
import sys
|
|
21
|
+
from enum import Enum
|
|
22
|
+
from functools import wraps
|
|
23
|
+
from types import TracebackType
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class OptionalDependencyError(ImportError):
|
|
28
|
+
"""Raised when a required optional dependency is not installed."""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
dep: OptionalDependency,
|
|
33
|
+
func_name: str,
|
|
34
|
+
cause: ImportError | None = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
from rich.console import Console
|
|
37
|
+
from rich.table import Table
|
|
38
|
+
|
|
39
|
+
console = Console(stderr=True)
|
|
40
|
+
table = Table(show_header=False, show_lines=True)
|
|
41
|
+
table.add_row(
|
|
42
|
+
"[blue]nvalchemi Optional Dependency Error\n"
|
|
43
|
+
"This error typically indicates an extra dependency group is needed.[/blue]"
|
|
44
|
+
)
|
|
45
|
+
escaped_target = dep.install_target.replace("[", "\\[")
|
|
46
|
+
table.add_row(
|
|
47
|
+
f"[yellow]This feature ('{func_name}') requires optional "
|
|
48
|
+
f"dependency '{dep.import_name}'.\n\n"
|
|
49
|
+
f"Install with: pip install '{escaped_target}'[/yellow]"
|
|
50
|
+
)
|
|
51
|
+
if cause:
|
|
52
|
+
table.add_row(f"[red]{type(cause).__name__}: {cause}[/red]")
|
|
53
|
+
console.print(table)
|
|
54
|
+
super().__init__(
|
|
55
|
+
f"'{dep.import_name}' is not installed. "
|
|
56
|
+
f"Run: pip install '{dep.install_target}'"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _install_excepthook() -> None:
|
|
61
|
+
"""Lazily install a sys.excepthook that suppresses the traceback for OptionalDependencyError."""
|
|
62
|
+
if getattr(_install_excepthook, "_installed", False):
|
|
63
|
+
return
|
|
64
|
+
_install_excepthook._installed = True # type: ignore[attr-defined]
|
|
65
|
+
|
|
66
|
+
_default_excepthook = sys.excepthook
|
|
67
|
+
|
|
68
|
+
def _optional_dep_excepthook(
|
|
69
|
+
exc_type: type[BaseException],
|
|
70
|
+
exc_value: BaseException,
|
|
71
|
+
exc_tb: TracebackType | None,
|
|
72
|
+
) -> None:
|
|
73
|
+
if isinstance(exc_value, OptionalDependencyError):
|
|
74
|
+
return
|
|
75
|
+
_default_excepthook(exc_type, exc_value, exc_tb)
|
|
76
|
+
|
|
77
|
+
sys.excepthook = _optional_dep_excepthook
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class OptionalDependency(Enum):
|
|
81
|
+
"""Registry of optional dependencies with install instructions.
|
|
82
|
+
|
|
83
|
+
Each member maps to an ``(import_name, install_target)`` pair.
|
|
84
|
+
Use :meth:`require` as a decorator to guard functions or classes
|
|
85
|
+
that need the dependency::
|
|
86
|
+
|
|
87
|
+
@OptionalDependency.PYMATGEN.require
|
|
88
|
+
def needs_pymatgen():
|
|
89
|
+
...
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
ASE = ("ase", "nvalchemi-toolkit[ase]")
|
|
93
|
+
PYMATGEN = ("pymatgen", "nvalchemi-toolkit[pymatgen]")
|
|
94
|
+
MACE = ("mace", "nvalchemi-toolkit[mace]")
|
|
95
|
+
AIMNET = ("aimnet", "nvalchemi-toolkit[aimnet]")
|
|
96
|
+
|
|
97
|
+
def __init__(self, import_name: str, install_target: str) -> None:
|
|
98
|
+
self.import_name = import_name
|
|
99
|
+
self.install_target = install_target
|
|
100
|
+
self._available: bool | None = None
|
|
101
|
+
self._import_error: ImportError | None = None
|
|
102
|
+
|
|
103
|
+
def is_available(self) -> bool:
|
|
104
|
+
"""Return True if the dependency can be imported (cached)."""
|
|
105
|
+
if self._available is None:
|
|
106
|
+
try:
|
|
107
|
+
importlib.import_module(self.import_name)
|
|
108
|
+
self._available = True
|
|
109
|
+
except ImportError as e:
|
|
110
|
+
self._available = False
|
|
111
|
+
self._import_error = e
|
|
112
|
+
return self._available
|
|
113
|
+
|
|
114
|
+
def _raise_error(self, name: str) -> None:
|
|
115
|
+
"""Raise :class:`OptionalDependencyError` with a clean traceback."""
|
|
116
|
+
_install_excepthook()
|
|
117
|
+
err = OptionalDependencyError(self, name, self._import_error)
|
|
118
|
+
err.__traceback__ = None
|
|
119
|
+
raise err from None
|
|
120
|
+
|
|
121
|
+
def require(self, obj: Any) -> Any:
|
|
122
|
+
"""Decorator that raises :class:`OptionalDependencyError` when the dependency is missing."""
|
|
123
|
+
dep = self
|
|
124
|
+
|
|
125
|
+
if isinstance(obj, type):
|
|
126
|
+
original_init = obj.__init__
|
|
127
|
+
|
|
128
|
+
@wraps(original_init)
|
|
129
|
+
def wrapped_init(self_arg: Any, *args: Any, **kwargs: Any) -> None:
|
|
130
|
+
if not dep.is_available():
|
|
131
|
+
dep._raise_error(obj.__qualname__)
|
|
132
|
+
original_init(self_arg, *args, **kwargs)
|
|
133
|
+
|
|
134
|
+
obj.__init__ = wrapped_init # type: ignore[method-assign]
|
|
135
|
+
return obj
|
|
136
|
+
|
|
137
|
+
@wraps(obj)
|
|
138
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
139
|
+
if not dep.is_available():
|
|
140
|
+
dep._raise_error(obj.__qualname__)
|
|
141
|
+
return obj(*args, **kwargs)
|
|
142
|
+
|
|
143
|
+
return wrapper
|
nvalchemi/_typing.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
"""
|
|
16
|
+
Type definitions for molecular and crystal graph representations.
|
|
17
|
+
|
|
18
|
+
For tensors, we use `jaxtyping` to annotate the types,
|
|
19
|
+
particularly to note their data type and shapes.
|
|
20
|
+
|
|
21
|
+
The notation we will use for shapes is as follows:
|
|
22
|
+
- B: Batch size
|
|
23
|
+
- V: Number of nodes (vertices)
|
|
24
|
+
- E: Number of edges
|
|
25
|
+
- H: Hidden feature dimensionality
|
|
26
|
+
- A: Number of attributes
|
|
27
|
+
- C: Number of centroids
|
|
28
|
+
- M: Number of ensemble members
|
|
29
|
+
- K: Number of max neighbors
|
|
30
|
+
- 3: Number of dimensions for coordinates
|
|
31
|
+
|
|
32
|
+
The notation for data types is as follows:
|
|
33
|
+
- Dimensionalities are assumed to be batch-able; i.e. there are redundant
|
|
34
|
+
dimensions for things like charges, spins, and energy. For concatenated
|
|
35
|
+
properties like atomic number and masses, they do not have a redundant dimension.
|
|
36
|
+
- masses refers to the atomic masses, assumed in amu.
|
|
37
|
+
- Coordinates can refer to fractional or Cartesian coordinates.
|
|
38
|
+
- Charges can refer to partial or total charges, and can be graph and node level.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from __future__ import annotations
|
|
42
|
+
|
|
43
|
+
from collections import OrderedDict
|
|
44
|
+
from enum import Enum
|
|
45
|
+
from typing import TYPE_CHECKING, Protocol, TypeAlias, TypeVar
|
|
46
|
+
|
|
47
|
+
import torch
|
|
48
|
+
from jaxtyping import Bool, Float, Integer, Num
|
|
49
|
+
|
|
50
|
+
if TYPE_CHECKING:
|
|
51
|
+
from nvalchemi.data import AtomicData, Batch
|
|
52
|
+
|
|
53
|
+
B: TypeAlias = int
|
|
54
|
+
V: TypeAlias = int
|
|
55
|
+
E: TypeAlias = int
|
|
56
|
+
H: TypeAlias = int
|
|
57
|
+
C: TypeAlias = int
|
|
58
|
+
M: TypeAlias = int
|
|
59
|
+
K: TypeAlias = int # max neighbors
|
|
60
|
+
# used for defining generic protocols
|
|
61
|
+
T = TypeVar("T")
|
|
62
|
+
|
|
63
|
+
# the noqa is a known bug with ruff
|
|
64
|
+
Scalar: TypeAlias = Float[torch.Tensor, ""] # noqa: F722
|
|
65
|
+
AtomicNumbers: TypeAlias = Integer[torch.Tensor, "V"] # noqa: F722
|
|
66
|
+
AtomicMasses: TypeAlias = Float[torch.Tensor, "V"] # noqa: F722
|
|
67
|
+
NodePositions: TypeAlias = Float[torch.Tensor, "V 3"] # noqa: F722
|
|
68
|
+
NodeVelocities: TypeAlias = Float[torch.Tensor, "V 3"] # noqa: F722
|
|
69
|
+
NodeMomentum: TypeAlias = Float[torch.Tensor, "V 3"] # noqa: F722
|
|
70
|
+
NodeEmbeddings: TypeAlias = Float[torch.Tensor, "V H"] # noqa: F722
|
|
71
|
+
EdgeEmbeddings: TypeAlias = Float[torch.Tensor, "E H"] # noqa: F722
|
|
72
|
+
GraphEmbeddings: TypeAlias = Float[torch.Tensor, "B H"] # noqa: F722
|
|
73
|
+
NodeAttributes: TypeAlias = Float[torch.Tensor, "V A"] # noqa: F722
|
|
74
|
+
NodeCharges: TypeAlias = Float[torch.Tensor, "V"] # noqa: F722
|
|
75
|
+
GraphCharges: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
76
|
+
AtomCategories: TypeAlias = Integer[torch.Tensor, "V"] # noqa: F722
|
|
77
|
+
NodeSpins: TypeAlias = Float[torch.Tensor, "V 1"] # noqa: F722
|
|
78
|
+
GraphSpins: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
79
|
+
# Cartesian displacement vectors: shifts = neighbor_list_shifts @ cell
|
|
80
|
+
PeriodicShifts: TypeAlias = Float[torch.Tensor, "E 3"] # noqa: F722
|
|
81
|
+
# Integer lattice image indices; stored as int or float depending on source
|
|
82
|
+
NeighborListShifts: TypeAlias = Num[torch.Tensor, "E 3"] # noqa: F722
|
|
83
|
+
LatticeVectors: TypeAlias = Float[torch.Tensor, "B 3 3"] # noqa: F722
|
|
84
|
+
Periodicity: TypeAlias = Bool[torch.Tensor, "B 3"] # noqa: F722
|
|
85
|
+
Forces: TypeAlias = Float[torch.Tensor, "V 3"] # noqa: F722
|
|
86
|
+
Hessian: TypeAlias = Float[torch.Tensor, "V 3 3"] # noqa: F722
|
|
87
|
+
Energy: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
88
|
+
Stress: TypeAlias = Float[torch.Tensor, "B 3 3"] # noqa: F722
|
|
89
|
+
Virials: TypeAlias = Float[torch.Tensor, "B 3 3"] # noqa: F722
|
|
90
|
+
Dipole: TypeAlias = Float[torch.Tensor, "B 3"] # noqa: F722
|
|
91
|
+
NeighborList: TypeAlias = Integer[torch.Tensor, "E 2"] # noqa: F722
|
|
92
|
+
BatchIndices: TypeAlias = Integer[torch.Tensor, "V"] # noqa: F722
|
|
93
|
+
NumSteps: TypeAlias = Integer[torch.Tensor, "B 1"] # noqa: F722
|
|
94
|
+
Status: TypeAlias = Integer[torch.Tensor, "B 1"] # noqa: F722
|
|
95
|
+
Fmax: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
96
|
+
ModelOutputs: TypeAlias = OrderedDict[
|
|
97
|
+
str, Energy | Forces | Hessian | Stress | Virials | Dipole | None
|
|
98
|
+
] # noqa: F722
|
|
99
|
+
SampleScores: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
100
|
+
Centroids: TypeAlias = Float[torch.Tensor, "C H"] # noqa: F722
|
|
101
|
+
NodeKineticEnergies: TypeAlias = Float[torch.Tensor, "V 1"] # noqa: F722
|
|
102
|
+
NodeTemperatures: TypeAlias = Float[torch.Tensor, "V 1"] # noqa: F722
|
|
103
|
+
GraphTemperatures: TypeAlias = Float[torch.Tensor, "B 1"] # noqa: F722
|
|
104
|
+
NeighborMatrix: TypeAlias = Integer[torch.Tensor, "V K"] # noqa: F722
|
|
105
|
+
# Integer lattice image indices; stored as int or float depending on source
|
|
106
|
+
NeighborMatrixShifts: TypeAlias = Num[torch.Tensor, "V K 3"] # noqa: F722
|
|
107
|
+
NumNeighbors: TypeAlias = Integer[torch.Tensor, "V"] # noqa: F722
|
|
108
|
+
|
|
109
|
+
# ensemble variations of above properties
|
|
110
|
+
EnsembleEnergies: TypeAlias = Float[torch.Tensor, "M B 1"] # noqa: F722
|
|
111
|
+
EnsembleForces: TypeAlias = Float[torch.Tensor, "M V 3"] # noqa: F722
|
|
112
|
+
EnsembleHessians: TypeAlias = Float[torch.Tensor, "M V 3 3"] # noqa: F722
|
|
113
|
+
EnsembleStresses: TypeAlias = Float[torch.Tensor, "M B 3 3"] # noqa: F722
|
|
114
|
+
EnsembleVirials: TypeAlias = Float[torch.Tensor, "M B 3 3"] # noqa: F722
|
|
115
|
+
EnsembleDipoles: TypeAlias = Float[torch.Tensor, "M B 3"] # noqa: F722
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class AtomCategory(Enum):
|
|
119
|
+
"""
|
|
120
|
+
Categorical mapping for atom classifications within a system.
|
|
121
|
+
|
|
122
|
+
This can be used to distinguish between different atoms during
|
|
123
|
+
modeling, such as applying different kinds of constraints to
|
|
124
|
+
them during training or inference (e.g. freezing dynamics for
|
|
125
|
+
surface and bulk atoms).
|
|
126
|
+
|
|
127
|
+
This Enum should encompass as many modeling types as possible,
|
|
128
|
+
and is not limited to condensed phase modeling.
|
|
129
|
+
|
|
130
|
+
The categories are as follows:
|
|
131
|
+
- GAS: Gas phase atoms.
|
|
132
|
+
- LIQUID: Liquid phase, or solvent atoms.
|
|
133
|
+
- GL_INTERFACE: Gas-liquid interface atoms.
|
|
134
|
+
- SURFACE: Surface atoms.
|
|
135
|
+
- GS_INTERFACE: Gas-surface interface atoms.
|
|
136
|
+
- BULK: Bulk atoms; typically those that can be assumed to be non-interacting.
|
|
137
|
+
- SB_INTERFACE: Solid-bulk interface atoms.
|
|
138
|
+
- FRAGMENT: Fragment atoms
|
|
139
|
+
- CLUSTER: Atoms consituting clusters.
|
|
140
|
+
- TERMINAL: Terminal atoms in molecules.
|
|
141
|
+
- CENTRAL: Central atoms in molecules.
|
|
142
|
+
- SPECIAL: Atoms designated to be generically special.
|
|
143
|
+
|
|
144
|
+
While the categories are meant to be mapped to their respective
|
|
145
|
+
chemistries, it would also be valid to just treat the Enum as
|
|
146
|
+
distinct types without the mapping (e.g. 0/1 to differentiate
|
|
147
|
+
between arbitrary types). In the binary case, where you just have
|
|
148
|
+
two atom categories, we recommend using 0/-1, with `SPECIAL` atoms
|
|
149
|
+
being used for your particular operation.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
GAS = 0
|
|
153
|
+
LIQUID = 1
|
|
154
|
+
GL_INTERFACE = 2
|
|
155
|
+
SURFACE = 3
|
|
156
|
+
GS_INTERFACE = 4
|
|
157
|
+
BULK = 5
|
|
158
|
+
SB_INTERFACE = 6
|
|
159
|
+
FRAGMENT = 7
|
|
160
|
+
CLUSTER = 8
|
|
161
|
+
TERMINAL = 9
|
|
162
|
+
CENTRAL = 10
|
|
163
|
+
SPECIAL = -1
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class AbstractQueue(Protocol[T]):
|
|
167
|
+
"""
|
|
168
|
+
Represents a generic queue interface; the requirements
|
|
169
|
+
are that the queue can be used to put and get items of type ``T``.
|
|
170
|
+
|
|
171
|
+
We do not require that the queue is thread-safe or process-safe,
|
|
172
|
+
nor the ordering of the items within the queue.
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
def put(self, item: T) -> None:
|
|
176
|
+
"""
|
|
177
|
+
Add an item to the queue.
|
|
178
|
+
|
|
179
|
+
The item can be placed anywhere in the queue by
|
|
180
|
+
the concrete implementation.
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
item: T
|
|
185
|
+
The item to add to the queue.
|
|
186
|
+
"""
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
def get(self) -> T:
|
|
190
|
+
"""
|
|
191
|
+
Remove an item from the queue.
|
|
192
|
+
|
|
193
|
+
Returns
|
|
194
|
+
-------
|
|
195
|
+
item: T
|
|
196
|
+
The item removed from the queue.
|
|
197
|
+
"""
|
|
198
|
+
...
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class EmbeddingModel(Protocol):
|
|
202
|
+
"""
|
|
203
|
+
A protocol that defines an abstract interface for retrieving
|
|
204
|
+
graph level embeddings from a model, given some data samples.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
def compute_embeddings(self, samples: AtomicData | Batch) -> GraphEmbeddings:
|
|
208
|
+
"""
|
|
209
|
+
Interface that will compute embeddings for a single or batch of samples.
|
|
210
|
+
|
|
211
|
+
Parameters
|
|
212
|
+
----------
|
|
213
|
+
samples: AtomicData | Batch
|
|
214
|
+
The samples to compute the embeddings for.
|
|
215
|
+
|
|
216
|
+
Returns
|
|
217
|
+
-------
|
|
218
|
+
graph_embeddings: GraphEmbeddings
|
|
219
|
+
The graph embeddings for the samples.
|
|
220
|
+
"""
|
|
221
|
+
...
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class AtomsLike(Protocol):
|
|
225
|
+
"""
|
|
226
|
+
Represents the minimum viable data structure that is agnostic to
|
|
227
|
+
batch and unbatched atomic data.
|
|
228
|
+
|
|
229
|
+
This is only intended for use when type-hinting, and when the
|
|
230
|
+
concrete cases can be used (e.g. ``AtomicData`` or ``Batch``),
|
|
231
|
+
those should be used instead of this.
|
|
232
|
+
|
|
233
|
+
Attributes
|
|
234
|
+
----------
|
|
235
|
+
atomic_numbers : AtomicNumbers
|
|
236
|
+
1D tensor containing atomic numbers.
|
|
237
|
+
positions : NodePositions
|
|
238
|
+
2D tensor containing atomic positions.
|
|
239
|
+
cell : LatticeVectors
|
|
240
|
+
3D tensor containing lattice parameters for each
|
|
241
|
+
structure within a batch.
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
atomic_numbers: AtomicNumbers
|
|
245
|
+
positions: NodePositions
|
|
246
|
+
cell: LatticeVectors | None
|
|
247
|
+
energy: Energy | None
|
|
248
|
+
forces: Forces | None
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from nvalchemi.data.atomic_data import AtomicData
|
|
18
|
+
from nvalchemi.data.batch import Batch
|
|
19
|
+
from nvalchemi.data.datapipes import (
|
|
20
|
+
AtomicDataZarrReader,
|
|
21
|
+
AtomicDataZarrWriter,
|
|
22
|
+
DataLoader,
|
|
23
|
+
Dataset,
|
|
24
|
+
Reader,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"AtomicData",
|
|
29
|
+
"Batch",
|
|
30
|
+
"Reader",
|
|
31
|
+
"AtomicDataZarrWriter",
|
|
32
|
+
"AtomicDataZarrReader",
|
|
33
|
+
"Dataset",
|
|
34
|
+
"DataLoader",
|
|
35
|
+
]
|