BUCToolkit 1.0b0__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.
- BUCToolkit/BatchGenerate/CheckStructures.py +198 -0
- BUCToolkit/BatchGenerate/__init__.py +6 -0
- BUCToolkit/BatchGenerate/coords_interp.py +127 -0
- BUCToolkit/BatchGenerate/initial_ads_structures.py +351 -0
- BUCToolkit/BatchGenerate/random_replace.py +88 -0
- BUCToolkit/BatchMC/MetropolisMC.py +210 -0
- BUCToolkit/BatchMC/_BaseMC.py +863 -0
- BUCToolkit/BatchMC/__init__.py +8 -0
- BUCToolkit/BatchMD/BiasedMD.py +276 -0
- BUCToolkit/BatchMD/NVE.py +92 -0
- BUCToolkit/BatchMD/NVT.py +510 -0
- BUCToolkit/BatchMD/_BaseMD.py +1251 -0
- BUCToolkit/BatchMD/__init__.py +18 -0
- BUCToolkit/BatchMD/constrained_md/BiasedMD.py +273 -0
- BUCToolkit/BatchMD/constrained_md/ConstrNVE.py +169 -0
- BUCToolkit/BatchMD/constrained_md/ConstrNVT.py +462 -0
- BUCToolkit/BatchMD/constrained_md/NVE.py +78 -0
- BUCToolkit/BatchMD/constrained_md/NVT.py +346 -0
- BUCToolkit/BatchMD/constrained_md/_BaseMD.py +440 -0
- BUCToolkit/BatchMD/constrained_md/_ConstrBaseMD.py +607 -0
- BUCToolkit/BatchMD/constrained_md/__init__.py +18 -0
- BUCToolkit/BatchOptim/TS/CI_NEB.py +286 -0
- BUCToolkit/BatchOptim/TS/Dimer.py +950 -0
- BUCToolkit/BatchOptim/TS/__init__.py +10 -0
- BUCToolkit/BatchOptim/_BaseOpt.py +702 -0
- BUCToolkit/BatchOptim/__init__.py +22 -0
- BUCToolkit/BatchOptim/_utils/__init__.py +6 -0
- BUCToolkit/BatchOptim/_utils/_line_search.py +972 -0
- BUCToolkit/BatchOptim/_utils/_warnings.py +11 -0
- BUCToolkit/BatchOptim/frequency.py +496 -0
- BUCToolkit/BatchOptim/minimize/CG.py +256 -0
- BUCToolkit/BatchOptim/minimize/FIRE.py +310 -0
- BUCToolkit/BatchOptim/minimize/QN.py +205 -0
- BUCToolkit/BatchOptim/minimize/__init__.py +17 -0
- BUCToolkit/BatchStructures/BatchStructuresBase.py +2261 -0
- BUCToolkit/BatchStructures/StructuresIO.py +1394 -0
- BUCToolkit/BatchStructures/__init__.py +15 -0
- BUCToolkit/Preprocessing/__init__.py +7 -0
- BUCToolkit/Preprocessing/load_files.py +1680 -0
- BUCToolkit/Preprocessing/preprocessing.py +923 -0
- BUCToolkit/Preprocessing/sampling.py +299 -0
- BUCToolkit/Preprocessing/supercells.py +140 -0
- BUCToolkit/Preprocessing/write_files.py +524 -0
- BUCToolkit/StandardTemplate.py +417 -0
- BUCToolkit/__init__.py +33 -0
- BUCToolkit/_version.py +7 -0
- BUCToolkit/api/ConstrainedMolecularDynamics.py +347 -0
- BUCToolkit/api/DataLoaders.py +321 -0
- BUCToolkit/api/Losses.py +170 -0
- BUCToolkit/api/Metrics.py +84 -0
- BUCToolkit/api/ModelOptims.py +296 -0
- BUCToolkit/api/MolecularDynamics.py +282 -0
- BUCToolkit/api/MonteCarlo.py +280 -0
- BUCToolkit/api/NEB.py +325 -0
- BUCToolkit/api/Predictor.py +292 -0
- BUCToolkit/api/StructureOptimization.py +484 -0
- BUCToolkit/api/Trainer.py +635 -0
- BUCToolkit/api/VibrationAnalysis.py +279 -0
- BUCToolkit/api/__init__.py +38 -0
- BUCToolkit/api/_io.py +1026 -0
- BUCToolkit/cli/__init__.py +20 -0
- BUCToolkit/cli/cli.py +934 -0
- BUCToolkit/cli/input_stub.py +140 -0
- BUCToolkit/cli/main.py +368 -0
- BUCToolkit/cli/print_logo.py +149 -0
- BUCToolkit/cli/template_model.py +6 -0
- BUCToolkit/io.py +30 -0
- BUCToolkit/utils/AtomSelector.py +64 -0
- BUCToolkit/utils/AtomicNumber2Properties.py +39 -0
- BUCToolkit/utils/ElemListReduce.py +52 -0
- BUCToolkit/utils/Ewald.py +210 -0
- BUCToolkit/utils/IrregularTensorReformat.py +59 -0
- BUCToolkit/utils/_CheckModules.py +30 -0
- BUCToolkit/utils/_Element_info.py +527 -0
- BUCToolkit/utils/__init__.py +22 -0
- BUCToolkit/utils/_para_flatt_list.py +131 -0
- BUCToolkit/utils/_print_formatter.py +59 -0
- BUCToolkit/utils/check_structures.py +204 -0
- BUCToolkit/utils/function_utils.py +147 -0
- BUCToolkit/utils/grad_functions.py +69 -0
- BUCToolkit/utils/index_ops.py +432 -0
- BUCToolkit/utils/setup_loggers.py +137 -0
- buctoolkit-1.0b0.dist-info/METADATA +28 -0
- buctoolkit-1.0b0.dist-info/RECORD +88 -0
- buctoolkit-1.0b0.dist-info/WHEEL +5 -0
- buctoolkit-1.0b0.dist-info/entry_points.txt +6 -0
- buctoolkit-1.0b0.dist-info/licenses/LICENSE +21 -0
- buctoolkit-1.0b0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The standard template of input object and models.
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (c) 2026.4.3, BUCToolkit.
|
|
5
|
+
# Authors: Pu Pengxin, Song Xin
|
|
6
|
+
# Version: 1.0b
|
|
7
|
+
# File: StandardTemplate.py
|
|
8
|
+
# Environment: Python 3.12
|
|
9
|
+
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from typing import Dict, Tuple, Optional, List, Any
|
|
12
|
+
|
|
13
|
+
import torch as th
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class StandardModel(ABC):
|
|
17
|
+
"""
|
|
18
|
+
An abstract base class that convert arbitrary function into BUCToolkit supported format to structure opt, MD, and MC, etc.
|
|
19
|
+
It can receive any user-defined Callable object `model` which returns torch.Tensors, and convert it to the standard dict format
|
|
20
|
+
{'energy': energy, 'forces': forces} by user-override `initialize_model` (optional), `calc_energy`, and `calc_forces` with
|
|
21
|
+
input `args` and `kwargs`.
|
|
22
|
+
DO NOT SUPPORT FOR TRAINING.
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
model,
|
|
28
|
+
args_for_init: Tuple = tuple(),
|
|
29
|
+
kwargs_for_init: Dict | None = None,
|
|
30
|
+
device: str = 'cpu',
|
|
31
|
+
*args,
|
|
32
|
+
**kwargs
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
The original PyTorch model with (hyper-)parameters args and kwargs.
|
|
36
|
+
Args:
|
|
37
|
+
model: the main function
|
|
38
|
+
args_for_init: arguments passed to model
|
|
39
|
+
kwargs_for_init: keyword arguments passed to model
|
|
40
|
+
args: additional positional arguments for calc_energy or calc_forces, if necessary
|
|
41
|
+
kwargs: additional keyword arguments for calc_energy or calc_forces, if necessary
|
|
42
|
+
"""
|
|
43
|
+
if kwargs_for_init is None: kwargs_for_init = {}
|
|
44
|
+
super().__init__()
|
|
45
|
+
self.model = model
|
|
46
|
+
self.args = args
|
|
47
|
+
self.kwargs = kwargs
|
|
48
|
+
self.device = th.device(device)
|
|
49
|
+
|
|
50
|
+
self.initialize_model(*args_for_init, **kwargs_for_init)
|
|
51
|
+
|
|
52
|
+
def initialize_model(self, *args, **kwargs):
|
|
53
|
+
"""
|
|
54
|
+
Initialize & config the model, if necessary.
|
|
55
|
+
Args:
|
|
56
|
+
*args:
|
|
57
|
+
**kwargs:
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def calc_energy(self, x) -> th.Tensor:
|
|
66
|
+
"""
|
|
67
|
+
The method that calculates the energy of given x.
|
|
68
|
+
One may use input args/kwargs in __init__
|
|
69
|
+
Args:
|
|
70
|
+
x: input variable
|
|
71
|
+
|
|
72
|
+
Returns: energy
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def calc_forces(self, x) -> th.Tensor:
|
|
79
|
+
"""
|
|
80
|
+
The method that calculates the forces of given x.
|
|
81
|
+
One may use input args/kwargs in __init__
|
|
82
|
+
Args:
|
|
83
|
+
x: input variable
|
|
84
|
+
|
|
85
|
+
Returns: forces
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
def __call__(self, x):
|
|
91
|
+
with th.no_grad():
|
|
92
|
+
ener = th.as_tensor(self.calc_energy(x), device=self.device)
|
|
93
|
+
forc = th.as_tensor(self.calc_forces(x), device=self.device)
|
|
94
|
+
return {'energy': ener, 'forces': forc}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class StandardInput(ABC):
|
|
98
|
+
"""
|
|
99
|
+
An abstract container as the standard input of advanced API `api`.
|
|
100
|
+
It is fully compatible with `torch-geometric.data.Batch` object.
|
|
101
|
+
Following properties with corresponding type are standard and may require by BUCToolkit:
|
|
102
|
+
_ATTR_TYPE = {
|
|
103
|
+
'idx': '<U128', # optional, the list of sample names to log out
|
|
104
|
+
|
|
105
|
+
'batch': '<i8', # shape (N, ), the sample sizes in a batch
|
|
106
|
+
|
|
107
|
+
'cell': '<f4', # shape (N, 3, 3), cell vectors. N is the batch size
|
|
108
|
+
|
|
109
|
+
'pos': '<f4', # shape (\sum_i n_atom_i, n_dim), batched structure coordinates
|
|
110
|
+
|
|
111
|
+
'mask': '|i1', # mask of fixed atoms with the same shape as `pos`. 0 is for fixed and 1 is for free
|
|
112
|
+
|
|
113
|
+
'atomic_numbers': '<i4', # shape (\sum_i n_atom_i, ), tensor of batched atomic numbers.
|
|
114
|
+
|
|
115
|
+
'x_diff': '<f4', # optional, initial displacement direction for Dimer, etc.
|
|
116
|
+
|
|
117
|
+
'velocity': '<f4', # optional, initial velocity for MD.
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
where '<' is for Little-endian order, 'i' is for integer, 'f' is for float, and the last number is the bytes of single element.
|
|
121
|
+
For example, `'pos': '<f4'` means each element of `pos` is 4-bytes float, i.e., float32 or single precision float.
|
|
122
|
+
|
|
123
|
+
It has properties that can be inquired by follow methods as the input arg `data`:
|
|
124
|
+
def get_batch_size(data):
|
|
125
|
+
# total batch size
|
|
126
|
+
return len(data)
|
|
127
|
+
|
|
128
|
+
def get_cell_vec(data):
|
|
129
|
+
# `batch_size` cell vectors stacked at the 1st dim.
|
|
130
|
+
return data.cell.numpy(force=True)
|
|
131
|
+
|
|
132
|
+
def get_atomic_number(data):
|
|
133
|
+
# `batch_size` atomic numbers tensor(int64) concatenated at the 1st dim.
|
|
134
|
+
return data.atomic_numbers.unsqueeze(0)
|
|
135
|
+
|
|
136
|
+
def get_indx(data):
|
|
137
|
+
# Python list object with `batch_size` elements of each sample's name.
|
|
138
|
+
# each name must have less than 128 bytes.
|
|
139
|
+
_indx: Dict = getattr(data, 'idx', None)
|
|
140
|
+
return _indx
|
|
141
|
+
|
|
142
|
+
def get_pos(data):
|
|
143
|
+
# Atomic coordinates tensor in dtype float32 concatenated at the 1st dim.
|
|
144
|
+
return data.pos.unsqueeze(0)
|
|
145
|
+
|
|
146
|
+
def get_fixed_mask(data):
|
|
147
|
+
# the same shape as `pos` with dtype int8. Exactly, only 0, 1.
|
|
148
|
+
# Optional. default is all ones.
|
|
149
|
+
mask = getattr(data, 'fixed', None)
|
|
150
|
+
if mask is not None:
|
|
151
|
+
mask = mask.unsqueeze(0)
|
|
152
|
+
return mask
|
|
153
|
+
|
|
154
|
+
def get_batch_indx(data):
|
|
155
|
+
# batch_indices in the form of 1d int64 th.Tensor [0, 0, 0, ..., 1, 1, ..., n]
|
|
156
|
+
# where the same number means the indexed data of the same sample.
|
|
157
|
+
return [len(dat.pos) for dat in data.to_data_list()] # or can directly store this attr and return `data.batch`
|
|
158
|
+
|
|
159
|
+
def get_init_dX(data):
|
|
160
|
+
# used for Dimer & other algo. requiring finite difference. Have the same shape & dtype as `pos`
|
|
161
|
+
# Optional.
|
|
162
|
+
return getattr(data, self.x_diff_attr, None)
|
|
163
|
+
|
|
164
|
+
def get_init_veloc(data):
|
|
165
|
+
# used for MD. The initial velocities that have the same shape & dtype as `pos`
|
|
166
|
+
# Optional.
|
|
167
|
+
veloc = getattr(data, 'velocity', None)
|
|
168
|
+
if veloc is not None:
|
|
169
|
+
veloc = veloc.unsqueeze(0)
|
|
170
|
+
return veloc
|
|
171
|
+
|
|
172
|
+
They are fully compatible with `torch_geometric.data.batch` object.
|
|
173
|
+
"""
|
|
174
|
+
_ATTR_TYPE = {
|
|
175
|
+
'idx': '<U128',
|
|
176
|
+
'batch': '<i8',
|
|
177
|
+
'cell': '<f4',
|
|
178
|
+
'pos': '<f4',
|
|
179
|
+
'mask': '|i1',
|
|
180
|
+
'atomic_numbers': '<i4',
|
|
181
|
+
'x_diff': '<f4',
|
|
182
|
+
'velocity': '<f4',
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
batch: th.Tensor,
|
|
188
|
+
cell: th.Tensor,
|
|
189
|
+
atomic_numbers: th.Tensor,
|
|
190
|
+
pos: th.Tensor,
|
|
191
|
+
idx: Optional[List[str]] = None,
|
|
192
|
+
fixed: Optional[th.Tensor] = None,
|
|
193
|
+
velocity: Optional[th.Tensor] = None,
|
|
194
|
+
x_diff: Optional[th.Tensor] = None,
|
|
195
|
+
**kwargs
|
|
196
|
+
):
|
|
197
|
+
self._batch = batch
|
|
198
|
+
self._cell = cell
|
|
199
|
+
self._atomic_numbers = atomic_numbers
|
|
200
|
+
self._pos = pos
|
|
201
|
+
self.idx = idx
|
|
202
|
+
self.fixed = fixed
|
|
203
|
+
self.velocity = velocity
|
|
204
|
+
self.x_diff = x_diff
|
|
205
|
+
self.__dict__.update(kwargs)
|
|
206
|
+
|
|
207
|
+
# the following properties must be implemented.
|
|
208
|
+
@abstractmethod
|
|
209
|
+
def __len__(self) -> int:
|
|
210
|
+
""" return the sample number in one batch """
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
@abstractmethod
|
|
215
|
+
def batch(self) -> Optional[th.Tensor]:
|
|
216
|
+
"""
|
|
217
|
+
batch indices tensor in the form of 1-D int64 th.Tensor [0, 0, 0, ..., 1, 1, ..., n]
|
|
218
|
+
where the same number means the indexed data of the same sample.
|
|
219
|
+
"""
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
@batch.setter
|
|
223
|
+
@abstractmethod
|
|
224
|
+
def batch(self, value: Optional[th.Tensor]) -> None:
|
|
225
|
+
pass
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
@abstractmethod
|
|
229
|
+
def pos(self) -> th.Tensor:
|
|
230
|
+
"""
|
|
231
|
+
Atomic coordinates tensor in dtype float32 concatenated at the 1st dim. shape: (sum_i^{n_batch} n_i, 3).
|
|
232
|
+
"""
|
|
233
|
+
pass
|
|
234
|
+
|
|
235
|
+
@pos.setter
|
|
236
|
+
@abstractmethod
|
|
237
|
+
def pos(self, value: th.Tensor) -> None:
|
|
238
|
+
pass
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
@abstractmethod
|
|
242
|
+
def cell(self) -> th.Tensor:
|
|
243
|
+
"""
|
|
244
|
+
cell tensor in dtype float32 concatenated at the 1st dim. shape: (n_batch, 3, 3)
|
|
245
|
+
"""
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
@cell.setter
|
|
249
|
+
@abstractmethod
|
|
250
|
+
def cell(self, value: th.Tensor) -> None:
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
@abstractmethod
|
|
255
|
+
def atomic_numbers(self) -> th.Tensor:
|
|
256
|
+
"""
|
|
257
|
+
Atomic number tensor in dtype int64 concatenated at the 1st dim. shape: (sum_i^{n_batch} n_i, ).
|
|
258
|
+
"""
|
|
259
|
+
pass
|
|
260
|
+
|
|
261
|
+
@atomic_numbers.setter
|
|
262
|
+
@abstractmethod
|
|
263
|
+
def atomic_numbers(self, value: th.Tensor) -> None:
|
|
264
|
+
pass
|
|
265
|
+
|
|
266
|
+
@abstractmethod
|
|
267
|
+
def to_data_list(self) -> List[Any]:
|
|
268
|
+
"""
|
|
269
|
+
Split batched data into the List of each sample.
|
|
270
|
+
Similar to torch_geometric.data.Batch.
|
|
271
|
+
Optional to override.
|
|
272
|
+
"""
|
|
273
|
+
raise NotImplementedError(f'Please implement `self.to_data_list()` by overriding in the subclass.')
|
|
274
|
+
|
|
275
|
+
def to(self, target: th.dtype | th.device | str) -> None:
|
|
276
|
+
"""
|
|
277
|
+
Move data of self to the given device or dtype.
|
|
278
|
+
Args:
|
|
279
|
+
target: the device or dtype to which to move the data.
|
|
280
|
+
|
|
281
|
+
"""
|
|
282
|
+
# normal attr
|
|
283
|
+
for k, dat in self.__dict__.items():
|
|
284
|
+
if k.startswith('__') and k.endswith('__'):
|
|
285
|
+
continue
|
|
286
|
+
elif isinstance(dat, th.Tensor):
|
|
287
|
+
self.__setattr__(k, dat.to(target))
|
|
288
|
+
|
|
289
|
+
# properties
|
|
290
|
+
for k in self._ATTR_TYPE.keys():
|
|
291
|
+
_x = getattr(self, k)
|
|
292
|
+
if isinstance(_x, th.Tensor):
|
|
293
|
+
_x = _x.to(target)
|
|
294
|
+
try:
|
|
295
|
+
setattr(self, k, _x)
|
|
296
|
+
except AttributeError:
|
|
297
|
+
pass
|
|
298
|
+
|
|
299
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
300
|
+
"""
|
|
301
|
+
Convert self to the dict format.
|
|
302
|
+
Note that private and special attr (start with '_'/'__') would not put in.
|
|
303
|
+
Returns: Dict of attributes.
|
|
304
|
+
"""
|
|
305
|
+
# normal attr
|
|
306
|
+
attr_dict = {k:dat for k, dat in self.__dict__.items() if not k.startswith('_')}
|
|
307
|
+
# properties
|
|
308
|
+
attr_dict.update({k: getattr(self, k) for k in self._ATTR_TYPE.keys() if not k.startswith('_')})
|
|
309
|
+
|
|
310
|
+
return attr_dict
|
|
311
|
+
|
|
312
|
+
class BatchData(StandardInput):
|
|
313
|
+
"""
|
|
314
|
+
An example of `StandardInput` for Batched data.
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
def __init__(
|
|
318
|
+
self,
|
|
319
|
+
batch: th.Tensor,
|
|
320
|
+
cell: th.Tensor,
|
|
321
|
+
atomic_numbers: th.Tensor,
|
|
322
|
+
pos: th.Tensor,
|
|
323
|
+
idx: Optional[List[str]] = None,
|
|
324
|
+
fixed: Optional[th.Tensor] = None,
|
|
325
|
+
velocity: Optional[th.Tensor] = None,
|
|
326
|
+
x_diff: Optional[th.Tensor] = None,
|
|
327
|
+
**kwargs
|
|
328
|
+
):
|
|
329
|
+
super(BatchData, self).__init__(
|
|
330
|
+
batch=batch,
|
|
331
|
+
cell=cell,
|
|
332
|
+
atomic_numbers=atomic_numbers,
|
|
333
|
+
pos=pos,
|
|
334
|
+
idx=idx,
|
|
335
|
+
fixed=fixed,
|
|
336
|
+
velocity=velocity,
|
|
337
|
+
x_diff=x_diff,
|
|
338
|
+
**kwargs
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
def __len__(self) -> int:
|
|
342
|
+
""" return the sample number in one batch """
|
|
343
|
+
return len(self._batch)
|
|
344
|
+
|
|
345
|
+
@property
|
|
346
|
+
def batch(self) -> th.Tensor:
|
|
347
|
+
"""
|
|
348
|
+
batch indices tensor in the form of 1-D int64 th.Tensor [0, 0, 0, ..., 1, 1, ..., n]
|
|
349
|
+
where the same number means the indexed data of the same sample.
|
|
350
|
+
"""
|
|
351
|
+
return self._batch
|
|
352
|
+
|
|
353
|
+
@batch.setter
|
|
354
|
+
def batch(self, value: th.Tensor) -> None:
|
|
355
|
+
if not isinstance(value, th.Tensor):
|
|
356
|
+
raise TypeError(f'Batch must be of type {th.Tensor}, not {type(value)}.')
|
|
357
|
+
elif value.dim() != 1:
|
|
358
|
+
raise ValueError(f'Batch must be a 1-D Tensor, but got {value.dim()}-D.')
|
|
359
|
+
elif th.sum(value) != self.pos.shape[0]:
|
|
360
|
+
raise ValueError(f'Atoms number given by `value` and `self.pos` do not match.')
|
|
361
|
+
|
|
362
|
+
self._batch = value.to(th.int64)
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def pos(self) -> th.Tensor:
|
|
366
|
+
"""
|
|
367
|
+
Atomic coordinates tensor in dtype float32 concatenated at the 1st dim. shape: (sum_i^{n_batch} n_i, 3).
|
|
368
|
+
"""
|
|
369
|
+
return self._pos
|
|
370
|
+
|
|
371
|
+
@pos.setter
|
|
372
|
+
def pos(self, value: th.Tensor) -> None:
|
|
373
|
+
if not isinstance(value, th.Tensor):
|
|
374
|
+
raise TypeError(f'`pos` must be of type {th.Tensor}, not {type(value)}.')
|
|
375
|
+
self._pos = value
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def cell(self) -> th.Tensor:
|
|
379
|
+
"""
|
|
380
|
+
cell tensor in dtype float32 concatenated at the 1st dim. shape: (n_batch, 3, 3)
|
|
381
|
+
"""
|
|
382
|
+
return self._cell
|
|
383
|
+
|
|
384
|
+
@cell.setter
|
|
385
|
+
def cell(self, value: th.Tensor) -> None:
|
|
386
|
+
if not isinstance(value, th.Tensor):
|
|
387
|
+
raise TypeError(f'`cell` must be of type {th.Tensor}, not {type(value)}.')
|
|
388
|
+
elif value.dim() != 3:
|
|
389
|
+
raise ValueError(f'`cell` must be a 3-D tensor, but got {value.dim()}-D.')
|
|
390
|
+
elif value.shape != (len(self._batch), 3, 3):
|
|
391
|
+
raise ValueError(f'batch size given by `value` and `self.batch` do not match.')
|
|
392
|
+
self._cell = value
|
|
393
|
+
|
|
394
|
+
@property
|
|
395
|
+
def atomic_numbers(self) -> th.Tensor:
|
|
396
|
+
"""
|
|
397
|
+
Atomic number tensor in dtype int64 concatenated at the 1st dim. shape: (sum_i^{n_batch} n_i, ).
|
|
398
|
+
"""
|
|
399
|
+
return self._atomic_numbers
|
|
400
|
+
|
|
401
|
+
@atomic_numbers.setter
|
|
402
|
+
def atomic_numbers(self, value: th.Tensor) -> None:
|
|
403
|
+
if not isinstance(value, th.Tensor):
|
|
404
|
+
raise TypeError(f"`atomic_numbers` must be of type {th.Tensor}, not {type(value)}.")
|
|
405
|
+
elif value.dim() != 1:
|
|
406
|
+
raise ValueError(f"`atomic_numbers` must be a 1-D tensor, but got {value.dim()}-D.")
|
|
407
|
+
elif len(value) != self.pos.shape[0]:
|
|
408
|
+
raise ValueError(f"Atomic number given by `value` and `self.pos` do not match.")
|
|
409
|
+
self._atomic_numbers = value.to(th.int32)
|
|
410
|
+
|
|
411
|
+
def to_data_list(self) -> List[Any]:
|
|
412
|
+
"""
|
|
413
|
+
Split batched data into the List of each sample.
|
|
414
|
+
Similar to torch_geometric.data.Batch.
|
|
415
|
+
Optional to override.
|
|
416
|
+
"""
|
|
417
|
+
raise NotImplementedError(f'Please implement `self.to_data_list()` by overriding in the subclass.')
|
BUCToolkit/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026.3.27, BUCToolkit.
|
|
2
|
+
# Authors: Pu Pengxin, Song Xin
|
|
3
|
+
# Version: 1.0b
|
|
4
|
+
# File: __init__.py
|
|
5
|
+
# Environment: Python 3.12
|
|
6
|
+
|
|
7
|
+
from BUCToolkit.BatchStructures.BatchStructuresBase import BatchStructures as Structures
|
|
8
|
+
from BUCToolkit import utils
|
|
9
|
+
from BUCToolkit.utils._Element_info import TRANSITION_METALS, TRANSITION_P_METALS, NOBLE_METALS, NONRADIOACTIVE_METALS
|
|
10
|
+
from BUCToolkit.Preprocessing import load_files
|
|
11
|
+
from BUCToolkit.Preprocessing.load_files import load_from_structures as load
|
|
12
|
+
from BUCToolkit.Preprocessing import preprocessing
|
|
13
|
+
from BUCToolkit import io
|
|
14
|
+
from BUCToolkit import api
|
|
15
|
+
from BUCToolkit import BatchMC, BatchMD, BatchOptim, BatchStructures
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
'Structures',
|
|
19
|
+
'load',
|
|
20
|
+
'load_files',
|
|
21
|
+
'preprocessing',
|
|
22
|
+
'TRANSITION_METALS',
|
|
23
|
+
'TRANSITION_P_METALS',
|
|
24
|
+
'NOBLE_METALS',
|
|
25
|
+
'NONRADIOACTIVE_METALS',
|
|
26
|
+
'utils',
|
|
27
|
+
'io',
|
|
28
|
+
'api',
|
|
29
|
+
'BatchMC',
|
|
30
|
+
'BatchMD',
|
|
31
|
+
'BatchOptim',
|
|
32
|
+
'BatchStructures'
|
|
33
|
+
]
|