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,432 @@
|
|
|
1
|
+
""" Indexed operations with given batch_indices """
|
|
2
|
+
# Copyright (c) 2026.1.22, BUCToolkit.
|
|
3
|
+
# Authors: Pu Pengxin, Song Xin
|
|
4
|
+
# Version: 0.9a
|
|
5
|
+
# File: index_ops.py
|
|
6
|
+
# Environment: Python 3.12
|
|
7
|
+
|
|
8
|
+
import warnings
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import torch as th
|
|
12
|
+
from typing import Optional, Literal, Callable, Tuple, Dict
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def scatter_reduce(
|
|
16
|
+
src: th.Tensor,
|
|
17
|
+
batch_indices: th.Tensor,
|
|
18
|
+
dim: int = -1,
|
|
19
|
+
ops: Literal['sum', 'prod', 'mean', 'amin', 'amax'] = 'sum',
|
|
20
|
+
init_value: float|int|bool = 0.
|
|
21
|
+
) -> th.Tensor:
|
|
22
|
+
"""
|
|
23
|
+
scatter_reduce method that reduces element in `src` with the same indices in `batch_indices` by `ops`.
|
|
24
|
+
Args:
|
|
25
|
+
src: source tensor
|
|
26
|
+
batch_indices: indices tensor
|
|
27
|
+
dim: reduce dimension
|
|
28
|
+
ops: reduce operation
|
|
29
|
+
init_value: default value of the output tensor that reduced values filled in.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
# manage batch_indices
|
|
35
|
+
_batch_indices = batch_indices.clone().to(th.int64)
|
|
36
|
+
if dim < 0:
|
|
37
|
+
dim = src.dim() + dim
|
|
38
|
+
if _batch_indices.dim() == 1:
|
|
39
|
+
for _ in range(0, dim): _batch_indices.unsqueeze_(0)
|
|
40
|
+
for _ in range(_batch_indices.dim(), src.dim()): _batch_indices.unsqueeze_(-1)
|
|
41
|
+
_batch_indices = _batch_indices.expand(src.shape)
|
|
42
|
+
# main
|
|
43
|
+
src_shape = list(src.shape)
|
|
44
|
+
src_shape[dim] = th.max(_batch_indices).item() + 1
|
|
45
|
+
out = th.full(src_shape, init_value, device=src.device)
|
|
46
|
+
out.scatter_reduce_(
|
|
47
|
+
dim,
|
|
48
|
+
_batch_indices,
|
|
49
|
+
src,
|
|
50
|
+
ops
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return out
|
|
54
|
+
|
|
55
|
+
def index_reduce(
|
|
56
|
+
src: th.Tensor,
|
|
57
|
+
batch_indices: th.Tensor,
|
|
58
|
+
dim: int = 0,
|
|
59
|
+
ops: Literal['prod', 'mean', 'amin', 'amax', 'sum'] = 'sum',
|
|
60
|
+
init_value: float = 0.,
|
|
61
|
+
out_size: int|None = None,
|
|
62
|
+
include_self: bool = True,
|
|
63
|
+
out: th.Tensor|None = None
|
|
64
|
+
):
|
|
65
|
+
"""
|
|
66
|
+
scatter_reduce method that reduces element in `src` with the same indices in `batch_indices` by `ops`.
|
|
67
|
+
Args:
|
|
68
|
+
src: source tensor
|
|
69
|
+
batch_indices: indices tensor of 1D
|
|
70
|
+
dim: reduce dimension
|
|
71
|
+
ops: reduce operation
|
|
72
|
+
init_value: default value of the output tensor that reduced values filled in.
|
|
73
|
+
out_size: size of the output tensor at the given dim. if None, it is equal to `batch_indices.max().item() + 1`
|
|
74
|
+
include_self: whether to let `init_value` really participate in the reduction.
|
|
75
|
+
out: the output tensor. If None, a new one will be returned.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
|
|
79
|
+
"""
|
|
80
|
+
assert batch_indices.dim() == 1, f'Invalid dimension of batch indices: {batch_indices.shape}. It must be 1D.'
|
|
81
|
+
dim = dim if dim >= 0 else src.dim() + dim
|
|
82
|
+
output_size = list(src.shape)
|
|
83
|
+
output_size[dim] = (batch_indices.max().item() + 1) if out_size is None else out_size
|
|
84
|
+
|
|
85
|
+
out = th.full(output_size, init_value, device=src.device, dtype=src.dtype) if out is None else out.fill_(init_value)
|
|
86
|
+
if ops == 'sum' and include_self:
|
|
87
|
+
out.index_add_(dim, batch_indices, src)
|
|
88
|
+
else:
|
|
89
|
+
out.index_reduce_(dim, batch_indices, src, ops, include_self=include_self)
|
|
90
|
+
return out
|
|
91
|
+
|
|
92
|
+
def index_inner_product(
|
|
93
|
+
u: th.Tensor,
|
|
94
|
+
v: th.Tensor,
|
|
95
|
+
dim: int,
|
|
96
|
+
batch_indices: th.Tensor,
|
|
97
|
+
out_size = None,
|
|
98
|
+
):
|
|
99
|
+
"""
|
|
100
|
+
Calculate the inner product of two tensors with given batch_indices .
|
|
101
|
+
Args:
|
|
102
|
+
u: tensor 1, in the dual space.
|
|
103
|
+
v: tensor 2, in the linear space.
|
|
104
|
+
dim: reduce dimension
|
|
105
|
+
batch_indices: indices tensor of 1D
|
|
106
|
+
out_size: size of the output tensor. If None, it is equal to `batch_indices.max().item() + 1`
|
|
107
|
+
|
|
108
|
+
Returns: u @ v with shape (u.shape[: `dim`], batch_number, u.shape[`dim` + 1: ])
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
w = u * v
|
|
112
|
+
w = index_reduce(w, batch_indices, dim, ops='sum', init_value=0., out_size=out_size)
|
|
113
|
+
return w
|
|
114
|
+
|
|
115
|
+
def indices_pairwise_dist(
|
|
116
|
+
X: th.Tensor, # [N, M]
|
|
117
|
+
Y: th.Tensor,
|
|
118
|
+
Qx: th.Tensor, # [N],continuous sample indices in the batch X, 0,0,...,1,1,...,B-1
|
|
119
|
+
Qy: th.Tensor | None = None,
|
|
120
|
+
thres: float | None = None,
|
|
121
|
+
metric: Literal['euclidean', 'dot', 'cosine']|Callable[[th.Tensor, th.Tensor, ...], th.Tensor] = "euclidean", # 'euclidean' | 'dot' | 'cosine'
|
|
122
|
+
metric_kwargs: Dict|None = None,
|
|
123
|
+
relation: Literal['lt', 'gt'] = "gt",
|
|
124
|
+
exclude_diag: bool = True,
|
|
125
|
+
is_symmetric: bool = False,
|
|
126
|
+
return_values: bool = True,
|
|
127
|
+
is_coalesce: bool = True,
|
|
128
|
+
eps: float = 1e-12,
|
|
129
|
+
):
|
|
130
|
+
"""
|
|
131
|
+
Compute pairwise distance between two tensors on only the same indices in Qx and Qy.
|
|
132
|
+
Args:
|
|
133
|
+
X: input tensor 1.
|
|
134
|
+
Y: input tensor 2.
|
|
135
|
+
Qx: Tensor[int64], indices tensor of X.
|
|
136
|
+
Qy: Tensor[int64], indices tensor of Y.
|
|
137
|
+
thres: if not None, only distance greater/less (depends on `relation`) than `thres` will be output. Otherwise, all dist will be output.
|
|
138
|
+
metric: distance calculation method.
|
|
139
|
+
metric_kwargs: the keyword arguments passed to `metric` if `metric` is Callable.
|
|
140
|
+
relation: check `thres` greater (gt) or less (lt) than `thres`.
|
|
141
|
+
exclude_diag: whether to exclude diagonals.
|
|
142
|
+
is_symmetric: whether the distance between `X` and `Y` is symmetric. If True, only lower triangular of dist. mat. will be computed.
|
|
143
|
+
return_values: whether to return both indices and distance or only indices of distance < `thres`.
|
|
144
|
+
is_coalesce: whether to coalesce/resort indices and distance before output.
|
|
145
|
+
eps: epsilon for numerical stability.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Tuple[indices: Tensor[int64], batch_tensor of dist: Tensor[int64]] |
|
|
149
|
+
Tuple[indices: Tensor[int64], distance: Tensor, batch_tensor of dist: Tensor[int64]]
|
|
150
|
+
|
|
151
|
+
"""
|
|
152
|
+
# check
|
|
153
|
+
assert relation in ("lt", "gt")
|
|
154
|
+
assert X.device == Y.device, f'X and Y must be on the same device, but got {X.device} and {Y.device}.'
|
|
155
|
+
assert X.dtype == Y.dtype, f'X and Y must be on the same dtype, but got {X.dtype} and {Y.dtype}.'
|
|
156
|
+
# initialize
|
|
157
|
+
if metric_kwargs is None:
|
|
158
|
+
metric_kwargs = dict()
|
|
159
|
+
if is_symmetric:
|
|
160
|
+
assert X.shape == Y.shape, f'For symmetric metric, X and Y must have the same shape.'
|
|
161
|
+
if Qy is None:
|
|
162
|
+
Qy = Qx.clone()
|
|
163
|
+
device = X.device
|
|
164
|
+
if thres is None:
|
|
165
|
+
thres = th.inf if relation == "lt" else -th.inf
|
|
166
|
+
# sort & rearrange X, Y, Qx, Qy
|
|
167
|
+
Qx_sorted, Qx_sort_indx = th.sort(Qx)
|
|
168
|
+
Qy_sorted, Qy_sort_indx = th.sort(Qy)
|
|
169
|
+
Xs, Ys = X[Qx_sort_indx], Y[Qy_sort_indx]
|
|
170
|
+
|
|
171
|
+
# calc. indices
|
|
172
|
+
def _starts_sizes(Qs):
|
|
173
|
+
N = Qs.numel()
|
|
174
|
+
ch = th.ones(N, dtype=th.bool, device=Qs.device)
|
|
175
|
+
ch[1:] = (Qs[1:] != Qs[:-1])
|
|
176
|
+
st = th.nonzero(ch, as_tuple=True)[0]
|
|
177
|
+
en = th.cat([st[1:], th.tensor([N], device=Qs.device)])
|
|
178
|
+
sz = (en - st).to(th.long)
|
|
179
|
+
labs = Qs[st]
|
|
180
|
+
return st, sz, labs
|
|
181
|
+
|
|
182
|
+
ptr_x, nx, labs_x = _starts_sizes(Qx_sorted)
|
|
183
|
+
ptr_y, ny, labs_y = _starts_sizes(Qy_sorted)
|
|
184
|
+
|
|
185
|
+
# align two indices
|
|
186
|
+
ix = th.searchsorted(labs_x, labs_y)
|
|
187
|
+
# screen into the intersection (labs_y[pos] == labs_x)
|
|
188
|
+
valid = (ix < labs_x.numel()) & (labs_x[ix] == labs_y)
|
|
189
|
+
labs_y = labs_y[valid]
|
|
190
|
+
ptr_y, ny = ptr_y[valid], ny[valid]
|
|
191
|
+
ix = ix[valid]
|
|
192
|
+
ptr_x, nx = ptr_x[ix], nx[ix] # ptr_x that aligned with y
|
|
193
|
+
if labs_y.numel() == 0:
|
|
194
|
+
empty = th.empty(2, 0, dtype=th.long, device=device)
|
|
195
|
+
Qe = th.empty(0, dtype=Qx.dtype, device=device)
|
|
196
|
+
return (empty, th.empty(0, device=device), Qe) if return_values else (empty, Qe)
|
|
197
|
+
|
|
198
|
+
# vectorized enumerate pairwise nx_i * ny_i, and mapping to Xs and Ys
|
|
199
|
+
pairs_per_img = nx * ny # [B]
|
|
200
|
+
total_pairs = int(pairs_per_img.sum().item())
|
|
201
|
+
|
|
202
|
+
pair_ptr = th.cumsum(pairs_per_img, 0) - pairs_per_img # [B]
|
|
203
|
+
pair_off_ex = th.repeat_interleave(pair_ptr, pairs_per_img) # [∑ nx_i*ny_i]
|
|
204
|
+
ny_ex = th.repeat_interleave(ny, pairs_per_img) # [∑ nx_i*ny_i]
|
|
205
|
+
k = th.arange(total_pairs, device=device) - pair_off_ex
|
|
206
|
+
|
|
207
|
+
i_loc = th.div(k, ny_ex, rounding_mode="floor") # [∑ nx_i*ny_i]
|
|
208
|
+
j_loc = (k % ny_ex)
|
|
209
|
+
|
|
210
|
+
xs_ex = th.repeat_interleave(ptr_x, pairs_per_img) # [∑ nx_i*ny_i]
|
|
211
|
+
ys_ex = th.repeat_interleave(ptr_y, pairs_per_img)
|
|
212
|
+
|
|
213
|
+
row_s = xs_ex + i_loc # indices of Xs
|
|
214
|
+
col_s = ys_ex + j_loc # indices of Ys
|
|
215
|
+
Qe_s = th.repeat_interleave(labs_y, pairs_per_img) # indices of pairwise-dist, i.e., the edge.
|
|
216
|
+
|
|
217
|
+
# Symmetric reduce
|
|
218
|
+
if is_symmetric:
|
|
219
|
+
if not th.all(nx == ny):
|
|
220
|
+
raise ValueError(f"Symmetric requires Qx, Qy have the same shape in each sample, but got {nx} and {ny}")
|
|
221
|
+
mask = th.ones(total_pairs, dtype=th.bool, device=device)
|
|
222
|
+
mask &= (i_loc <= j_loc) # select only lower triangular parts.
|
|
223
|
+
if exclude_diag:
|
|
224
|
+
mask &= (i_loc != j_loc) # remove diag.
|
|
225
|
+
row_s = row_s[mask]
|
|
226
|
+
col_s = col_s[mask]
|
|
227
|
+
Qe_s = Qe_s[mask]
|
|
228
|
+
|
|
229
|
+
if row_s.numel() == 0:
|
|
230
|
+
empty = th.empty(2, 0, dtype=th.long, device=device)
|
|
231
|
+
Qe = th.empty(0, dtype=Qx.dtype, device=device)
|
|
232
|
+
return (empty, th.empty(0, device=device), Qe) if return_values else (empty, Qe)
|
|
233
|
+
|
|
234
|
+
# Main Calc. Dist.
|
|
235
|
+
xr, yc = Xs[row_s], Ys[col_s] # [E, M], x_row, y_column
|
|
236
|
+
|
|
237
|
+
if isinstance(metric, Callable):
|
|
238
|
+
val = metric(xr, yc, **metric_kwargs)
|
|
239
|
+
elif metric == "euclidean":
|
|
240
|
+
n2x = th.linalg.vecdot(Xs, Xs)
|
|
241
|
+
n2y = th.linalg.vecdot(Ys, Ys)
|
|
242
|
+
dot = th.linalg.vecdot(xr, yc)
|
|
243
|
+
val = n2x[row_s] + n2y[col_s] - 2.0 * dot # [E]
|
|
244
|
+
thres **= 2 if th.isfinite(th.tensor(thres)) else 1
|
|
245
|
+
elif metric == "dot":
|
|
246
|
+
val = th.linalg.vecdot(xr, yc)
|
|
247
|
+
elif metric == "cosine":
|
|
248
|
+
val = th.linalg.vecdot(xr, yc) / (th.linalg.vector_norm(xr, dim=-1) * th.linalg.vector_norm(yc, dim=-1) + eps)
|
|
249
|
+
else:
|
|
250
|
+
raise ValueError(f"Unknown metric {metric}.")
|
|
251
|
+
|
|
252
|
+
is_selected = (th.abs(val) < thres) if relation == "lt" else (th.abs(val) > thres)
|
|
253
|
+
row_s, col_s, Qe = row_s[is_selected], col_s[is_selected], Qe_s[is_selected]
|
|
254
|
+
|
|
255
|
+
# remapping to unsorted original X, Y
|
|
256
|
+
row = Qx_sort_indx[row_s]
|
|
257
|
+
col = Qy_sort_indx[col_s]
|
|
258
|
+
indices = th.stack([row, col], dim=0)
|
|
259
|
+
if return_values:
|
|
260
|
+
out_vals: th.Tensor = val[is_selected].clone()
|
|
261
|
+
if metric == "euclidean": out_vals.add_(eps**2).sqrt_()
|
|
262
|
+
else:
|
|
263
|
+
out_vals = val # only a placeholder
|
|
264
|
+
if is_symmetric: # appending upper diagonal part
|
|
265
|
+
nd_mask = (row != col) # non-diagonal
|
|
266
|
+
if th.any(nd_mask):
|
|
267
|
+
upper_diag = th.stack([col[nd_mask], row[nd_mask]], dim=0)
|
|
268
|
+
indices = th.cat([indices, upper_diag], dim=1)
|
|
269
|
+
if return_values:
|
|
270
|
+
out_vals = th.cat([out_vals, out_vals[nd_mask]], dim=0)
|
|
271
|
+
Qe = th.cat([Qe, Qe[nd_mask]], dim=0)
|
|
272
|
+
|
|
273
|
+
# coalesce & rearrange indices
|
|
274
|
+
if is_coalesce:
|
|
275
|
+
coalesce_indx = th.argsort(indices[0], dim=0)
|
|
276
|
+
indices = indices[:, coalesce_indx]
|
|
277
|
+
Qe = Qe[coalesce_indx]
|
|
278
|
+
out_vals = out_vals[coalesce_indx] if return_values else out_vals
|
|
279
|
+
|
|
280
|
+
if return_values:
|
|
281
|
+
return indices, out_vals, Qe
|
|
282
|
+
return indices, Qe
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def inner_product_for_halfspace(u: th.Tensor, v: th.Tensor, volumes: th.Tensor|float = 1.) -> th.Tensor:
|
|
286
|
+
"""
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
u:
|
|
290
|
+
v:
|
|
291
|
+
volumes:
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
|
|
295
|
+
"""
|
|
296
|
+
u0 = u[:, 0] # (B,)
|
|
297
|
+
v0 = v[:, 0]
|
|
298
|
+
u_tail = u[:, 1:] # (B, nG-1)
|
|
299
|
+
v_tail = v[:, 1:] # (B, nG-1)
|
|
300
|
+
|
|
301
|
+
p = th.baddbmm(
|
|
302
|
+
th.empty_like(u[:,0]).unsqueeze(-1).unsqueeze(-1),
|
|
303
|
+
u_tail.conj().unsqueeze(1).contiguous(), # (B, 1, n)
|
|
304
|
+
v_tail.unsqueeze(-1).contiguous(), # (B, n, 1)
|
|
305
|
+
beta=0.0,
|
|
306
|
+
alpha=2.0,
|
|
307
|
+
).squeeze(-2, -1) # (B,)
|
|
308
|
+
|
|
309
|
+
# adding gamma point
|
|
310
|
+
p.add_(u0.conj() * v0) # (B,)
|
|
311
|
+
p = p.real
|
|
312
|
+
if isinstance(volumes, th.Tensor) or volumes != 1.0:
|
|
313
|
+
p.mul_(volumes)
|
|
314
|
+
|
|
315
|
+
return p
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def standardize_cell(cell: th.Tensor) -> Tuple[th.Tensor, th.Tensor]:
|
|
319
|
+
"""
|
|
320
|
+
Rotation a cell vector matrix into a standardized form where ay = az = 0, bz = 0, cz > 0.
|
|
321
|
+
Args:
|
|
322
|
+
cell: Tensor[B, 3, 3], batch of cell vectors.
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
L: Tensor[B, 3, 3], standardized cell vector matrix with lower triangular forms.
|
|
326
|
+
Q: Tensor[B, 3, 3], the corresponding rotation transform
|
|
327
|
+
|
|
328
|
+
"""
|
|
329
|
+
# determined the cell is a right-hand system
|
|
330
|
+
_cell_std = cell.clone()
|
|
331
|
+
vol = th.linalg.det(_cell_std).unsqueeze(-1) # (B, 1)
|
|
332
|
+
_cell_std[:, 2, :] = th.where(vol < 0., - cell[:, 2, :], cell[:, 2, :])
|
|
333
|
+
ill_mask = th.abs(vol) < 1e-5
|
|
334
|
+
if ill_mask.any():
|
|
335
|
+
warnings.warn(f'A cell very close to low-dimensional system was detected in [{th.argwhere(ill_mask)}]-th samples.')
|
|
336
|
+
# QR factorization
|
|
337
|
+
Q, R = th.linalg.qr(_cell_std.mT.contiguous())
|
|
338
|
+
_cell_std = R.mT.contiguous()
|
|
339
|
+
_rot_op = Q.mT.contiguous()
|
|
340
|
+
# put diag of R.mT positive
|
|
341
|
+
cell_diag = th.diagonal(_cell_std, dim1=-2, dim2=-1) # (B, 3)
|
|
342
|
+
neg_diag_mask = (cell_diag < 0.) # (B, 3)
|
|
343
|
+
_rot_op = th.where(neg_diag_mask.unsqueeze(-1), -_rot_op, _rot_op) # D Q^T
|
|
344
|
+
_cell_std = th.where(neg_diag_mask.unsqueeze(-2), -_cell_std, _cell_std) # R^T D
|
|
345
|
+
|
|
346
|
+
return _cell_std, _rot_op
|
|
347
|
+
|
|
348
|
+
def generate_half_space_grids(n_grids: Tuple[int, int, int], device: str = 'cpu') -> th.Tensor:
|
|
349
|
+
"""
|
|
350
|
+
Generate a half space grid of given `n_grids`. where: h > 0 or (h = 0 and k > 0) or ((h=0 and k=0) or l>=0)
|
|
351
|
+
* Conventionally, position 0 is set to the gamma point [0, 0, 0] *
|
|
352
|
+
Args:
|
|
353
|
+
n_grids: the number of grids at directions x, y, z.
|
|
354
|
+
device: the device on which the grid is to be generated.
|
|
355
|
+
|
|
356
|
+
Returns: (N_grids, 3), grids
|
|
357
|
+
|
|
358
|
+
"""
|
|
359
|
+
N = [abs(int(_)) + (_ + 1) % 2 for _ in n_grids] # to ensure an odd positive integer grid number.
|
|
360
|
+
|
|
361
|
+
# check the longest axis
|
|
362
|
+
cut_axis = max(range(3), key=lambda i: N[i])
|
|
363
|
+
perm = [cut_axis] + [i for i in range(3) if i != cut_axis]
|
|
364
|
+
N_h, N_k, N_l = (N[perm[0]], N[perm[1]], N[perm[2]])
|
|
365
|
+
|
|
366
|
+
# centered int indices [-Nh//2, ..., 0, ..., -Nh//2+Nh-1]
|
|
367
|
+
h_vals = th.arange(0, -(N_h // 2) + N_h, device=device, dtype=th.int64)
|
|
368
|
+
k_vals = th.arange(-(N_k // 2), -(N_k // 2) + N_k, device=device, dtype=th.int64)
|
|
369
|
+
l_vals = th.arange(-(N_l // 2), -(N_l // 2) + N_l, device=device, dtype=th.int64)
|
|
370
|
+
|
|
371
|
+
idx_parts = []
|
|
372
|
+
|
|
373
|
+
# ---------- 1) h > 0, k,l \in Z ----------
|
|
374
|
+
h_pos = h_vals[1:]
|
|
375
|
+
if h_pos.numel() > 0:
|
|
376
|
+
N_h_pos = h_pos.numel()
|
|
377
|
+
N_k_all, N_l_all = N_k, N_l
|
|
378
|
+
|
|
379
|
+
hh1 = h_pos.view(-1, 1, 1).expand(-1, N_k_all, N_l_all)
|
|
380
|
+
kk1 = k_vals.view(1, -1, 1).expand(N_h_pos, -1, N_l_all)
|
|
381
|
+
ll1 = l_vals.view(1, 1, -1).expand(N_h_pos, N_k_all, -1)
|
|
382
|
+
|
|
383
|
+
idx1 = th.empty((N_h_pos * N_k_all * N_l_all, 3), device=device, dtype=th.int64)
|
|
384
|
+
idx1[:, 0] = hh1.reshape(-1)
|
|
385
|
+
idx1[:, 1] = kk1.reshape(-1)
|
|
386
|
+
idx1[:, 2] = ll1.reshape(-1)
|
|
387
|
+
idx_parts.append(idx1)
|
|
388
|
+
|
|
389
|
+
# ---------- 2) h = 0, k > 0, l \in Z ----------
|
|
390
|
+
k_pos = k_vals[k_vals > 0]
|
|
391
|
+
if k_pos.numel() > 0:
|
|
392
|
+
N_k_pos = k_pos.numel()
|
|
393
|
+
N_l_all = N_l
|
|
394
|
+
|
|
395
|
+
hh2 = th.zeros((N_k_pos, N_l_all), device=device, dtype=th.int64)
|
|
396
|
+
kk2 = k_pos.view(-1, 1).expand(-1, N_l_all)
|
|
397
|
+
ll2 = l_vals.view(1, -1).expand(N_k_pos, -1)
|
|
398
|
+
|
|
399
|
+
idx2 = th.empty((N_k_pos * N_l_all, 3), device=device, dtype=th.int64)
|
|
400
|
+
idx2[:, 0] = hh2.reshape(-1)
|
|
401
|
+
idx2[:, 1] = kk2.reshape(-1)
|
|
402
|
+
idx2[:, 2] = ll2.reshape(-1)
|
|
403
|
+
idx_parts.append(idx2)
|
|
404
|
+
|
|
405
|
+
# ---------- 3) h = 0, k = 0, l > 0 ----------
|
|
406
|
+
l_pos = l_vals[l_vals > 0]
|
|
407
|
+
if l_pos.numel() > 0:
|
|
408
|
+
idx3 = th.empty((l_pos.numel(), 3), device=device, dtype=th.int64)
|
|
409
|
+
idx3[:, 0] = 0
|
|
410
|
+
idx3[:, 1] = 0
|
|
411
|
+
idx3[:, 2] = l_pos
|
|
412
|
+
idx_parts.append(idx3)
|
|
413
|
+
|
|
414
|
+
# all non-zero (h,k,l)
|
|
415
|
+
if len(idx_parts) > 0:
|
|
416
|
+
indices_pos = th.cat(idx_parts, dim=0) # (nG_half, 3)
|
|
417
|
+
else:
|
|
418
|
+
# only G=0
|
|
419
|
+
indices_pos = th.empty((0, 3), device=device, dtype=th.int64)
|
|
420
|
+
|
|
421
|
+
# re-permute to original order
|
|
422
|
+
n_pos = indices_pos.shape[0]
|
|
423
|
+
indices_orig = th.empty_like(indices_pos)
|
|
424
|
+
indices_orig[:, perm[0]] = indices_pos[:, 0]
|
|
425
|
+
indices_orig[:, perm[1]] = indices_pos[:, 1]
|
|
426
|
+
indices_orig[:, perm[2]] = indices_pos[:, 2]
|
|
427
|
+
# manually set the 1st element to [0,0,0]
|
|
428
|
+
G_indices = th.empty((n_pos + 1, 3), device=device, dtype=th.int64)
|
|
429
|
+
G_indices[0, :] = 0.0
|
|
430
|
+
G_indices[1:, :] = indices_orig
|
|
431
|
+
|
|
432
|
+
return G_indices
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
""" Setup logger for all modules """
|
|
2
|
+
# Copyright (c) 2026.3.26, BUCToolkit.
|
|
3
|
+
# Authors: Pu Pengxin, Song Xin
|
|
4
|
+
# Version: 0.9a
|
|
5
|
+
# File: setup_loggers.py
|
|
6
|
+
# Environment: Python 3.12
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import sys
|
|
10
|
+
import warnings
|
|
11
|
+
import os
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from BUCToolkit.BatchStructures.StructuresIO import structures_io_dumper
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def clear_all_handlers(logger: logging.Logger):
|
|
18
|
+
"""
|
|
19
|
+
Clear all handlers of this current logger and its all ancestors until one does not propagate.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
logger: the input logger instance. If it is not a logging.Logger, nothing is done.
|
|
23
|
+
Returns:
|
|
24
|
+
the logger instance
|
|
25
|
+
"""
|
|
26
|
+
current = logger
|
|
27
|
+
while current:
|
|
28
|
+
for _hdl in list(current.handlers):
|
|
29
|
+
current.removeHandler(_hdl)
|
|
30
|
+
try:
|
|
31
|
+
_hdl.close()
|
|
32
|
+
except Exception as ehdl:
|
|
33
|
+
warnings.warn(f'Failed to close handler {_hdl}: {ehdl}', RuntimeWarning)
|
|
34
|
+
# if propagate=False,stop checking
|
|
35
|
+
if not current.propagate:
|
|
36
|
+
break
|
|
37
|
+
current = current.parent
|
|
38
|
+
|
|
39
|
+
def has_any_handler(logger: logging.Logger) -> bool:
|
|
40
|
+
"""
|
|
41
|
+
Check whether the current logger and its all ancestor loggers have any handlers.
|
|
42
|
+
Args:
|
|
43
|
+
logger: the input logger instance. If it is not a logging.Logger, False is returned.
|
|
44
|
+
|
|
45
|
+
Returns: bool, the logger has any handlers.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
if not isinstance(logger, logging.Logger):
|
|
49
|
+
return False
|
|
50
|
+
has_handler = False
|
|
51
|
+
current = logger
|
|
52
|
+
while current:
|
|
53
|
+
if current.handlers:
|
|
54
|
+
has_handler = True
|
|
55
|
+
break
|
|
56
|
+
# if propagate=False,stop checking
|
|
57
|
+
if not current.propagate:
|
|
58
|
+
break
|
|
59
|
+
current = current.parent
|
|
60
|
+
|
|
61
|
+
return has_handler
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class BaseIO:
|
|
65
|
+
"""
|
|
66
|
+
Base class for logs of all classes.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def __init__(self, output_file: str|None = None) -> None:
|
|
70
|
+
self.logger = None
|
|
71
|
+
self.log_handler = None
|
|
72
|
+
self.output_file = str(output_file) if output_file is not None else None
|
|
73
|
+
self.dumper = structures_io_dumper(
|
|
74
|
+
path=self.output_file,
|
|
75
|
+
mode='x',
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def init_logger(self, logger_name: str):
|
|
79
|
+
# logging
|
|
80
|
+
if self.logger is None:
|
|
81
|
+
# cut off propagation
|
|
82
|
+
supreme_name = logger_name.split('.')[0]
|
|
83
|
+
top_logger = logging.getLogger(supreme_name)
|
|
84
|
+
top_logger.propagate = False
|
|
85
|
+
# set true logger
|
|
86
|
+
self.logger = logging.getLogger(logger_name)
|
|
87
|
+
self.logger.setLevel(logging.INFO)
|
|
88
|
+
formatter = logging.Formatter('%(message)s')
|
|
89
|
+
if not has_any_handler(self.logger):
|
|
90
|
+
self.log_handler = logging.StreamHandler(sys.stdout)
|
|
91
|
+
self.log_handler.setLevel(logging.INFO)
|
|
92
|
+
self.log_handler.setFormatter(formatter)
|
|
93
|
+
top_logger.addHandler(self.log_handler)
|
|
94
|
+
else:
|
|
95
|
+
warnings.warn('Logger has already initialized. Nothing will be done.', RuntimeWarning)
|
|
96
|
+
|
|
97
|
+
def reset_logger_handler(self, handler: str|logging.StreamHandler|logging.FileHandler):
|
|
98
|
+
"""
|
|
99
|
+
Clear all logging handlers including current logger and its ancestors, and reset one.
|
|
100
|
+
Args:
|
|
101
|
+
handler: the new handler.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
clear_all_handlers(self.logger)
|
|
107
|
+
# redirect to supreme logger
|
|
108
|
+
top_logger = self.logger
|
|
109
|
+
while top_logger.parent and top_logger.propagate:
|
|
110
|
+
top_logger = top_logger.parent
|
|
111
|
+
|
|
112
|
+
formatter = logging.Formatter('%(message)s')
|
|
113
|
+
if isinstance(handler, logging.Handler):
|
|
114
|
+
self.log_handler = handler
|
|
115
|
+
elif isinstance(handler, str):
|
|
116
|
+
output_path = os.path.dirname(handler)
|
|
117
|
+
# check whether path exists
|
|
118
|
+
if not os.path.isdir(output_path): os.makedirs(output_path)
|
|
119
|
+
# set log handler
|
|
120
|
+
self.log_handler = logging.FileHandler(handler, 'w', delay=True)
|
|
121
|
+
else:
|
|
122
|
+
raise TypeError("handler must be a string path or a logging.Handler instance")
|
|
123
|
+
|
|
124
|
+
self.log_handler.setLevel(logging.INFO)
|
|
125
|
+
self.log_handler.setFormatter(formatter)
|
|
126
|
+
top_logger.addHandler(self.log_handler)
|
|
127
|
+
|
|
128
|
+
def reset_dumper(self, dumper: Any) -> None:
|
|
129
|
+
if self.output_file is not None:
|
|
130
|
+
self.dumper.close()
|
|
131
|
+
del self.dumper
|
|
132
|
+
self.dumper = dumper
|
|
133
|
+
else:
|
|
134
|
+
self.logger.error(
|
|
135
|
+
"ERROR: No output file specified. Hence, resetting dumper is meaningless.\n"
|
|
136
|
+
"'reset_dumper': Operation REFUSED."
|
|
137
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BUCToolkit
|
|
3
|
+
Version: 1.0b0
|
|
4
|
+
Summary: Batch-upscaled Catalysis Toolkit (BUCToolkit), which can apply PyTorch-based deep-learning model to perform training, predictions, batched structure optimization, batched molecular dynamics with/without constraints, and batched Monte Carlo simulations. Various tools for handling catalyst structure files are also included.
|
|
5
|
+
Home-page: https://github.com/TrinitroCat/BUCToolkit
|
|
6
|
+
Author: Pu Pengxin, Song xin
|
|
7
|
+
Author-email:
|
|
8
|
+
License: MIT
|
|
9
|
+
Requires-Python: >= 3.11
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: joblib>=1.4.2
|
|
12
|
+
Requires-Dist: numpy>=1.26.4
|
|
13
|
+
Requires-Dist: PyYAML>=6.0.1
|
|
14
|
+
Requires-Dist: torch>=2.4.1
|
|
15
|
+
Provides-Extra: dgl
|
|
16
|
+
Requires-Dist: dgl; extra == "dgl"
|
|
17
|
+
Provides-Extra: pyg
|
|
18
|
+
Requires-Dist: torch_geometric>=2.6.1; extra == "pyg"
|
|
19
|
+
Provides-Extra: prompt-toolkit
|
|
20
|
+
Requires-Dist: prompt-toolkit>=3.0.43; extra == "prompt-toolkit"
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: home-page
|
|
23
|
+
Dynamic: license
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
Dynamic: provides-extra
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: requires-python
|
|
28
|
+
Dynamic: summary
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
BUCToolkit/StandardTemplate.py,sha256=kk0-8lELWLeXbBeSPoqgUzhSTG3GetDTjjjWae8s18A,14028
|
|
2
|
+
BUCToolkit/__init__.py,sha256=TJoGfkDSSLhT82miEG7lZmjeDDIdluu4XzJVquJmz-0,969
|
|
3
|
+
BUCToolkit/_version.py,sha256=4CEfQ0nGY9ug2lulGd9iwNCj3y4F3T8spLR6bilyNAY,159
|
|
4
|
+
BUCToolkit/io.py,sha256=rlQpRBX5NmyYyETioOzqa2fEnil_EA_EZqbjReddzH4,810
|
|
5
|
+
BUCToolkit/BatchGenerate/CheckStructures.py,sha256=kvjWipwJ33owshUUKmW0lKXTolsiyh9vARs4Epm_trE,8427
|
|
6
|
+
BUCToolkit/BatchGenerate/__init__.py,sha256=jSXI-67YFF7iu545d6IbC1agnYIJeCQ6sEarL7-sxfo,144
|
|
7
|
+
BUCToolkit/BatchGenerate/coords_interp.py,sha256=fQHsQfJEd4J73sscp3LiddgcmbhvgrXWtu4Nz66r4Mw,5183
|
|
8
|
+
BUCToolkit/BatchGenerate/initial_ads_structures.py,sha256=QYdt3O0oU6bfZE1yombqq2NALt-4wEV_aGPtM_QbN_0,14415
|
|
9
|
+
BUCToolkit/BatchGenerate/random_replace.py,sha256=5_oeVLrdbkm_vXWs1HTPNrNxkcLx5357eLy-XUY6v1c,3497
|
|
10
|
+
BUCToolkit/BatchMC/MetropolisMC.py,sha256=B48hKYNYCucSGwJhBexFdl9Wu8RT2Gsrr7Pj-6bw-30,8170
|
|
11
|
+
BUCToolkit/BatchMC/_BaseMC.py,sha256=-9izjbTi30hWEQ4aLGcAIa5AuBmwlnG2lxsBTr-6WqM,38495
|
|
12
|
+
BUCToolkit/BatchMC/__init__.py,sha256=MN9NTbJz-K7lT6xpRJ1W583kxiwFRz7iLUzbC0ti4RA,187
|
|
13
|
+
BUCToolkit/BatchMD/BiasedMD.py,sha256=-9i3XN9CEFyUZa6JNl9mxVj2bVb-_PJ6eO6GBTPwkUU,10050
|
|
14
|
+
BUCToolkit/BatchMD/NVE.py,sha256=tjZrLFOmKUhkDFYmUaCqP0qYyy8kTbdAscHCK8QvR_8,3445
|
|
15
|
+
BUCToolkit/BatchMD/NVT.py,sha256=49uETm96AA1b4T_JymBMJmK4qoSTgXbikX69AY8dAts,21166
|
|
16
|
+
BUCToolkit/BatchMD/_BaseMD.py,sha256=ZOzePJmbC484XsBxTPCSuqzxIE-sGy9dYKqucng3YRU,56911
|
|
17
|
+
BUCToolkit/BatchMD/__init__.py,sha256=iVpmxNuIbd-tBYZe13DtjYTIevOy_Q0nDI817eXVjO4,377
|
|
18
|
+
BUCToolkit/BatchMD/constrained_md/BiasedMD.py,sha256=qgktB1Z_a7AEjQtPJn1GGeB9hDzsZe08UtHqr4FbatM,9955
|
|
19
|
+
BUCToolkit/BatchMD/constrained_md/ConstrNVE.py,sha256=szKte1SPFUZBZRmvlFlHFclEQRlhAhTbowOliag_eoY,6964
|
|
20
|
+
BUCToolkit/BatchMD/constrained_md/ConstrNVT.py,sha256=MV6B9gy3ai3Hbrs0qvP9ZgGxXUwOFEAdElwXx6aBAWA,19494
|
|
21
|
+
BUCToolkit/BatchMD/constrained_md/NVE.py,sha256=o6QBhAAVx-3wOUI5dOmQz2kKnhAQhwxM9UuqAfnmAQ8,3087
|
|
22
|
+
BUCToolkit/BatchMD/constrained_md/NVT.py,sha256=9n6VEy4mjHNMLrKLvaJiqIfx5xAC-8MSRRHC-_4qN34,15160
|
|
23
|
+
BUCToolkit/BatchMD/constrained_md/_BaseMD.py,sha256=Ibu5YbPRgEcNKBKYfKN9icblNrI_m8eie1wk0xiEX1A,20665
|
|
24
|
+
BUCToolkit/BatchMD/constrained_md/_ConstrBaseMD.py,sha256=mlLsrezk4u8ImgzTCF1EeX-Pq-b5586MyaGhKGcMf-c,27592
|
|
25
|
+
BUCToolkit/BatchMD/constrained_md/__init__.py,sha256=--wBxaTL2jeFodU2WVFfYD7P2XQOYJtTxmV93CTi1O4,402
|
|
26
|
+
BUCToolkit/BatchOptim/_BaseOpt.py,sha256=saO1uicOX5cHrV1m5-6m5xb8vjnmEhifLjaeT59tFbY,34694
|
|
27
|
+
BUCToolkit/BatchOptim/__init__.py,sha256=CCSaaM3yYx2TP0QnOlQT4fubtV9Zb0Vbcskgxk1eupQ,529
|
|
28
|
+
BUCToolkit/BatchOptim/frequency.py,sha256=dzgD2-bt4vUKY8fTn1yiSXyZNsifm2Hp9JtHLFlWqAY,19376
|
|
29
|
+
BUCToolkit/BatchOptim/TS/CI_NEB.py,sha256=xIpVZBX0VmrvTCyzHVAFOX2DuLCpjU5Yo68duvRemUo,11994
|
|
30
|
+
BUCToolkit/BatchOptim/TS/Dimer.py,sha256=c_eSXVJaD6enWpfZyEPLe0w85XZ3mFnUidujr8OEAGU,42754
|
|
31
|
+
BUCToolkit/BatchOptim/TS/__init__.py,sha256=JgrkjZOnd30e8cunMAQYWKIygY0PWUeUMwfn8HF-8tQ,195
|
|
32
|
+
BUCToolkit/BatchOptim/_utils/__init__.py,sha256=jSXI-67YFF7iu545d6IbC1agnYIJeCQ6sEarL7-sxfo,144
|
|
33
|
+
BUCToolkit/BatchOptim/_utils/_line_search.py,sha256=dMvsU7UmxYY5HfbGqbxJOhFx2zWOqiT4u-lgXhc46Ro,39295
|
|
34
|
+
BUCToolkit/BatchOptim/_utils/_warnings.py,sha256=1Z-y3LbElwFF1mEQ75R8RWDQz5lTBlug_eDf7jzvzuc,261
|
|
35
|
+
BUCToolkit/BatchOptim/minimize/CG.py,sha256=-70KyQroR6rHujNrigWujNbKW5Jq_i13M-lmxjF8Mc0,8876
|
|
36
|
+
BUCToolkit/BatchOptim/minimize/FIRE.py,sha256=l8jyhP58G0Q5G1XHtRuphKtsVx9X9zIQuBI_r4h8Yvs,13070
|
|
37
|
+
BUCToolkit/BatchOptim/minimize/QN.py,sha256=GkmIU7Wvs_zjS4n24ISamjSXq3uIx_WP48TosazB6NQ,8309
|
|
38
|
+
BUCToolkit/BatchOptim/minimize/__init__.py,sha256=39lqioP-wQpBkpOZV0ZckyvwGzZ3C-jIkbYwAYZgcBM,325
|
|
39
|
+
BUCToolkit/BatchStructures/BatchStructuresBase.py,sha256=iN6bJzgYY64ShL4H4ou8V6capvUJ19phvqQUJF8kwuA,105716
|
|
40
|
+
BUCToolkit/BatchStructures/StructuresIO.py,sha256=JLCntgMC6te_g76caJBAGZzueoB0wXJxayck_r9E7hY,58804
|
|
41
|
+
BUCToolkit/BatchStructures/__init__.py,sha256=cBRJ7r7n2oqp6T91bGt9PkuMgX6L1QNUmsUaHN-Jqjs,397
|
|
42
|
+
BUCToolkit/Preprocessing/__init__.py,sha256=_8paUhW8u-B1PwNXyM5eniBu2KamjYTDHWK_MNmopcc,145
|
|
43
|
+
BUCToolkit/Preprocessing/load_files.py,sha256=kqPxa9Q4nLugNkymQ2HNmN0-iirOShZydC-jus2IzmI,77101
|
|
44
|
+
BUCToolkit/Preprocessing/preprocessing.py,sha256=wsB9ehxIGgKVn0NFgfQOSc3_ldS3b0tiia4vBXP3kJw,39534
|
|
45
|
+
BUCToolkit/Preprocessing/sampling.py,sha256=2eEAYJP2j_Yf5YVLWJ8H0LlDsyxsPbodfsvt-x5SnPs,11836
|
|
46
|
+
BUCToolkit/Preprocessing/supercells.py,sha256=86cfN9VLBM6AgAq_r8nlfuujs2rR_fN2JcbQdlt32_o,6006
|
|
47
|
+
BUCToolkit/Preprocessing/write_files.py,sha256=7XduHCBFGe6KuDo9WPNE2fWaREumemqWd9QWkeKlKFo,23012
|
|
48
|
+
BUCToolkit/api/ConstrainedMolecularDynamics.py,sha256=IW7N6tI30U_Xj7MkpilqIJwCN74xCDnGjxcoHWAaN4o,16618
|
|
49
|
+
BUCToolkit/api/DataLoaders.py,sha256=dLkdgih8RLVMJ0kpYbk-KZWJm6718Ux3_i-FcglYh_M,13057
|
|
50
|
+
BUCToolkit/api/Losses.py,sha256=qoofPFwe_lpc1hLaDbpAlX-v8x2r94g6azJGsq6lv3Y,5813
|
|
51
|
+
BUCToolkit/api/Metrics.py,sha256=NStR94teQfWQNPEbEwD43Ov91Uj55V2OL_MKIdkxGw0,2565
|
|
52
|
+
BUCToolkit/api/ModelOptims.py,sha256=4U1fYIm8LkjY6ti6kdRTnqhQ-M7_4EO6HU6jUG1NPQw,12442
|
|
53
|
+
BUCToolkit/api/MolecularDynamics.py,sha256=NN-h9UTJyShW3nvDjfCldQqOTRl185G-MT-MLe2PmE4,12787
|
|
54
|
+
BUCToolkit/api/MonteCarlo.py,sha256=CgnpNwLCwWQ_vp3h1cjj8CABTKnW_zm81B1cZOseRYM,12805
|
|
55
|
+
BUCToolkit/api/NEB.py,sha256=PHl0qbJl_iKKO5q2MqAaH1e_H3yd7WwdnisSKjqKGiE,15325
|
|
56
|
+
BUCToolkit/api/Predictor.py,sha256=skEoPLnGPOeDREBYjRzNy9ZLZQUVtGUuydJT6p5z9Fw,11836
|
|
57
|
+
BUCToolkit/api/StructureOptimization.py,sha256=kcxcJrHbuIF068oKxvRKfoCtxP0ZoslUK8_f497ZTYk,25131
|
|
58
|
+
BUCToolkit/api/Trainer.py,sha256=dxWUnGEZ-imdJTw0hV6ATASbU5q3T_F7pDaHVZEigBE,35442
|
|
59
|
+
BUCToolkit/api/VibrationAnalysis.py,sha256=o2t_TEyQB4CmPNFvSWMzniKE1NIUQDx-z_jrLQITtPs,13438
|
|
60
|
+
BUCToolkit/api/__init__.py,sha256=IE9cVu0Qf4sN1wckSoRo2JbxBPTXY8xQv3eHFwTIbiY,1006
|
|
61
|
+
BUCToolkit/api/_io.py,sha256=FMwaAh5ObYE9PlpTSP1f1UtiW9GLifg0g74PCCs4uJA,41158
|
|
62
|
+
BUCToolkit/cli/__init__.py,sha256=sy9uD5-x74DG21f7EEzWjJbWxN8vcqCIZ6WYF_a7nFU,425
|
|
63
|
+
BUCToolkit/cli/cli.py,sha256=9azg2EJKeKCmTTaU61iDXSfJgZjFz7I874SEm28s-OI,40523
|
|
64
|
+
BUCToolkit/cli/input_stub.py,sha256=p8PJFKfyvyB0r9jXkWLim3x0Y1noUyA5TFJQeEM9qic,9333
|
|
65
|
+
BUCToolkit/cli/main.py,sha256=xP3OKaxwfw76n2V_AWXwb4Y8TTPDrJqOTsHJOGjvTig,13948
|
|
66
|
+
BUCToolkit/cli/print_logo.py,sha256=TmMfeRtvIRDqrUQcxZe1FMpUlExKfUfsR6VhDqM982Q,4046
|
|
67
|
+
BUCToolkit/cli/template_model.py,sha256=x8PwATqv1VkeTwzOa5HYowJMLIx142t0GVZeBN07Axw,207
|
|
68
|
+
BUCToolkit/utils/AtomSelector.py,sha256=O8aLqCHy3tKNXsjSOYM9noIw0fAakug8LnrYL_KGxmc,2422
|
|
69
|
+
BUCToolkit/utils/AtomicNumber2Properties.py,sha256=T3LqXfw8TMdnqFu-9rgL1_4x5HsSeutgTq_pLkxzwI0,1031
|
|
70
|
+
BUCToolkit/utils/ElemListReduce.py,sha256=m3ZyulRtLRjMyb5RHrUUFT7_gVfqpun63Smq1EJXU4c,1715
|
|
71
|
+
BUCToolkit/utils/Ewald.py,sha256=DAWBJprknpCdOSZ-g72DwxXrGCER5Y3huilbusrzT88,9371
|
|
72
|
+
BUCToolkit/utils/IrregularTensorReformat.py,sha256=sgQAPI98NeGNVajojD1BWDQnYDQGtd9YrVDzEQWtDiI,1989
|
|
73
|
+
BUCToolkit/utils/_CheckModules.py,sha256=5i-GiY9qFmVvPl1QzDTMBVP-NvzZM7Ivlq3ll1ea_cI,968
|
|
74
|
+
BUCToolkit/utils/_Element_info.py,sha256=7bLGi7EA0Hn1OTz1iV_ZFTasOuebbgbFEuVhQsMtU4E,8086
|
|
75
|
+
BUCToolkit/utils/__init__.py,sha256=39qYNYXTbkva4oGb5vsCI6Squ-WX9o0NitJzrhdFXD0,741
|
|
76
|
+
BUCToolkit/utils/_para_flatt_list.py,sha256=vyQaqd1ghbo1oAW2Cq1Nuv5ceUYYiwaPbukeBBDLqSk,3503
|
|
77
|
+
BUCToolkit/utils/_print_formatter.py,sha256=dxG-yhyQPnpl6xa2OmniBXKfbYn5lci589YZYhGy6Bo,1507
|
|
78
|
+
BUCToolkit/utils/check_structures.py,sha256=0h4MpQsbANdRR2whLyk1GNi1KDoef_tisHWBxbU0UDk,9242
|
|
79
|
+
BUCToolkit/utils/function_utils.py,sha256=u8f5S8_odS0UPKCQK_4pniaY0lyenQFpYC6UrQTShFA,4530
|
|
80
|
+
BUCToolkit/utils/grad_functions.py,sha256=TAuaT6tIkjiS412_jknLiR9wb9uWSKl_FCKKs_hhmuw,2302
|
|
81
|
+
BUCToolkit/utils/index_ops.py,sha256=BlYo9UdN9GjLsEflI5KYqwmEjrkpl3MNWpLFLZuVn9Y,16292
|
|
82
|
+
BUCToolkit/utils/setup_loggers.py,sha256=F0Y-vPBFNw3ShHbeX0wb2Cmy-TcSfghBNutfOVwy_54,4579
|
|
83
|
+
buctoolkit-1.0b0.dist-info/licenses/LICENSE,sha256=Fy5D7kAV4b5O6_mK1bBg6dIvljsl1k5gHhRldMxKIRw,1082
|
|
84
|
+
buctoolkit-1.0b0.dist-info/METADATA,sha256=QzsUkmLqzfpVbbmDZZWdn4LbrcilTADSv4oJWScESK4,1047
|
|
85
|
+
buctoolkit-1.0b0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
86
|
+
buctoolkit-1.0b0.dist-info/entry_points.txt,sha256=PAZckBYiDWzv10IyRazgc957czw2Ww0SgDO9z__mN0Q,154
|
|
87
|
+
buctoolkit-1.0b0.dist-info/top_level.txt,sha256=dL0flE_C5sul1HwYQO_iR7mH9TlH5UgH9mGL9ns_yas,11
|
|
88
|
+
buctoolkit-1.0b0.dist-info/RECORD,,
|