Path: blob/main/chemistry-simulations/aux_files/krylov/qchem/uccsd_init_param.py
583 views
try:1from pyscf import gto, scf, cc, mcscf, mp, solvent2except ValueError:3print('PySCF should be installed to use pyscf. Use pip install pyscf')45import numpy as np678###################################9def get_thetas_unpack_restricted(singles, doubles, n_occupied, n_virtual):1011theta_1 = np.zeros((2 * n_occupied, 2 * n_virtual))12theta_2 = np.zeros(13(2 * n_occupied, 2 * n_occupied, 2 * n_virtual, 2 * n_virtual))1415for p in range(n_occupied):16for q in range(n_virtual):17theta_1[2 * p, 2 * q] = singles[p, q]18theta_1[2 * p + 1, 2 * q + 1] = singles[p, q]1920for p in range(n_occupied):21for q in range(n_occupied):22for r in range(n_virtual):23for s in range(n_virtual):24theta_2[2 * p, 2 * q, 2 * s, 2 * r] = doubles[p, q, r, s]25theta_2[2 * p + 1, 2 * q + 1, 2 * r + 1,262 * s + 1] = doubles[p, q, r, s]27theta_2[2 * p, 2 * q + 1, 2 * r + 1, 2 * s] = doubles[p, q,28r, s]29theta_2[2 * p + 1, 2 * q, 2 * r, 2 * s + 1] = doubles[p, q,30r, s]3132return theta_1, theta_2333435##############################################36def uccsd_get_amplitude(single_theta, double_theta, n_electrons, n_qubits, UR):3738# compute a packed list that contains relevant amplitude for the UCCSD.39# We store first single excitation amplitudes then double excitation amplitudes.4041# `single_amplitude: [N_occ, N_virt] array storing the single excitation amplitude.`42# `double_amplitude: [N_occ, N_occ, N_virt, N_virt] array storing double excitation amplitude.`4344if n_qubits % 2 != 0:45raise ValueError(46"Total number of spin molecular orbitals (number of qubits) should be even."47)48else:49n_spatial_orbitals = n_qubits // 25051#if n_electrons%2!=0 and spin>0:52if UR:53t1a, t1b = single_theta54t2aa, t2ab, t2bb = double_theta55t2ab = np.asarray(t2ab.transpose(0, 1, 3, 2), order='C')5657n_occupied_alpha, n_virtual_alpha = t1a.shape58n_occupied_beta, n_virtual_beta = t1b.shape5960singles_alpha = []61singles_beta = []62doubles_mixed = []63doubles_alpha = []64doubles_beta = []6566for p in range(n_occupied_alpha):67for q in range(n_virtual_alpha):68singles_alpha.append(t1a[p, q])6970for p in range(n_occupied_beta):71for q in range(n_virtual_beta):72singles_beta.append(t1b[p, q])7374for p in range(n_occupied_alpha):75for q in range(n_occupied_beta):76for r in range(n_virtual_beta):77for s in range(n_virtual_alpha):78doubles_mixed.append(t2ab[p, q, r, s])7980for p in range(n_occupied_alpha - 1):81for q in range(p + 1, n_occupied_alpha):82for r in range(n_virtual_alpha - 1):83for s in range(r + 1, n_virtual_alpha):84doubles_alpha.append(t2aa[p, q, r, s])8586for p in range(n_occupied_beta - 1):87for q in range(p + 1, n_occupied_beta):88for r in range(n_virtual_beta - 1):89for s in range(r + 1, n_virtual_beta):90doubles_alpha.append(t2bb[p, q, r, s])9192#`elif n_electrons%2==0 and spin==0:`93else:94n_occupied = n_electrons // 295n_virtual = n_spatial_orbitals - n_occupied9697single_amplitude, double_amplitude = get_thetas_unpack_restricted(98single_theta, double_theta, n_occupied, n_virtual)99100singles_alpha = []101singles_beta = []102doubles_mixed = []103doubles_alpha = []104doubles_beta = []105106occupied_alpha_indices = [i * 2 for i in range(n_occupied)]107virtual_alpha_indices = [i * 2 for i in range(n_virtual)]108109occupied_beta_indices = [i * 2 + 1 for i in range(n_occupied)]110virtual_beta_indices = [i * 2 + 1 for i in range(n_virtual)]111112# Same spin single excitation113for p in occupied_alpha_indices:114for q in virtual_alpha_indices:115singles_alpha.append(single_amplitude[p, q])116117for p in occupied_beta_indices:118for q in virtual_beta_indices:119singles_beta.append(single_amplitude[p, q])120121#Mixed spin double excitation122for p in occupied_alpha_indices:123for q in occupied_beta_indices:124for r in virtual_beta_indices:125for s in virtual_alpha_indices:126doubles_mixed.append(double_amplitude[p, q, r, s])127128# same spin double excitation129n_occ_alpha = len(occupied_alpha_indices)130n_occ_beta = len(occupied_beta_indices)131n_virt_alpha = len(virtual_alpha_indices)132n_virt_beta = len(virtual_beta_indices)133134for p in range(n_occ_alpha - 1):135for q in range(p + 1, n_occ_alpha):136for r in range(n_virt_alpha - 1):137for s in range(r + 1, n_virt_alpha):138139# Same spin: all alpha140doubles_alpha.append(double_amplitude[occupied_alpha_indices[p], occupied_alpha_indices[q],\141virtual_alpha_indices[r], virtual_alpha_indices[s]])142143for p in range(n_occ_beta - 1):144for q in range(p + 1, n_occ_beta):145for r in range(n_virt_beta - 1):146for s in range(r + 1, n_virt_beta):147148# Same spin: all beta149doubles_beta.append(double_amplitude[occupied_beta_indices[p], occupied_beta_indices[q],\150virtual_beta_indices[r], virtual_beta_indices[s]])151152return singles_alpha + singles_beta + doubles_mixed + doubles_alpha + doubles_beta153154155##############################156157def get_parameters(xyz:str, spin:int, charge: int, basis:str, symmetry:bool=False, memory:float=4000,cycles:int=100, \158initguess:str='minao', UR:bool=False, nele_cas=None, norb_cas=None, MP2:bool=False, natorb:bool=False,\159ccsd:bool=False, without_solvent:bool=True, potfile:str=None, verbose:bool=False):160161if verbose:162print(163'[pyscf] Computing initial guess parameters using the classical CCSD'164)165166filename = xyz.split('.')[0]167mol = gto.M(atom=xyz,168spin=spin,169charge=charge,170basis=basis,171max_memory=memory,172symmetry=symmetry,173output=filename + '-pyscf.log',174verbose=4)175176if without_solvent:177if UR:178myhf = scf.UHF(mol)179myhf.max_cycle = cycles180myhf.chkfile = filename + '-pyscf.chk'181myhf.init_guess = initguess182myhf.kernel()183184norb = myhf.mo_coeff[0].shape[1]185if verbose:186print('[pyscf] Total number of alpha molecular orbitals = ',187norb)188norb = myhf.mo_coeff[1].shape[1]189if verbose:190print('[pyscf] Total number of beta molecular orbitals = ',191norb)192193else:194myhf = scf.RHF(mol)195myhf.max_cycle = cycles196myhf.chkfile = filename + '-pyscf.chk'197myhf.init_guess = initguess198myhf.kernel()199200norb = myhf.mo_coeff.shape[1]201if verbose:202print('[pyscf] Total number of orbitals = ', norb)203204nelec = mol.nelectron205if verbose:206print('[pyscf] Total number of electrons = ', nelec)207if verbose:208print('[pyscf] HF energy = ', myhf.e_tot)209210##########################211# MP2212##########################213if MP2:214215if UR:216mymp = mp.UMP2(myhf)217mp_ecorr, mp_t2 = mymp.kernel()218if verbose:219print('[pyscf] UR-MP2 energy= ', mymp.e_tot)220221if natorb:222# Compute natural orbitals223dma, dmb = mymp.make_rdm1()224noon_a, U_a = np.linalg.eigh(dma)225noon_b, U_b = np.linalg.eigh(dmb)226noon_a = np.flip(noon_a)227noon_b = np.flip(noon_b)228229if verbose:230print(231'Natural orbital (alpha orbitals) occupation number from UR-MP2: '232)233if verbose:234print(noon_a)235if verbose:236print(237'Natural orbital (beta orbitals) occupation number from UR-MP2: '238)239if verbose:240print(noon_b)241242natorbs = np.zeros(np.shape(myhf.mo_coeff))243natorbs[0, :, :] = np.dot(myhf.mo_coeff[0], U_a)244natorbs[0, :, :] = np.fliplr(natorbs[0, :, :])245natorbs[1, :, :] = np.dot(myhf.mo_coeff[1], U_b)246natorbs[1, :, :] = np.fliplr(natorbs[1, :, :])247248else:249if spin != 0:250raise ValueError("WARN: ROMP2 is unvailable in pyscf.")251else:252mymp = mp.MP2(myhf)253mp_ecorr, mp_t2 = mymp.kernel()254if verbose:255print('[pyscf] R-MP2 energy= ', mymp.e_tot)256257if natorb:258# Compute natural orbitals259noons, natorbs = mcscf.addons.make_natural_orbitals(260mymp)261if verbose:262print(263'Natural orbital occupation number from R-MP2: '264)265if verbose:266print(noons)267268if ccsd:269270if UR:271272mc = mcscf.UCASCI(myhf, norb_cas, nele_cas)273frozen = []274frozen = [y for y in range(0, mc.ncore[0])]275frozen += [276y for y in range(mc.ncore[0] +277mc.ncas, len(myhf.mo_coeff[0]))278]279280if natorb:281mycc = cc.UCCSD(myhf, frozen=frozen, mo_coeff=natorbs)282mycc.max_cycle = cycles283mycc.kernel()284if verbose:285print(286'[pyscf] UR-CCSD energy of the active space using natural orbitals= ',287mycc.e_tot)288289else:290mycc = cc.UCCSD(myhf, frozen=frozen)291mycc.max_cycle = cycles292mycc.kernel()293if verbose:294print(295'[pyscf] UR-CCSD energy of the active space using molecular orbitals= ',296mycc.e_tot)297298else:299if nele_cas is None:300mycc = cc.CCSD(myhf)301mycc.max_cycle = cycles302mycc.kernel()303if verbose:304print('[pyscf] Total R-CCSD energy = ', mycc.e_tot)305qubits_num = 2 * norb306init_params = uccsd_get_amplitude(mycc.t1, mycc.t2, nelec,307qubits_num, UR)308#`np.array(init_params).tofile(f'{filename}_params.dat')`309return init_params310311else:312mc = mcscf.CASCI(myhf, norb_cas, nele_cas)313frozen = []314frozen += [y for y in range(0, mc.ncore)]315frozen += [316y for y in range(mc.ncore +317norb_cas, len(myhf.mo_coeff))318]319if natorb and (spin == 0):320mycc = cc.CCSD(myhf, frozen=frozen, mo_coeff=natorbs)321mycc.max_cycle = cycles322mycc.kernel()323if verbose:324print(325'[pyscf] R-CCSD energy of the active space using natural orbitals= ',326mycc.e_tot)327328elif natorb and (spin != 0):329raise ValueError(330"WARN: Natural orbitals cannot be computed. ROMP2 is unvailable in pyscf."331)332333else:334mycc = cc.CCSD(myhf, frozen=frozen)335mycc.max_cycle = cycles336mycc.kernel()337if verbose:338print(339'[pyscf] R-CCSD energy of the active space using molecular orbitals= ',340mycc.e_tot)341342qubits_num = 2 * norb_cas343init_params = uccsd_get_amplitude(mycc.t1, mycc.t2,344nele_cas, qubits_num, UR)345#`np.array(init_params).tofile(f'{filename}_params.dat')`346return init_params347348# With solvent349else:350nelec = mol.nelectron351if verbose:352print('[Pyscf] Total number of electrons = ', nelec)353354# HF with PE model.355mf_pe = scf.RHF(mol)356mf_pe.init_guess = initguess357mf_pe = solvent.PE(mf_pe, potfile).run()358norb = mf_pe.mo_coeff.shape[1]359if verbose:360print('[Pyscf] Total number of orbitals = ', norb)361if verbose:362print('[Pyscf] Total HF energy with solvent:', mf_pe.e_tot)363if verbose:364print('[Pyscf] Polarizable embedding energy from HF: ',365mf_pe.with_solvent.e)366367if MP2:368if spin != 0:369raise ValueError("WARN: ROMP2 is unvailable in pyscf.")370else:371mymp = mp.MP2(mf_pe)372mymp = solvent.PE(mymp, potfile)373mymp.run()374if verbose:375print('[pyscf] R-MP2 energy with solvent= ', mymp.e_tot)376if verbose:377print('[Pyscf] Polarizable embedding energy from MP: ',378mymp.with_solvent.e)379380if natorb:381# Compute natural orbitals382noons, natorbs = mcscf.addons.make_natural_orbitals(mymp)383if verbose:384print(385'[Pyscf] Natural orbital occupation number from R-MP2: '386)387if verbose:388print(noons)389390if ccsd:391if nele_cas is None:392mycc = cc.CCSD(mf_pe)393mycc = solvent.PE(mycc, potfile)394mycc.run()395if verbose:396print('[Pyscf] Total CCSD energy with solvent: ',397mycc.e_tot)398if verbose:399print('[Pyscf] Polarizable embedding energy from CCSD: ',400mycc.with_solvent.e)401qubits_num = 2 * norb402init_params = uccsd_get_amplitude(mycc.t1, mycc.t2, nelec,403qubits_num, UR)404#`np.array(init_params).tofile(f'{filename}_params.dat')```405return init_params406407else:408mc = mcscf.CASCI(mf_pe, norb_cas, nele_cas)409frozen = []410frozen += [y for y in range(0, mc.ncore)]411frozen += [412y for y in range(mc.ncore + norb_cas, len(mf_pe.mo_coeff))413]414415if natorb and (spin == 0):416mycc = cc.CCSD(mf_pe, frozen=frozen, mo_coeff=natorbs)417mycc = solvent.PE(mycc, potfile)418mycc.run()419if verbose:420print(421'[pyscf] R-CCSD energy of the active space (using natural orbitals) with solvent= ',422mycc.e_tot)423else:424mycc = cc.CCSD(mf_pe, frozen=frozen)425mycc = solvent.PE(mycc, potfile)426mycc.run()427if verbose:428print(429'[pyscf] CCSD energy of the active space (using molecular orbitals) with solvent= ',430mycc.e_tot)431if verbose:432print(433'[Pyscf] Polarizable embedding energy from CCSD: ',434mycc.with_solvent.e)435436qubits_num = 2 * norb_cas437init_params = uccsd_get_amplitude(mycc.t1, mycc.t2, nele_cas,438qubits_num, UR)439#`np.array(init_params).tofile(f'{filename}_params.dat')`440return init_params441442