mlatom 2.0.5__tar.gz → 2.1.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 (100) hide show
  1. {MLatom-2.0.5 → MLatom-2.1.0}/PKG-INFO +3 -3
  2. {MLatom-2.0.5 → MLatom-2.1.0}/README.md +2 -2
  3. {MLatom-2.0.5 → MLatom-2.1.0}/setup.py +1 -1
  4. MLatom-2.1.0/src/MLatom/AIQM1.py +463 -0
  5. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatom.py +18 -5
  6. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLtasks.py +10 -0
  7. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/README +4 -4
  8. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv0.pt +0 -0
  9. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv1.pt +0 -0
  10. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv2.pt +0 -0
  11. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv3.pt +0 -0
  12. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv4.pt +0 -0
  13. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv5.pt +0 -0
  14. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv6.pt +0 -0
  15. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv7.pt +0 -0
  16. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv0.pt +0 -0
  17. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv1.pt +0 -0
  18. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv2.pt +0 -0
  19. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv3.pt +0 -0
  20. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv4.pt +0 -0
  21. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv5.pt +0 -0
  22. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv6.pt +0 -0
  23. MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv7.pt +0 -0
  24. MLatom-2.1.0/src/MLatom/calculator.py +46 -0
  25. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/doc.py +65 -4
  26. MLatom-2.1.0/src/MLatom/geomopt.py +421 -0
  27. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/header.py +15 -0
  28. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/ref.json +8 -2
  29. MLatom-2.1.0/src/MLatom/thermo.py +163 -0
  30. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom.egg-info/PKG-INFO +3 -3
  31. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom.egg-info/SOURCES.txt +21 -0
  32. {MLatom-2.0.5 → MLatom-2.1.0}/LICENSE.txt +0 -0
  33. {MLatom-2.0.5 → MLatom-2.1.0}/setup.cfg +0 -0
  34. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/LICENSE.CC-BY-NC-ND-4.0 +0 -0
  35. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/ML_NEA.py +0 -0
  36. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF +0 -0
  37. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/A_KRR.f90 +0 -0
  38. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/A_KRR_kernel.f90 +0 -0
  39. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/D_CoulombMatrix.f90 +0 -0
  40. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/D_rel2eq.f90 +0 -0
  41. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLatomF.f90 +0 -0
  42. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLatomFInfo.f90 +0 -0
  43. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLmodel.f90 +0 -0
  44. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/Makefile +0 -0
  45. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/Makefile.intel +0 -0
  46. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/analyze.f90 +0 -0
  47. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/constants.f90 +0 -0
  48. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/cs.cpp +0 -0
  49. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/dataset.f90 +0 -0
  50. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/mathUtils.f90 +0 -0
  51. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/molDescr.f90 +0 -0
  52. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/optionsModule.f90 +0 -0
  53. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/precision.f90 +0 -0
  54. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/sampling.f90 +0 -0
  55. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/statistics.f90 +0 -0
  56. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/stopper.f90 +0 -0
  57. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/strings.f90 +0 -0
  58. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/timing.f90 +0 -0
  59. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/MLatomF_src/types.f90 +0 -0
  60. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/__init__.py +0 -0
  61. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/args_class.py +0 -0
  62. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/cs.so +0 -0
  63. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/documentation/installation.txt +0 -0
  64. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/E_FCI_451.dat +0 -0
  65. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/E_UHF_451.dat +0 -0
  66. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/R_451.dat +0 -0
  67. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/isubtrain.dat +0 -0
  68. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/itest.dat +0 -0
  69. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/itrain.dat +0 -0
  70. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/ivalidate.dat +0 -0
  71. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/mlatom.inp +0 -0
  72. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/mlatom.saved +0 -0
  73. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/example/test.sh +0 -0
  74. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interface_MLatomF.py +0 -0
  75. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/DP_inference.py +0 -0
  76. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/__init__.py +0 -0
  77. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +0 -0
  78. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/template.json +0 -0
  79. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/GAP/__init__.py +0 -0
  80. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/GAP/interface_GAP.py +0 -0
  81. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/PhysNet_predict.py +0 -0
  82. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/PhysNet_train.py +0 -0
  83. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/__init__.py +0 -0
  84. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/interface_PhysNet.py +0 -0
  85. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/TorchANI_predict.py +0 -0
  86. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/TorchANI_train.py +0 -0
  87. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/__init__.py +0 -0
  88. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/interface_TorchANI.py +0 -0
  89. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/__init__.py +0 -0
  90. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/__init__.py +0 -0
  91. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/interface_sGDML.py +0 -0
  92. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +0 -0
  93. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/mlatom_gui.py +0 -0
  94. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/shell_cmd.py +0 -0
  95. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/sliceData.py +0 -0
  96. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom/stopper.py +0 -0
  97. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom.egg-info/dependency_links.txt +0 -0
  98. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom.egg-info/entry_points.txt +0 -0
  99. {MLatom-2.0.5 → MLatom-2.1.0}/src/MLatom.egg-info/requires.txt +0 -0
  100. {MLatom-2.0.5 → MLatom-2.1.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: 2.0.5
3
+ Version: 2.1.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
@@ -122,7 +122,7 @@ MLatom also provides interfaces to some third-party software where extra ML mode
122
122
 
123
123
  # About Program
124
124
  MLatom: a Package for Atomistic Simulations with Machine Learning
125
- Version 2.0.5
125
+ Version 2.1.0
126
126
  http://mlatom.com/
127
127
 
128
128
  Copyright (c) 2013-2021 Pavlo O. Dral
@@ -136,7 +136,7 @@ Cite as:
136
136
 
137
137
  1. Pavlo O. Dral, J. Comput. Chem. 2019, 40, 2339-2347
138
138
  2. Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27
139
- 3. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.0.5, Xiamen University, Xiamen, China, 2013-2021.
139
+ 3. Pavlo O. Dral, Peikun Zheng, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.1.0, Xiamen University, Xiamen, China, 2013-2021.
140
140
 
141
141
 
142
142
  # License
@@ -104,7 +104,7 @@ MLatom also provides interfaces to some third-party software where extra ML mode
104
104
 
105
105
  # About Program
106
106
  MLatom: a Package for Atomistic Simulations with Machine Learning
107
- Version 2.0.5
107
+ Version 2.1.0
108
108
  http://mlatom.com/
109
109
 
110
110
  Copyright (c) 2013-2021 Pavlo O. Dral
@@ -118,7 +118,7 @@ Cite as:
118
118
 
119
119
  1. Pavlo O. Dral, J. Comput. Chem. 2019, 40, 2339-2347
120
120
  2. Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27
121
- 3. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.0.5, Xiamen University, Xiamen, China, 2013-2021.
121
+ 3. Pavlo O. Dral, Peikun Zheng, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.1.0, Xiamen University, Xiamen, China, 2013-2021.
122
122
 
123
123
 
124
124
  # License
@@ -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 = "2.0.5",
46
+ version = "2.1.0",
47
47
  author = "Pavlo O. Dral",
48
48
  author_email = "admin@mlatom.com",
49
49
  license = 'CC BY-NC-ND 4.0', # https://creativecommons.org/licenses/by-nc-nd/4.0/
@@ -0,0 +1,463 @@
1
+ #!/usr/bin/env python3
2
+ '''
3
+ !---------------------------------------------------------------------------!
4
+ ! AIQM1: Artificial intelligence quantum-mechanical method 1 !
5
+ ! Implementations by: Peikung Zheng !
6
+ !---------------------------------------------------------------------------!
7
+ '''
8
+ import numpy as np
9
+ import os
10
+ import sys
11
+ from collections import Counter
12
+ import stopper
13
+ import json
14
+ import struct
15
+ import re
16
+ #import time
17
+ import warnings
18
+ warnings.filterwarnings("ignore")
19
+
20
+ mlatomdir=os.path.dirname(__file__)
21
+ bohr2a = 0.52917721067
22
+
23
+ class AIQM1Cls(object):
24
+ def __init__(self, argsAIQM1 = sys.argv[1:]):
25
+
26
+ args.parse(argsAIQM1)
27
+ self.mndobin = args.mndobin
28
+ self.dftd4bin = args.dftd4bin
29
+
30
+ self.xyzfile = args.xyzfile
31
+ self.device = args.device
32
+ self.level = args.level
33
+ self.d4 = args.d4
34
+ self.model_index = args.model_index
35
+ self.mndokw = args.mndokw
36
+ self.yestfile = args.yestfile
37
+ self.ygradestfile = args.ygradxyzestfile
38
+ self.hessianestfile = args.hessianestfile
39
+ self.hesscalc = args.hesscalc
40
+ self.species_order = [1, 6, 7, 8]
41
+ self.dftsae = [-4.27888067e-02, -3.34869833e+01, -4.69896148e+01, -6.30294433e+01]
42
+ self.ccsae = [-4.29365862e-02, -3.34329586e+01, -4.69301173e+01, -6.29634763e+01]
43
+
44
+ def define_aev(self):
45
+ Rcr = 5.2000e+00
46
+ Rca = 4.0000e+00
47
+ EtaR = torch.tensor([1.6000000e+01], device=self.device)
48
+ ShfR = torch.tensor([9.0000000e-01, 1.1687500e+00, 1.4375000e+00, 1.7062500e+00, 1.9750000e+00, 2.2437500e+00, 2.5125000e+00, 2.7812500e+00, 3.0500000e+00, 3.3187500e+00, 3.5875000e+00, 3.8562500e+00, 4.1250000e+00, 4.3937500e+00, 4.6625000e+00, 4.9312500e+00], device=self.device)
49
+ Zeta = torch.tensor([3.2000000e+01], device=self.device)
50
+ ShfZ = torch.tensor([1.9634954e-01, 5.8904862e-01, 9.8174770e-01, 1.3744468e+00, 1.7671459e+00, 2.1598449e+00, 2.5525440e+00, 2.9452431e+00], device=self.device)
51
+ EtaA = torch.tensor([8.0000000e+00], device=self.device)
52
+ ShfA = torch.tensor([9.0000000e-01, 1.6750000e+00, 2.4499998e+00, 3.2250000e+00], device=self.device)
53
+ num_species = len(self.species_order)
54
+ aev_computer = torchani.AEVComputer(Rcr, Rca, EtaR, ShfR, EtaA, Zeta, ShfA, ShfZ, num_species)
55
+ self.aev_computer = aev_computer
56
+
57
+ def define_nn(self):
58
+ aev_dim = self.aev_computer.aev_length
59
+ H_network = torch.nn.Sequential(
60
+ torch.nn.Linear(aev_dim, 160),
61
+ torch.nn.GELU(),
62
+ torch.nn.Linear(160, 128),
63
+ torch.nn.GELU(),
64
+ torch.nn.Linear(128, 96),
65
+ torch.nn.GELU(),
66
+ torch.nn.Linear(96, 1)
67
+ )
68
+
69
+ C_network = torch.nn.Sequential(
70
+ torch.nn.Linear(aev_dim, 144),
71
+ torch.nn.GELU(),
72
+ torch.nn.Linear(144, 112),
73
+ torch.nn.GELU(),
74
+ torch.nn.Linear(112, 96),
75
+ torch.nn.GELU(),
76
+ torch.nn.Linear(96, 1)
77
+ )
78
+
79
+ N_network = torch.nn.Sequential(
80
+ torch.nn.Linear(aev_dim, 128),
81
+ torch.nn.GELU(),
82
+ torch.nn.Linear(128, 112),
83
+ torch.nn.GELU(),
84
+ torch.nn.Linear(112, 96),
85
+ torch.nn.GELU(),
86
+ torch.nn.Linear(96, 1)
87
+ )
88
+
89
+ O_network = torch.nn.Sequential(
90
+ torch.nn.Linear(aev_dim, 128),
91
+ torch.nn.GELU(),
92
+ torch.nn.Linear(128, 112),
93
+ torch.nn.GELU(),
94
+ torch.nn.Linear(112, 96),
95
+ torch.nn.GELU(),
96
+ torch.nn.Linear(96, 1)
97
+ )
98
+
99
+ nn = torchani.ANIModel([H_network, C_network, N_network, O_network])
100
+ #print(nn)
101
+ self.nn = nn
102
+
103
+ def load_models(self):
104
+ dirname = os.path.join(mlatomdir, 'aiqm1_model')
105
+ method = 'aiqm1_' + self.level
106
+ models = list()
107
+ if self.model_index is None:
108
+ for i in range(8):
109
+ self.define_nn()
110
+ checkpoint = torch.load(os.path.join(dirname, f'{method}_cv{i}.pt'), map_location=self.device)
111
+ self.nn.load_state_dict(checkpoint['nn'])
112
+ model = torchani.nn.Sequential(self.aev_computer, self.nn).to(self.device).double()
113
+ models.append(model)
114
+ else:
115
+ self.define_nn()
116
+ checkpoint = torch.load(os.path.join(dirname, f'{method}_cv{self.model_index}.pt'), map_location=self.device)
117
+ self.nn.load_state_dict(checkpoint['nn'])
118
+ model = torchani.nn.Sequential(self.aev_computer, self.nn).to(self.device).double()
119
+ models.append(model)
120
+ self.models = models
121
+
122
+ def predict(self, device, d4, sae, optmol):
123
+
124
+ numbers, coordinates = get_xyz(self.xyzfile)
125
+ charges, mults, odm2_energies, odm2_grads, odm2_hesses = run_odm2_calculation(self.mndobin, numbers, coordinates, self.hesscalc, self.mndokw, optmol)
126
+ shifts = cal_shifts(numbers, sae)
127
+ if d4:
128
+ d4_energies, d4_grads, d4_hesses = run_d4_calculation(self.dftd4bin, self.xyzfile, numbers, coordinates, charges, self.hesscalc)
129
+ species_to_tensor = ChemicalSymbolsToInts(self.species_order)
130
+
131
+ fenergy = open(args.yestfile, 'w')
132
+ fgrad = open(args.ygradxyzestfile, 'w')
133
+ if self.hesscalc:
134
+ fhess = open(args.hessianestfile, 'w')
135
+
136
+ for i in range(len(numbers)):
137
+ nat = len(numbers[i])
138
+ coordinate = torch.tensor(coordinates[i]).to(device).requires_grad_(True)
139
+ shift = torch.tensor(shifts[i]).to(device)
140
+ odm2_energy = torch.tensor(odm2_energies[i]).to(device)
141
+ odm2_grad = torch.tensor(odm2_grads[i]).to(device)
142
+ coordinate = coordinate.unsqueeze(0)
143
+ species = species_to_tensor(numbers[i]).to(device).unsqueeze(0)
144
+ delta_energies = []; delta_grads = []; delta_hesses = []
145
+ for mod in self.models:
146
+ delta_energy = mod((species, coordinate)).energies
147
+ delta_grad = torch.autograd.grad(delta_energy.sum(), coordinate, create_graph=True, retain_graph=True)[0]
148
+ delta_energies.append(delta_energy)
149
+ delta_grads.append(delta_grad)
150
+ if self.hesscalc:
151
+ delta_hess = torchani.utils.hessian(coordinate, energies=delta_energy)
152
+ delta_hesses.append(delta_hess)
153
+
154
+ delta_energy = torch.stack([e for e in delta_energies], dim=0).mean(0)
155
+ delta_grad = torch.stack([g for g in delta_grads], dim=0).mean(0)
156
+ energy = delta_energy[0] + odm2_energy + shift
157
+ grad = delta_grad[0] + odm2_grad
158
+ if self.hesscalc:
159
+ odm2_hess = torch.tensor(odm2_hesses[i]).to(device)
160
+ delta_hess = torch.stack([h for h in delta_hesses], dim=0).mean(0)
161
+ hess = delta_hess + odm2_hess
162
+ if d4:
163
+ d4_energy = torch.tensor(d4_energies[i]).to(device)
164
+ d4_grad = torch.tensor(d4_grads[i]).to(device)
165
+ energy = energy + d4_energy
166
+ grad = grad + d4_grad
167
+ if self.hesscalc:
168
+ d4_hess = torch.tensor(d4_hesses[i]).to(device)
169
+ hess = hess + d4_hess
170
+ fenergy.write('%20.12f\n' % energy)
171
+ fgrad.write('%d\n\n' % nat)
172
+ for j in range(nat):
173
+ fgrad.write('%20.12f %20.12f %20.12f\n' % (grad[j][0], grad[j][1], grad[j][2]))
174
+ if self.hesscalc:
175
+ hess = hess.flatten()
176
+ fhess.write('%d\n\n' % nat)
177
+ for j in range(len(hess)):
178
+ fhess.write('%20.12f\n' % hess[j])
179
+ fenergy.close()
180
+ fgrad.close()
181
+ if self.hesscalc:
182
+ fhess.close()
183
+ return charges, mults
184
+
185
+ def forward(self, optmol=None):
186
+ # optmol is used for geomopt
187
+ if self.level == 'dft':
188
+ sae = self.dftsae
189
+ elif self.level == 'cc':
190
+ sae = self.ccsae
191
+ self.define_aev()
192
+ self.load_models()
193
+ charges, mults = self.predict(self.device, self.d4, sae, optmol)
194
+ return charges, mults
195
+
196
+ class args(object):
197
+
198
+ @classmethod
199
+ def check_prog(cls):
200
+ # MNDO
201
+ status = os.popen('echo $mndobin').read().strip()
202
+ if len(status) != 0:
203
+ mndobin = status
204
+ else:
205
+ stopper.stopMLatom('Can not find MNDO software, please set the environment variable: export mndobin=...')
206
+ # dftd4
207
+ dftd4bin = None
208
+ if cls.d4:
209
+ status = os.popen('echo $dftd4bin').read().strip()
210
+ if len(status) != 0:
211
+ dftd4bin = status
212
+ else:
213
+ stopper.stopMLatom('Can not find dftd4 software, please set the environment variable: export dftd4bin=...')
214
+ # TorchANI
215
+ try:
216
+ import torch
217
+ import torchani
218
+ from torchani.utils import ChemicalSymbolsToInts
219
+ except:
220
+ stopper.stopMLatom('Please install all Python module required for TorchANI')
221
+ globals()['torch'] = torch
222
+ globals()['torchani'] = torchani
223
+ globals()['ChemicalSymbolsToInts'] = ChemicalSymbolsToInts
224
+
225
+ cls.mndobin = mndobin
226
+ cls.dftd4bin = dftd4bin
227
+
228
+ @classmethod
229
+ def parse(cls, argsraw):
230
+ # Default values:
231
+ cls.xyzfile = None
232
+ cls.level = 'cc'
233
+ cls.d4 = False
234
+ cls.model_index = None
235
+ cls.mndokw = None
236
+ cls.yestfile = 'enest.dat'
237
+ cls.ygradxyzestfile = 'gradest.dat'
238
+ cls.hessianestfile = None
239
+ cls.hesscalc = False
240
+
241
+ argslower = [arg.lower() for arg in argsraw]
242
+ if 'xyzfile' not in ''.join(argslower):
243
+ printHelp()
244
+ stopper.stopMLatom('At least xyzfile should be provided')
245
+ for arg in argsraw:
246
+ if (arg.lower() == 'help'
247
+ or arg.lower() == '-help'
248
+ or arg.lower() == '-h'
249
+ or arg.lower() == '--help'):
250
+ printHelp()
251
+ stopper.stopMLatom('')
252
+ elif arg.lower()[0:len('aiqm1dftstar')] == 'aiqm1dftstar':
253
+ cls.level = 'dft'
254
+ elif arg.lower()[0:len('aiqm1dft')] == 'aiqm1dft':
255
+ cls.level = 'dft'
256
+ cls.d4 = True
257
+ elif arg.lower()[0:len('aiqm1')] == 'aiqm1':
258
+ cls.level = 'cc'
259
+ cls.d4 = True
260
+ elif arg.lower()[0:len('xyzfile=')] == 'xyzfile=':
261
+ cls.xyzfile = arg[len('xyzfile='):]
262
+ #elif arg.lower()[0:len('gpu=')] == 'gpu=':
263
+ # os.environ["CUDA_VISIBLE_DEVICES"] = arg[len('gpu='):]
264
+ # cls.device = torch.device('cuda')
265
+ elif arg.lower()[0:len('model_index=')] == 'model_index=':
266
+ cls.model_index = int(arg[len('model_index='):])
267
+ elif arg.lower()[0:len('mndokeywords=')] == 'mndokeywords=':
268
+ cls.mndokw = arg[len('mndokeywords='):]
269
+ elif arg.lower()[0:len('yestfile=')] == 'yestfile=':
270
+ cls.yestfile = arg[len('yestfile='):]
271
+ elif arg.lower()[0:len('ygradxyzestfile=')] == 'ygradxyzestfile=':
272
+ cls.ygradxyzestfile = arg[len('ygradxyzestfile='):]
273
+ elif arg.lower()[0:len('hessianestfile=')] == 'hessianestfile=':
274
+ cls.hessianestfile = arg[len('hessianestfile='):]
275
+ cls.hesscalc = True
276
+ #else:
277
+ # printHelp()
278
+ # stopper.stopMLatom('Option "%s" is not recognized' % arg)
279
+ cls.check_prog()
280
+ cls.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
281
+
282
+ def get_xyz(xyzfile):
283
+ element2number = {'H':1, 'C':6, 'N':7, 'O':8}
284
+ coordinates = []; numbers = []
285
+ with open(xyzfile, 'r') as f:
286
+ lines = f.readlines()
287
+ for i in range(len(lines)):
288
+ if lines[i].strip().isdigit():
289
+ element = []; coordinate = []
290
+ nat = int(lines[i])
291
+ for j in range(i+2, i+2+nat):
292
+ element.append(lines[j].strip().split()[0])
293
+ coordinate.append(lines[j].strip().split()[1:])
294
+ if element[0].isdigit():
295
+ number = element
296
+ else:
297
+ number = np.array([element2number[i.upper()] for i in element])
298
+ number = np.array(number).astype('int')
299
+ coordinate = np.array(coordinate).astype('float')
300
+ numbers.append(number)
301
+ coordinates.append(coordinate)
302
+ return numbers, coordinates
303
+
304
+ def run_odm2_calculation(mndobin, numbers, coordinates, hesscalc, mndokw, optmol):
305
+ charges = np.full(len(numbers), 0)
306
+ mults = np.full(len(numbers), 1)
307
+ energies = []; grads = []; hesses = []
308
+ if mndokw:
309
+ mndokeywords, charges, mults = read_mndokw(mndokw, optmol)
310
+ if len(mndokeywords) != len(numbers):
311
+ stopper.stopMLatom('Inconsistency of the nubmer of keywords and molecules')
312
+ for i in range(len(numbers)):
313
+ with open('mndo.inp', 'w') as f:
314
+ if mndokw:
315
+ f.write(mndokeywords[i] + '\n\n\n')
316
+ else:
317
+ if hesscalc:
318
+ f.write('jop=2 +\n')
319
+ else:
320
+ f.write('jop=-2 +\n')
321
+ f.write('iop=-22 igeom=1 iform=1 immdp=-1 nsav15=3 +\n')
322
+ f.write('icuts=-1 icutg=-1 kitscf=9999 iscf=9 iplscf=9 +\n')
323
+ f.write('iprint=-1 kprint=-5 lprint=-2 mprint=0 jprint=-1 +\n')
324
+ f.write('kharge=0 imult=0 nprint=-1\n\n\n')
325
+ number = numbers[i]
326
+ coordinate = coordinates[i]
327
+ for j in range(len(number)):
328
+ f.write('%2s' % (number[j]) + ' '*5)
329
+ f.write('%12.8f %3d' % (coordinate[j][0], 1))
330
+ f.write(' '*5)
331
+ f.write('%12.8f %3d' % (coordinate[j][1], 1))
332
+ f.write(' '*5)
333
+ f.write('%12.8f %3d' % (coordinate[j][2], 1))
334
+ f.write('\n')
335
+ f.write('\n')
336
+ os.system(mndobin + " < mndo.inp > mndo.out")
337
+ energy, grad, hess = get_odm2_result(hesscalc)
338
+ energies.append(energy)
339
+ grads.append(grad)
340
+ hesses.append(hess)
341
+ return charges, mults, energies, grads, hesses
342
+
343
+ def read_mndokw(mndokw, optmol):
344
+ with open(mndokw, 'r') as f:
345
+ mndokeywords = f.read().strip('\n')
346
+ mndokeywords = mndokeywords.split('\n\n')
347
+ charges = np.full(len(mndokeywords), 0)
348
+ mults = np.full(len(mndokeywords), 1)
349
+ for i in range(len(mndokeywords)):
350
+ status = re.search('kharge=\d+', mndokeywords[i])
351
+ if status:
352
+ charges[i] = int(status.group().split('=')[1])
353
+ status = re.search('imult=\d+', mndokeywords[i])
354
+ if status:
355
+ imult = int(status.group().split('=')[1])
356
+ if imult == 0:
357
+ mults[i] = 1
358
+ else:
359
+ mults[i] = imult
360
+ if optmol is not None:
361
+ mndokeywords = [mndokeywords[optmol]]
362
+ charges = [charges[optmol]]
363
+ mults = [mults[optmol]]
364
+
365
+ return mndokeywords, charges, mults
366
+
367
+ def get_odm2_result(hesscalc):
368
+ hess = None
369
+ with open('fort.15', 'r') as f:
370
+ lines = f.readlines()
371
+ for i in range(len(lines)):
372
+ if 'NUMAT' in lines[i]:
373
+ nat = int(lines[i].strip().split()[-1])
374
+ if 'ENERGY' in lines[i]:
375
+ energy = lines[i+1].strip().split()[0]
376
+ energy = float(energy) / (27.21 * 23.061)
377
+ if 'CARTESIAN GRADIENT' in lines[i]:
378
+ grad = []
379
+ for j in range(nat):
380
+ grad.append(lines[i+j+1].strip().split()[-3:])
381
+ grad = np.array(grad).astype('float') / (27.21 * 23.061)
382
+ if hesscalc:
383
+ lhess = nat * nat * 9
384
+ fhess = open('fort.4', 'rb')
385
+ data = fhess.read()
386
+ dt = f'id{lhess}d'
387
+ dat_size = struct.calcsize(dt)
388
+ temp = struct.unpack(dt, data[:dat_size])
389
+ hess = np.array(temp[2:]).reshape(-1, nat*3) / (0.529167 * 0.529167)
390
+
391
+ return energy, grad, hess
392
+
393
+ def cal_shifts(numbers, sae):
394
+ shifts = []
395
+ for i in range(len(numbers)):
396
+ count = Counter(numbers[i])
397
+ ncount = [count[1], count[6], count[7], count[8]]
398
+ shift = np.dot(ncount, sae)
399
+ shifts.append(shift)
400
+ return shifts
401
+
402
+ def run_d4_calculation(dftd4bin, xyzfile, numbers, coordinates, charges, hesscalc):
403
+ number2element = {1:'H', 6:'C', 7:'N', 8:'O'}
404
+ shifts = []
405
+ d4_energies = []; d4_grads = []; d4_hesses = []
406
+ for i in range(len(numbers)):
407
+ number = numbers[i]
408
+ coordinate = coordinates[i]
409
+ charge = charges[i]
410
+ nat = len(numbers[i])
411
+ with open('coordinate', 'w') as f:
412
+ f.write(str(nat) + '\n\n')
413
+ for j in range(nat):
414
+ f.write('%s %15.12f %15.12f %15.12f\n'
415
+ % (number2element[number[j]], coordinate[j][0], coordinate[j][1], coordinate[j][2]))
416
+ if hesscalc:
417
+ os.system(dftd4bin + " coordinate -s --grad --hess --orca --json -f wb97x -c " + str(charge) + " > /dev/null 2>&1")
418
+ else:
419
+ os.system(dftd4bin + " coordinate -s --grad --orca --json -f wb97x -c " + str(charge) + " > /dev/null 2>&1")
420
+ with open('dftd4.json', 'r') as f:
421
+ d4_results = json.load(f)
422
+ #try:
423
+ # with open('dftd4.json', 'r') as f:
424
+ # d4_results = json.load(f)
425
+ #except:
426
+ # time.sleep(0.5)
427
+ # with open('dftd4.json', 'r') as f:
428
+ # d4_results = json.load(f)
429
+ d4_energy = np.array(d4_results['energy'])
430
+ d4_grad = np.array(d4_results['gradient']) / bohr2a
431
+ d4_grad = d4_grad.reshape(-1, 3)
432
+ d4_energies.append(d4_energy)
433
+ d4_grads.append(d4_grad)
434
+ if hesscalc:
435
+ d4_hess = np.array(d4_results['hessian']).reshape(-1, nat*3) / (bohr2a * bohr2a)
436
+ d4_hesses.append(d4_hess)
437
+ #os.system('rm -f coordinate dftd4.json')
438
+ os.system('rm -f coordinate dftd4.json')
439
+ return d4_energies, d4_grads, d4_hesses
440
+
441
+ def printHelp():
442
+ helpText = '''
443
+ !---------------------------------------------------------------------------!
444
+ ! AIQM1 usage and options !
445
+ !---------------------------------------------------------------------------!
446
+
447
+ Usage:
448
+ MLatom.py AIQM1@DFT* xyzfile=... [options]
449
+ MLatom.py AIQM1@DFT xyzfile=... [options]
450
+ MLatom.py AIQM1 xyzfile=... [options]
451
+
452
+ Options:
453
+ xyzfile=S file S with xyz coordinates
454
+ model_index=N 0-7 (by default the ensemble of 8 models are used)
455
+ YestFile=S file S with estimated Y values
456
+ YgradXYZestFile=S file S with estimated XYZ gradients
457
+ HessianestFile=S file S with estimated Hessians
458
+ mndokeywords=S read MNDO keyword from file S, separating by a blank line for each molecules
459
+ (it is required to set iop=-22, jop=-2 or 2, igeom=1, nsav15=3, immdp=-1)
460
+ '''
461
+ print(helpText)
462
+
463
+
@@ -31,9 +31,10 @@
31
31
  ! Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, !
32
32
  ! Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27 !
33
33
  ! !
34
- ! Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, !
34
+ ! Pavlo O. Dral, Peikun Zheng, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, !
35
+ ! Max Pinheiro Jr, !
35
36
  ! MLatom: A Package for Atomistic Simulations with Machine Learning !
36
- ! version 2.0, Xiamen University, Xiamen, China, 2013-2021 !
37
+ ! version 2.1, Xiamen University, Xiamen, China, 2013-2021 !
37
38
  ! !
38
39
  !---------------------------------------------------------------------------!
39
40
 
@@ -88,6 +89,8 @@ class MLatomMainCls(object):
88
89
  sliceData.sliceDataCls(argsSD = args.args2pass)
89
90
  elif (args.useMLmodel or args.createMLmodel or
90
91
  args.estAccMLmodel or args.learningCurve or
92
+ args.AIQM1DFTstar or args.AIQM1DFT or args.AIQM1 or
93
+ args.geomopt or args.freq or
91
94
  args.MLNEA):
92
95
  MLtasks.MLtasksCls(argsMLtasks = args.args2pass)
93
96
 
@@ -105,11 +108,14 @@ class Args(ArgsBase):
105
108
  self.task_list = [
106
109
  'XYZ2X', 'analyze', 'sample', 'sampleFromSlices', 'mergeSlices','slice',
107
110
  'useMLmodel', 'createMLmodel', 'estAccMLmodel', 'learningCurve',
108
- 'crossSection'
111
+ 'crossSection', # Interfaces
112
+ 'callNXinterface', 'AIQM1DFTstar', 'AIQM1DFT', 'AIQM1', # DEVELOPMENT VERSION
113
+ 'geomopt', 'freq'
109
114
  ]
110
115
  self.add_default_dict_args(self.task_list, bool)
111
116
  self.add_default_dict_args([
112
- 'useMLmodel', 'createMLmodel', 'estAccMLmodel', 'learningCurve','deltaLearn','selfCorrect','MLmodelType'
117
+ 'useMLmodel', 'createMLmodel', 'estAccMLmodel', 'learningCurve','deltaLearn','selfCorrect','MLmodelType',
118
+ 'geomopt', 'freq'
113
119
  ],
114
120
  bool
115
121
  )
@@ -119,13 +125,20 @@ class Args(ArgsBase):
119
125
  ''
120
126
  )
