mlatom 3.3.0__tar.gz → 3.4.0__tar.gz

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 (118) hide show
  1. {mlatom-3.3.0/src/mlatom.egg-info → mlatom-3.4.0}/PKG-INFO +3 -3
  2. {mlatom-3.3.0 → mlatom-3.4.0}/README.md +2 -2
  3. {mlatom-3.3.0 → mlatom-3.4.0}/setup.py +1 -1
  4. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatom.py +2 -2
  5. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLtasks.py +22 -5
  6. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1.py +3 -2
  7. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/args_class.py +54 -56
  8. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/conversions.py +2 -2
  9. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/data.py +33 -1
  10. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/doc.py +1 -0
  11. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/header.py +4 -0
  12. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/initial_conditions.py +53 -16
  13. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/ase_interface.py +24 -7
  14. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/gaussian_interface.py +18 -16
  15. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/torchani_interface.py +7 -3
  16. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/log.py +6 -2
  17. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/md.py +1 -1
  18. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/models.py +35 -0
  19. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/namd.py +31 -46
  20. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/ref.json +2 -1
  21. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/simulations.py +158 -34
  22. {mlatom-3.3.0 → mlatom-3.4.0/src/mlatom.egg-info}/PKG-INFO +3 -3
  23. {mlatom-3.3.0 → mlatom-3.4.0}/LICENSE.txt +0 -0
  24. {mlatom-3.3.0 → mlatom-3.4.0}/setup.cfg +0 -0
  25. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLTPA.py +0 -0
  26. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/ML_NEA.py +0 -0
  27. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF +0 -0
  28. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/A_KRR.f90 +0 -0
  29. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/A_KRR_kernel.f90 +0 -0
  30. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/D_CoulombMatrix.f90 +0 -0
  31. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/D_ID.f90 +0 -0
  32. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/D_rel2eq.f90 +0 -0
  33. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/MLatomF.f90 +0 -0
  34. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/MLatomFInfo.f90 +0 -0
  35. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/MLmodel.f90 +0 -0
  36. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/Makefile +0 -0
  37. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/Makefile.intel +0 -0
  38. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/__init__.py +0 -0
  39. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/analyze.f90 +0 -0
  40. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/constants.f90 +0 -0
  41. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/cs.cpp +0 -0
  42. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/dataset.f90 +0 -0
  43. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/mathUtils.f90 +0 -0
  44. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/molDescr.f90 +0 -0
  45. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/optionsModule.f90 +0 -0
  46. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/precision.f90 +0 -0
  47. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/recover.sh +0 -0
  48. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/sampling.f90 +0 -0
  49. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/statistics.f90 +0 -0
  50. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/stopper.f90 +0 -0
  51. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/strings.f90 +0 -0
  52. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/timing.f90 +0 -0
  53. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/MLatomF_src/types.f90 +0 -0
  54. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/__init__.py +0 -0
  55. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/__init__.py +0 -0
  56. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv0.pt +0 -0
  57. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv1.pt +0 -0
  58. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv2.pt +0 -0
  59. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv3.pt +0 -0
  60. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv4.pt +0 -0
  61. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv5.pt +0 -0
  62. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv6.pt +0 -0
  63. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_cc_cv7.pt +0 -0
  64. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv0.pt +0 -0
  65. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv1.pt +0 -0
  66. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv2.pt +0 -0
  67. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv3.pt +0 -0
  68. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv4.pt +0 -0
  69. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv5.pt +0 -0
  70. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv6.pt +0 -0
  71. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/aiqm1_model/aiqm1_dft_cv7.pt +0 -0
  72. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/ccsdtstarcbs.py +0 -0
  73. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/composite_methods.py +0 -0
  74. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/constants.py +0 -0
  75. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/cs.so +0 -0
  76. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/decorators.py +0 -0
  77. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/fortran/KREG.f90 +0 -0
  78. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/fortran/__init__.py +0 -0
  79. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/fortran/compile.py +0 -0
  80. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/fortran/mathUtils.f90 +0 -0
  81. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/fortran/stopper.f90 +0 -0
  82. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interface_MLatomF.py +0 -0
  83. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/__init__.py +0 -0
  84. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/columbus_interface.py +0 -0
  85. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/dftd4_interface.py +0 -0
  86. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/dpmd_interface.py +0 -0
  87. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/gap_interface.py +0 -0
  88. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/mace_interface.py +0 -0
  89. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/mndo_interface.py +0 -0
  90. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/orca_interface.py +0 -0
  91. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/physnet_interface.py +0 -0
  92. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/pyscf_interface.py +0 -0
  93. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/sgdml_interface.py +0 -0
  94. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/sparrow_interface.py +0 -0
  95. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/turbomole_interface.py +0 -0
  96. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/interfaces/xtb_interface.py +0 -0
  97. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/kreg_api.py +0 -0
  98. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/md2vibr.py +0 -0
  99. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/md2vibr_cmd.py +0 -0
  100. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/md_cmd.py +0 -0
  101. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/mlatom_gui.py +0 -0
  102. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/mltpa/__init__.py +0 -0
  103. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/mltpa/mff.txt +0 -0
  104. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/mltpa/mltpa2022_2.pkl +0 -0
  105. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/mltpa/mltpa2022_2_new_.pkl +0 -0
  106. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/plot.py +0 -0
  107. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/shell_cmd.py +0 -0
  108. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/sliceData.py +0 -0
  109. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/stats.py +0 -0
  110. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/stopper.py +0 -0
  111. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/thermostat.py +0 -0
  112. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/utils.py +0 -0
  113. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom/xyz.py +0 -0
  114. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom.egg-info/SOURCES.txt +0 -0
  115. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom.egg-info/dependency_links.txt +0 -0
  116. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom.egg-info/entry_points.txt +0 -0
  117. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom.egg-info/requires.txt +0 -0
  118. {mlatom-3.3.0 → mlatom-3.4.0}/src/mlatom.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mlatom
