|
本帖最后由 flyingchow 于 2023-6-27 05:37 编辑
在看了Multiwfn的NOCV源码之后,我就想用python计算NOCV的eigenvalue,计算过程和Multiwfn是一样的。但是得不到最后成对的eigenvalue。
我现在把这个错误的脚本发到论坛上来,各位老师检查一下,看看哪里能是我搞错了。
我原计划是支持pyscf和turbomole两种软件。
构建CObasapro
- # build diagonal block coefficient matrix for fragments A and B
- def get_coeff_pro(self):
- # obtain the coefficient matrix of fragments A and B
- fragA_coeff = self.mol1_coeff
- fragB_coeff = self.mol2_coeff
- zero_like_A = np.zeros((len(fragA_coeff),len(fragB_coeff)))
- zero_like_B = np.zeros((len(fragB_coeff),len(fragA_coeff)))
- # build the full coefficient matrix for fragments A and B
- self.coeff_pro = np.block([[fragA_coeff, zero_like_A],
- [zero_like_B, fragB_coeff]])
复制代码 计算nocc/norb 总轨道和occupied轨道 以及occupied轨道在CObasapro中的列数
- def get_occupied(self):
- # obtain the column number of occupied orbitals in s_frag and coeff_frz
- self.nocc = self.mol_3.nelectron//2
- norb = self.mol_3.nao_nr()
- nocc_A = self.mol_1.nelectron//2
- norb_A = self.mol_1.nao_nr()
- nocc_B = self.mol_2.nelectron//2
- norb_B = self.mol_2.nao_nr()
- self.occupied_rows = []
- if norb == norb_A + norb_B:
- for i in range(nocc_A):
- self.occupied_rows.append(i)
- # starting from occ_A, ending at occ_A+nocc_B
- for i in range(norb_A,norb_A+nocc_B):
- self.occupied_rows.append(i)
- print (f'{norb} basis sets were used and {self.nocc} orbitals are occupied')
- print(f'{norb_A} basis sets were used for fragment A and {nocc_A} orbitals are occupied')
- print(f'{norb_B} basis sets were used for fragment B and {nocc_B} orbitals are occupied')
复制代码 计算Cobasa_frz和P_diff
- def get_coeff_frz(self):
- # obtain the overlap matrix of mol3 (AB combined)
- self.s = self.mol_3.intor_symmetric('int1e_ovlp')
- # calculate MO overlap matrix from AO overlap matrix
- self.s_frag_total = matmul(self.coeff_pro.T,matmul(self.s,self.coeff_pro))
- self.s_frag = self.s_frag_total[self.occupied_rows, :][:, self.occupied_rows]
- # get eigenvalues and eigenvectors of s_frag
- eigval_s_frag,eigvec_s_frag = np.linalg.eigh(self.s_frag)
- # calculate eigenvalues inverse square root and get S^(-1/2)
- eigval_inv_sqrt = np.diag(1 / np.sqrt(eigval_s_frag))
- self.s_frag_inv_sqrt = matmul(eigvec_s_frag,matmul(eigval_inv_sqrt,eigvec_s_frag.T))
- # get coefficient matrix of frozen orbitals
- self.coeff_frz = np.einsum('ij,jk->ik',self.coeff_pro[:,self.occupied_rows],self.s_frag_inv_sqrt)
- # get density matrix of frozen orbitals
- self.den_frz = np.einsum('pi,qi->pq', self.coeff_frz, np.conj(self.coeff_frz))*2
- def get_nocv_eig(self):
- self.den_deform = self.den_total - self.den_frz
- self.den_deform = np.matmul(self.den_deform, self.s)
- self.nocv_eigval,self.nocv_eigvec = np.linalg.eigh(self.den_deform)
复制代码 请老师帮忙看看,到底问题出在哪里。谢谢大家了。
|
-
-
nocv.py
10.65 KB, 下载次数 Times of downloads: 4
|