121
127
  self.add_default_dict_args([
122
- 'Yb', 'Yt', 'YestT', 'YestFile','XYZfile', 'XfileIn', 'Yfile', 'YgradXYZfile', 'absXfileIn', 'absXYZfile', 'absYfile', 'absYgradXYZfile', 'YgradXYZestFile', 'Ntrain', 'Nsubtrain', 'Nvalidate', 'Ntest', 'iTrainIn', 'iTestIn', 'iSubtrainIn', 'iValidateIn', 'sampling', 'MLmodelIn', 'MLmodelOut',
128
+ 'XYZfile', 'XfileIn',
129
+ 'Yfile', 'YestFile', 'Yb', 'Yt', 'YestT',
130
+ 'YgradFile', 'YgradEstFile', 'YgradB', 'YgradT', 'YgradEstT',
131
+ 'YgradXYZfile', 'YgradXYZestFile', 'YgradXYZb', 'YgradXYZt', 'YgradXYZestT',
132
+ 'absXfileIn', 'absXYZfile', 'absYfile', 'absYgradXYZfile',
133
+ 'Nuse', 'Ntrain', 'Nsubtrain', 'Nvalidate', 'Ntest', 'iTrainIn', 'iTestIn', 'iSubtrainIn', 'iValidateIn', 'sampling', 'MLmodelIn', 'MLmodelOut',
123
134
  'molDescriptor', 'kernel'
124
135
  ],
125
136
  ''
126
137
  )
