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,709 @@
1
+ import numpy as np
2
+ import copy
3
+
4
+ from multioptpy.Parameters.parameter import UnitValueLib, atomic_mass
5
+ from multioptpy.Utils.calc_tools import Calculationtools
6
+
7
+ from multioptpy.Optimizer.adabelief import Adabelief
8
+ #from multioptpy.Optimizer.fastadabelief import FastAdabelief
9
+ #from multioptpy.Optimizer.adaderivative import Adaderivative
10
+ #from multioptpy.Optimizer.sadam import SAdam
11
+ #from multioptpy.Optimizer.samsgrad import SAMSGrad
12
+ #from multioptpy.Optimizer.QHAdam import QHAdam
13
+ #from multioptpy.Optimizer.adamax import AdaMax
14
+ #from multioptpy.Optimizer.yogi import YOGI
15
+ #from multioptpy.Optimizer.nadam import NAdam
16
+ from multioptpy.Optimizer.fire import FIRE
17
+ from multioptpy.Optimizer.abc_fire import ABC_FIRE
18
+ from multioptpy.Optimizer.fire2 import FIRE2
19
+ #from multioptpy.Optimizer.adadiff import AdaDiff
20
+ #from multioptpy.Optimizer.adamod import Adamod
21
+ from multioptpy.Optimizer.radam import RADAM
22
+ from multioptpy.Optimizer.eve import EVE
23
+ #from multioptpy.Optimizer.adamw import AdamW
24
+ from multioptpy.Optimizer.adam import Adam
25
+ #from multioptpy.Optimizer.adafactor import Adafactor
26
+ from multioptpy.Optimizer.prodigy import Prodigy
27
+ #from multioptpy.Optimizer.adabound import AdaBound
28
+ #from multioptpy.Optimizer.adadelta import Adadelta
29
+ from multioptpy.Optimizer.conjugate_gradient import ConjgateGradient
30
+ #from multioptpy.Optimizer.hybrid_rfo import HybridRFO
31
+ #from multioptpy.Optimizer.rfo import RationalFunctionOptimization
32
+ #from multioptpy.Optimizer.ric_rfo import RedundantInternalRFO
33
+ from multioptpy.Optimizer.rsprfo import EnhancedRSPRFO
34
+ from multioptpy.Optimizer.rsirfo import RSIRFO
35
+ #from multioptpy.Optimizer.newton import Newton
36
+ from multioptpy.Optimizer.lbfgs import LBFGS
37
+ from multioptpy.Optimizer.tr_lbfgs import TRLBFGS
38
+ #from multioptpy.Optimizer.rmspropgrave import RMSpropGrave
39
+ from multioptpy.Optimizer.lookahead import LookAhead
40
+ from multioptpy.Optimizer.lars import LARS
41
+ from multioptpy.Optimizer.gdiis import GDIIS
42
+ from multioptpy.Optimizer.ediis import EDIIS
43
+ from multioptpy.Optimizer.gediis import GEDIIS
44
+ from multioptpy.Optimizer.c2diis import C2DIIS
45
+ from multioptpy.Optimizer.adiis import ADIIS
46
+ from multioptpy.Optimizer.kdiis import KrylovDIIS as KDIIS
47
+ from multioptpy.Optimizer.gpr_step import GPRStep
48
+ from multioptpy.Optimizer.gan_step import GANStep
49
+ from multioptpy.Optimizer.rl_step import RLStepSizeOptimizer
50
+ from multioptpy.Optimizer.geodesic_step import GeodesicStepper
51
+ from multioptpy.Optimizer.linesearch import LineSearch
52
+ from multioptpy.Optimizer.component_wise_scaling import ComponentWiseScaling
53
+ from multioptpy.Optimizer.coordinate_locking import CoordinateLocking
54
+ from multioptpy.Optimizer.trust_radius import TrustRadius
55
+ from multioptpy.Optimizer.gradientdescent import GradientDescent, MassWeightedGradientDescent
56
+ from multioptpy.Optimizer.gpmin import GPmin
57
+ from multioptpy.Optimizer.trim import TRIM
58
+
59
+ optimizer_mapping = {
60
+ "adabelief": Adabelief,
61
+ "radam": RADAM,
62
+ "eve": EVE,
63
+ "prodigy": Prodigy,
64
+ "abcfire": ABC_FIRE,
65
+ "fire2": FIRE2,
66
+ "fire": FIRE,
67
+ "mwgradientdescent": MassWeightedGradientDescent,
68
+ "gradientdescent": GradientDescent,
69
+ "steepest_descent": GradientDescent,
70
+ "gpmin": GPmin,
71
+ "tr_lbfgs": TRLBFGS,
72
+ "lbfgs": LBFGS,
73
+ }
74
+
75
+ specific_cases = {
76
+ "ranger": {"optimizer": RADAM, "lookahead": LookAhead(), "lars": None},
77
+ "rangerlars": {"optimizer": RADAM, "lookahead": LookAhead(), "lars": LARS()},
78
+ "adam": {"optimizer": Adam, "lookahead": LookAhead(), "lars": None},
79
+ "adamlars": {"optimizer": Adam, "lookahead": None, "lars": LARS()},
80
+ "adamlookahead": {"optimizer": Adam, "lookahead": LookAhead(), "lars": None},
81
+ "adamlookaheadlars": {"optimizer": Adam, "lookahead": LookAhead(), "lars": LARS()},
82
+ }
83
+
84
+ quasi_newton_mapping = {
85
+ "rsirfo_bfgs_dd": {"delta": 0.50, "rfo_type": 1},
86
+ "rsirfo_bfgs": {"delta": 0.50, "rfo_type": 1},
87
+ "rsirfo_block_bfgs_dd": {"delta": 0.50, "rfo_type": 1},
88
+ "rsirfo_block_bfgs": {"delta": 0.50, "rfo_type": 1},
89
+ "rsirfo_fsb_dd": {"delta": 0.50, "rfo_type": 1},
90
+ "rsirfo_fsb": {"delta": 0.50, "rfo_type": 1},
91
+ "rsirfo_block_fsb_dd": {"delta": 0.50, "rfo_type": 1},
92
+ "rsirfo_block_fsb_weighted": {"delta": 0.50, "rfo_type": 1},
93
+ "rsirfo_block_fsb": {"delta": 0.50, "rfo_type": 1},
94
+ "rsirfo_block_cfd_fsb_dd": {"delta": 0.50, "rfo_type": 1},
95
+ "rsirfo_block_cfd_fsb_weighted": {"delta": 0.50, "rfo_type": 1},
96
+ "rsirfo_block_cfd_fsb": {"delta": 0.50, "rfo_type": 1},
97
+ "rsirfo_cfd_fsb_dd": {"delta": 0.50, "rfo_type": 1},
98
+ "rsirfo_cfd_fsb": {"delta": 0.50, "rfo_type": 1},
99
+ "rsirfo_bofill": {"delta": 0.50, "rfo_type": 1},
100
+ "rsirfo_block_bofill_weighted": {"delta": 0.50, "rfo_type": 1},
101
+ "rsirfo_block_bofill": {"delta": 0.50, "rfo_type": 1},
102
+ "rsirfo_block_cfd_bofill_weighted": {"delta": 0.50, "rfo_type": 1},
103
+ "rsirfo_block_cfd_bofill": {"delta": 0.50, "rfo_type": 1},
104
+ "rsirfo_cfd_bofill": {"delta": 0.50, "rfo_type": 1},
105
+ "rsirfo_pcfd_bofill": {"delta": 0.50, "rfo_type": 1},
106
+ "rsirfo_msp": {"delta": 0.50, "rfo_type": 1},
107
+ "rsirfo_sr1": {"delta": 0.50, "rfo_type": 1},
108
+ "rsirfo_psb": {"delta": 0.50, "rfo_type": 1},
109
+ "rsirfo_flowchart": {"delta": 0.50, "rfo_type": 1},
110
+
111
+ "rsprfo_bfgs_dd": {"delta": 0.50, "rfo_type": 1},
112
+ "rsprfo_bfgs": {"delta": 0.50, "rfo_type": 1},
113
+ "rsprfo_block_bfgs_dd": {"delta": 0.50, "rfo_type": 1},
114
+ "rsprfo_block_bfgs": {"delta": 0.50, "rfo_type": 1},
115
+ "rsprfo_fsb_dd": {"delta": 0.50, "rfo_type": 1},
116
+ "rsprfo_fsb": {"delta": 0.50, "rfo_type": 1},
117
+ "rsprfo_block_fsb_dd": {"delta": 0.50, "rfo_type": 1},
118
+ "rsprfo_block_fsb_weighted": {"delta": 0.50, "rfo_type": 1},
119
+ "rsprfo_block_fsb": {"delta": 0.50, "rfo_type": 1},
120
+ "rsprfo_block_cfd_fsb_dd": {"delta": 0.50, "rfo_type": 1},
121
+ "rsprfo_block_cfd_fsb_weighted": {"delta": 0.50, "rfo_type": 1},
122
+ "rsprfo_block_cfd_fsb": {"delta": 0.50, "rfo_type": 1},
123
+ "rsprfo_cfd_fsb_dd": {"delta": 0.50, "rfo_type": 1},
124
+ "rsprfo_cfd_fsb": {"delta": 0.50, "rfo_type": 1},
125
+ "rsprfo_bofill": {"delta": 0.50, "rfo_type": 1},
126
+ "rsprfo_block_bofill_weighted": {"delta": 0.50, "rfo_type": 1},
127
+ "rsprfo_block_bofill": {"delta": 0.50, "rfo_type": 1},
128
+ "rsprfo_block_cfd_bofill_weighted": {"delta": 0.50, "rfo_type": 1},
129
+ "rsprfo_block_cfd_bofill": {"delta": 0.50, "rfo_type": 1},
130
+ "rsprfo_cfd_bofill": {"delta": 0.50, "rfo_type": 1},
131
+ "rsprfo_pcfd_bofill": {"delta": 0.50, "rfo_type": 1},
132
+ "rsprfo_msp": {"delta": 0.50, "rfo_type": 1},
133
+ "rsprfo_sr1": {"delta": 0.50, "rfo_type": 1},
134
+ "rsprfo_psb": {"delta": 0.50, "rfo_type": 1},
135
+ "rsprfo_flowchart": {"delta": 0.50, "rfo_type": 1},
136
+ }
137
+
138
+
139
+
140
+ class CalculateMoveVector:
141
+ def __init__(self, DELTA, element_list, saddle_order=0, FC_COUNT=-1, temperature=0.0, model_hess_flag=None, max_trust_radius=None, min_trust_radius=None):
142
+ self.DELTA = DELTA
143
+ self.temperature = temperature
144
+ np.set_printoptions(precision=12, floatmode="fixed", suppress=True)
145
+ self.unitval = UnitValueLib()
146
+ self.FC_COUNT = FC_COUNT
147
+ self.MAX_MAX_FORCE_SWITCHING_THRESHOLD = 0.0050
148
+ self.MIN_MAX_FORCE_SWITCHING_THRESHOLD = 0.0010
149
+ self.MAX_RMS_FORCE_SWITCHING_THRESHOLD = 0.05
150
+ self.MIN_RMS_FORCE_SWITCHING_THRESHOLD = 0.005
151
+
152
+ self.max_trust_radius = max_trust_radius
153
+ self.min_trust_radius = min_trust_radius
154
+ self.CALC_TRUST_RADII = TrustRadius()
155
+ if self.max_trust_radius is not None:
156
+ if self.max_trust_radius <= 0.0:
157
+ print("max_trust_radius must be greater than 0.0")
158
+ exit()
159
+
160
+ self.CALC_TRUST_RADII.set_max_trust_radius(self.max_trust_radius)
161
+ if self.max_trust_radius is None:
162
+ if saddle_order > 0:
163
+ self.max_trust_radius = 0.1
164
+ self.trust_radii = 0.1
165
+ else:
166
+ self.max_trust_radius = 0.5
167
+ self.trust_radii = 0.5
168
+ else:
169
+ if saddle_order > 0:
170
+ self.trust_radii = min(self.max_trust_radius, 0.1)
171
+ else:
172
+ self.trust_radii = self.max_trust_radius if type(self.max_trust_radius) is float else 0.5
173
+
174
+ if self.min_trust_radius is not None:
175
+ if self.min_trust_radius <= 0.0:
176
+ print("min_trust_radius must be greater than 0.0")
177
+ exit()
178
+ if self.trust_radii < self.min_trust_radius:
179
+ print("min_trust_radius must be smaller than max_trust_radius")
180
+ exit()
181
+
182
+ self.CALC_TRUST_RADII.set_min_trust_radius(self.min_trust_radius)
183
+
184
+ self.min_trust_radius = min_trust_radius if min_trust_radius is not None else 0.01
185
+
186
+ self.saddle_order = saddle_order
187
+ self.iter = 0
188
+ self.element_list = element_list
189
+ self.model_hess_flag = model_hess_flag
190
+
191
+ def initialization(self, method):
192
+ """
193
+ Initializes the optimizer instances based on the provided method names.
194
+
195
+ This function parses a list of method strings. Each string defines a
196
+ base optimizer (e.g., LBFGS, FIRE, RSIRFO) and optionally
197
+ a set of enhancements (e.g., "lookahead", "gdiis", "lars")
198
+ which are chained together.
199
+
200
+ Args:
201
+ method (list[str]): A list of method name strings.
202
+
203
+ Returns:
204
+ list: A list of initialized base optimizer instances.
205
+ """
206
+
207
+ # --- Helper Function to Handle Enhancements ---
208
+
209
+ def _append_enhancements(lower_m, is_newton_method, specific_lookahead=None, specific_lars=None):
210
+ """
211
+ Private helper to append all enhancement instances for a given method.
212
+ This avoids duplicating this logic in every 'if/elif' block.
213
+
214
+ Args:
215
+ lower_m (str): The lowercased method name string.
216
+ is_newton_method (bool): Flag indicating if the base optimizer is a quasi-Newton method.
217
+ specific_lookahead (object, optional): A pre-defined LookAhead instance from 'specific_cases'.
218
+ specific_lars (object, optional): A pre-defined LARS instance from 'specific_cases'.
219
+ """
220
+
221
+ # Handle LookAhead and LARS, prioritizing 'specific_cases' config
222
+ if specific_lookahead is not None:
223
+ lookahead_instances.append(specific_lookahead)
224
+ else:
225
+ lookahead_instances.append(LookAhead() if "lookahead" in lower_m else None)
226
+
227
+ if specific_lars is not None:
228
+ lars_instances.append(specific_lars)
229
+ else:
230
+ lars_instances.append(LARS() if "lars" in lower_m else None)
231
+
232
+ # LineSearch
233
+ linesearch_instances.append(LineSearch() if "linesearch" in lower_m else None)
234
+
235
+
236
+ # DIIS family
237
+ gdiis_instances.append(GDIIS() if "gdiis" in lower_m else None)
238
+ kdiis_instances.append(KDIIS() if "kdiis" in lower_m else None)
239
+ adiis_instances.append(ADIIS() if "adiis" in lower_m else None)
240
+ c2diis_instances.append(C2DIIS() if "c2diis" in lower_m else None)
241
+
242
+
243
+ # Handle mutually exclusive EDIIS/GEDIIS
244
+ if "gediis" in lower_m:
245
+ gediis_instances.append(GEDIIS())
246
+ ediis_instances.append(None)
247
+ else:
248
+ ediis_instances.append(EDIIS() if "ediis" in lower_m else None)
249
+ gediis_instances.append(None)
250
+
251
+ # Coordinate transformations
252
+ coordinate_locking_instances.append(CoordinateLocking() if "coordinate_locking" in lower_m else None)
253
+ coordinate_wise_scaling_instances.append(ComponentWiseScaling() if "component_wise_scaling" in lower_m else None)
254
+
255
+ # ML-based step optimizers
256
+ gpr_step_instances.append(GPRStep() if "gpr_step" in lower_m else None)
257
+ gan_step_instances.append(GANStep() if "gan_step" in lower_m else None)
258
+ rl_step_instances.append(RLStepSizeOptimizer() if "rl_step" in lower_m else None)
259
+
260
+ # Other step modifiers
261
+ geodesic_step_instances.append(GeodesicStepper(element_list=self.element_list) if "geodesic_step" in lower_m else None)
262
+
263
+ # TRIM is only relevant for quasi-Newton methods
264
+ if is_newton_method:
265
+ trim_step_instances.append(TRIM(saddle_order=self.saddle_order) if "trim" in lower_m else None)
266
+ else:
267
+ trim_step_instances.append(None)
268
+
269
+ # --- End of Helper Function ---
270
+
271
+ # Initialize lists to store instances for each method
272
+ optimizer_instances = []
273
+ newton_tag = []
274
+ lookahead_instances = []
275
+ lars_instances = []
276
+ gdiis_instances = []
277
+ ediis_instances = []
278
+ gediis_instances = []
279
+ c2diis_instances = []
280
+ adiis_instances = []
281
+ kdiis_instances = []
282
+ coordinate_locking_instances = []
283
+ coordinate_wise_scaling_instances = []
284
+ gpr_step_instances = []
285
+ gan_step_instances = []
286
+ rl_step_instances = []
287
+ geodesic_step_instances = []
288
+ trim_step_instances = []
289
+ linesearch_instances = []
290
+
291
+ # Loop over each requested method string
292
+ for i, m in enumerate(method):
293
+ lower_m = m.lower()
294
+ optimizer_added = False
295
+ is_newton = False
296
+ optimizer = None
297
+
298
+ # 1. Check hard-coded specific cases (e.g., "ranger")
299
+ if lower_m in specific_cases:
300
+ case = specific_cases[lower_m]
301
+ optimizer = case["optimizer"]()
302
+ is_newton = False
303
+ optimizer_instances.append(optimizer)
304
+ newton_tag.append(is_newton)
305
+ _append_enhancements(lower_m,
306
+ is_newton,
307
+ specific_lookahead=case.get("lookahead"),
308
+ specific_lars=case.get("lars"))
309
+ optimizer_added = True
310
+
311
+ # 2. Check quasi-Newton methods
312
+ elif any(key in lower_m for key in quasi_newton_mapping):
313
+ for key, settings in quasi_newton_mapping.items():
314
+ if key in lower_m:
315
+ print(key)
316
+ if "rsprfo" in key:
317
+ optimizer = EnhancedRSPRFO(method=m, saddle_order=self.saddle_order, element_list=self.element_list, trust_radius_max=self.max_trust_radius, trust_radius_min=self.min_trust_radius)
318
+ elif "rsirfo" in key:
319
+ optimizer = RSIRFO(method=m, saddle_order=self.saddle_order, element_list=self.element_list, trust_radius_max=self.max_trust_radius, trust_radius_min=self.min_trust_radius)
320
+ else:
321
+ print(f"This method is not implemented: {m}. Thus, exiting.")
322
+ exit()
323
+
324
+ optimizer.DELTA = settings["delta"]
325
+ if "linesearch" in settings:
326
+ optimizer.linesearchflag = True
327
+
328
+ is_newton = True
329
+ optimizer_instances.append(optimizer)
330
+ newton_tag.append(is_newton)
331
+ _append_enhancements(lower_m, is_newton)
332
+ optimizer_added = True
333
+ break # Exit inner loop once match is found
334
+
335
+ # 3. Check standard gradient-based optimizers
336
+ if not optimizer_added:
337
+ for key, optimizer_class in optimizer_mapping.items():
338
+ if key in lower_m:
339
+ optimizer = optimizer_class()
340
+ if lower_m == "mwgradientdescent":
341
+ optimizer.element_list = self.element_list
342
+ optimizer.atomic_mass = atomic_mass
343
+
344
+ is_newton = False
345
+ optimizer_instances.append(optimizer)
346
+ newton_tag.append(is_newton)
347
+ _append_enhancements(lower_m, is_newton)
348
+ optimizer_added = True
349
+ break # Exit inner loop once match is found
350
+
351
+ # 4. Check Conjugate Gradient methods
352
+ # Define CG keys. Put "cg" last so "cg_pr" matches first if present.
353
+ cg_keys = ["cg_pr", "cg_fr", "cg_hs", "cg_dy", "cg"]
354
+ if not optimizer_added:
355
+ for key in cg_keys:
356
+ if key in lower_m:
357
+ # Use the matched key (e.g., "cg" or "cg_pr") for the constructor,
358
+ optimizer = ConjgateGradient(method=key)
359
+ is_newton = False
360
+ optimizer_instances.append(optimizer)
361
+ newton_tag.append(is_newton)
362
+ # Pass the full 'lower_m' string to check for other enhancements
363
+ _append_enhancements(lower_m, is_newton)
364
+ optimizer_added = True
365
+ break # Found a cg match, exit inner loop
366
+
367
+ # 5. Handle default case (method not found)
368
+ if not optimizer_added:
369
+ print(f"This method is not implemented: {m}. Thus, Default method (FIRE) is used.")
370
+ optimizer = FIRE()
371
+ is_newton = False
372
+ optimizer_instances.append(optimizer)
373
+ newton_tag.append(is_newton)
374
+ _append_enhancements(lower_m, is_newton)
375
+
376
+ # --- End of loop ---
377
+
378
+ # Store all instance lists as class attributes
379
+ # These are used by other methods in the class
380
+ self.method = method
381
+ self.newton_tag = newton_tag
382
+ self.lookahead_instances = lookahead_instances
383
+ self.lars_instances = lars_instances
384
+ self.gdiis_instances = gdiis_instances
385
+ self.ediis_instances = ediis_instances
386
+ self.gediis_instances = gediis_instances
387
+ self.c2diis_instances = c2diis_instances
388
+ self.adiis_instances = adiis_instances
389
+ self.kdiis_instances = kdiis_instances
390
+ self.coordinate_locking_instances = coordinate_locking_instances
391
+ self.coordinate_wise_scaling_instances = coordinate_wise_scaling_instances
392
+ self.gpr_step_instances = gpr_step_instances
393
+ self.gan_step_instances = gan_step_instances
394
+ self.rl_step_instances = rl_step_instances
395
+ self.geodesic_step_instances = geodesic_step_instances
396
+ self.trim_step_instances = trim_step_instances
397
+ self.linesearch_instances = linesearch_instances
398
+ return optimizer_instances
399
+
400
+ def update_trust_radius_conditionally(self, optimizer_instances, B_e, pre_B_e, pre_B_g, pre_move_vector, geom_num_list):
401
+ """
402
+ Refactored method to handle trust radius updates and conditions.
403
+ """
404
+ # Early exit if no full-coordinate count and no Hessian flag
405
+ if self.FC_COUNT == -1 and not self.model_hess_flag is not None:
406
+ return
407
+
408
+ # Determine if there's a model Hessian to use
409
+ model_hess = None
410
+ for i in range(len(optimizer_instances)):
411
+ if self.newton_tag[i]:
412
+ model_hess = optimizer_instances[i].hessian + optimizer_instances[i].bias_hessian
413
+ break
414
+
415
+ # Update trust radii only if we have a Hessian or if FC_COUNT is not -1
416
+ if not (model_hess is None and self.FC_COUNT == -1) and True in self.newton_tag:
417
+ self.trust_radii = self.CALC_TRUST_RADII.update_trust_radii(
418
+ B_e, pre_B_e, pre_B_g, pre_move_vector, model_hess, geom_num_list, self.trust_radii
419
+ )
420
+
421
+ if self.min_trust_radius is not None:
422
+ print("user_difined_min_trust_radius: ", self.min_trust_radius)
423
+
424
+ if self.max_trust_radius is not None:
425
+ print("user_difined_max_trust_radius: ", self.max_trust_radius)
426
+ else:
427
+ # If saddle order is positive, constrain the trust radii
428
+ if self.saddle_order > 0:
429
+ self.trust_radii = min(self.trust_radii, self.max_trust_radius if self.max_trust_radius is not None else 0.1)
430
+
431
+ # If this is the first iteration but not full-coordinate -1 check
432
+ if self.iter == 0 and self.FC_COUNT != -1:
433
+ if self.saddle_order > 0:
434
+ self.trust_radii = min(self.trust_radii, self.max_trust_radius if self.max_trust_radius is not None else 0.1)
435
+
436
+ def handle_projection_constraint(self, projection_constrain):
437
+ """
438
+ Constrain the trust radii if projection constraint is enabled.
439
+ """
440
+ if projection_constrain:
441
+ if self.max_trust_radius is not None:
442
+ pass
443
+ else:
444
+ self.trust_radii = min(self.trust_radii, self.max_trust_radius if self.max_trust_radius is not None else 0.1)
445
+
446
+
447
+
448
+ def switch_move_vector(self,
449
+ B_g,
450
+ move_vector_list,
451
+ method_list=None,
452
+ max_rms_force_switching_threshold=0.05,
453
+ min_rms_force_switching_threshold=0.005,
454
+ steepness=10.0,
455
+ offset=0.5):
456
+
457
+
458
+ if len(method_list) == 1:
459
+ return copy.copy(move_vector_list[0]), method_list
460
+
461
+ rms_force = abs(np.sqrt(np.square(B_g).mean()))
462
+
463
+ if rms_force > max_rms_force_switching_threshold:
464
+
465
+ print(f"Switching to {method_list[0]}")
466
+ return copy.copy(move_vector_list[0]), method_list
467
+ elif min_rms_force_switching_threshold < rms_force <= max_rms_force_switching_threshold:
468
+
469
+ x_j = (rms_force - min_rms_force_switching_threshold) / (
470
+ max_rms_force_switching_threshold - min_rms_force_switching_threshold
471
+ )
472
+
473
+ f_val = 1 / (1 + np.exp(-steepness * (x_j - offset)))
474
+ combined_vector = (
475
+ np.array(move_vector_list[0], dtype="float64") * f_val
476
+ + np.array(move_vector_list[1], dtype="float64") * (1.0 - f_val)
477
+ )
478
+ print(f"Weighted switching: {f_val:.3f} {method_list[0]} {method_list[1]}")
479
+ return combined_vector, method_list
480
+ else:
481
+
482
+ print(f"Switching to {method_list[1]}")
483
+ return copy.copy(move_vector_list[1]), method_list
484
+
485
+ def update_move_vector_list(
486
+ self,
487
+ optimizer_instances,
488
+ B_g,
489
+ pre_B_g,
490
+ pre_geom,
491
+ B_e,
492
+ pre_B_e,
493
+ pre_move_vector,
494
+ initial_geom_num_list,
495
+ g,
496
+ pre_g,
497
+ ):
498
+ """
499
+ Update a list of move vectors from multiple optimizer instances,
500
+ including optional enhancements through various techniques.
501
+ """
502
+ move_vector_list = []
503
+
504
+ tmp_hess = None
505
+ for i in range(len(optimizer_instances)):
506
+ if self.newton_tag[i]:
507
+ tmp_hess = optimizer_instances[i].hessian + optimizer_instances[i].bias_hessian
508
+ break
509
+ # Enhancement techniques and their parameter configurations
510
+ # Format: [list_of_instances, method_name, [parameters]]
511
+ enhancement_config = [
512
+ # Base optimizer - separate handling
513
+
514
+ # Trust region and momentum techniques
515
+ [self.lars_instances, "apply_lars", [B_g, pre_B_g, pre_geom, B_e, pre_B_e, pre_move_vector,
516
+ initial_geom_num_list, g, pre_g]],
517
+ [self.lookahead_instances, "apply_lookahead", [B_g, pre_B_g, pre_geom, B_e, pre_B_e, pre_move_vector,
518
+ initial_geom_num_list, g, pre_g]],
519
+
520
+ # linesearch
521
+ [self.linesearch_instances, "apply_linesearch", [B_g, pre_B_g, B_e, pre_B_e]],
522
+
523
+ # DIIS family techniques
524
+ [self.ediis_instances, "apply_ediis", [B_e, B_g]],
525
+ [self.gdiis_instances, "apply_gdiis", [B_g, pre_B_g]],
526
+ [self.c2diis_instances, "apply_c2diis", [B_g, pre_B_g]],
527
+ [self.adiis_instances, "apply_adiis", [B_e, B_g]],
528
+ [self.kdiis_instances, "apply_kdiis", [B_e, B_g]],
529
+ [self.gediis_instances, "apply_gediis", [B_e, B_g, pre_B_g]],
530
+
531
+ # Coordinate transformation techniques
532
+ [self.coordinate_locking_instances, "apply_coordinate_locking", [B_e, B_g]],
533
+ [self.coordinate_wise_scaling_instances, "apply_coordinate_scaling", [B_e, B_g]],
534
+
535
+ # ML-based step prediction techniques
536
+ [self.gpr_step_instances, "apply_ml_step", [B_e, B_g]],
537
+
538
+ # GAN-based step prediction techniques
539
+ [self.gan_step_instances, "apply_gan_step", [B_e, B_g]],
540
+
541
+ # Reinforcement learning-based step prediction techniques
542
+ [self.rl_step_instances, "apply_rl_step", [B_g, pre_B_g, B_e, pre_B_e]],
543
+ # Geodesic stepping techniques
544
+ [self.geodesic_step_instances, "apply_geodesic_step", []],
545
+ # TRIM step adjustment techniques
546
+ [self.trim_step_instances, "apply_trim_step", [B_g, tmp_hess, self.trust_radii]],
547
+ ]
548
+
549
+ for i, optimizer_instance in enumerate(optimizer_instances):
550
+ # Get initial move vector from base optimizer
551
+ tmp_move_vector = optimizer_instance.run(
552
+ self.geom_num_list,
553
+ B_g,
554
+ pre_B_g,
555
+ pre_geom,
556
+ B_e,
557
+ pre_B_e,
558
+ pre_move_vector,
559
+ initial_geom_num_list,
560
+ g,
561
+ pre_g
562
+ )
563
+ tmp_move_vector = np.array(tmp_move_vector, dtype="float64")
564
+
565
+ # Apply each enhancement technique if available
566
+ for instance_list, method_name, base_params in enhancement_config:
567
+ if i < len(instance_list) and instance_list[i] is not None:
568
+ tmp_move_vector = self._apply_enhancement(
569
+ instance_list[i],
570
+ method_name,
571
+ [self.geom_num_list] + base_params + [tmp_move_vector]
572
+ )
573
+
574
+ move_vector_list.append(tmp_move_vector)
575
+
576
+ return move_vector_list
577
+
578
+ def _apply_enhancement(self, instance, method_name, params):
579
+ """
580
+ Helper method to apply enhancement techniques to the move vector.
581
+
582
+ Parameters:
583
+ -----------
584
+ instance : object
585
+ The enhancement technique instance
586
+ method_name : str
587
+ The name of the method to use (for logging/debugging)
588
+ params : list
589
+ Parameters to pass to the run method
590
+
591
+ Returns:
592
+ --------
593
+ numpy.ndarray
594
+ The modified move vector
595
+ """
596
+ # For LARS, special handling is needed as it returns a scaling factor
597
+ if method_name == "apply_lars":
598
+ trust_delta = instance.run(*params)
599
+ # Last parameter is the move vector
600
+ return params[-1] * trust_delta
601
+ else:
602
+ # Standard run pattern for most enhancement techniques
603
+ return instance.run(*params)
604
+
605
+
606
+ def calc_move_vector(self, iter, geom_num_list, B_g, pre_B_g, pre_geom, B_e, pre_B_e, pre_move_vector, initial_geom_num_list, g, pre_g, optimizer_instances, projection_constrain=False, print_flag=True):#geom_num_list:Bohr
607
+ natom = len(geom_num_list)
608
+
609
+ ###
610
+ #-------------------------------------------------------------
611
+ geom_num_list = geom_num_list.reshape(natom*3, 1)
612
+ B_g = B_g.reshape(natom*3, 1)
613
+ pre_B_g = pre_B_g.reshape(natom*3, 1)
614
+ pre_geom = pre_geom.reshape(natom*3, 1)
615
+ g = g.reshape(natom*3, 1)
616
+ pre_g = pre_g.reshape(natom*3, 1)
617
+ pre_move_vector = pre_move_vector.reshape(natom*3, 1)
618
+ initial_geom_num_list = initial_geom_num_list.reshape(natom*3, 1)
619
+ #-------------------------------------------------------------
620
+ ###
621
+ self.iter = iter
622
+ self.geom_num_list = geom_num_list
623
+
624
+ #-------------------------------------------------------------
625
+ # update trust radii
626
+ #-------------------------------------------------------------
627
+ self.update_trust_radius_conditionally(optimizer_instances, B_e, pre_B_e, pre_B_g, pre_move_vector, geom_num_list)
628
+ self.handle_projection_constraint(projection_constrain)
629
+
630
+ #---------------------------------
631
+ #calculate move vector
632
+ #---------------------------------
633
+
634
+ move_vector_list = self.update_move_vector_list(optimizer_instances,
635
+ B_g,
636
+ pre_B_g,
637
+ pre_geom,
638
+ B_e,
639
+ pre_B_e,
640
+ pre_move_vector,
641
+ initial_geom_num_list,
642
+ g,
643
+ pre_g)
644
+
645
+ #---------------------------------
646
+ # switch step update method
647
+ #---------------------------------
648
+ move_vector, optimizer_instances = self.switch_move_vector(B_g,
649
+ move_vector_list,
650
+ optimizer_instances,
651
+ max_rms_force_switching_threshold=0.05,
652
+ min_rms_force_switching_threshold=0.005
653
+ )
654
+
655
+ if print_flag:
656
+ print("==================================================================================")
657
+
658
+ if np.linalg.norm(move_vector) > self.trust_radii:
659
+ move_vector = self.trust_radii * move_vector/np.linalg.norm(move_vector)
660
+
661
+ if print_flag:
662
+ print("trust radii (unit. ang.): ", self.trust_radii)
663
+ print("step radii (unit. ang.): ", np.linalg.norm(move_vector))
664
+ new_geometry = (geom_num_list - move_vector)
665
+
666
+ new_geometry = new_geometry.reshape(natom, 3)
667
+ move_vector = move_vector.reshape(natom, 3)
668
+
669
+ for i in range(len(optimizer_instances)):
670
+ if print_flag:
671
+ print(f"Optimizer instance {i}: ", optimizer_instances[i])
672
+ if self.newton_tag[i]:
673
+ tmp_hess = optimizer_instances[i].hessian
674
+ tmp_bias_hess = optimizer_instances[i].bias_hessian
675
+ display_eigvals(tmp_hess, tmp_bias_hess, self.element_list, new_geometry)
676
+ if print_flag:
677
+ print("==================================================================================")
678
+ new_geometry *= self.unitval.bohr2angstroms #Bohr -> ang.
679
+ #new_lambda_list : a.u.
680
+ #new_geometry : angstrom
681
+ #move_vector : bohr
682
+ #lambda_movestep : a.u.
683
+
684
+ return new_geometry, np.array(move_vector, dtype="float64"), optimizer_instances
685
+
686
+
687
+
688
+ def display_eigvals(hessian, bias_hessian, element_list, geom):
689
+
690
+ if bias_hessian is not None:
691
+ tmp_hess = hessian
692
+ H = Calculationtools().project_out_hess_tr_and_rot_for_coord(tmp_hess + bias_hessian, element_list, geom, display_eigval=False)
693
+ else:
694
+ tmp_hess = hessian
695
+ H = Calculationtools().project_out_hess_tr_and_rot_for_coord(tmp_hess, element_list, geom, display_eigval=False)
696
+ H = (H + H.T) / 2 # Make sure H is symmetric
697
+ evals, _ = np.linalg.eigh(H)
698
+
699
+ # Filter eigenvalues with absolute value greater than 1e-10
700
+ filtered_evals = evals[np.abs(evals) > 1e-10]
701
+ filtered_evals = np.sort(filtered_evals)
702
+ num_values = len(filtered_evals)
703
+
704
+ print(f"EIGENVALUES (NORMAL COORDINATE, NUMBER OF VALUES: {num_values}):")
705
+ for i in range(0, num_values, 6):
706
+ line = ' '.join(f'{v:12.8f}' for v in filtered_evals[i:i+6])
707
+ print(line)
708
+
709
+