MultiOptPy 1.20.2__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.
Files changed (246) hide show
  1. multioptpy/Calculator/__init__.py +0 -0
  2. multioptpy/Calculator/ase_calculation_tools.py +424 -0
  3. multioptpy/Calculator/ase_tools/__init__.py +0 -0
  4. multioptpy/Calculator/ase_tools/fairchem.py +28 -0
  5. multioptpy/Calculator/ase_tools/gamess.py +19 -0
  6. multioptpy/Calculator/ase_tools/gaussian.py +165 -0
  7. multioptpy/Calculator/ase_tools/mace.py +28 -0
  8. multioptpy/Calculator/ase_tools/mopac.py +19 -0
  9. multioptpy/Calculator/ase_tools/nwchem.py +31 -0
  10. multioptpy/Calculator/ase_tools/orca.py +22 -0
  11. multioptpy/Calculator/ase_tools/pygfn0.py +37 -0
  12. multioptpy/Calculator/dxtb_calculation_tools.py +344 -0
  13. multioptpy/Calculator/emt_calculation_tools.py +458 -0
  14. multioptpy/Calculator/gpaw_calculation_tools.py +183 -0
  15. multioptpy/Calculator/lj_calculation_tools.py +314 -0
  16. multioptpy/Calculator/psi4_calculation_tools.py +334 -0
  17. multioptpy/Calculator/pwscf_calculation_tools.py +189 -0
  18. multioptpy/Calculator/pyscf_calculation_tools.py +327 -0
  19. multioptpy/Calculator/sqm1_calculation_tools.py +611 -0
  20. multioptpy/Calculator/sqm2_calculation_tools.py +376 -0
  21. multioptpy/Calculator/tblite_calculation_tools.py +352 -0
  22. multioptpy/Calculator/tersoff_calculation_tools.py +818 -0
  23. multioptpy/Constraint/__init__.py +0 -0
  24. multioptpy/Constraint/constraint_condition.py +834 -0
  25. multioptpy/Coordinate/__init__.py +0 -0
  26. multioptpy/Coordinate/polar_coordinate.py +199 -0
  27. multioptpy/Coordinate/redundant_coordinate.py +638 -0
  28. multioptpy/IRC/__init__.py +0 -0
  29. multioptpy/IRC/converge_criteria.py +28 -0
  30. multioptpy/IRC/dvv.py +544 -0
  31. multioptpy/IRC/euler.py +439 -0
  32. multioptpy/IRC/hpc.py +564 -0
  33. multioptpy/IRC/lqa.py +540 -0
  34. multioptpy/IRC/modekill.py +662 -0
  35. multioptpy/IRC/rk4.py +579 -0
  36. multioptpy/Interpolation/__init__.py +0 -0
  37. multioptpy/Interpolation/adaptive_interpolation.py +283 -0
  38. multioptpy/Interpolation/binomial_interpolation.py +179 -0
  39. multioptpy/Interpolation/geodesic_interpolation.py +785 -0
  40. multioptpy/Interpolation/interpolation.py +156 -0
  41. multioptpy/Interpolation/linear_interpolation.py +473 -0
  42. multioptpy/Interpolation/savitzky_golay_interpolation.py +252 -0
  43. multioptpy/Interpolation/spline_interpolation.py +353 -0
  44. multioptpy/MD/__init__.py +0 -0
  45. multioptpy/MD/thermostat.py +185 -0
  46. multioptpy/MEP/__init__.py +0 -0
  47. multioptpy/MEP/pathopt_bneb_force.py +443 -0
  48. multioptpy/MEP/pathopt_dmf_force.py +448 -0
  49. multioptpy/MEP/pathopt_dneb_force.py +130 -0
  50. multioptpy/MEP/pathopt_ewbneb_force.py +207 -0
  51. multioptpy/MEP/pathopt_gpneb_force.py +512 -0
  52. multioptpy/MEP/pathopt_lup_force.py +113 -0
  53. multioptpy/MEP/pathopt_neb_force.py +225 -0
  54. multioptpy/MEP/pathopt_nesb_force.py +205 -0
  55. multioptpy/MEP/pathopt_om_force.py +153 -0
  56. multioptpy/MEP/pathopt_qsm_force.py +174 -0
  57. multioptpy/MEP/pathopt_qsmv2_force.py +304 -0
  58. multioptpy/ModelFunction/__init__.py +7 -0
  59. multioptpy/ModelFunction/avoiding_model_function.py +29 -0
  60. multioptpy/ModelFunction/binary_image_ts_search_model_function.py +47 -0
  61. multioptpy/ModelFunction/conical_model_function.py +26 -0
  62. multioptpy/ModelFunction/opt_meci.py +50 -0
  63. multioptpy/ModelFunction/opt_mesx.py +47 -0
  64. multioptpy/ModelFunction/opt_mesx_2.py +49 -0
  65. multioptpy/ModelFunction/seam_model_function.py +27 -0
  66. multioptpy/ModelHessian/__init__.py +0 -0
  67. multioptpy/ModelHessian/approx_hessian.py +147 -0
  68. multioptpy/ModelHessian/calc_params.py +227 -0
  69. multioptpy/ModelHessian/fischer.py +236 -0
  70. multioptpy/ModelHessian/fischerd3.py +360 -0
  71. multioptpy/ModelHessian/fischerd4.py +398 -0
  72. multioptpy/ModelHessian/gfn0xtb.py +633 -0
  73. multioptpy/ModelHessian/gfnff.py +709 -0
  74. multioptpy/ModelHessian/lindh.py +165 -0
  75. multioptpy/ModelHessian/lindh2007d2.py +707 -0
  76. multioptpy/ModelHessian/lindh2007d3.py +822 -0
  77. multioptpy/ModelHessian/lindh2007d4.py +1030 -0
  78. multioptpy/ModelHessian/morse.py +106 -0
  79. multioptpy/ModelHessian/schlegel.py +144 -0
  80. multioptpy/ModelHessian/schlegeld3.py +322 -0
  81. multioptpy/ModelHessian/schlegeld4.py +559 -0
  82. multioptpy/ModelHessian/shortrange.py +346 -0
  83. multioptpy/ModelHessian/swartd2.py +496 -0
  84. multioptpy/ModelHessian/swartd3.py +706 -0
  85. multioptpy/ModelHessian/swartd4.py +918 -0
  86. multioptpy/ModelHessian/tshess.py +40 -0
  87. multioptpy/Optimizer/QHAdam.py +61 -0
  88. multioptpy/Optimizer/__init__.py +0 -0
  89. multioptpy/Optimizer/abc_fire.py +83 -0
  90. multioptpy/Optimizer/adabelief.py +58 -0
  91. multioptpy/Optimizer/adabound.py +68 -0
  92. multioptpy/Optimizer/adadelta.py +65 -0
  93. multioptpy/Optimizer/adaderivative.py +56 -0
  94. multioptpy/Optimizer/adadiff.py +68 -0
  95. multioptpy/Optimizer/adafactor.py +70 -0
  96. multioptpy/Optimizer/adam.py +65 -0
  97. multioptpy/Optimizer/adamax.py +62 -0
  98. multioptpy/Optimizer/adamod.py +83 -0
  99. multioptpy/Optimizer/adamw.py +65 -0
  100. multioptpy/Optimizer/adiis.py +523 -0
  101. multioptpy/Optimizer/afire_neb.py +282 -0
  102. multioptpy/Optimizer/block_hessian_update.py +709 -0
  103. multioptpy/Optimizer/c2diis.py +491 -0
  104. multioptpy/Optimizer/component_wise_scaling.py +405 -0
  105. multioptpy/Optimizer/conjugate_gradient.py +82 -0
  106. multioptpy/Optimizer/conjugate_gradient_neb.py +345 -0
  107. multioptpy/Optimizer/coordinate_locking.py +405 -0
  108. multioptpy/Optimizer/dic_rsirfo.py +1015 -0
  109. multioptpy/Optimizer/ediis.py +417 -0
  110. multioptpy/Optimizer/eve.py +76 -0
  111. multioptpy/Optimizer/fastadabelief.py +61 -0
  112. multioptpy/Optimizer/fire.py +77 -0
  113. multioptpy/Optimizer/fire2.py +249 -0
  114. multioptpy/Optimizer/fire_neb.py +92 -0
  115. multioptpy/Optimizer/gan_step.py +486 -0
  116. multioptpy/Optimizer/gdiis.py +609 -0
  117. multioptpy/Optimizer/gediis.py +203 -0
  118. multioptpy/Optimizer/geodesic_step.py +433 -0
  119. multioptpy/Optimizer/gpmin.py +633 -0
  120. multioptpy/Optimizer/gpr_step.py +364 -0
  121. multioptpy/Optimizer/gradientdescent.py +78 -0
  122. multioptpy/Optimizer/gradientdescent_neb.py +52 -0
  123. multioptpy/Optimizer/hessian_update.py +433 -0
  124. multioptpy/Optimizer/hybrid_rfo.py +998 -0
  125. multioptpy/Optimizer/kdiis.py +625 -0
  126. multioptpy/Optimizer/lars.py +21 -0
  127. multioptpy/Optimizer/lbfgs.py +253 -0
  128. multioptpy/Optimizer/lbfgs_neb.py +355 -0
  129. multioptpy/Optimizer/linesearch.py +236 -0
  130. multioptpy/Optimizer/lookahead.py +40 -0
  131. multioptpy/Optimizer/nadam.py +64 -0
  132. multioptpy/Optimizer/newton.py +200 -0
  133. multioptpy/Optimizer/prodigy.py +70 -0
  134. multioptpy/Optimizer/purtubation.py +16 -0
  135. multioptpy/Optimizer/quickmin_neb.py +245 -0
  136. multioptpy/Optimizer/radam.py +75 -0
  137. multioptpy/Optimizer/rfo_neb.py +302 -0
  138. multioptpy/Optimizer/ric_rfo.py +842 -0
  139. multioptpy/Optimizer/rl_step.py +627 -0
  140. multioptpy/Optimizer/rmspropgrave.py +65 -0
  141. multioptpy/Optimizer/rsirfo.py +1647 -0
  142. multioptpy/Optimizer/rsprfo.py +1056 -0
  143. multioptpy/Optimizer/sadam.py +60 -0
  144. multioptpy/Optimizer/samsgrad.py +63 -0
  145. multioptpy/Optimizer/tr_lbfgs.py +678 -0
  146. multioptpy/Optimizer/trim.py +273 -0
  147. multioptpy/Optimizer/trust_radius.py +207 -0
  148. multioptpy/Optimizer/trust_radius_neb.py +121 -0
  149. multioptpy/Optimizer/yogi.py +60 -0
  150. multioptpy/OtherMethod/__init__.py +0 -0
  151. multioptpy/OtherMethod/addf.py +1150 -0
  152. multioptpy/OtherMethod/dimer.py +895 -0
  153. multioptpy/OtherMethod/elastic_image_pair.py +629 -0
  154. multioptpy/OtherMethod/modelfunction.py +456 -0
  155. multioptpy/OtherMethod/newton_traj.py +454 -0
  156. multioptpy/OtherMethod/twopshs.py +1095 -0
  157. multioptpy/PESAnalyzer/__init__.py +0 -0
  158. multioptpy/PESAnalyzer/calc_irc_curvature.py +125 -0
  159. multioptpy/PESAnalyzer/cmds_analysis.py +152 -0
  160. multioptpy/PESAnalyzer/koopman_analysis.py +268 -0
  161. multioptpy/PESAnalyzer/pca_analysis.py +314 -0
  162. multioptpy/Parameters/__init__.py +0 -0
  163. multioptpy/Parameters/atomic_mass.py +20 -0
  164. multioptpy/Parameters/atomic_number.py +22 -0
  165. multioptpy/Parameters/covalent_radii.py +44 -0
  166. multioptpy/Parameters/d2.py +61 -0
  167. multioptpy/Parameters/d3.py +63 -0
  168. multioptpy/Parameters/d4.py +103 -0
  169. multioptpy/Parameters/dreiding.py +34 -0
  170. multioptpy/Parameters/gfn0xtb_param.py +137 -0
  171. multioptpy/Parameters/gfnff_param.py +315 -0
  172. multioptpy/Parameters/gnb.py +104 -0
  173. multioptpy/Parameters/parameter.py +22 -0
  174. multioptpy/Parameters/uff.py +72 -0
  175. multioptpy/Parameters/unit_values.py +20 -0
  176. multioptpy/Potential/AFIR_potential.py +55 -0
  177. multioptpy/Potential/LJ_repulsive_potential.py +345 -0
  178. multioptpy/Potential/__init__.py +0 -0
  179. multioptpy/Potential/anharmonic_keep_potential.py +28 -0
  180. multioptpy/Potential/asym_elllipsoidal_potential.py +718 -0
  181. multioptpy/Potential/electrostatic_potential.py +69 -0
  182. multioptpy/Potential/flux_potential.py +30 -0
  183. multioptpy/Potential/gaussian_potential.py +101 -0
  184. multioptpy/Potential/idpp.py +516 -0
  185. multioptpy/Potential/keep_angle_potential.py +146 -0
  186. multioptpy/Potential/keep_dihedral_angle_potential.py +105 -0
  187. multioptpy/Potential/keep_outofplain_angle_potential.py +70 -0
  188. multioptpy/Potential/keep_potential.py +99 -0
  189. multioptpy/Potential/mechano_force_potential.py +74 -0
  190. multioptpy/Potential/nanoreactor_potential.py +52 -0
  191. multioptpy/Potential/potential.py +896 -0
  192. multioptpy/Potential/spacer_model_potential.py +221 -0
  193. multioptpy/Potential/switching_potential.py +258 -0
  194. multioptpy/Potential/universal_potential.py +34 -0
  195. multioptpy/Potential/value_range_potential.py +36 -0
  196. multioptpy/Potential/void_point_potential.py +25 -0
  197. multioptpy/SQM/__init__.py +0 -0
  198. multioptpy/SQM/sqm1/__init__.py +0 -0
  199. multioptpy/SQM/sqm1/sqm1_core.py +1792 -0
  200. multioptpy/SQM/sqm2/__init__.py +0 -0
  201. multioptpy/SQM/sqm2/calc_tools.py +95 -0
  202. multioptpy/SQM/sqm2/sqm2_basis.py +850 -0
  203. multioptpy/SQM/sqm2/sqm2_bond.py +119 -0
  204. multioptpy/SQM/sqm2/sqm2_core.py +303 -0
  205. multioptpy/SQM/sqm2/sqm2_data.py +1229 -0
  206. multioptpy/SQM/sqm2/sqm2_disp.py +65 -0
  207. multioptpy/SQM/sqm2/sqm2_eeq.py +243 -0
  208. multioptpy/SQM/sqm2/sqm2_overlapint.py +704 -0
  209. multioptpy/SQM/sqm2/sqm2_qm.py +578 -0
  210. multioptpy/SQM/sqm2/sqm2_rep.py +66 -0
  211. multioptpy/SQM/sqm2/sqm2_srb.py +70 -0
  212. multioptpy/Thermo/__init__.py +0 -0
  213. multioptpy/Thermo/normal_mode_analyzer.py +865 -0
  214. multioptpy/Utils/__init__.py +0 -0
  215. multioptpy/Utils/bond_connectivity.py +264 -0
  216. multioptpy/Utils/calc_tools.py +884 -0
  217. multioptpy/Utils/oniom.py +96 -0
  218. multioptpy/Utils/pbc.py +48 -0
  219. multioptpy/Utils/riemann_curvature.py +208 -0
  220. multioptpy/Utils/symmetry_analyzer.py +482 -0
  221. multioptpy/Visualization/__init__.py +0 -0
  222. multioptpy/Visualization/visualization.py +156 -0
  223. multioptpy/WFAnalyzer/MO_analysis.py +104 -0
  224. multioptpy/WFAnalyzer/__init__.py +0 -0
  225. multioptpy/Wrapper/__init__.py +0 -0
  226. multioptpy/Wrapper/autots.py +1239 -0
  227. multioptpy/Wrapper/ieip_wrapper.py +93 -0
  228. multioptpy/Wrapper/md_wrapper.py +92 -0
  229. multioptpy/Wrapper/neb_wrapper.py +94 -0
  230. multioptpy/Wrapper/optimize_wrapper.py +76 -0
  231. multioptpy/__init__.py +5 -0
  232. multioptpy/entrypoints.py +916 -0
  233. multioptpy/fileio.py +660 -0
  234. multioptpy/ieip.py +340 -0
  235. multioptpy/interface.py +1086 -0
  236. multioptpy/irc.py +529 -0
  237. multioptpy/moleculardynamics.py +432 -0
  238. multioptpy/neb.py +1267 -0
  239. multioptpy/optimization.py +1553 -0
  240. multioptpy/optimizer.py +709 -0
  241. multioptpy-1.20.2.dist-info/METADATA +438 -0
  242. multioptpy-1.20.2.dist-info/RECORD +246 -0
  243. multioptpy-1.20.2.dist-info/WHEEL +5 -0
  244. multioptpy-1.20.2.dist-info/entry_points.txt +9 -0
  245. multioptpy-1.20.2.dist-info/licenses/LICENSE +674 -0
  246. multioptpy-1.20.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,19 @@