127
138
  self.add_dict_args({'MLmodelType': '', 'nthreads': None})
128
139
  self.set_keyword_alias('crossSection', ['ML-NEA', 'ML_NEA', 'crossSection', 'cross-section', 'cross_section','MLNEA'])
140
+ self.set_keyword_alias('AIQM1DFTstar', ['AIQM1@DFT*'])
141
+ self.set_keyword_alias('AIQM1DFT', ['AIQM1@DFT'])
129
142
  self.args2pass = []
130
143
 
131
144
  def parse(self, argsraw):
@@ -12,6 +12,7 @@ import numpy as np
12
12
  import stopper
13
13
  import interface_MLatomF
14
14
  import ML_NEA
15
+ import geomopt
15
16
  from io import StringIO
16
17
  from contextlib import redirect_stdout
17
18
  from math import inf, log
@@ -68,6 +69,11 @@ class MLtasksCls(object):
68
69
  for i in deadlist: CrossSection_args.remove(i)
69
70
  print(CrossSection_args)
70
71
  ML_NEA.parse_api(CrossSection_args)
72
+ elif args.geomopt or args.freq:
73
+ geomopt.geomoptCls(args.args2pass)
74
+ elif args.AIQM1DFTstar or args.AIQM1DFT or args.AIQM1:
75
+ import AIQM1
76
+ AIQM1.AIQM1Cls(args.args2pass).forward()
71
77
  else:
