MultiOptPy 1.20.6__py3-none-any.whl → 1.20.8__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.
@@ -1,8 +1,15 @@
1
-
2
1
  from multioptpy.Parameters.parameter import UnitValueLib
3
2
  import torch
4
-
3
+
5
4
  class StructKeepPotential:
5
+ """
6
+ Class for calculating harmonic distance potential between two atoms.
7
+
8
+ Robustness Improvements:
9
+ - Uses robust norm calculation (sqrt(sum^2 + eps)) to avoid NaN gradients
10
+ if atoms perfectly overlap (r=0).
11
+ - Automatically adapts to the device and dtype of the input geometry.
12
+ """
6
13
  def __init__(self, **kwarg):
7
14
  self.config = kwarg
8
15
  UVL = UnitValueLib()
@@ -19,14 +26,48 @@ class StructKeepPotential:
19
26
  bias_pot_params[0] : keep_pot_spring_const
20
27
  bias_pot_params[1] : keep_pot_distance
21
28
  """
22
- vector = torch.linalg.norm((geom_num_list[self.config["keep_pot_atom_pairs"][0]-1] - geom_num_list[self.config["keep_pot_atom_pairs"][1]-1]), ord=2)
29
+ # 1. Parameter Retrieval & Device/Dtype handling
30
+ device = geom_num_list.device if isinstance(geom_num_list, torch.Tensor) else torch.device("cpu")
31
+ dtype = geom_num_list.dtype
32
+
23
33
  if len(bias_pot_params) == 0:
24
- energy = 0.5 * self.config["keep_pot_spring_const"] * (vector - self.config["keep_pot_distance"]/self.bohr2angstroms) ** 2
34
+ k = self.config["keep_pot_spring_const"]
35
+ r0_ang = self.config["keep_pot_distance"]
25
36
  else:
26
- energy = 0.5 * bias_pot_params[0] * (vector - bias_pot_params[1]/self.bohr2angstroms) ** 2
27
- return energy #hartree
28
-
37
+ k = bias_pot_params[0]
38
+ r0_ang = bias_pot_params[1]
39
+
40
+ # Convert r0 to Bohr (assuming parameter is in Angstroms) and ensure tensor
41
+ if not isinstance(r0_ang, torch.Tensor):
42
+ r0_ang = torch.tensor(r0_ang, device=device, dtype=dtype)
43
+ r0 = r0_ang / self.bohr2angstroms
44
+
45
+ # 2. Vector Calculation
46
+ # Indices are 1-based in config
47
+ idx1 = self.config["keep_pot_atom_pairs"][0] - 1
48
+ idx2 = self.config["keep_pot_atom_pairs"][1] - 1
49
+
50
+ vec = geom_num_list[idx1] - geom_num_list[idx2]
51
+
52
+ # 3. Robust Distance Calculation
53
+
54
+ dist = torch.clamp(torch.sqrt(torch.sum(vec**2)), min=1e-12)
55
+
56
+ # 4. Energy Calculation
57
+ # E = 0.5 * k * (r - r0)^2
58
+ energy = 0.5 * k * (dist - r0) ** 2
59
+
60
+ return energy # hartree
61
+
62
+
29
63
  class StructKeepPotentialv2:
64
+ """
65
+ Class for calculating harmonic distance potential between two fragment centers.
66
+
67
+ Robustness Improvements:
68
+ - Uses robust norm calculation.
69
+ - vectorized center of mass calculation.
70
+ """
30
71
  def __init__(self, **kwarg):
31
72
  self.config = kwarg
32
73
  UVL = UnitValueLib()
@@ -34,31 +75,55 @@ class StructKeepPotentialv2:
34
75
  self.bohr2angstroms = UVL.bohr2angstroms
35
76
  self.hartree2kjmol = UVL.hartree2kjmol
36
77
  return
78
+
37
79
  def calc_energy(self, geom_num_list, bias_pot_params=[]):
38
80
  """
39
81
  # required variables: self.config["keep_pot_v2_spring_const"],
40
82
  self.config["keep_pot_v2_distance"],
41
83
  self.config["keep_pot_v2_fragm1"],
42
84
  self.config["keep_pot_v2_fragm2"],
