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 get_mol(): nphonons = 5 ph_levels = 2 delta = 1 epsilon = 1 ph_list = [Phonon.simple_phonon(Quantity(1), Quantity(1), ph_levels) ] * nphonons m = Mol(Quantity(epsilon), ph_list, tunnel=Quantity(-delta)) return m
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_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_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_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_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 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 test_holstein_kubo(scheme): ph = Phonon.simple_phonon(Quantity(1), Quantity(1), 2) mol = Mol(Quantity(0), [ph]) model = HolsteinModel([mol] * 5, Quantity(1), scheme) 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) kubo = TransportKubo(model, temperature, compress_config=compress_config, ievolve_config=ievolve_config, evolve_config=evolve_config) kubo.evolve(nsteps=5, evolve_time=5) qutip_res = get_qutip_holstein_kubo(model, temperature, kubo.evolve_times_array) rtol = 5e-2 assert np.allclose(kubo.auto_corr, qutip_res, rtol=rtol)
# -*- coding: utf-8 -*- import numpy as np from renormalizer.model import Phonon, Mol, HolsteinModel 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_model = HolsteinModel([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 assert np.allclose(analytical_r_square, ct.r_square_array, rtol=rtol)
# -*- 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)