72
78
  self.chooseMLop(args.args2pass)
73
79
 
@@ -714,6 +720,8 @@ class Args(ArgsBase):
714
720
  self.task_list = [
715
721
  'XYZ2X', 'analyze', 'sample', 'slicedata', 'sampleFromSlices', 'mergeSlices',
716
722
  'useMLmodel', 'createMLmodel', 'estAccMLmodel', 'learningCurve',
723
+ 'AIQM1DFTstar', 'AIQM1DFT', 'AIQM1',
724
+ 'geomopt', 'freq', 'CVopt','CVtest',
717
725
  'crossSection'
718
726
  ]
719
727
  self.add_default_dict_args(self.task_list, bool)
@@ -735,6 +743,8 @@ class Args(ArgsBase):
735
743
  )
736
744
  self.add_dict_args({'MLmodelType': None, 'nthreads': None})
737
745
  self.set_keyword_alias('crossSection', ['ML-NEA', 'ML_NEA', 'crossSection', 'cross-section', 'cross_section','MLNEA'])
746
+ self.set_keyword_alias('AIQM1DFTstar', ['AIQM1@DFT*'])
747
+ self.set_keyword_alias('AIQM1DFT', ['AIQM1@DFT'])
738
748
  self.args2pass = []
739
749
  self.parse_input_content([
740
750
  'hyperopt.max_evals=8',
@@ -1,5 +1,5 @@
1
1
  MLatom: a Package for Atomistic Simulations with Machine Learning
2
- Version 2.0.5
2
+ Version 2.1.0
3
3
  http://mlatom.com/
4
4
 
5
5
  Copyright (c) 2013-2021 Pavlo O. Dral
@@ -15,7 +15,7 @@ Cite as:
15
15
 
16
16
  1. Pavlo O. Dral, J. Comput. Chem. 2019, 40, 2339-2347
17
17
  2. Pavlo O. Dral, Fuchun Ge, Bao-Xin Xue, Yi-Fan Hou, Max Pinheiro Jr, Jianxing Huang, Mario Barbatti, Top. Curr. Chem. 2021, 379, 27
18
- 3. Pavlo O. Dral, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.0.5, Xiamen University, Xiamen, China, 2013-2021.
18
+ 3. Pavlo O. Dral, Peikun Zheng, Bao-Xin Xue, Fuchun Ge, Yi-Fan Hou, Max Pinheiro Jr, MLatom: A Package for Atomistic Simulations with Machine Learning, version 2.1.0, Xiamen University, Xiamen, China, 2013-2021.
19
19
 
20
20
  In addition to above citations in the published work, the users have to cite the relevant literature for the MLatom features used. Examples of suggested citations are provided on http://mlatom.com/features page in form of web links and in the output of MLatom.
21
21
 
@@ -28,8 +28,8 @@ Tutorial: http://mlatom.com/tutorial/
28
28
  This package has the folowing content:
29
29
  * README - this file
30
30
  * LICENSE.CC-BY-NC-ND-4.0 - text of the CC-BY-NC-ND-4.0 license
31
- * this directory contains the Python scripts and executables
32
- * MLatomF_src - directory with the Fortran and C++ source code
31
+ * bin - directory with the Python scripts and executables
32
+ * src - directory with the Fortran and C++ source code
33
33
  * documentation - a directory with brief instructions on installation of the third-party packages
34
34
  * example - an directory containing example files including:
35
35
  ** mlatom.inp - example of input file for delta-learning