43
- bias_pot_params[0] : keep_pot_v2_spring_const
44
- bias_pot_params[1] : keep_pot_v2_distance
45
85
  """
46
- fragm_1_indices = torch.tensor(self.config["keep_pot_v2_fragm1"]) - 1
47
- fragm_2_indices = torch.tensor(self.config["keep_pot_v2_fragm2"]) - 1
86
+ device = geom_num_list.device if isinstance(geom_num_list, torch.Tensor) else torch.device("cpu")
87
+ dtype = geom_num_list.dtype
48
88
 
49
- fragm_1_center = torch.mean(geom_num_list[fragm_1_indices], dim=0)
50
- fragm_2_center = torch.mean(geom_num_list[fragm_2_indices], dim=0)
51
-
52
- distance = torch.linalg.norm(fragm_1_center - fragm_2_center, ord=2)
89
+ # 1. Parameter Retrieval
53
90
  if len(bias_pot_params) == 0:
54
- energy = 0.5 * self.config["keep_pot_v2_spring_const"] * (distance - self.config["keep_pot_v2_distance"]/self.bohr2angstroms) ** 2
55
-
91
+ k = self.config["keep_pot_v2_spring_const"]
92
+ r0_ang = self.config["keep_pot_v2_distance"]
56
93
  else:
57
- energy = 0.5 * bias_pot_params[0] * (distance - bias_pot_params[1]/self.bohr2angstroms) ** 2
94
+ k = bias_pot_params[0]
95
+ r0_ang = bias_pot_params[1]
96
+
97
+ if not isinstance(r0_ang, torch.Tensor):
98
+ r0_ang = torch.tensor(r0_ang, device=device, dtype=dtype)
99
+ r0 = r0_ang / self.bohr2angstroms
100
+
101
+ # 2. Center Calculation (Vectorized)
102
+ # Convert indices lists to tensors for efficient indexing
103
+ idx1 = torch.tensor(self.config["keep_pot_v2_fragm1"], device=device, dtype=torch.long) - 1
104
+ idx2 = torch.tensor(self.config["keep_pot_v2_fragm2"], device=device, dtype=torch.long) - 1
105
+
106
+ fragm_1_center = torch.mean(geom_num_list[idx1], dim=0)
107
+ fragm_2_center = torch.mean(geom_num_list[idx2], dim=0)
58
108
 
59
- return energy #hartree
60
-
109
+ # 3. Robust Distance Calculation
110
+ vec = fragm_1_center - fragm_2_center
111
+ distance = torch.clamp(torch.sqrt(torch.sum(vec**2)), min=1e-12)
112
+
113
+ # 4. Energy
114
+ energy = 0.5 * k * (distance - r0) ** 2
115
+
116
+ return energy # hartree
117
+
118
+
61
119
  class StructKeepPotentialAniso:
120
+ """
121
+ Class for calculating anisotropic distance potential between fragment centers.
122
+
123
+ Robustness Improvements:
124
+ - Vectorized centroid calculation (replaced inefficient loops).
125
+ - Device/Dtype safety for matrix operations.
126
+ """
62
127
  def __init__(self, **kwarg):
63
128
  self.config = kwarg
64
129
  UVL = UnitValueLib()
@@ -66,34 +131,48 @@ class StructKeepPotentialAniso:
66
131
  self.bohr2angstroms = UVL.bohr2angstroms
67
132
  self.hartree2kjmol = UVL.hartree2kjmol
68
133
  return
134
+
69
135
  def calc_energy(self, geom_num_list, bias_pot_params=[]):
70
136
  """
71
137
  # required variables: self.config["aniso_keep_pot_v2_spring_const_mat"]
72
138
  self.config["aniso_keep_pot_v2_dist"]
73
139
  self.config["aniso_keep_pot_v2_fragm1"]
74
140
  self.config["aniso_keep_pot_v2_fragm2"]
