mlatom 2.0.4__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.
- {MLatom-2.0.4 → MLatom-2.1.0}/PKG-INFO +3 -3
- {MLatom-2.0.4 → MLatom-2.1.0}/README.md +2 -2
- {MLatom-2.0.4 → MLatom-2.1.0}/setup.py +1 -1
- MLatom-2.1.0/src/MLatom/AIQM1.py +463 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/ML_NEA.py +29 -29
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatom.py +18 -5
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLtasks.py +10 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/README +4 -4
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv0.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv1.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv2.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv3.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv4.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv5.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv6.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_cc_cv7.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv0.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv1.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv2.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv3.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv4.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv5.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv6.pt +0 -0
- MLatom-2.1.0/src/MLatom/aiqm1_model/aiqm1_dft_cv7.pt +0 -0
- MLatom-2.1.0/src/MLatom/calculator.py +46 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/doc.py +65 -4
- MLatom-2.1.0/src/MLatom/geomopt.py +421 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/header.py +15 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/ref.json +8 -2
- MLatom-2.1.0/src/MLatom/thermo.py +163 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom.egg-info/PKG-INFO +3 -3
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom.egg-info/SOURCES.txt +21 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/LICENSE.txt +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/setup.cfg +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/LICENSE.CC-BY-NC-ND-4.0 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/A_KRR.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/A_KRR_kernel.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/D_CoulombMatrix.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/D_rel2eq.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLatomF.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLatomFInfo.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/MLmodel.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/Makefile +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/Makefile.intel +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/analyze.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/constants.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/cs.cpp +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/dataset.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/mathUtils.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/molDescr.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/optionsModule.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/precision.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/sampling.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/statistics.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/stopper.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/strings.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/timing.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/MLatomF_src/types.f90 +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/args_class.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/cs.so +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/documentation/installation.txt +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/E_FCI_451.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/E_UHF_451.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/R_451.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/isubtrain.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/itest.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/itrain.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/ivalidate.dat +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/mlatom.inp +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/mlatom.saved +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/example/test.sh +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interface_MLatomF.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/DP_inference.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/DeePMDkit/template.json +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/GAP/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/GAP/interface_GAP.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/PhysNet_predict.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/PhysNet_train.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/PhysNet/interface_PhysNet.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/TorchANI_predict.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/TorchANI_train.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/TorchANI/interface_TorchANI.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/__init__.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/interface_sGDML.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/mlatom_gui.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/shell_cmd.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/sliceData.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom/stopper.py +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom.egg-info/dependency_links.txt +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom.egg-info/entry_points.txt +0 -0
- {MLatom-2.0.4 → MLatom-2.1.0}/src/MLatom.egg-info/requires.txt +0 -0
- {MLatom-2.0.4 → 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
+
|
|
@@ -824,19 +824,9 @@ class NewtonXCalc(LinuxInterface):
|
|
|
824
824
|
' nis = 1\n nfs = 2\n kvert = 1\n de = 100\n prog = 6.5\n iseed = 1234\n lvprt = 1\n/\n'
|
|
825
825
|
with open(inp_name, 'w') as f:
|
|
826
826
|
f.write(nx_inp)
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
'$NX/weight < initqp_input &> weight.log ; ' \
|
|
831
|
-
'$NX/initqp < initqp_input &> initqp.log ')
|
|
832
|
-
if err_code != 0 or out != '':
|
|
833
|
-
err_print(f'Newton-X calculation failed!!!\nstatus code: {err_code} (0 stands for normal exit, none 0 stands for error)\noutput: {out}')
|
|
834
|
-
except:
|
|
835
|
-
os.system('$NX/mk_qvector < initqp_input ; ' \
|
|
836
|
-
'$NX/weight < initqp_input &> weight.log ; ' \
|
|
837
|
-
'$NX/initqp < initqp_input &> initqp.log ')
|
|
838
|
-
import time
|
|
839
|
-
time.sleep(0.01)
|
|
827
|
+
os.system('$NX/mk_qvector < initqp_input')
|
|
828
|
+
os.system('$NX/weight < initqp_input > weight.log')
|
|
829
|
+
os.system('$NX/initqp < initqp_input > initqp.log')
|
|
840
830
|
|
|
841
831
|
def restore_multi_xyz(self, atom_num: int):
|
|
842
832
|
with open('ini_qv') as f:
|
|
@@ -2356,11 +2346,12 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
|
|
|
2356
2346
|
self.delta_QC = 0.01
|
|
2357
2347
|
self.delta_SPC = 0.3
|
|
2358
2348
|
|
|
2359
|
-
def opt_freq_calc(self):
|
|
2349
|
+
def opt_freq_calc(self, force_calc: bool=False):
|
|
2360
2350
|
self.cd(self.work_path)
|
|
2361
|
-
if
|
|
2362
|
-
self.
|
|
2363
|
-
|
|
2351
|
+
if not force_calc:
|
|
2352
|
+
if self.exist_path(self.eq_init_xyz_name) and self.exist_path(self.nx_nea_geom_name):
|
|
2353
|
+
self.opt_molecule.read_xyz(self.eq_init_xyz_name)
|
|
2354
|
+
return
|
|
2364
2355
|
if not EnvCheck.check_NX():
|
|
2365
2356
|
exit()
|
|
2366
2357
|
self.cd(self.work_path)
|
|
@@ -2372,28 +2363,37 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
|
|
|
2372
2363
|
else: # not exists opt-freq.com, raise error
|
|
2373
2364
|
err_print(f'not exists {self.gauss_opt_inp_name} or {self.gauss_opt_log_name}, exit')
|
|
2374
2365
|
exit()
|
|
2366
|
+
else:
|
|
2367
|
+
self.cp(self.gauss_opt_log_name, os.path.join(self.gauss.gauss_path, self.gauss_opt_log_name))
|
|
2375
2368
|
# now exists opt-freq.log, extract opt.xyz & freq
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2369
|
+
if not force_calc:
|
|
2370
|
+
self.opt_molecule = self.gauss.extract_xyz(
|
|
2371
|
+
os.path.join(self.gauss.gauss_path, self.gauss_opt_log_name))
|
|
2372
|
+
# self.opt_molecule.print_xyz(self.eq_xyz_name) # no needed, don't pollute the working directory
|
|
2379
2373
|
|
|
2380
2374
|
def NX_multi_xyz_calc(self):
|
|
2381
|
-
|
|
2382
|
-
|
|
2375
|
+
def NX_gen_ensemble():
|
|
2376
|
+
if not EnvCheck.check_NX():
|
|
2377
|
+
exit()
|
|
2383
2378
|
self.cd(self.nx.NX_path)
|
|
2384
2379
|
self.opt_molecule.print_xyz('opt.xyz')
|
|
2385
2380
|
self.cp(os.path.join(self.gauss.gauss_path, self.gauss_opt_log_name),
|
|
2386
2381
|
os.path.join(self.nx.NX_path, 'opt.log'))
|
|
2387
|
-
if not EnvCheck.check_NX():
|
|
2388
|
-
exit()
|
|
2389
2382
|
self.nx.invoke_NX('opt.xyz', 'opt.log', self.opt_molecule.atom_num, self.ML_point)
|
|
2390
2383
|
self.multi_xyz = self.nx.multi_xyz
|
|
2391
|
-
|
|
2392
|
-
|
|
2384
|
+
|
|
2385
|
+
self.cd(self.work_path)
|
|
2386
|
+
if self.exist_path(self.nx_nea_geom_name): # exists nea geom path
|
|
2393
2387
|
self.multi_xyz = Molecule.read_multi_xyz(self.nx_nea_geom_name)
|
|
2394
|
-
|
|
2395
|
-
if len(self.multi_xyz) - 1 >= self.ML_point:
|
|
2388
|
+
if len(self.multi_xyz) - 1 > self.ML_point:
|
|
2396
2389
|
self.multi_xyz = self.multi_xyz[:self.ML_point + 1]
|
|
2390
|
+
elif len(self.multi_xyz) - 1 < self.ML_point:
|
|
2391
|
+
orig_xyz = self.multi_xyz
|
|
2392
|
+
self.opt_freq_calc(force_calc=True)
|
|
2393
|
+
NX_gen_ensemble()
|
|
2394
|
+
self.multi_xyz = orig_xyz + self.multi_xyz[len(orig_xyz): ]
|
|
2395
|
+
else: # not exists multiple nea geom data, need to calc it with NX
|
|
2396
|
+
NX_gen_ensemble()
|
|
2397
2397
|
|
|
2398
2398
|
def ML_NEA_calc_all(self):
|
|
2399
2399
|
self.cd(self.cs_ML.ML_path)
|
|
@@ -2403,7 +2403,7 @@ class RecurPaperProcedure(ArgParser, LinuxInterface):
|
|
|
2403
2403
|
# self.gauss.process_gaussian_log(self.gauss.all_log_path, self.max_state, pattern='', regex=False)
|
|
2404
2404
|
ctl_adapter = CtlPartAdapter(self, CtlPartAdapter.paper_adapter)
|
|
2405
2405
|
self.cs_ML.define_data_set(this=ctl_adapter, TD_point=self.TD_point, xyz_file=self.nx_nea_geom_name,
|
|
2406
|
-
max_state=self.max_state, delta=
|
|
2406
|
+
max_state=self.max_state, delta=self.delta_ML)
|
|
2407
2407
|
self.cs_ML.ML_train_all()
|
|
2408
2408
|
|
|
2409
2409
|
def ML_NEA_calc_iter(self):
|
|
@@ -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,
|
|
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.
|
|
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
|
-
'
|
|
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):
|