3
- Version: 3.3.0
3
+ Version: 3.4.0
4
4
  Summary: A Package for Atomistic Simulations with Machine Learning
5
5
  Home-page: http://mlatom.com
6
6
  Author: Pavlo O. Dral
@@ -27,7 +27,7 @@ Requires-Dist: tqdm
27
27
  # About Program
28
28
  MLatom: a Package for Atomistic Simulations with Machine Learning
29
29
 
30
- Version 3.3.0
30
+ Version 3.4.0
31
31
 
32
32
  **Official website**: http://mlatom.com/
33
33
  **Manual**: http://mlatom.com/manual/
@@ -60,7 +60,7 @@ When this Software or its derivatives are used in scientific publications, it sh
60
60
  * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Mario Barbatti, Olexandr Isayev, Cheng Wang, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Lina Zhang, Shuang Zhang, Arif Ullah, Quanhao Zhang, Yanchi Ou. [MLatom 3: A Platform for Machine Learning-enhanced Computational Chemistry Simulations and Workflows](https://doi.org/10.1021/acs.jctc.3c01203). *J. Chem. Theory Comput.* **2024**, *20*, 1193--1213.
61
61
  * Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti. [MLatom 2: An Integrative Platform for Atomistic Machine Learning](http://doi.org/10.1007/s41061-021-00339-5). *Top. Curr. Chem.* **2021**, *379*, 27.
62
62
  * Pavlo O. Dral. [MLatom: A Program Package for Quantum Chemical Research Assisted by Machine Learning](http://dx.doi.org/10.1002/jcc.26004). *J. Comput. Chem.* **2019**, *40*, 2339--2347.
63
- * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Shuang Zhang, Lina Zhang, Arif Ullah, Quanhao Zhang, Sebastian V. Pios, Yanchi Ou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 3.3.0, Xiamen University, Xiamen, China, 2013-2024.
63
+ * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Shuang Zhang, Lina Zhang, Arif Ullah, Quanhao Zhang, Sebastian V. Pios, Yanchi Ou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 3.4.0, Xiamen University, Xiamen, China, 2013-2024.
64
64
  [MLatom.com](http://mlatom.com).
65
65
 
66
66
  The citations for MLatom's interfaces and features shall be eventually
@@ -1,7 +1,7 @@
1
1
  # About Program
2
2
  MLatom: a Package for Atomistic Simulations with Machine Learning
3
3
 
4
- Version 3.3.0
4
+ Version 3.4.0
5
5
 
6
6
  **Official website**: http://mlatom.com/
7
7
  **Manual**: http://mlatom.com/manual/
@@ -34,7 +34,7 @@ When this Software or its derivatives are used in scientific publications, it sh
34
34
  * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Mario Barbatti, Olexandr Isayev, Cheng Wang, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Lina Zhang, Shuang Zhang, Arif Ullah, Quanhao Zhang, Yanchi Ou. [MLatom 3: A Platform for Machine Learning-enhanced Computational Chemistry Simulations and Workflows](https://doi.org/10.1021/acs.jctc.3c01203). *J. Chem. Theory Comput.* **2024**, *20*, 1193--1213.
35
35
  * Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti. [MLatom 2: An Integrative Platform for Atomistic Machine Learning](http://doi.org/10.1007/s41061-021-00339-5). *Top. Curr. Chem.* **2021**, *379*, 27.
36
36
  * Pavlo O. Dral. [MLatom: A Program Package for Quantum Chemical Research Assisted by Machine Learning](http://dx.doi.org/10.1002/jcc.26004). *J. Comput. Chem.* **2019**, *40*, 2339--2347.
37
- * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Shuang Zhang, Lina Zhang, Arif Ullah, Quanhao Zhang, Sebastian V. Pios, Yanchi Ou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 3.3.0, Xiamen University, Xiamen, China, 2013-2024.
37
+ * Pavlo O. Dral, Fuchun Ge, Yi-Fan Hou, Peikun Zheng, Yuxinxin Chen, Bao-Xin Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Shuang Zhang, Lina Zhang, Arif Ullah, Quanhao Zhang, Sebastian V. Pios, Yanchi Ou, MLatom: A Package for Atomistic Simulations with Machine Learning, version 3.4.0, Xiamen University, Xiamen, China, 2013-2024.
38
38
  [MLatom.com](http://mlatom.com).
39
39
 
40
40
  The citations for MLatom's interfaces and features shall be eventually
@@ -43,7 +43,7 @@ with open(os.path.join(here, 'README.md')) as f:
43
43
 
44
44
  setup(
45
45
  name = pkg_name,
46
- version = "3.3.0",
46
+ version = "3.4.0",
47
47
  author = "Pavlo O. Dral",
48
48
  author_email = "admin@mlatom.com",
49
49
  license = 'MIT (modified)',
@@ -4,7 +4,7 @@
4
4
  !---------------------------------------------------------------------------!
5
5
  ! !
6
6
  ! MLatom: a Package for Atomistic Simulations with Machine Learning !
7
- ! MLatom 3.3.0 !
7
+ ! MLatom 3.4.0 !
8
8
  ! @ !
9
9
  ! Xiamen Atomistic Computing Suite (XACS) !
10
10
  ! !
@@ -36,7 +36,7 @@
36
36
  ! Xue, Max Pinheiro Jr, Yuming Su, Yiheng Dai, Yangtao Chen, Shuang Zhang, !
37
37
  ! Lina Zhang, Arif Ullah, Quanhao Zhang, Sebastian V. Pios, Yanchi Ou, !
38
38
  ! MLatom: A Package for Atomistic Simulations with Machine Learning, !
39
- ! version 3.3.0, Xiamen University, Xiamen, China, 2013-2024. !
39
+ ! version 3.4.0, Xiamen University, Xiamen, China, 2013-2024. !
40
40
  ! !
41
41
  ! The citations for MLatom's interfaces and features shall be eventually !
42
42
  ! included too. See header.py, ref.json and http://mlatom.com. !
@@ -367,7 +367,10 @@ def geomopt(args):
367
367
  molDB = loading_data(XYZfile=args.XYZfile, charges=args.charges, multiplicities=args.multiplicities)
368
368
  model = loading_model(args)
369
369
  fname = args.optXYZ
370
- if os.path.exists(fname): stopper.stopMLatom(f'File {fname} already exists; please delete or rename it')
370
+ # if os.path.exists(fname): stopper.stopMLatom(f'File {fname} already exists; please delete or rename it')
371
+ if os.path.exists(fname):
372
+ os.remove(fname)
373
+ print(f' * Warning * File {fname} already exists; MLatom will overwrite {fname}')
371
374
  db_opt = data.molecular_database()
372
375
  kwargs = {}
373
376
  if args.optProg: kwargs['program'] = args.optprog
@@ -375,16 +378,28 @@ def geomopt(args):
375
378
  if args.ase.fmax: kwargs['convergence_criterion_for_forces'] = float(args.ase.fmax)
376
379
  if args.ase.steps: kwargs['maximum_number_of_steps'] = int(args.ase.steps)
377
380
  if args.ase.optimizer: kwargs['optimization_algorithm'] = args.ase.optimizer
381
+ if len(molDB.molecules)<=10:
382
+ kwargs['print_properties'] = 'all'
383
+ else:
384
+ kwargs['print_properties'] = 'min'
385
+ if args.printall: kwargs['print_properties'] = 'all'
386
+ if args.printmin: kwargs['print_properties'] = None
387
+ if args.dumpopttrajs:
388
+ kwargs['dump_trajectory_interval'] = 1
389
+ else:
390
+ kwargs['dump_trajectory_interval'] = None
391
+ kwargs['format'] = 'json'
378
392
  for imol, mol in enumerate(molDB):
379
393
  mol.number = imol+1
394
+ print(' %s ' % ('='*78))
395
+ print(' Optimization of molecule %d' % (imol+1))
396
+ print(' %s \n' % ('='*78))
397
+ kwargs['filename'] = f'opttraj{imol+1}.json'
380
398
  geomopt = simulations.optimize_geometry(model=model,
381
399
  initial_molecule=mol,
382
400
  **kwargs)
383
401
  db_opt.molecules.append(geomopt.optimized_molecule)
384
- print(' %s ' % ('='*78))
385
- print(' Optimization of molecule %d' % (imol+1))
386
- print(' %s \n' % ('='*78))
387
- print(f' {"Iteration":^10s} {"Energy (Hartree)":^25s}') # units?
402
+ print(f'\n\n {"Iteration":^10s} {"Energy (Hartree)":^25s}')
388
403
  for step in geomopt.optimization_trajectory.steps:
389
404
  print(' %10d %25.13f' % (step.step+1, step.molecule.energy))
390
405
  if args.AIQM1 or args.AIQM1DFT or args.AIQM1DFTstar:
@@ -522,6 +537,8 @@ def MLTPA(args):
522
537
  # Reusable functions below. Name with -ing form
523
538
  def loading_data(XYZfile, Yfile=None, YgradXYZfile=None, charges=None, multiplicities=None):
524
539
  assert XYZfile, 'please provide data file(s) needed.'
540
+ if not os.path.exists(XYZfile):
541
+ stopper.stopMLatom(f'xyz file {XYZfile} is not found!')
525
542
  molecular_database = data.molecular_database.from_xyz_file(XYZfile)
526
543
  if Yfile:
527
544
  molecular_database.add_scalar_properties_from_file(Yfile)
@@ -80,8 +80,9 @@ class aiqm1(models.torchani_model):
80
80
 
81
81
  for atom in molecule.atoms:
82
82
  if not atom.atomic_number in [1, 6, 7, 8]:
83
- print(' * Warning * Molecule contains elements other than CHNO, no calculations performed')
84
- return
83
+ errmsg = ' * Warning * Molecule contains elements other than CHNO, no calculations performed'
84
+ # print(errmsg)
85
+ raise ValueError(errmsg)
85
86
 
86
87
  if nstates >1:
87
88
  mol_copy = molecule.copy()
@@ -202,53 +202,53 @@ class ArgsBase():
202
202
  @staticmethod
203
203
  def _args_extractor(string: str) -> List[str]:
204
204
  pair_dict = {'(': ')', '[': ']', '{': '}', '<': '>', "'": "'", '"': '"'}
205
- pair_level = 0
206
205
  pair_right: List[str] = []
207
206
  tmp = ''
208
- prev = ''
207
+ comment = False
209
208
  out_string_list: List[str] = []
210
209
  for chr in string:
211
210
  pair_right_last = pair_right[-1] if pair_right else ''
211
+ if chr == '#':
212
+ comment = True
213
+ if chr == '\n':
214
+ comment = False
215
+ if comment:
216
+ continue
212
217
  if chr in pair_dict.keys() and chr != pair_right_last:
213
- pair_level += 1
214
218
  pair_right.append(pair_dict[chr])
215
219
  elif chr == pair_right_last:
216
- pair_level -= 1
217
220
  pair_right.pop()
218
- elif chr == ' ' and pair_level == 0 and prev.strip(): # end
219
- out_string_list.append(tmp)
220
- tmp = ''
221
- prev = chr
222
- continue
223
- if '"' in pair_right or "'" in pair_right:
221
+ if pair_right:
224
222
  tmp += chr
223
+ elif chr in [' ', '\n'] and tmp: # end
224
+ out_string_list.append(tmp.strip())
225
+ tmp = ''
225
226
  else:
226
227
  tmp += chr.strip()
227
- prev = chr
228
- if pair_level:
228
+ if pair_right:
229
229
  stopper.stopMLatom(f'pair character unmatched args: "{tmp}"')
230
230
  else:
231
231
  if tmp: out_string_list.append(tmp)
232
+
232
233
  return out_string_list
233
234
 
234
235
  def parse_input_file(self, file: str):
235
- try:
236
- with open(file) as f:
237
- content = f.read().splitlines()
238
- except:
239
- self._raise_error(f'can not open file {file}! exit!'); exit()
236
+ with open(file) as f:
237
+ content = self._args_extractor(f.read())
240
238
  self.parse_input_content(content)
241
239
 
242
240
  def parse_input_content(self, content: Union[List[str], str]):
243
- help = False
244
241
  if type(content) is str:
245
- content = content.splitlines()
246
- for c in self._clean_input_content(content):
242
+ content = [content]
243
+ _content = []
244
+ for c in content:
245
+ _content.extend(self._args_extractor(c) if '\n' not in c else [c])
246
+ for c in _content:
247
247
  splitted = c.split('=')
248
248
  if len(splitted) == 1:
249
249
  key = splitted[0]
250
250
  if key.lower() in ['help', '-help', '-h', '--help']:
251
- help = True
251
+ self._print_doc()
252
252
  elif key.lower() in self.ignore_list:
253
253
  pass
254
254
  else:
@@ -265,8 +265,6 @@ class ArgsBase():
265
265
  self.data[key] = value
266
266
  else:
267
267
  self._raise_error(f'error happends at your input file, error content:\n {c}')
268
- if help:
269
- self._print_doc()
270
268
 
271
269
  @classmethod
272
270
  def _multi_level_dict(cls, key: str, value: Any) -> Tuple[str, Union[AttributeDict, Dict[str, Union[str, Dict[str, Any]]]]]:
@@ -283,19 +281,7 @@ class ArgsBase():
283
281
  try: Doc.printDoc(self.args_dict)
284
282
  except: self._warning_print('Doc not imported')
285
283
  stopper.stopMLatom('')
286
-
287
- @classmethod
288
- def _clean_input_content(cls, content: List[str]) -> List[str]:
289
- to_return: List[str] = []
290
- for c in content:
291
- usable = c.split('#')[0].strip()
292
- while usable.find(' =') != -1:
293
- usable = usable.replace(' =', '=')
294
- while usable.find('= ') != -1:
295
- usable = usable.replace('= ', '=')
296
- to_return.extend(cls._args_extractor(usable))
297
- return to_return
298
-
284
+
299
285
  @property
300
286
  def args_dict(self) -> Dict[str, Any]:
301
287
  return AttributeDict.normal_dict(self.data)
@@ -616,6 +602,14 @@ class mlatom_args(ArgsBase):
616
602
  'DOF':-6,
617
603
  'linear':0,
618
604
  })
605
+ # geomopt output
606
+ self.add_default_dict_args(
607
+ [
608
+ 'printall', # print out all information in geometry optimization
609
+ 'printmin', # print out minimal infomation in geometry optimization
610
+ 'dumpopttrajs' # whether to dump optimization trajectory
611
+ ], ''
612
+ )
619
613
 
620
614
  self.defualt_args2pass = self.args_string_list(['', None])
621
615
 
@@ -628,23 +622,35 @@ class mlatom_args(ArgsBase):
628
622
  if len(argsraw) == 0:
629
623
  Doc.printDoc({})
630
624
  stopper.stopMLatom('At least one option should be provided')
631
- elif len(argsraw) == 1:
632
- if os.path.exists(argsraw[0]):
633
- # self.parse_input_file(argsraw[0])
634
- self.argsraw = []
635
- with open(argsraw[0]) as f:
636
- content = f.read().splitlines()
637
- for c in self._clean_input_content(content):
638
- self.argsraw += [c]
639
- self.parse_input_content(self.argsraw)
640
- else:
641
- self.parse_input_content(argsraw[0])
642
- elif len(argsraw) >= 2:
625
+ elif len(argsraw) == 1 and os.path.exists(argsraw[0]):
626
+ self.parse_input_file(argsraw[0])
627
+ else:
643
628
  self.parse_input_content(argsraw)
644
629
 
645
630
  self._post_operations()
631
+
632
+ def _post_operations(self):
633
+ if not self.MLprog:
634
+ if self.MLmodelType :
635
+ try: self.MLprog = default_MLprog[self.MLmodelType.lower()]
636
+ except: stopper.stopMLatom('Unkown MLmodelType')
637
+ else:
638
+ self.MLprog = 'MLatomF'
646
639
  self._checkArgs()
647
640
  self._check_hyperopt()
641
+ self._multi_lines_to_file()
642
+
643
+ def _multi_lines_to_file(self):
644
+ import hashlib
645
+ for arg in self.args2pass:
646
+ if '\n' in arg:
647
+ key, value = arg.split('=')
648
+ tmpfile = f"{key}_{hashlib.md5(value.encode('utf-8')).hexdigest()[:6]}"
649
+ if 'xyz' in key.lower():
650
+ tmpfile += '.xyz'
651
+ with open(tmpfile, 'w') as f:
652
+ f.write(value.strip("'").strip('"').strip() + '\n')
653
+ self.parse_input_content([f'{key}={tmpfile}'])
648
654
 
649
655
  def _check_hyperopt(self):
650
656
  self.hyperparameter_optimization = {
@@ -660,14 +666,6 @@ class mlatom_args(ArgsBase):
660
666
  self._hyperopt_str_dict[key.split('.')[-1]] = value
661
667
  if self._hyperopt_str_dict:
662
668
  self.hyperparameter_optimization['optimization_algorithm'] = self.hyperopt.algorithm
663
-
664
- def _post_operations(self):
665
- if not self.MLprog:
666
- if self.MLmodelType :
667
- try: self.MLprog = default_MLprog[self.MLmodelType.lower()]
668
- except: stopper.stopMLatom('Unkown MLmodelType')
669
- else:
670
- self.MLprog = 'MLatomF'
671
669
 
672
670
  def _checkArgs(self):
673
671
  if not self._task:
@@ -2,7 +2,7 @@ import numpy as np
2
2
 
3
3
  def smi2xyz(smi_strings):
4
4
  from openbabel import pybel as pb
5
- if type(smi_strings) == str:
5
+ if isinstance(smi_strings, str):
6
6
  smi_strings = smi_strings.strip().split('\n')
7
7
  xyz_strings = []
8
8
  for smi_string in smi_strings:
@@ -13,7 +13,7 @@ def smi2xyz(smi_strings):
13
13
 
14
14
  def xyz2smi(xyz_strings):
15
15
  from openbabel import pybel as pb
16
- if type(xyz_strings) == str:
16
+ if isinstance(xyz_strings, str):
17
17
  xyz_strings = split_xyz_string(xyz_strings)
18
18
  smi_strings = []
19
19
  for string in xyz_strings:
@@ -585,6 +585,37 @@ class molecule:
585
585
 
586
586
  def align(self, ref, pivot='CoM'):
587
587
  pass
588
+
589
+ def info(self, properties = 'all', return_string=False):
590
+ printstrs = []
591
+ printstrs += [f" Molecule with {len(self.get_element_symbols())} atom(s): {', '.join(self.get_element_symbols())}", '']
592
+ if (properties == 'all' or 'xyz_coordinates' in properties) and 'xyz_coordinates' in self.atoms[0].__dict__:
593
+ printstrs += [f' XYZ coordinates, Angstrom\n']
594
+ iatom = 0
595
+ for atom in self.atoms:
596
+ iatom += 1
597
+ printstrs += [' %-4d %-3s %18.6f %18.6f %18.6f' % (iatom, atom.element_symbol,
598
+ atom.xyz_coordinates[0], atom.xyz_coordinates[1], atom.xyz_coordinates[2])]
599
+ printstrs += ['']
600
+ if (properties == 'all' or 'distance_matrix' in properties) and 'xyz_coordinates' in self.atoms[0].__dict__:
601
+ printstrs += [f' Interatomic distance matrix, Angstrom\n']
602
+ dist_mat = self.get_internuclear_distance_matrix()
603
+ printstrs += [f'{dist_mat}']
604
+ printstrs += ['']
605
+ if (properties == 'all' or 'energy' in properties) and 'energy' in self.__dict__:
606
+ printstrs += [' Energy: %18.6f Hartree\n' % self.energy]
607
+ if (properties == 'all' or 'energy_gradients' in properties) and 'energy_gradients' in self.atoms[0].__dict__:
608
+ printstrs += [f' Energy gradients, Hartree/Angstrom\n']
609
+ iatom = 0
610
+ for atom in self.atoms:
611
+ iatom += 1
612
+ printstrs += [' %-4d %-3s %18.6f %18.6f %18.6f' % (iatom, atom.element_symbol,
613
+ atom.energy_gradients[0], atom.energy_gradients[1], atom.energy_gradients[2])]
614
+ printstrs += ['']
615
+ printstrs += [' Energy gradients norm: %18.6f Hartree/Angstrom\n' % np.linalg.norm(self.energy_gradients)]
616
+ printstr = '\n'.join(printstrs)
617
+ if return_string: return printstr
618
+ else: print(printstr)
588
619
 
589
620
  def __add__(self, obj):
590
621
  if isinstance(obj, molecular_database):
@@ -593,7 +624,8 @@ class molecule:
593
624
  return molecular_database([self] + [obj])
594
625
 
595
626
  def __str__(self):
596
- return f"molecule with {len(self.get_element_symbols())} atom(s): {', '.join(self.get_element_symbols())}"
627
+ printstr = self.info(properties = 'all', return_string=True)
628
+ return printstr
597
629
 
598
630
  def __iter__(self):
599
631
  for atom in self.atoms:
@@ -250,6 +250,7 @@ class Doc():
250
250
  optProg=scipy use scipy package [default]
251
251
  optProg=gaussian use Gaussian program
252
252
  optProg=ASE use ASE
253
+ optProg=geometric use geomeTRIC
253
254
  optxyz=S save optimized geometries in file S [default: optgeoms.xyz]
254
255
  The following options only used for ASE program:
255
256
  ase.fmax=R threshold of maximum force (in eV/A)
@@ -132,6 +132,8 @@ def printHeader(args):
132
132
  if args.geomopt:
133
133
  if 'optprog=ase' in ' '.join(args.args2pass).lower():
134
134
  refItems['Atomic simulation environment (ASE)'] = refs['ASE']
135
+ elif 'optprog=geometric' in ' '.join(args.args2pass).lower():
136
+ refItems['geomeTRIC program'] = refs['geometric']
135
137
  elif 'optprog=gaussian' in ' '.join(args.args2pass).lower():
136
138
  refItems['Gaussian program'] = refs['Gaussian']
137
139
  elif args.freq and 'optprog=pyscf' in ' '.join(args.args2pass).lower():
@@ -174,6 +176,8 @@ def printHeader(args):
174
176
  if args.ts:
175
177
  if 'optprog=ase' in ' '.join(args.args2pass).lower():
176
178
  refItems['Atomic simulation environment (ASE)'] = refs['ASE']
179
+ if 'optprog=geometric' in ' '.join(args.args2pass).lower():
180
+ refItems['geomeTRIC program'] = refs['geometric']
177
181
  elif 'optprog=gaussian' in ' '.join(args.args2pass).lower():
178
182
  refItems['Gaussian program'] = refs['Gaussian']
179
183
  elif "GAUSS_EXEDIR" in os.environ:
@@ -6,7 +6,7 @@ from . import constants
6
6
 
7
7
  !---------------------------------------------------------------------------!
8
8
  ! initial_conditions: Module for generating initial conditions !
9
- ! Implementations by: Yi-Fan Hou & Pavlo O. Dral !
9
+ ! Implementations by: Yi-Fan Hou, Lina Zhang, Fuchun Ge, Pavlo O. Dral !
10
10
  !---------------------------------------------------------------------------!
11
11
  '''
12
12
  import numpy as np
@@ -14,7 +14,13 @@ from . import data
14
14
  from . import stopper
15
15
  from . import constants
16
16
 
17
- def excitation_energy_window_filter(molecular_database=None, model=None, model_predict_kwargs={}, target_excitation_energy=1, window_half_width=0.1, f_max=None, random_seed=None):
17
+ def excitation_energy_window_filter(molecular_database=None,
18
+ model=None,
19
+ model_predict_kwargs={},
20
+ target_excitation_energy=1,
21
+ window_half_width=0.1,
22
+ f_max=None,
23
+ random_seed=None):
18
24
  molDB = molecular_database
19
25
  if not random_seed is None:
20
26
  np.random.seed(random_seed)
@@ -66,16 +72,18 @@ def generate_initial_conditions(molecule=None, generation_method=None, number_of
66
72
  Generate initial conditions
67
73
 
68
74
  Arguments:
69
- molecule (:class:`data.molecule`): Molecule with necessary information
70
- generation_method (str): Initial condition generation method
71
- number_of_initial_conditions (int): Number of initial conditions to generate, 1 by default
72
- file_with_initial_xyz_coordinates (str): File with initial xyz coordinates, only valid for ``generation_method='user-defined'``
73
- file_with_initial_xyz_velocities (str): File with initial xyz velocities, only valid for ``generation_method='user-defined'``
74
- eliminate_angular_momentum (bool): Remove angular momentum from velocities, valid for ``generation_method='random'`` and ``generation_method='wigner'``
75
- degrees_of_freedom (int): Degrees of freedom of the molecule, by default remove translational and rotational degrees of freedom. It can be a negative value, which means that some value is subtracted from 3*Natoms
76
- initial_temperature (float): Initial temperature in Kelvin, control random initial velocities
77
- initial_kinetic_energy (float): Initial kinetic energy in Hartree, control random initial velocities
78
- random_seed (int): Random seed for numpy random number generator
75
+ molecule (:class:`data.molecule`): molecule with necessary information
76
+ generation_method (str): initial condition generation method, see below the table
77
+ number_of_initial_conditions (int): number of initial conditions to generate, 1 by default
78
+ file_with_initial_xyz_coordinates (str): file with initial xyz coordinates, only valid for ``generation_method='user-defined'``
79
+ file_with_initial_xyz_velocities (str): file with initial xyz velocities, only valid for ``generation_method='user-defined'``
80
+ eliminate_angular_momentum (bool): remove angular momentum from velocities, valid for ``generation_method='random'`` and ``generation_method='wigner'``
81
+ degrees_of_freedom (int): degrees of freedom of the molecule, by default remove translational and rotational degrees of freedom. It can be a negative value, which means that some value is subtracted from 3*Natoms
82
+ initial_temperature (float): initial temperature in Kelvin, control random initial velocities
83
+ initial_kinetic_energy (float): initial kinetic energy in Hartree, control random initial velocities
84
+ random_seed (int): random seed for numpy random number generator (do not use unless you want to obtain the same results every time)
85
+ filter_by_energy_window (bool): filter by excitation energy window
86
+ window_filter_kwargs (dict): keyword arguments for filtering the energy window, see below the table
79
87
 
80
88
  .. table::
81
89
  :align: center
@@ -83,13 +91,26 @@ def generate_initial_conditions(molecule=None, generation_method=None, number_of
83
91
  ============================= =============================================
84
92
  generation_method description
85
93
  ============================= =============================================
86
- ``'user-defined'`` (default) Use user-defined initial conditions
87
- ``'random'`` Generate random velocities
88
- ``'maxwell-boltzmann'`` Randomly generate initial velocities from Maxwell-Boltzmann distribution
89
- ``'wigner'`` Use Wigner sampling as implemented in `Newton-X <https://doi.org/10.1021/acs.jctc.2c00804>`__
94
+ ``'user-defined'`` (default) use user-defined initial conditions
95
+ ``'random'`` generate random velocities
96
+ ``'maxwell-boltzmann'`` randomly generate initial velocities from Maxwell-Boltzmann distribution
97
+ ``'wigner'`` use Wigner sampling as implemented in `Newton-X <https://doi.org/10.1021/acs.jctc.2c00804>`__
90
98
  ============================= =============================================
91
99
 
92
100
 
101
+ .. table::
102
+ :align: center
103
+
104
+ ================================ ================================================================================================================
105
+ window_filter_kwargs description
106
+ ================================ ================================================================================================================
107
+ model model or method that can calculate excitation energies and oscillator strengths
108
+ model_predict_kwargs keyword arguments for above model, typically ``nstates`` specifying how many states to calculate
109
+ target_excitation_energy (float) in eV
110
+ window_half_width (float) in eV
111
+ random_seed (int) random seed for numpy random number generator (do not use unless you want to obtain the same results every time)
112
+ ================================ ================================================================================================================
113
+
93
114
  Returns:
94
115
  A molecular database (:class:`ml.data.molecular_database`) with ``number_of_initial_conditions`` initial conditions
95
116
 
@@ -113,6 +134,22 @@ def generate_initial_conditions(molecule=None, generation_method=None, number_of
113
134
  generation_method = 'wigner',
114
135
  number_of_initial_conditions = 1)
115
136
 
137
+ # Sample with filtering by excitation energy window. Requires the model for calculating excitation energies and oscillator strengths.
138
+ model = ml.models.methods(method='AIQM1')
139
+ model_predict_kwargs={'nstates':9} # requests calculation of 9 electronic states
140
+ window_filter_kwargs={'model':model,
141
+ 'model_predict_kwargs':model_predict_kwargs,
142
+ 'target_excitation_energy':5.7, # eV
143
+ 'window_half_width':0.1, # eV}
144
+ init_cond_db = ml.generate_initial_conditions(molecule=mol,
145
+ generation_method='wigner',
146
+ number_of_initial_conditions=5,
147
+ initial_temperature=0,
148
+ random_seed=0,
149
+ use_hessian=False,
150
+ filter_by_energy_window=True,
151
+ window_filter_kwargs=window_filter_kwargs)
152
+
116
153
  .. note::
117
154
 
118
155
  Wigner sampling needs Hessian matrix. You can use ``ml.models.methods.predict(molecule=mol,calculate_hessian=True)`` to get Hessian matrix.
@@ -24,6 +24,11 @@ def optimize_geometry(initial_molecule, model, convergence_criterion_for_forces,
24
24
  if optimization_algorithm == None:
25
25
  optimization_algorithm = 'LBFGS'
26
26
 
27
+ if 'model_predict_kwargs' in kwargs:
28
+ model_predict_kwargs = kwargs['model_predict_kwargs']
29
+ else:
30
+ model_predict_kwargs = {}
31
+
27
32
  optimization_trajectory = data.molecular_trajectory()
28
33
  globals()['initial_molecule'] = initial_molecule
29
34
  globals()['optimization_trajectory'] = optimization_trajectory
@@ -64,7 +69,7 @@ def optimize_geometry(initial_molecule, model, convergence_criterion_for_forces,
64
69
 
65
70
  # atoms.set_calculator(MLatomCalculator(model=model, save_optimization_trajectory=True))
66
71
  # atoms.set_calculator() is deprecated
67
- atoms.calc = MLatomCalculator(model=model, save_optimization_trajectory=True)
72
+ atoms.calc = MLatomCalculator(model=model, save_optimization_trajectory=True, model_predict_kwargs=model_predict_kwargs)
68
73
 
69
74
  from ase import optimize
70
75
  opt = optimize.__dict__[optimization_algorithm](atoms)
@@ -86,16 +91,26 @@ def transition_state(initial_molecule, model,
86
91
  **kwargs):
87
92
  if optimization_algorithm == None:
88
93
  optimization_algorithm = 'dimer'
94
+
95
+ if 'model_predict_kwargs' in kwargs:
96
+ # model_predict_kwargs = kwargs['model_predict_kwargs']
97
+ model_predict_kwargs = kwargs.pop('model_predict_kwargs')
98
+ else:
99
+ model_predict_kwargs = {}
100
+
89
101
  if optimization_algorithm.casefold() == 'dimer'.casefold():
90
102
  return dimer_method(initial_molecule, model,
103
+ model_predict_kwargs,
91
104
  convergence_criterion_for_forces,
92
105
  maximum_number_of_steps, **kwargs)
93
106
  elif optimization_algorithm.casefold() == 'NEB'.casefold():
94
107
  return nudged_elastic_band(initial_molecule, kwargs.pop('final_molecule'), model,
95
- convergence_criterion_for_forces,
96
- maximum_number_of_steps, **kwargs)
108
+ model_predict_kwargs,
109
+ convergence_criterion_for_forces,
110
+ maximum_number_of_steps, **kwargs)
97
111
 
98
112
  def dimer_method(initial_molecule, model,
113
+ model_predict_kwargs,
99
114
  convergence_criterion_for_forces,
100
115
  maximum_number_of_steps, **kwargs):
101
116
  optimization_trajectory = data.molecular_trajectory()
@@ -107,7 +122,7 @@ def dimer_method(initial_molecule, model,
107
122
  initial_molecule.write_file_with_xyz_coordinates(filename=xyzfilename)
108
123
  atoms = io.read(xyzfilename, index=':', format='xyz')[0]
109
124
 
110
- atoms.calc = MLatomCalculator(model=model, save_optimization_trajectory=True)
125
+ atoms.calc = MLatomCalculator(model=model, model_predict_kwargs= model_predict_kwargs, save_optimization_trajectory=True)
111
126
 
112
127
  from ase.dimer import DimerControl, MinModeAtoms, MinModeTranslate
113
128
 
@@ -121,6 +136,7 @@ def dimer_method(initial_molecule, model,
121
136
  return optimization_trajectory
122
137
 
123
138
  def nudged_elastic_band(initial_molecule, final_molecule, model,
139
+ model_predict_kwargs,
124
140
  convergence_criterion_for_forces,
125
141
  maximum_number_of_steps,
126
142
  number_of_middle_images=3, **kwargs):
@@ -144,7 +160,7 @@ def nudged_elastic_band(initial_molecule, final_molecule, model,
144
160
  neb = NEB(images, **kwargs)
145
161
  neb.interpolate()
146
162
  for image in images[1:number_of_middle_images+1]:
147
- image.calc = MLatomCalculator(model=model, save_optimization_trajectory=True)
163
+ image.calc = MLatomCalculator(model=model, model_predict_kwargs= model_predict_kwargs, save_optimization_trajectory=True)
148
164
  optimizer = MDMin(neb, trajectory='A2B.traj')
149
165
  optimizer.run(fmax=convergence_criterion_for_forces,
150
166
  steps=maximum_number_of_steps)
@@ -153,9 +169,10 @@ def nudged_elastic_band(initial_molecule, final_molecule, model,
153
169
 
154
170
  class MLatomCalculator(Calculator):
155
171
  implemented_properties = ['energy', 'forces']
156
- def __init__(self, model, save_optimization_trajectory = False):
172
+ def __init__(self, model, model_predict_kwargs, save_optimization_trajectory = False):
157
173
  super(MLatomCalculator, self).__init__()
158
174
  self.model = model
175
+ self.model_predict_kwargs = model_predict_kwargs
159
176
  self.save_optimization_trajectory = save_optimization_trajectory
160
177
 
161
178
  def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes):
@@ -172,7 +189,7 @@ class MLatomCalculator(Calculator):
172
189
  coordinates = mol_from_file.xyz_coordinates
173
190
  current_molecule.xyz_coordinates = coordinates
174
191
 
175
- self.model.predict(molecule=current_molecule, calculate_energy=True, calculate_energy_gradients=True)
192
+ self.model._predict_geomopt(molecule=current_molecule, calculate_energy=True, calculate_energy_gradients=True, **self.model_predict_kwargs)
176
193
  if not 'energy' in current_molecule.__dict__:
177
194
  raise ValueError('model did not return any energy')
178
195