1
+ import os
2
+
3
+ class ASE_MOPAC:
4
+ def __init__(self, **kwargs):
5
+ self.atom_obj = kwargs.get('atom_obj', None)
6
+ self.electric_charge_and_multiplicity = kwargs.get('electric_charge_and_multiplicity', None)
7
+ self.input_file = kwargs.get('input_file', None)
8
+
9
+
10
+ def run(self):
11
+
12
+ from ase.calculators.mopac import MOPAC
13
+ input_dir = os.path.dirname(self.input_file)
14
+ self.atom_obj.calc = MOPAC(label=input_dir,
15
+ task="1SCF GRADIENTS DISP",
16
+ charge=int(self.electric_charge_and_multiplicity[0]),
17
+ mult=int(self.electric_charge_and_multiplicity[1]))
18
+
19
+ return self.atom_obj
@@ -0,0 +1,31 @@
1
+ import os
2
+ import re
3
+
4
+
5
+ class ASE_NWCHEM:
6
+ def __init__(self, **kwargs):
7
+ self.atom_obj = kwargs.get('atom_obj', None)
8
+ self.electric_charge_and_multiplicity = kwargs.get('electric_charge_and_multiplicity', None)
9
+ self.input_file = kwargs.get('input_file', None)
10
+ self.functional = kwargs.get('functional', None)
11
+ self.basis_set = kwargs.get('basis_set', None)
12
+ self.memory = kwargs.get('memory', None)
13
+
14
+ def run(self):
15
+ from ase.calculators.nwchem import NWChem
16
+ input_dir = os.path.dirname(self.input_file)
17
+ pattern = r"(\d+)([A-Za-z]+)"
18
+ match = re.match(pattern, self.memory.lower())
19
+ if match:
20
+ number = match.group(1)
21
+ unit = match.group(2)
22
+ else:
23
+ raise ValueError("Invalid memory string format")
24
+
25
+ calc = NWChem(label=input_dir,
26
+ xc=self.functional,
27
+ charge=self.electric_charge_and_multiplicity[0],
28
+ basis=self.basis_set,
29
+ memory=number+" "+unit)
30
+ self.atom_obj.set_calculator(calc)
31
+ return self.atom_obj
@@ -0,0 +1,22 @@
1
+ import os
2
+
3
+ class ASE_ORCA:
4
+ def __init__(self, **kwargs):
5
+ self.atom_obj = kwargs.get('atom_obj', None)
6
+ self.electric_charge_and_multiplicity = kwargs.get('electric_charge_and_multiplicity', None)
7
+ self.input_file = kwargs.get('input_file', None)
8
+ self.orca_path = kwargs.get('orca_path', None)
9
+ self.functional = kwargs.get('functional', None)
10
+ self.basis_set = kwargs.get('basis_set', None)
11
+
12
+ def run(self):
13
+
14
+ from ase.calculators.orca import ORCA
15
+ input_dir = os.path.dirname(self.input_file)
16
+ self.atom_obj.calc = ORCA(label=input_dir,
17
+ profile=self.orca_path,
18
+ charge=int(self.electric_charge_and_multiplicity[0]),
19
+ mult=int(self.electric_charge_and_multiplicity[1]),
20
+ orcasimpleinput=self.functional+' '+self.basis_set)
21
+ #orcablocks='%pal nprocs 16 end')
22
+ return self.atom_obj
@@ -0,0 +1,37 @@
1
+ class ASE_GFN0:
2
+ """
3
+ Wrapper class to set up and run GFN0-xTB calculations via ASE.
4
+ """
5
+ def __init__(self, **kwargs):
6
+
7
+ self.atom_obj = kwargs.get('atom_obj', None)
8
+ self.electric_charge_and_multiplicity = kwargs.get('electric_charge_and_multiplicity', None)
9
+ self.software_path = kwargs.get('software_path', None)
10
+ self.software_type = kwargs.get('software_type', None)
11
+
12
+ def set_calculator(self):
13
+ """
14
+ Sets the ASE calculator object based on software_type.
15
+ """
16
+ import pygfn0 # pygfn0==0.0.3 https://github.com/LiuGaoyong/PyGFN0
17
+ charge = 0 # Default charge
18
+ if self.electric_charge_and_multiplicity is not None:
19
+ try:
20
+ # Get charge from [charge, multiplicity] list
21
+ charge = int(self.electric_charge_and_multiplicity[0])
22
+ except (IndexError, TypeError, ValueError):
23
+ print(f"Warning: Could not parse charge from {self.electric_charge_and_multiplicity}. Defaulting to 0.")
24
+ pass
25
+
26
+ # Instantiate GFN0 class and pass the charge
27
+ gfn0_calc = pygfn0.GFN0(charge=charge)
28
+ return gfn0_calc
29
+
30
+
31
+ def run(self):
32
+ """
33
+ Attaches the calculator to the atoms object and returns it.
34
+ """
35
+ calc_obj = self.set_calculator()
36
+ self.atom_obj.calc = calc_obj
37
+ return self.atom_obj
@@ -0,0 +1,344 @@
1
+ import glob
2
+ import os
3
+ import copy
4
+
5
+ import numpy as np
6
+ import torch
7
+
8
+ from abc import ABC, abstractmethod
9
+
10
+
11
+ try:
12
+ import dxtb
13
+ dxtb.timer.disable()
14
+ except:
15
+ pass
16
+
17
+ from multioptpy.Utils.calc_tools import Calculationtools
18
+ from multioptpy.Parameters.parameter import UnitValueLib, element_number
19
+ from multioptpy.fileio import xyz2list
20
+ from multioptpy.Visualization.visualization import NEBVisualizer
21
+
22
+ """
23
+ ref:
24
+ dxtb
25
+ M. Friede, C. Hölzer, S. Ehlert, S. Grimme, dxtb -- An Efficient and Fully Differentiable Framework for Extended Tight-Binding, J. Chem. Phys., 2024, 161, 062501.
26
+ DOI: https://doi.org/10.1063/5.0216715
27
+ """
28
+
29
+
30
+ class Calculation:
31
+ def __init__(self, **kwarg):
32
+ UVL = UnitValueLib()
33
+
34
+ self.bohr2angstroms = UVL.bohr2angstroms
35
+
36
+ self.START_FILE = kwarg["START_FILE"]
37
+ self.N_THREAD = kwarg["N_THREAD"]
38
+ self.SET_MEMORY = kwarg["SET_MEMORY"]
39
+ self.FUNCTIONAL = kwarg["FUNCTIONAL"]
40
+ self.FC_COUNT = kwarg["FC_COUNT"]
41
+ self.BPA_FOLDER_DIRECTORY = kwarg["BPA_FOLDER_DIRECTORY"]
42
+ self.Model_hess = kwarg["Model_hess"]
43
+ self.unrestrict = kwarg["unrestrict"]
44
+ self.dft_grid = kwarg["dft_grid"]
45
+ self.hessian_flag = False
46
+
47
+ def single_point(self, file_directory, element_number_list, iter, electric_charge_and_multiplicity, method, geom_num_list=None):
48
+ """execute extended tight binding method calclation."""
49
+
50
+ finish_frag = False
51
+
52
+ if type(element_number_list[0]) is str:
53
+ tmp = copy.copy(element_number_list)
54
+ element_number_list = []
55
+
56
+ for elem in tmp:
57
+ element_number_list.append(element_number(elem))
58
+ element_number_list = np.array(element_number_list)
59
+ torch_element_number_list = torch.tensor(element_number_list)
60
+
61
+ try:
62
+ os.mkdir(file_directory)
63
+ except:
64
+ pass
65
+
66
+ if file_directory is None:
67
+ file_list = ["dummy"]
68
+ else:
69
+ file_list = glob.glob(file_directory+"/*_[0-9].xyz")
70
+
71
+ for num, input_file in enumerate(file_list):
72
+ try:
73
+
74
+ if geom_num_list is None:
75
+
76
+ positions, _, electric_charge_and_multiplicity = xyz2list(input_file, electric_charge_and_multiplicity)
77
+ else:
78
+ positions = geom_num_list
79
+
80
+ positions = np.array(positions, dtype="float64") / self.bohr2angstroms
81
+ torch_positions = torch.tensor(positions, requires_grad=True, dtype=torch.float32)
82
+
83
+ max_scf_iteration = len(element_number_list) * 50 + 1000
84
+ settings = {"maxiter": max_scf_iteration}
85
+
86
+
87
+ if method == "GFN1-xTB":
88
+ calc = dxtb.calculators.GFN1Calculator(torch_element_number_list, opts=settings)
89
+ elif method == "GFN2-xTB":
90
+ calc = dxtb.calculators.GFN2Calculator(torch_element_number_list, opts=settings)
91
+ else:
92
+ print("method error")
93
+ raise
94
+
95
+ if int(electric_charge_and_multiplicity[1]) > 1:
96
+
97
+ pos = torch_positions.clone().requires_grad_(True)
98
+ e = calc.get_energy(pos, chrg=int(electric_charge_and_multiplicity[0]), spin=int(electric_charge_and_multiplicity[1])) # hartree
99
+ calc.reset()
100
+ pos = torch_positions.clone().requires_grad_(True)
101
+ g = -1 * calc.get_forces(pos, chrg=int(electric_charge_and_multiplicity[0]), spin=int(electric_charge_and_multiplicity[1])) #hartree/Bohr
102
+ calc.reset()
103
+ else:
104
+ pos = torch_positions.clone().requires_grad_(True)
105
+ e = calc.get_energy(pos, chrg=int(electric_charge_and_multiplicity[0])) # hartree
106
+ calc.reset()
107
+ pos = torch_positions.clone().requires_grad_(True)
108
+ g = -1 * calc.get_forces(pos, chrg=int(electric_charge_and_multiplicity[0])) #hartree/Bohr
109
+ calc.reset()
110
+
111
+ #print("Orbital_energies :", self.orbital_energies)
112
+ #print("Orbital_occupations :", self.orbital_occupations)
113
+ #tmp = list(map(str, self.orbital_energies.tolist()))
114
+ #with open(self.BPA_FOLDER_DIRECTORY+"orbital-energies.csv" ,"a") as f:
115
+ # f.write(",".join(tmp)+"\n")
116
+ #tmp = list(map(str, self.orbital_occupations.tolist()))
117
+ #with open(self.BPA_FOLDER_DIRECTORY+"orbital_occupations.csv" ,"a") as f:
118
+ # f.write(",".join(tmp)+"\n")
119
+ #tmp = list(map(str, self.charges.tolist()))
120
+ #with open(self.BPA_FOLDER_DIRECTORY+"charges.csv" ,"a") as f:
121
+ # f.write(",".join(tmp)+"\n")
122
+
123
+ if self.FC_COUNT == -1 or type(iter) is str:
124
+ if self.hessian_flag:
125
+ self.exact_hessian(element_number_list, electric_charge_and_multiplicity, positions, torch_positions, calc)
126
+
127
+
128
+ elif iter % self.FC_COUNT == 0 or self.hessian_flag:
129
+ self.exact_hessian(element_number_list, electric_charge_and_multiplicity, positions, torch_positions, calc)
130
+
131
+
132
+
133
+ except Exception as error:
134
+ print(error)
135
+ print("This molecule could not be optimized.")
136
+ print("Input file: ",file_list,"\n")
137
+ finish_frag = True
138
+ return np.array([0]), np.array([0]), positions, finish_frag
139
+
140
+ return_e = e.to('cpu').detach().numpy().copy()
141
+ return_g = g.to('cpu').detach().numpy().copy()
142
+ self.energy = return_e
143
+ self.gradient = return_g
144
+ self.coordinate = positions
145
+
146
+ return return_e, return_g, positions, finish_frag
147
+
148
+ def exact_hessian(self, element_number_list, electric_charge_and_multiplicity, positions, torch_positions, calc):
149
+ """exact autograd hessian"""
150
+
151
+ pos = torch_positions.clone().requires_grad_(True)
152
+ if int(electric_charge_and_multiplicity[1]) > 1:
153
+ exact_hess = calc.get_hessian(pos, chrg=int(electric_charge_and_multiplicity[0]), spin=int(electric_charge_and_multiplicity[1]))
154
+ else:
155
+ exact_hess = calc.get_hessian(pos, chrg=int(electric_charge_and_multiplicity[0]))
156
+ exact_hess = exact_hess.reshape(3*len(element_number_list), 3*len(element_number_list))
157
+ return_exact_hess = exact_hess.to('cpu').detach().numpy().copy()
158
+
159
+ #eigenvalues, _ = np.linalg.eigh(return_exact_hess)
160
+ #print("=== hessian (before add bias potential) ===")
161
+ #print("eigenvalues: ", eigenvalues)
162
+
163
+ return_exact_hess = copy.copy(Calculationtools().project_out_hess_tr_and_rot_for_coord(return_exact_hess, element_number_list.tolist(), positions, display_eigval=False))
164
+ self.Model_hess = copy.copy(return_exact_hess)
165
+ calc.reset()
166
+
167
+ def ir(self, geom_num_list, element_number_list, electric_charge_and_multiplicity, method):
168
+ finish_frag = False
169
+ torch_positions = torch.tensor(geom_num_list, requires_grad=True, dtype=torch.float32)
170
+ if type(element_number_list[0]) is str:
171
+ tmp = copy.copy(element_number_list)
172
+ element_number_list = []
173
+
174
+ for elem in tmp:
175
+ element_number_list.append(element_number(elem))
176
+ element_number_list = np.array(element_number_list)
177
+ torch_element_number_list = torch.tensor(element_number_list)
178
+ max_scf_iteration = len(element_number_list) * 50 + 1000
179
+ ef = dxtb.components.field.new_efield(torch.tensor([0.0, 0.0, 0.0], requires_grad=True))
180
+ settings = {"maxiter": max_scf_iteration}
181
+ if method == "GFN1-xTB":
182
+ calc = dxtb.calculators.GFN1Calculator(torch_element_number_list, opts=settings, interaction=[ef])
183
+ elif method == "GFN2-xTB":
184
+ calc = dxtb.calculators.GFN2Calculator(torch_element_number_list, opts=settings, interaction=[ef])
185
+ else:
186
+ print("method error")
187
+ raise
188
+
189
+ if int(electric_charge_and_multiplicity[1]) > 1:
190
+ pos = torch_positions.clone().requires_grad_(True)
191
+ res = calc.ir(pos, chrg=int(electric_charge_and_multiplicity[0]), spin=int(electric_charge_and_multiplicity[1]))
192
+ au_int = res.ints
193
+ else:
194
+ pos = torch_positions.clone().requires_grad_(True)
195
+ res = calc.ir(pos, chrg=int(electric_charge_and_multiplicity[0]))
196
+ au_int = res.ints
197
+ res.use_common_units()
198
+ common_freqs = res.freqs.cpu().detach().numpy().copy()
199
+ au_int = au_int.cpu().detach().numpy().copy()
200
+ return common_freqs, au_int
201
+
202
+ class CalculationEngine(ABC):
203
+ """Base class for calculation engines"""
204
+
205
+ @abstractmethod
206
+ def calculate(self, file_directory, optimize_num, pre_total_velocity, config):
207
+ """Calculate energy and gradients"""
208
+ pass
209
+
210
+ def _get_file_list(self, file_directory):
211
+ """Get list of input files"""
212
+ return sum([sorted(glob.glob(os.path.join(file_directory, f"*_" + "[0-9]" * i + ".xyz")))
213
+ for i in range(1, 7)], [])
214
+
215
+ def _process_visualization(self, energy_list, gradient_list, num_list, optimize_num, config):
216
+ """Process common visualization tasks"""
217
+ try:
218
+ if config.save_pict:
219
+ visualizer = NEBVisualizer(config)
220
+ tmp_ene_list = np.array(energy_list, dtype="float64") * config.hartree2kcalmol
221
+ visualizer.plot_energy(num_list, tmp_ene_list - tmp_ene_list[0], optimize_num)
222
+ print("energy graph plotted.")
223
+
224
+ gradient_norm_list = [np.sqrt(np.linalg.norm(g)**2/(len(g)*3)) for g in gradient_list]
225
+ visualizer.plot_gradient(num_list, gradient_norm_list, optimize_num)
226
+ print("gradient graph plotted.")
227
+ except Exception as e:
228
+ print(f"Visualization error: {e}")
229
+
230
+
231
+
232
+
233
+
234
+ class DXTBEngine(CalculationEngine):
235
+ """DXTB calculation engine"""
236
+
237
+ def calculate(self, file_directory, optimize_num, pre_total_velocity, config):
238
+ gradient_list = []
239
+ energy_list = []
240
+ geometry_num_list = []
241
+ gradient_norm_list = []
242
+ delete_pre_total_velocity = []
243
+ num_list = []
244
+ method = config.usedxtb
245
+
246
+ os.makedirs(file_directory, exist_ok=True)
247
+ file_list = self._get_file_list(file_directory)
248
+
249
+ # Get element number list from the first file
250
+ geometry_list_tmp, element_list, _ = xyz2list(file_list[0], None)
251
+ element_number_list = []
252
+ for elem in element_list:
253
+ element_number_list.append(element_number(elem))
254
+ element_number_list = np.array(element_number_list, dtype="int")
255
+ torch_element_number_list = torch.tensor(element_number_list)
256
+
257
+ hess_count = 0
258
+
259
+ for num, input_file in enumerate(file_list):
260
+ try:
261
+ print(input_file)
262
+ positions, _, electric_charge_and_multiplicity = xyz2list(input_file, None)
263
+
264
+ positions = np.array(positions, dtype="float64") / config.bohr2angstroms
265
+ torch_positions = torch.tensor(positions, requires_grad=True, dtype=torch.float32)
266
+
267
+ max_scf_iteration = len(element_number_list) * 50 + 1000
268
+ settings = {"maxiter": max_scf_iteration}
269
+
270
+ if method == "GFN1-xTB":
271
+ calc = dxtb.calculators.GFN1Calculator(torch_element_number_list, opts=settings)
272
+ elif method == "GFN2-xTB":
273
+ calc = dxtb.calculators.GFN2Calculator(torch_element_number_list, opts=settings)
274
+ else:
275
+ print("method error")
276
+ raise
277
+
278
+ if int(electric_charge_and_multiplicity[1]) > 1:
279
+ pos = torch_positions.clone().requires_grad_(True)
280
+ e = calc.get_energy(pos, chrg=int(electric_charge_and_multiplicity[0]),
281
+ spin=int(electric_charge_and_multiplicity[1])) # hartree
282
+ calc.reset()
283
+ pos = torch_positions.clone().requires_grad_(True)
284
+ g = -1 * calc.get_forces(pos, chrg=int(electric_charge_and_multiplicity[0]),
285
+ spin=int(electric_charge_and_multiplicity[1])) # hartree/Bohr
286
+ calc.reset()
287
+ else:
288
+ pos = torch_positions.clone().requires_grad_(True)
289
+ e = calc.get_energy(pos, chrg=int(electric_charge_and_multiplicity[0])) # hartree
290
+ calc.reset()
291
+ pos = torch_positions.clone().requires_grad_(True)
292
+ g = -1 * calc.get_forces(pos, chrg=int(electric_charge_and_multiplicity[0])) # hartree/Bohr
293
+ calc.reset()
294
+
295
+ return_e = e.to('cpu').detach().numpy().copy()
296
+ return_g = g.to('cpu').detach().numpy().copy()
297
+
298
+ energy_list.append(return_e)
299
+ gradient_list.append(return_g)
300
+ gradient_norm_list.append(np.sqrt(np.linalg.norm(return_g)**2/(len(return_g)*3))) # RMS
301
+ geometry_num_list.append(positions)
302
+ num_list.append(num)
303
+
304
+ if config.FC_COUNT == -1 or type(optimize_num) is str:
305
+ pass
306
+ elif optimize_num % config.FC_COUNT == 0:
307
+ """exact autograd hessian"""
308
+ pos = torch_positions.clone().requires_grad_(True)
309
+ if int(electric_charge_and_multiplicity[1]) > 1:
310
+ exact_hess = calc.get_hessian(pos, chrg=int(electric_charge_and_multiplicity[0]),
311
+ spin=int(electric_charge_and_multiplicity[1]))
312
+ else:
313
+ exact_hess = calc.get_hessian(pos, chrg=int(electric_charge_and_multiplicity[0]))
314
+ exact_hess = exact_hess.reshape(3*len(element_number_list), 3*len(element_number_list))
315
+ return_exact_hess = exact_hess.to('cpu').detach().numpy().copy()
316
+
317
+ return_exact_hess = copy.copy(Calculationtools().project_out_hess_tr_and_rot_for_coord(
318
+ return_exact_hess, element_number_list.tolist(), positions))
319
+ np.save(config.NEB_FOLDER_DIRECTORY + "tmp_hessian_" + str(hess_count) + ".npy", return_exact_hess)
320
+
321
+ calc.reset()
322
+ hess_count += 1
323
+
324
+ except Exception as error:
325
+ print(error)
326
+ calc.reset()
327
+ print("This molecule could not be optimized.")
328
+ if optimize_num != 0:
329
+ delete_pre_total_velocity.append(num)
330
+
331
+ self._process_visualization(energy_list, gradient_list, num_list, optimize_num, config)
332
+
333
+ if optimize_num != 0 and len(pre_total_velocity) != 0:
334
+ pre_total_velocity = np.array(pre_total_velocity, dtype="float64")
335
+ pre_total_velocity = pre_total_velocity.tolist()
336
+ for i in sorted(delete_pre_total_velocity, reverse=True):
337
+ pre_total_velocity.pop(i)
338
+ pre_total_velocity = np.array(pre_total_velocity, dtype="float64")
339
+
340
+ return (np.array(energy_list, dtype="float64"),
341
+ np.array(gradient_list, dtype="float64"),
342
+ np.array(geometry_num_list, dtype="float64"),
343
+ pre_total_velocity)
344
+