def test_scheme4(): ph = Phonon.simple_phonon(Quantity(3.33), Quantity(1), 2) m1 = Mol(Quantity(0), [ph]) m2 = Mol(Quantity(0), [ph]*2) mlist1 = MolList([m1, m2], Quantity(17), 4) mlist2 = MolList([m1, m2], Quantity(17), 3) mpo4 = Mpo(mlist1) assert mpo4.is_hermitian() # for debugging f = mpo4.full_operator() mpo3 = Mpo(mlist2) assert mpo3.is_hermitian() # makeup two states mps4 = Mps() mps4.mol_list = mlist1 mps4.use_dummy_qn = True mps4.append(np.array([1, 0]).reshape((1,2,1))) mps4.append(np.array([0, 1]).reshape((1,2,1))) mps4.append(np.array([0.707, 0.707]).reshape((1,2,1))) mps4.append(np.array([1, 0]).reshape((1,2,1))) mps4.build_empty_qn() e4 = mps4.expectation(mpo4) mps3 = Mps() mps3.mol_list = mlist2 mps3.append(np.array([1, 0]).reshape((1,2,1))) mps3.append(np.array([1, 0]).reshape((1,2,1))) mps3.append(np.array([0, 1]).reshape((1,2,1))) mps3.append(np.array([0.707, 0.707]).reshape((1,2,1))) mps3.append(np.array([1, 0]).reshape((1,2,1))) e3 = mps3.expectation(mpo3) assert pytest.approx(e4) == e3
def test_general_mpo_sbm(): mol = get_mol() mol_list = MolList([mol], Quantity(0)) mol_list.mol_list2_para() mpo = Mpo.general_mpo(mol_list, const=Quantity(-mol_list[0].gs_zpe * mol_list.mol_num)) mpo_std = Mpo(mol_list) check_result(mpo, mpo_std)
def test_band_limit_finite_t( mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps, scheme, ): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList( [Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=scheme, ) ct1 = ChargeTransport(mol_list, stop_at_edge=False) ct1.evolve(evolve_dt, nsteps) ct2 = ChargeTransport(mol_list, temperature=low_t, stop_at_edge=False) ct2.evolve(evolve_dt, nsteps) assert ct1.is_similar(ct2)
def test_evolve(mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList( [Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=3, ) ct1 = ChargeTransport(mol_list, stop_at_edge=False) half_nsteps = nsteps // 2 ct1.evolve(evolve_dt, half_nsteps) ct1.evolve(evolve_dt, nsteps - half_nsteps) ct2 = ChargeTransport(mol_list, stop_at_edge=False) ct2.evolve(evolve_dt, nsteps) assert ct1.is_similar(ct2) assert_iterable_equal(ct1.get_dump_dict(), ct2.get_dump_dict()) # test dump ct2.dump_dir = "." ct2.job_name = "test" ct2.dump_dict() os.remove("test.npz")
def ph_onsite(cls, mol_list: MolList, opera: str, mol_idx:int, ph_idx=0): assert opera in ["b", r"b^\dagger", r"b^\dagger b"] mpo = cls() mpo.mol_list = mol_list for imol, mol in enumerate(mol_list): if mol_list.scheme < 4: mpo.append(xp.eye(2).reshape(1, 2, 2, 1)) elif mol_list.scheme == 4: if len(mpo) == mol_list.e_idx(): n = mol_list.mol_num mpo.append(xp.eye(n).reshape(1, n, n, 1)) else: assert False iph = 0 for ph in mol.dmrg_phs: for iqph in range(ph.nqboson): ph_pbond = ph.pbond[iqph] if imol == mol_idx and iph == ph_idx: mt = ph_op_matrix(opera, ph_pbond) else: mt = ph_op_matrix("Iden", ph_pbond) mpo.append(mt.reshape(1, ph_pbond, ph_pbond, 1)) iph += 1 mpo.build_empty_qn() return mpo
def test_reduced_density_matrix( mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps, temperature, ): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList([Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=3) ct = ChargeTransport(mol_list, temperature=Quantity(temperature, "K"), stop_at_edge=False, rdm=True) ct.evolve(evolve_dt, nsteps) for rdm, e in zip(ct.reduced_density_matrices, ct.e_occupations_array): # best we can do? assert np.allclose(np.diag(rdm), e)
def test_autocorr(scheme, mollist2): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 2) mol = Mol(Quantity(0), [ph]) mol_list1 = MolList([mol] * 5, Quantity(1), scheme) if mollist2: mol_list = MolList2.MolList_to_MolList2(mol_list1) else: mol_list = mol_list1 temperature = Quantity(50000, 'K') compress_config = CompressConfig(CompressCriteria.fixed, max_bonddim=24) evolve_config = EvolveConfig(EvolveMethod.tdvp_ps, adaptive=True, guess_dt=0.5, adaptive_rtol=1e-3) ievolve_config = EvolveConfig(EvolveMethod.tdvp_ps, adaptive=True, guess_dt=-0.1j) ac = TransportAutoCorr(mol_list, temperature, compress_config=compress_config, ievolve_config=ievolve_config, evolve_config=evolve_config) ac.evolve(nsteps=5, evolve_time=5) corr_real = ac.auto_corr.real exact_real = get_exact_autocorr(mol_list1, temperature, ac.evolve_times_array).real atol = 1e-2 # direct comparison may fail because of different sign assert np.allclose(corr_real, exact_real, atol=atol) or np.allclose( corr_real, -exact_real, atol=atol)
def custom_mol_list( custom_j_matrix=None, n_phys_dim=None, nqboson=None, qbtrunc=None, force3rd=None, dis=None, hartrees=None, nmols=3, ) -> MolList: if custom_j_matrix is None: custom_j_matrix = _j_matrix if n_phys_dim is None: n_phys_dim = ph_phys_dim if nqboson is None: nqboson = [1, 1] if qbtrunc is None: qbtrunc = [0.0, 0.0] if force3rd is None: force3rd = [None, None] if dis is None: dis = displacement_quantities if hartrees is None: hartrees = [False, False] displacement = [[Quantity(0), dis[0]], [Quantity(0), dis[1]]] ph_list = [ Phonon(*args) for args in zip(omega, displacement, n_phys_dim, force3rd, nqboson, qbtrunc, hartrees) ] return MolList([Mol(elocalex, ph_list, dipole_abs)] * nmols, custom_j_matrix)
def test_zt_init_state(): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 10) mol_list = MolList([Mol(Quantity(0), [ph])], Quantity(0), scheme=3) mpo = Mpo(mol_list) mps = Mps.random(mol_list, 1, 10) optimize_mps(mps, mpo) ct = ChargeTransport(mol_list) assert mps.angle(ct.latest_mps) == pytest.approx(1)
def test_scheme4_finite_t(mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps): temperature = Quantity(1, "a.u.") ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList([Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV")) ct1 = ChargeTransport(mol_list.switch_scheme(3), temperature=temperature, stop_at_edge=False) ct1.evolve(evolve_dt, nsteps) ct2 = ChargeTransport(mol_list.switch_scheme(4), temperature=temperature, stop_at_edge=False) ct2.evolve(evolve_dt, nsteps) assert ct1.is_similar(ct2, rtol=1e-2)
def test_bogoliubov(): # REF: JCP, 2016, 145, 224101 evolve_config = EvolveConfig(EvolveMethod.tdvp_ps) # evolve_config = EvolveConfig() omega = 1 D = 1 nlevel = 10 T = Quantity(1) ph1 = Phonon.simple_phonon(Quantity(omega), Quantity(D), nlevel) mol1 = Mol(Quantity(0), [ph1]) mlist = MolList([mol1] * 2, Quantity(1), scheme=4) mpdm1 = MpDm.max_entangled_gs(mlist) mpdm1.evolve_config = evolve_config mpo1 = Mpo(mlist) tp = ThermalProp(mpdm1, mpo1, exact=True) tp.evolve(nsteps=20, evolve_time=T.to_beta() / 2j) mpdm2 = tp.latest_mps e1 = mpdm2.expectation(mpo1) mpdm3 = (Mpo.onsite(mlist, r"a^\dagger", False, {0}) @ mpdm2).expand_bond_dimension(mpo1) es1 = [mpdm3.e_occupations] for i in range(40): mpdm3 = mpdm3.evolve(mpo1, 0.1) es1.append(mpdm3.e_occupations) theta = np.arctanh(np.exp(-T.to_beta() * omega / 2)) ph2 = Phonon.simple_phonon(Quantity(omega), Quantity(D * np.cosh(theta)), nlevel) ph3 = Phonon.simple_phonon(Quantity(-omega), Quantity(-D * np.sinh(theta)), nlevel) mol2 = Mol(Quantity(0), [ph2, ph3]) mlist2 = MolList([mol2] * 2, Quantity(1), scheme=4) mps1 = Mps.gs(mlist2, False) mps1.evolve_config = evolve_config mpo2 = Mpo(mlist2) e2 = mps1.expectation(mpo2) mps2 = (Mpo.onsite(mlist2, r"a^\dagger", False, {0}) @ mps1).expand_bond_dimension(mpo2) es2 = [mps2.e_occupations] for i in range(20): mps2 = mps2.evolve(mpo2, 0.2) es2.append(mps2.e_occupations) assert np.allclose(es1[::2], es2, atol=5e-3)
def test_ft_init_state(): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 10) mol_list = MolList([Mol(Quantity(0), [ph])], Quantity(0), scheme=3) temperature = Quantity(0.1) mpo = Mpo(mol_list) init_mpdm = MpDm.max_entangled_ex(mol_list) tp = ThermalProp(init_mpdm, mpo, space="EX", exact=True) tp.evolve(nsteps=20, evolve_time=temperature.to_beta() / 2j) ct = ChargeTransport(mol_list, temperature=temperature) tp_mpdm = MpDmFull.from_mpdm(tp.latest_mps) ct_mpdm = MpDmFull.from_mpdm(ct.latest_mps) assert tp_mpdm.angle(ct_mpdm) == pytest.approx(1)
def test_offset(scheme): ph = Phonon.simple_phonon(Quantity(3.33), Quantity(1), 2) m = Mol(Quantity(0), [ph] * 2) mlist = MolList([m] * 2, Quantity(17), scheme=scheme) mpo1 = Mpo(mlist) assert mpo1.is_hermitian() f1 = mpo1.full_operator() evals1, _ = np.linalg.eigh(f1.asnumpy()) offset = Quantity(0.123) mpo2 = Mpo(mlist, offset=offset) f2 = mpo2.full_operator() evals2, _ = np.linalg.eigh(f2.asnumpy()) assert np.allclose(evals1 - offset.as_au(), evals2)
def test_reduced_density_matrix( mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps, temperature, ): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list3 = MolList( [Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=3, ) ct3 = ChargeTransport(mol_list3, temperature=Quantity(temperature, "K"), stop_at_edge=False, rdm=True) ct3.evolve(evolve_dt, nsteps) mol_list4 = mol_list3.switch_scheme(4) ct4 = ChargeTransport(mol_list4, temperature=Quantity(temperature, "K"), stop_at_edge=False, rdm=True) ct4.evolve(evolve_dt, nsteps) for rdm3, rdm4, e in zip(ct3.reduced_density_matrices, ct4.reduced_density_matrices, ct3.e_occupations_array): assert np.allclose(rdm3, rdm4, atol=1e-3) assert np.allclose(np.diag(rdm3), e)
def param2mollist(alpha: float, raw_delta: Quantity, omega_c: Quantity, renormalization_p: float, n_phonons: int): sdf = SpectralDensityFunction(alpha, omega_c) delta, max_omega = sdf.adiabatic_renormalization(raw_delta, renormalization_p) omega_list, displacement_list = sdf.trapz(n_phonons, 0.0, max_omega.as_au()) ph_list = [ Phonon.simplest_phonon(o, d) for o, d in zip(omega_list, displacement_list) ] mol = Mol(Quantity(0), ph_list, tunnel=delta) return MolList([mol], None)
def test_similar(mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList([Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=3) ct1 = ChargeTransport(mol_list) ct1.evolve(evolve_dt, nsteps) ct2 = ChargeTransport(mol_list) ct2.evolve(evolve_dt + 1e-5, nsteps) assert ct1.is_similar(ct2)
def test_autocorr(insteps, atol): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 2) mol = Mol(Quantity(0), [ph]) mol_list = MolList([mol] * 5, Quantity(1), 3) temperature = Quantity(50000, 'K') compress_config = CompressConfig(threshold=1e-3) ac = TransportAutoCorr(mol_list, temperature, insteps, compress_config=compress_config) ac.evolve(0.2, 50) corr_real = ac.auto_corr.real exact_real = get_exact_autocorr(mol_list, temperature, ac.evolve_times_array).real # direct comparison may fail because of different sign assert np.allclose(corr_real, exact_real, atol=atol) or np.allclose( corr_real, -exact_real, atol=atol)
def test_zt(): mol = get_mol() mol_list = MolList([mol], Quantity(0)) mps = Mps.gs(mol_list, False) mps.compress_config = CompressConfig(threshold=1e-6) mps.evolve_config = EvolveConfig(adaptive=True, guess_dt=0.1) mps.use_dummy_qn = True mpo = Mpo(mol_list) time_series = [0] spin = [1] for i in range(30): dt = mps.evolve_config.guess_dt mps = mps.evolve(mpo, evolve_dt=dt) time_series.append(time_series[-1] + dt) spin.append(1 - 2 * mps.e_occupations[0]) exact = get_exact_zt(mol, time_series) assert np.allclose(exact, spin, atol=1e-3)
def test_compress_add(mol_num, j_constant_value, elocalex_value, ph_info, ph_phys_dim, evolve_dt, nsteps): ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), ph_phys_dim) for omega, displacement in ph_info ] mol_list = MolList([Mol(Quantity(elocalex_value, "a.u."), ph_list)] * mol_num, Quantity(j_constant_value, "eV"), scheme=3) ct1 = ChargeTransport(mol_list, temperature=Quantity(298, "K")) ct1.reduced_density_matrices = None ct1.evolve(evolve_dt, nsteps) ct2 = ChargeTransport(mol_list, temperature=Quantity(298, "K")) ct2.reduced_density_matrices = None ct2.latest_mps.compress_add = True ct2.evolve(evolve_dt, nsteps) assert ct1.is_similar(ct2, rtol=1e-2)
def test_mpdm_full(nmols, phonon_freq): ph = Phonon.simple_phonon(Quantity(phonon_freq), Quantity(1), 2) m = Mol(Quantity(0), [ph]) mol_list = MolList([m] * nmols, Quantity(1)) gs_dm = MpDm.max_entangled_gs(mol_list) beta = Quantity(1000, "K").to_beta() tp = ThermalProp(gs_dm, Mpo(mol_list), exact=True, space="GS") tp.evolve(None, 50, beta / 1j) gs_dm = tp.latest_mps assert np.allclose(gs_dm.e_occupations, [0] * nmols) e_gs_dm = Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}).apply(gs_dm, canonicalise=True) assert np.allclose(e_gs_dm.e_occupations, [1] + [0] * (nmols - 1)) mpdm_full = MpDmFull.from_mpdm(e_gs_dm) assert np.allclose(mpdm_full.e_occupations, e_gs_dm.e_occupations) assert np.allclose(mpdm_full.ph_occupations, e_gs_dm.ph_occupations, rtol=1e-3)
def test_2site(): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 2) m = Mol(Quantity(0), [ph]) mol_list = MolList([m] * 2, Quantity(1), scheme=3) gs_mp = Mpo.onsite(mol_list, opera=r"a^\dagger", mol_idx_set={0}).apply(Mps.gs(mol_list, max_entangled=False)) mpdm = MpDm.from_mps(gs_mp) mpdm_full = MpDmFull.from_mpdm(mpdm) mpdm_full.compress_config = CompressConfig(threshold=1e-4) liouville = SuperLiouville(Mpo(mol_list), dissipation=1) ph_occupations_array = [] energies = [] for i in range(51): logger.info(mpdm_full) logger.info(mpdm_full.ph_occupations) ph_occupations_array.append(mpdm_full.ph_occupations) logger.info(mpdm_full.expectation(liouville)) energies.append(mpdm_full.expectation(liouville)) mpdm_full = mpdm_full.evolve(liouville, 0.4) ph_occupations_array = np.array(ph_occupations_array) assert energies[-1] == pytest.approx(-0.340162, rel=1e-2) assert np.allclose(ph_occupations_array[-1], [0.0930588, 0.099115], rtol=1e-2)
def construct_mol(nmols, dmrg_nphs, hartree_nphs) -> MolList: assert dmrg_nphs + hartree_nphs == 10 elocalex = Quantity(2.13 / constant.au2ev) dipole_abs = 1.0 # cm^-1 omega_value = (np.array([ 206.0, 211.0, 540.0, 552.0, 751.0, 1325.0, 1371.0, 1469.0, 1570.0, 1628.0 ]) * constant.cm2au) S_value = np.array( [0.197, 0.215, 0.019, 0.037, 0.033, 0.010, 0.208, 0.042, 0.083, 0.039]) # sort from large to small gw = np.sqrt(S_value) * omega_value idx = np.argsort(gw)[::-1] omega_value = omega_value[idx] S_value = S_value[idx] omega = [[Quantity(x), Quantity(x)] for x in omega_value] D_value = np.sqrt(S_value) / np.sqrt(omega_value / 2.0) displacement = [[Quantity(0), Quantity(x)] for x in D_value] ph_phys_dim = [5] * 10 # print(dmrg_nphs, hartree_nphs) is_hartree = [False] * dmrg_nphs + [True] * hartree_nphs ph_list = [ Phonon(*args[:3], hartree=args[3]) for args in zip(omega, displacement, ph_phys_dim, is_hartree) ] mol_list = MolList([Mol(elocalex, ph_list, dipole_abs)] * nmols, Quantity(500, "cm-1"), scheme=3) #mol_list = MolList([Mol(elocalex, ph_list, dipole_abs, heatbath=True)] * nmols, Quantity(0.0124, "eV")) return mol_list
def test_ft(): mol = get_mol() mol_list = MolList([mol], Quantity(0)) mpo = Mpo(mol_list) impdm = MpDm.max_entangled_gs(mol_list) impdm.compress_config = CompressConfig(threshold=1e-6) impdm.use_dummy_qn = True temperature = Quantity(3) evolve_config = EvolveConfig(adaptive=True, guess_dt=-0.001j) tp = ThermalProp(impdm, mpo, evolve_config=evolve_config) tp.evolve(nsteps=1, evolve_time=temperature.to_beta() / 2j) mpdm = tp.latest_mps mpdm = Mpo.onsite(mol_list, r"sigma_x").contract(mpdm) mpdm.evolve_config = EvolveConfig(adaptive=True, guess_dt=0.1) time_series = [0] spin = [1 - 2 * mpdm.e_occupations[0]] for i in range(30): dt = mpdm.evolve_config.guess_dt mpdm = mpdm.evolve(mpo, evolve_dt=dt) time_series.append(time_series[-1] + dt) spin.append(1 - 2 * mpdm.e_occupations[0]) exact = get_exact_ft(mol, temperature, time_series) assert np.allclose(exact, spin, atol=1e-3)
def test_1mol_ZTabs(): log.init_log(logging.WARNING) nmols = 1 mol_list = MolList( [Mol(elocalex, hartree_ph_list, dipole_abs) for _ in range(nmols)], np.zeros([1, 1]), ) E_offset = -mol_list[0].elocalex - mol_list[0].hartree_e0 ls = tdh.LinearSpectra("abs", mol_list, E_offset=E_offset, prop_method="unitary") nsteps = 1000 - 1 dt = 30.0 ls.evolve(dt, nsteps) with open(os.path.join(cur_dir, "1mol_ZTabs.npy"), "rb") as f: mol1_ZTabs_std = np.load(f) assert np.allclose(ls.autocorr, mol1_ZTabs_std)
lams = hr_factors * omegas_au phonons = [ Phonon.simplest_phonon(Quantity(o), Quantity(l), lam=True) for o, l in zip(omegas_au, lams) ] j_matrix_au = j_matrix_cm * cm2au mlist = [] for j in np.diag(j_matrix_au): m = Mol(Quantity(j), phonons) mlist.append(m) # starts from 1 mol_arangement = np.array([7, 5, 3, 1, 2, 4, 6]) - 1 mol_list = MolList(list(np.array(mlist)[mol_arangement]), j_matrix_au[mol_arangement][:, mol_arangement]) evolve_dt = 40 evolve_config = EvolveConfig(evolve_dt=evolve_dt) compress_config = CompressConfig(CompressCriteria.fixed, max_bonddim=16) ct = ChargeTransport(mol_list, evolve_config=evolve_config, compress_config=compress_config) ct.dump_dir = "./fmo" ct.job_name = 'hybrid' ct.stop_at_edge = False ct.evolve(evolve_dt=evolve_dt, nsteps=10) new_evolve_config = EvolveConfig(EvolveMethod.tdvp_mctdh_new) ct.latest_mps.evolve_config = ct.evolve_config = new_evolve_config ct.evolve(evolve_dt=evolve_dt, nsteps=100000)
# -*- coding: utf-8 -*- import numpy as np from renormalizer.model import Phonon, Mol, MolList from renormalizer.utils import Quantity from renormalizer.transport import EDGE_THRESHOLD mol_num = 13 ph_list = [ Phonon.simple_phonon(Quantity(omega, "cm^{-1}"), Quantity(displacement, "a.u."), 4) for omega, displacement in [[1e-10, 1e-10]] ] j_constant = Quantity(0.8, "eV") band_limit_mol_list = MolList([Mol(Quantity(0), ph_list)] * mol_num, j_constant, 3) # the temperature should be compatible with the low vibration frequency in TestBandLimitFiniteT # otherwise underflow happens in exact propagator low_t = Quantity(1e-7, "K") def get_analytical_r_square(time_series: np.ndarray): return 2 * (j_constant.as_au())**2 * time_series**2 def assert_band_limit(ct, rtol): analytical_r_square = get_analytical_r_square(ct.evolve_times_array) # has evolved to the edge but not too large assert EDGE_THRESHOLD < ct.latest_mps.e_occupations[0] < 0.1 # value OK
[omega_quantities[1], omega_quantities[1]], ] displacement_quantities = [Quantity(30.1370, "a.u."), Quantity(8.7729, "a.u.")] displacement = [ [Quantity(0), displacement_quantities[0]], [Quantity(0), displacement_quantities[1]], ] ph_phys_dim = [4, 4] ph_list = [Phonon(*args) for args in zip(omega, displacement, ph_phys_dim)] hartree_ph_list = [ Phonon(*args, hartree=True) for args in zip(omega, displacement, ph_phys_dim) ] hybrid_ph_list = [ph_list[1], hartree_ph_list[0]] mol_list = MolList([Mol(elocalex, ph_list, dipole_abs)] * nmols, _j_matrix) hartree_mol_list = MolList([Mol(elocalex, hartree_ph_list, dipole_abs)] * nmols, _j_matrix) hybrid_mol_list = MolList([Mol(elocalex, hybrid_ph_list, dipole_abs)] * nmols, _j_matrix) offset = Quantity(2.28614053, "ev") def custom_mol_list( custom_j_matrix=None, n_phys_dim=None, nqboson=None, qbtrunc=None, force3rd=None, dis=None,
# -*- coding: utf-8 -*- import numpy as np from renormalizer.mps import Mpo from renormalizer.model import Phonon, Mol, MolList from renormalizer.utils import Quantity from renormalizer.utils.qutip_utils import get_clist, get_blist, get_hamiltonian, get_gs OMEGA = 1 DISPLACEMENT = 1 N_LEVELS = 2 N_SITES = 3 J = 1 ph = Phonon.simple_phonon(Quantity(OMEGA), Quantity(DISPLACEMENT), N_LEVELS) mol = Mol(Quantity(0), [ph]) mol_list = MolList([mol] * N_SITES, Quantity(J), 3) qutip_clist = get_clist(N_SITES, N_LEVELS) qutip_blist = get_blist(N_SITES, N_LEVELS) G = np.sqrt(DISPLACEMENT**2 * OMEGA / 2) qutip_h = get_hamiltonian(N_SITES, J, OMEGA, G, qutip_clist, qutip_blist) qutip_gs = get_gs(N_SITES, N_LEVELS)
logger.info(f"g:{g_value}") logger.info(f"lambda:{lambda_value*constant.au2ev}ev,{lambda_value*constant.au2cm}cm^-1") logger.info(f"J:{j_value*constant.au2ev}ev, {j_value*constant.au2cm}cm^-1") j_matrix = np.diag(np.ones(nmols-1)*j_value,k=-1) j_matrix += j_matrix.T ph_phys_dim = 5 omega = [Quantity(omega_value),Quantity(omega_value)] D = [Quantity(0.),Quantity(D_value)] ph = Phonon(omega, D, ph_phys_dim) mol_list = MolList([Mol(Quantity(elocalex), [ph], dipole_abs)] * nmols, j_matrix, scheme=3) # periodic nearest-neighbour interaction mpo = Mpo(mol_list) periodic = Mpo.intersite(mol_list, {0: r"a^\dagger", nmols - 1: "a"}, {}, Quantity(j_value)) mpo = mpo.add(periodic).add(periodic.conj_trans()) @pytest.mark.parametrize("periodic",(True, False)) def test_thermal_equilibrium(periodic): if periodic: # define properties # periodic case prop_mpos = ops.e_ph_static_correlation(mol_list, periodic=True)
def exact_propagator(cls, mol_list: MolList, x, space="GS", shift=0.0): """ construct the GS space propagator e^{xH} exact MPO H=\\sum_{in} \\omega_{in} b^\\dagger_{in} b_{in} fortunately, the H is local. so e^{xH} = e^{xh1}e^{xh2}...e^{xhn} the bond dimension is 1 shift is the a constant for H+shift """ assert space in ["GS", "EX"] mpo = cls() if np.iscomplex(x): mpo.to_complex(inplace=True) mpo.mol_list = mol_list for imol, mol in enumerate(mol_list): if mol_list.scheme < 4: mo = np.eye(2).reshape(1, 2, 2, 1) mpo.append(mo) elif mol_list.scheme == 4: if len(mpo) == mol_list.e_idx(): n = mol_list.mol_num mpo.append(np.eye(n).reshape(1, n, n, 1)) else: assert False for ph in mol.dmrg_phs: if space == "EX": # for the EX space, with quasiboson algorithm, the b^\dagger + b # operator is not local anymore. assert ph.nqboson == 1 ph_pbond = ph.pbond[0] # construct the matrix exponential by diagonalize the matrix first phop = construct_ph_op_dict(ph_pbond) h_mo = ( phop[r"b^\dagger b"] * ph.omega[0] + phop[r"(b^\dagger + b)^3"] * ph.term30 + phop[r"b^\dagger + b"] * (ph.term10 + ph.term11) + phop[r"(b^\dagger + b)^2"] * (ph.term20 + ph.term21) + phop[r"(b^\dagger + b)^3"] * (ph.term31 - ph.term30) ) w, v = scipy.linalg.eigh(h_mo) h_mo = np.diag(np.exp(x * w)) h_mo = v.dot(h_mo) h_mo = h_mo.dot(v.T) mo = h_mo.reshape(1, ph_pbond, ph_pbond, 1) mpo.append(mo) elif space == "GS": anharmo = False # for the ground state space, yet doesn't support 3rd force # potential quasiboson algorithm ph_pbond = ph.pbond[0] for i in range(len(ph.force3rd)): anharmo = not np.allclose( ph.force3rd[i] * ph.dis[i] / ph.omega[i], 0.0 ) if anharmo: break if not anharmo: for iboson in range(ph.nqboson): d = np.exp( x * ph.omega[0] * ph.base ** (ph.nqboson - iboson - 1) * np.arange(ph_pbond) ) mo = np.diag(d).reshape(1, ph_pbond, ph_pbond, 1) mpo.append(mo) else: assert ph.nqboson == 1 # construct the matrix exponential by diagonalize the matrix first phop = construct_ph_op_dict(ph_pbond) h_mo = ( phop[r"b^\dagger b"] * ph.omega[0] + phop[r"(b^\dagger + b)^3"] * ph.term30 ) w, v = scipy.linalg.eigh(h_mo) h_mo = np.diag(np.exp(x * w)) h_mo = v.dot(h_mo) h_mo = h_mo.dot(v.T) mo = np.zeros([1, ph_pbond, ph_pbond, 1]) mo[0, :, :, 0] = h_mo mpo.append(mo) else: assert False # shift the H by plus a constant mpo.qn = [[0]] * (len(mpo) + 1) mpo.qnidx = len(mpo) - 1 mpo.qntot = 0 # np.exp(shift * x) is usually very large mpo = mpo.scale(np.exp(shift * x), inplace=True) return mpo