├── GGA.py ├── LICENSE ├── LSDA.py ├── NNGGA ├── NNLSDA ├── NNNRA ├── NNmGGA ├── NRA.py ├── README.md ├── metaGGA.py ├── numint.py └── numint_1.5.py /GGA.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python 3 | import numpy as np 4 | from pyscf import gto, dft 5 | import math 6 | import torch 7 | from torch.autograd import Variable 8 | import torch.nn as nn 9 | import torch.nn.functional as F 10 | 11 | 12 | # definition of target molecule # 13 | mol = gto.Mole() 14 | mol.verbose = 4 15 | 16 | mol.atom="""8 .000000 .000000 .119262 17 | 1 .000000 .763239 -.477047 18 | 1 .000000 -.763239 -.477047""" 19 | mol.charge=0 20 | mol.spin =0 21 | mol.basis = "6-31G" 22 | mol.build() 23 | 24 | # definition of NN structure # 25 | hidden=100 26 | print("hidden nodes= "+str(hidden)) 27 | 28 | class Net(nn.Module): 29 | def __init__(self): 30 | super(Net, self).__init__() 31 | self.fc1 = nn.Linear(3, hidden) 32 | self.fc2 = nn.Linear(hidden, hidden) 33 | self.fc3 = nn.Linear(hidden, hidden) 34 | self.fc4 = nn.Linear(hidden, 1) 35 | 36 | 37 | def forward(self, x): 38 | t=torch.empty((x.shape[0],3)) 39 | unif=(x[:,1]+x[:,0]+1e-7)**(1.0/3) 40 | t[:,0]=unif 41 | t[:,1]=((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5 42 | t[:,2]=((x[:,2]+x[:,4]+2*x[:,3])**0.5+1e-7)/unif**4 43 | ds=(1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(5.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(5.0/3) 44 | 45 | #print(t) 46 | logt=torch.log(t) 47 | g1=F.elu(self.fc1(logt)) 48 | g2=F.elu(self.fc2(g1)) 49 | g3=F.elu(self.fc3(g2)) 50 | 51 | eunif=(x[:,1]+x[:,0]).view(-1,1)**(1.0/3) 52 | spinscale=(((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5).view(-1,1) 53 | g4=-(F.elu(self.fc4(g3))+1)*eunif*spinscale 54 | return g4 55 | 56 | #loading NN weights 57 | model = Net() 58 | model.load_state_dict(torch.load("NNGGA",map_location='cpu')) 59 | 60 | # definition of functional # 61 | def eval_xc(xc_code, rho, spin, relativity=0, deriv=2, verbose=None): 62 | if spin!=0: 63 | rho1=rho[0] 64 | rho2=rho[1] 65 | rho01, dx1, dy1, dz1 = rho1[:4] 66 | rho02, dx2, dy2, dz2 = rho2[:4] 67 | gamma1=dx1**2+dy1**2+dz1**2+1e-7 68 | gamma2=dx2**2+dy2**2+dz2**2+1e-7 69 | gamma12=dx1*dx2+dy1*dy2+dz1*dz2+1e-7 70 | else: 71 | rho0, dx, dy, dz= rho[:4] 72 | gamma1=gamma2=gamma12=(dx**2+dy**2+dz**2)*0.25+1e-7 73 | rho01=rho02=rho0*0.5 74 | 75 | rho0=np.concatenate((rho01.reshape((-1,1)),rho02.reshape((-1,1)),gamma1.reshape((-1,1)),gamma12.reshape((-1,1)),gamma2.reshape((-1,1))),axis=1) 76 | 77 | N=rho0.shape[0] 78 | 79 | x=Variable(torch.Tensor(rho0),requires_grad=True) 80 | pred_exc=model(x) 81 | 82 | exc=pred_exc.data[:,0].numpy()#+0.015471944-0.002533411+0.001574637 83 | eneden=torch.dot(pred_exc[:,0],x[:,0]+x[:,1]) 84 | eneden.backward() 85 | grad=x.grad.data.numpy() 86 | 87 | if spin!=0: 88 | vlapl=np.zeros((N,2)) 89 | vrho=np.hstack((grad[:,0].reshape((-1,1)),grad[:,1].reshape((-1,1)))) 90 | vgamma=np.hstack((grad[:,2].reshape((-1,1)),grad[:,3].reshape((-1,1)),grad[:,4].reshape((-1,1)))) 91 | 92 | else: 93 | vlapl=np.zeros(N) 94 | vrho=(grad[:,0]+grad[:,1])/2 95 | vgamma=(grad[:,2]+grad[:,4]+grad[:,3])/4 96 | 97 | vxc=(vrho,vgamma,None,None) 98 | return exc, vxc, None, None 99 | 100 | # DFT calculation # 101 | if mol.spin==0: 102 | mfl = dft.RKS(mol) 103 | else: 104 | mfl = dft.UKS(mol) 105 | 106 | mfl = mfl.define_xc_(eval_xc, 'GGA') 107 | mfl.kernel() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LSDA.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python 3 | import numpy as np 4 | from pyscf import gto, dft 5 | import math 6 | import torch 7 | from torch.autograd import Variable 8 | import torch.nn as nn 9 | import torch.nn.functional as F 10 | 11 | 12 | # definition of target molecule # 13 | mol = gto.Mole() 14 | mol.verbose = 4 15 | 16 | mol.atom="""8 .000000 .000000 .119262 17 | 1 .000000 .763239 -.477047 18 | 1 .000000 -.763239 -.477047""" 19 | mol.charge=0 20 | mol.spin =0 21 | mol.basis = "6-31G" 22 | mol.build() 23 | 24 | # definition of NN structure # 25 | hidden=100 26 | print("hidden nodes= "+str(hidden)) 27 | 28 | class Net(nn.Module): 29 | def __init__(self): 30 | super(Net, self).__init__() 31 | self.fc1 = nn.Linear(2, hidden) 32 | self.fc2 = nn.Linear(hidden, hidden) 33 | self.fc3 = nn.Linear(hidden, hidden) 34 | self.fc4 = nn.Linear(hidden, 1) 35 | 36 | 37 | def forward(self, x): 38 | t=torch.empty((x.shape[0],2)) 39 | unif=(x[:,1]+x[:,0]+1e-7)**(1.0/3) 40 | t[:,0]=unif 41 | t[:,1]=((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5 42 | 43 | #print(t) 44 | logt=torch.log(t)#/scale.float() 45 | g1=F.elu(self.fc1(logt)) 46 | g2=F.elu(self.fc2(g1)) 47 | g3=F.elu(self.fc3(g2)) 48 | #g4=F.elu(self.fc4(g3)) 49 | eunif=(x[:,1]+x[:,0]).view(-1,1)**(1.0/3) 50 | spinscale=(((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5).view(-1,1) 51 | g4=-(F.elu(self.fc4(g3))+1)*eunif*spinscale 52 | return g4 53 | 54 | 55 | #loading NN weights 56 | model = Net() 57 | model.load_state_dict(torch.load("NNLSDA",map_location='cpu')) 58 | 59 | # definition of functional # 60 | 61 | def eval_xc(xc_code, rho, spin, relativity=0, deriv=2, verbose=None): 62 | if spin!=0: 63 | rho01=rho[0] 64 | rho02=rho[1] 65 | 66 | else: 67 | rho01=rho02=rho*0.5 68 | 69 | rho0=np.concatenate((rho01.reshape((-1,1)),rho02.reshape((-1,1))),axis=1) 70 | N=rho0.shape[0] 71 | x=Variable(torch.Tensor(rho0),requires_grad=True) 72 | pred_exc=model(x) 73 | exc=pred_exc.data[:,0].numpy() 74 | eneden=torch.dot(pred_exc[:,0],x[:,0]+x[:,1]) 75 | eneden.backward() 76 | grad=x.grad.data.numpy() 77 | 78 | if spin!=0: 79 | vrho=np.hstack((grad[:,0].reshape((-1,1)),grad[:,1].reshape((-1,1)))) 80 | 81 | else: 82 | vlapl=np.zeros(N) 83 | vrho=(grad[:,0]+grad[:,1])/2 84 | vxc=(vrho, None, None, None) 85 | return exc, vxc, None, None 86 | 87 | # DFT calculation # 88 | if mol.spin==0: 89 | mfl = dft.RKS(mol) 90 | else: 91 | mfl = dft.UKS(mol) 92 | 93 | mfl = mfl.define_xc_(eval_xc, 'LDA') 94 | mfl.kernel() 95 | -------------------------------------------------------------------------------- /NNGGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-electron-project/NNfunctional/3f4a97998747dc14a9296a88d16572601621efab/NNGGA -------------------------------------------------------------------------------- /NNLSDA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-electron-project/NNfunctional/3f4a97998747dc14a9296a88d16572601621efab/NNLSDA -------------------------------------------------------------------------------- /NNNRA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-electron-project/NNfunctional/3f4a97998747dc14a9296a88d16572601621efab/NNNRA -------------------------------------------------------------------------------- /NNmGGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-electron-project/NNfunctional/3f4a97998747dc14a9296a88d16572601621efab/NNmGGA -------------------------------------------------------------------------------- /NRA.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python 3 | import numpy as np 4 | from pyscf import gto, dft 5 | import math 6 | import torch 7 | from torch.autograd import Variable 8 | import torch.nn as nn 9 | import torch.nn.functional as F 10 | 11 | #################### 12 | # In order to use the NRA functional, please replace 13 | # "(where you installed PySCF)/pyscf/dft/numint.py" 14 | #into numint.py in this folder. 15 | #################### 16 | 17 | # definition of target molecule # 18 | mol = gto.Mole() 19 | mol.verbose = 4 20 | 21 | mol.atom="""8 .000000 .000000 .119262 22 | 1 .000000 .763239 -.477047 23 | 1 .000000 -.763239 -.477047""" 24 | mol.charge=0 25 | mol.spin =0 26 | mol.basis = "6-31G" 27 | mol.build() 28 | 29 | # definition of NN structure # 30 | hidden=100 31 | print("hidden nodes= "+str(hidden)) 32 | 33 | class Net(nn.Module): 34 | def __init__(self): 35 | super(Net, self).__init__() 36 | self.fc1 = nn.Linear(5, hidden) 37 | self.fc2 = nn.Linear(hidden, hidden) 38 | self.fc3 = nn.Linear(hidden, hidden) 39 | self.fc4 = nn.Linear(hidden, 1) 40 | 41 | 42 | def forward(self, x): 43 | t=torch.empty((x.shape[0],5)) 44 | unif=(x[:,1]+x[:,0]+1e-7)**(1.0/3) 45 | t[:,0]=unif 46 | t[:,1]=((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5 47 | t[:,2]=((x[:,2]+x[:,4]+2*x[:,3])**0.5+1e-7)/unif**4 48 | ds=(1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(5.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(5.0/3) 49 | t[:,3]=(x[:,5]+x[:,6]+1e-7)/(unif**5*ds) 50 | t[:,4]=x[:,7] 51 | logt=torch.log(t) 52 | g1=F.elu(self.fc1(logt)) 53 | g2=F.elu(self.fc2(g1)) 54 | g3=F.elu(self.fc3(g2)) 55 | eunif=(x[:,1]+x[:,0]).view(-1,1)**(1.0/3) 56 | spinscale=(((1+torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3)+(1-torch.div((x[:,0]-x[:,1]),(x[:,1]+x[:,0]+1e-7)))**(4.0/3))*0.5).view(-1,1) 57 | g4=-(F.elu(self.fc4(g3))+1)*eunif*spinscale 58 | return g4 59 | 60 | #loading NN weights 61 | model = Net() 62 | model.load_state_dict(torch.load("NNNRA",map_location='cpu')) 63 | 64 | # definition of functional # 65 | 66 | old_coords=np.empty(1) 67 | cutoff=math.log(1e3) 68 | intlist=[] 69 | def eval_xc(xc_code, rho, spin, weight, coords, relativity=0, deriv=2, verbose=None): 70 | global old_coords 71 | global intlist 72 | if spin!=0: 73 | rho1=rho[0] 74 | rho2=rho[1] 75 | rho01, dx1, dy1, dz1, lapl1, tau1 = rho1[:6] 76 | rho02, dx2, dy2, dz2, lapl2, tau2 = rho2[:6] 77 | gamma1=dx1**2+dy1**2+dz1**2+1e-7 78 | gamma2=dx2**2+dy2**2+dz2**2+1e-7 79 | gamma12=dx1*dx2+dy1*dy2+dz1*dz2+1e-7 80 | else: 81 | rho0, dx, dy, dz, lapl, tau = rho[:6] 82 | gamma1=gamma2=gamma12=(dx**2+dy**2+dz**2)*0.25+1e-7 83 | rho01=rho02=rho0*0.5 84 | tau1=tau2=tau*0.5 85 | 86 | rhos=rho01+rho02 87 | 88 | N=rhos.shape[0] 89 | Kr=np.empty(N) 90 | dKr=np.empty(N) 91 | if np.array_equal(coords,old_coords) : 92 | for i in range (0,N): 93 | dis=((coords[i]-coords[intlist[i]])**2).sum(axis=1)**0.5/0.2 94 | Rw=weight[intlist[i]]*np.exp(-dis) 95 | Kr[i]=np.dot(Rw,rhos[intlist[i]]) 96 | 97 | else: 98 | intlist=[] 99 | for i in range (0,N): 100 | dis=((coords[i]-coords)**2).sum(axis=1)**0.5/0.2 101 | intlist.append(np.where(dis