75
-
76
141
  """
77
- fragm_1_center = torch.tensor([0.0, 0.0, 0.0], dtype=torch.float64, requires_grad=True)
78
- for i in self.config["aniso_keep_pot_v2_fragm1"]:
79
- fragm_1_center = fragm_1_center + geom_num_list[i-1]
142
+ device = geom_num_list.device if isinstance(geom_num_list, torch.Tensor) else torch.device("cpu")
143
+ dtype = geom_num_list.dtype
144
+
145
+ # 1. Centroid Calculation (Vectorized)
146
+ idx1 = torch.tensor(self.config["aniso_keep_pot_v2_fragm1"], device=device, dtype=torch.long) - 1
147
+ idx2 = torch.tensor(self.config["aniso_keep_pot_v2_fragm2"], device=device, dtype=torch.long) - 1
80
148
 
81
- fragm_1_center = fragm_1_center / len(self.config["aniso_keep_pot_v2_fragm1"])
149
+ fragm_1_center = torch.mean(geom_num_list[idx1], dim=0)
150
+ fragm_2_center = torch.mean(geom_num_list[idx2], dim=0)
82
151
 
83
- fragm_2_center = torch.tensor([0.0, 0.0, 0.0], dtype=torch.float64, requires_grad=True)
84
- for i in self.config["aniso_keep_pot_v2_fragm2"]:
85
- fragm_2_center = fragm_2_center + geom_num_list[i-1]
152
+ # 2. Anisotropic Distance Components
153
+ # Distance diff vector: |x1-x2|, |y1-y2|, |z1-z2|
154
+ # Note: Derivative of abs(x) at 0 is 0 in PyTorch subgradient, usually safe enough here.
155
+ xyz_dist = torch.abs(fragm_1_center - fragm_2_center)
86
156
 
87
- fragm_2_center = fragm_2_center / len(self.config["aniso_keep_pot_v2_fragm2"])
88
- x_dist = torch.abs(fragm_1_center[0] - fragm_2_center[0])
89
- y_dist = torch.abs(fragm_1_center[1] - fragm_2_center[1])
90
- z_dist = torch.abs(fragm_1_center[2] - fragm_2_center[2])
91
- eq_dist = self.config["aniso_keep_pot_v2_dist"] / (3 ** 0.5) / self.bohr2angstroms
92
- dist_vec = torch.stack([(x_dist - eq_dist) ** 2,(y_dist - eq_dist) ** 2,(z_dist - eq_dist) ** 2])
93
- dist_vec = torch.reshape(dist_vec, (3, 1))
94
- vec_pot = torch.matmul(torch.tensor(self.config["aniso_keep_pot_v2_spring_const_mat"], dtype=torch.float32), dist_vec)
157
+ # Equilibrium distance logic (from original code)
158
+ # Original: eq_dist = dist / sqrt(3)
159
+ # This implies the target distance is distributed equally among x,y,z components?
160
+ ref_dist_val = self.config["aniso_keep_pot_v2_dist"]
161
+ if not isinstance(ref_dist_val, torch.Tensor):
162
+ ref_dist_val = torch.tensor(ref_dist_val, device=device, dtype=dtype)
163
+
164
+ eq_dist_component = (ref_dist_val / (3 ** 0.5)) / self.bohr2angstroms
95
165
 
96
- energy = torch.sum(vec_pot)
166
+ # Squared deviation vector: [(dx - d0)^2, (dy - d0)^2, (dz - d0)^2]
167
+ dist_vec = (xyz_dist - eq_dist_component) ** 2
168
+ dist_vec = dist_vec.unsqueeze(1) # Shape (3, 1)
169
+
170
+ # 3. Matrix Multiplication
171
+ # Ensure spring constant matrix matches device/dtype
172
+ spring_mat = torch.tensor(self.config["aniso_keep_pot_v2_spring_const_mat"], device=device, dtype=dtype)
97
173
 
174
+ vec_pot = torch.matmul(spring_mat, dist_vec)
175
+
176
+ energy = torch.sum(vec_pot)
98
177
 
99
- return energy #hartree
178
+ return energy # hartree
@@ -1,21 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MultiOptPy
3
- Version: 1.20.6
3
+ Version: 1.20.8
4
4
  Summary: Multifunctional geometry optimization tools for quantum chemical calculations.
5
5
  Author-email: ss0832 <highlighty876@gmail.com>
6
6
  License-Expression: GPL-3.0-or-later
7
7
  Requires-Python: >=3.12
8
8
  Description-Content-Type: text/markdown
9
9
  License-File: LICENSE
10
- Requires-Dist: numpy>=2.2.0
11
- Requires-Dist: scipy>=1.13.0
12
- Requires-Dist: matplotlib>=3.10.0
10
+ Requires-Dist: numpy~=2.2.0
11
+ Requires-Dist: scipy~=1.13.0
12
+ Requires-Dist: matplotlib~=3.10.0
13
13
  Requires-Dist: torch~=2.6.0
14
- Requires-Dist: pyscf>=2.9.0
15
- Requires-Dist: tblite>=0.4.0
14
+ Requires-Dist: pyscf~=2.9.0
15
+ Requires-Dist: tblite~=0.4.0
16
16
  Requires-Dist: ase~=3.26.0
17
17
  Requires-Dist: fairchem-core~=2.7.0
18
- Requires-Dist: sympy>=1.13.0
18
+ Requires-Dist: sympy~=1.13.0
19
19
  Dynamic: license-file
20
20
 
21
21
  # MultiOptPy
@@ -75,10 +75,11 @@ multioptpy/ModelFunction/opt_mesx.py,sha256=IiUzigFlZqn3ZDjbx4mHTaUEJqUEjXFmsG1l
75
75
  multioptpy/ModelFunction/opt_mesx_2.py,sha256=J1lr7LxcgVeAfR0WkvJg4Nt5VTaYPC2ITbP2RL7CwwQ,2530
76
76
  multioptpy/ModelFunction/seam_model_function.py,sha256=epOjUcrFpwqLXUYedJeVE5BDl1b0_2vgIFUepL_JjkI,1136
77
77
  multioptpy/ModelHessian/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- multioptpy/ModelHessian/approx_hessian.py,sha256=efF8FA7lqBuw8h4DmkfU7T78yZiS5tQ_FhMm0CAseYE,6717
78
+ multioptpy/ModelHessian/approx_hessian.py,sha256=0_fE9-HOCL9l2lV3aAXusOPaYVil0wWWFDPNA9mR23c,6982
79
79
  multioptpy/ModelHessian/calc_params.py,sha256=aWkXqqyYpg5_qemflM2oIkFA8g-h3wTiE_C_a5dkLxc,7645
80
80
  multioptpy/ModelHessian/fischer.py,sha256=pdXmOMGF4Ie8cA3qN-KuyhJl_cuetvmpoI9t0fE3tNE,11011
81
81
  multioptpy/ModelHessian/fischerd3.py,sha256=QWS-vWkHEzPLiMl8bAhd5A9BV1fKj8ym7GVVdZ8fg5M,13450
82
+ multioptpy/ModelHessian/fischerd3old.py,sha256=55JNPGCKZkk5zu3jLxn7hDDOk1_ldOxWCW_Se8i1WUc,17041
82
83
  multioptpy/ModelHessian/fischerd4.py,sha256=GuSwCjzMV8g6BHvX0DJjHr_8AfjVdrfNn5DO_BEdDj4,17070
83
84
  multioptpy/ModelHessian/gfn0xtb.py,sha256=xUipDBP_o9Y9bJ74RehCY06kroueStc0MsSm1llg638,27051
84
85
  multioptpy/ModelHessian/gfnff.py,sha256=INsTLJ2c7wEqk0mxn_lURsQ2JsT8dM6JClR2etEein8,31162
@@ -197,10 +198,10 @@ multioptpy/Potential/electrostatic_potential.py,sha256=13dPbQZnDB_-utsZ2pnMImof9
197
198
  multioptpy/Potential/flux_potential.py,sha256=RAZobWEHjRa_S1zSH_RberX5zdZjYspR7rF4uQ7HdXI,1221
198
199
  multioptpy/Potential/gaussian_potential.py,sha256=mvuALiAOvtXt5dGGuZq1gJGBhhtkuDNJWyMUW5M5gPY,5636
199
200
  multioptpy/Potential/idpp.py,sha256=RlSpElPJ2kyHJRHNsY5zgILaES3d4xAO_50rz0yBE0Q,21690
200
- multioptpy/Potential/keep_angle_potential.py,sha256=-8P3ZFtzR1axa-j1QHf4MNTZGfrshQqhWzIUShTotho,8791
201
- multioptpy/Potential/keep_dihedral_angle_potential.py,sha256=HUZL2A8e9zoXDvZDn7rXZZ2K-3VwtZa7s6-dE79CsZA,5951
202
- multioptpy/Potential/keep_outofplain_angle_potential.py,sha256=CX6R2R_8HcQiq2lONb42yclw5dWGmM3fmQQ45ZQnMAI,3870
203
- multioptpy/Potential/keep_potential.py,sha256=osK1VI43jHkpTjXslZ8nubeME5LcWTGIbbf91bTTlEw,4827
201
+ multioptpy/Potential/keep_angle_potential.py,sha256=3R2DJkRU88QSxuBCxpiIhI9dN-WYt_lTh1mjldZR3Z0,26229
202
+ multioptpy/Potential/keep_dihedral_angle_potential.py,sha256=vjdPP79eokXS4n7l3x46BCivcqCgGdxI5eBHV1u4mVA,13244
203
+ multioptpy/Potential/keep_outofplain_angle_potential.py,sha256=P1YABikwxwx6v72aaw3s9XwiN2gCYK_sePFnrp7AtHw,12057
204
+ multioptpy/Potential/keep_potential.py,sha256=KHqEA08mk5d1UylhJgYLFOHUQnLh_Z8XPip7nGk8YHM,7413
204
205
  multioptpy/Potential/mechano_force_potential.py,sha256=wf18Zl_ogffBD53z3G6u4c4KD3RXmbUkVDQTu6Ny4oY,3394
205
206
  multioptpy/Potential/nanoreactor_potential.py,sha256=UIN0dmgyM67TKcCew42rWBWd_cs1XQjxR4WN5gP3K3w,3133
206
207
  multioptpy/Potential/potential.py,sha256=WVKrXoWfawsR-gLvDEQvzgzettw6Q5Lz8_344c6b4Hs,52771
@@ -243,9 +244,9 @@ multioptpy/Wrapper/ieip_wrapper.py,sha256=H0Fa7x5mzyFu5rnig7GdcZGX9LFclzRxDuREX5
243
244
  multioptpy/Wrapper/md_wrapper.py,sha256=EGQKY8BwBbjWkXxKQGlelzht872OsUp9GmyxPDgWav4,3050
244
245
  multioptpy/Wrapper/neb_wrapper.py,sha256=ZOyHhuSDKA5hABnQB7PYPfbQ9OyaAj9KKBeKu_HLiY4,3254
245
246
  multioptpy/Wrapper/optimize_wrapper.py,sha256=b5DoiSb5Y4YjzYaSfxNa4A5QMn7_UzAvActPOpL78Ok,2667
246
- multioptpy-1.20.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
247
- multioptpy-1.20.6.dist-info/METADATA,sha256=wPARwptr8gTPYvTEG3kamkh_rOecyhJbNndyInlmngc,16713
248
- multioptpy-1.20.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
249
- multioptpy-1.20.6.dist-info/entry_points.txt,sha256=u2Y0tgYMu7UyZumhLCfoME92lCQXhurAAsixL_B3caw,404
250
- multioptpy-1.20.6.dist-info/top_level.txt,sha256=_MXQNcS1xJbRbGnYUM-F_G-PlLK7wTIkuqx-EvfAhRc,11
251
- multioptpy-1.20.6.dist-info/RECORD,,
247
+ multioptpy-1.20.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
248
+ multioptpy-1.20.8.dist-info/METADATA,sha256=sT6ygFbX30OuibZcZQTN3Ov7-rrF2Kq02QF3A6PxxkE,16713
249
+ multioptpy-1.20.8.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
250
+ multioptpy-1.20.8.dist-info/entry_points.txt,sha256=u2Y0tgYMu7UyZumhLCfoME92lCQXhurAAsixL_B3caw,404
251
+ multioptpy-1.20.8.dist-info/top_level.txt,sha256=_MXQNcS1xJbRbGnYUM-F_G-PlLK7wTIkuqx-EvfAhRc,11
252
+ multioptpy-1.20.8.dist-info/RECORD,,