def test_intersite(scheme): local_mlist = mol_list.switch_scheme(scheme) mpo1 = Mpo.intersite(local_mlist, {0: r"a^\dagger"}, {}, Quantity(1.0)) mpo2 = Mpo.onsite(local_mlist, r"a^\dagger", mol_idx_set=[0]) assert mpo1.distance(mpo2) == pytest.approx(0, abs=1e-5) mpo3 = Mpo.intersite(local_mlist, {2: r"a^\dagger a"}, {}, Quantity(1.0)) mpo4 = Mpo.onsite(local_mlist, r"a^\dagger a", mol_idx_set=[2]) assert mpo3.distance(mpo4) == pytest.approx(0, abs=1e-5) mpo5 = Mpo.intersite(local_mlist, {2: r"a^\dagger a"}, {}, Quantity(0.5)) assert mpo5.add(mpo5).distance(mpo4) == pytest.approx(0, abs=1e-5) mpo6 = Mpo.intersite(local_mlist, { 0: r"a^\dagger", 2: "a" }, {}, Quantity(1.0)) mpo7 = Mpo.onsite(local_mlist, "a", mol_idx_set=[2]) assert mpo2.apply(mpo7).distance(mpo6) == pytest.approx(0, abs=1e-5) # the tests are based on the similarity between scheme 2 and scheme 3 # so scheme 3 and scheme 4 will be skipped if scheme == 2: mpo8 = Mpo(local_mlist) # a dirty hack to switch from scheme 2 to scheme 3 test_mlist = local_mlist.switch_scheme(2) test_mlist.scheme = 3 mpo9 = Mpo(test_mlist) mpo10 = Mpo.intersite(test_mlist, { 0: r"a^\dagger", 2: "a" }, {}, Quantity(local_mlist.j_matrix[0, 2])) mpo11 = Mpo.intersite(test_mlist, { 2: r"a^\dagger", 0: "a" }, {}, Quantity(local_mlist.j_matrix[0, 2])) assert mpo11.conj_trans().distance(mpo10) == pytest.approx(0, abs=1e-6) assert mpo8.distance(mpo9 + mpo10 + mpo11) == pytest.approx(0, abs=1e-6) test_mlist.periodic = True mpo12 = Mpo(test_mlist) assert mpo12.distance(mpo9 + mpo10 + mpo11) == pytest.approx(0, abs=1e-6) ph_mpo1 = Mpo.ph_onsite(local_mlist, "b", 1, 1) ph_mpo2 = Mpo.intersite(local_mlist, {}, {(1, 1): "b"}) assert ph_mpo1.distance(ph_mpo2) == pytest.approx(0, abs=1e-6)
def init_mps(self): mmax = self.optimize_config.procedure[0][0] i_mps = Mps.random(self.h_mpo.model, self.nexciton, mmax, 1) i_mps.optimize_config = self.optimize_config energy, i_mps = gs.optimize_mps(i_mps, self.h_mpo) if self.spectratype == "emi": operator = "a" else: operator = r"a^\dagger" dipole_mpo = Mpo.onsite(self.model, operator, dipole=True) if self.temperature != 0: beta = self.temperature.to_beta() # print "beta=", beta # thermal_mpo = Mpo.exact_propagator(self.model, -beta / 2.0, space=self.space1, shift=self.shift1) # ket_mps = thermal_mpo.apply(i_mps) # ket_mps.normalize() # no test, don't know work or not i_mpdm = MpDm.from_mps(i_mps) tp = ThermalProp(i_mpdm, self.h_mpo, exact=True, space=self.space1) tp.evolve(None, 1, beta / 2j) ket_mps = tp.latest_mps else: ket_mps = i_mps a_ket_mps = dipole_mpo.apply(ket_mps, canonicalise=True) a_ket_mps.canonical_normalize() if self.temperature != 0: a_bra_mps = ket_mps.copy() else: a_bra_mps = a_ket_mps.copy() return BraKetPair(a_bra_mps, a_ket_mps)
def test_FT_dynamics_hybrid_TDDMRG_TDH(n_dmrg_phs, scheme): mol_list = parameter_PBI.construct_mol(4, n_dmrg_phs, 10 - n_dmrg_phs).switch_scheme(scheme) mpdm = MpDm.max_entangled_gs(mol_list) tentative_mpo = Mpo(mol_list) temperature = Quantity(2000, "K") tp = ThermalProp(mpdm, tentative_mpo, exact=True, space="GS") tp.evolve(None, 1, temperature.to_beta() / 2j) mpdm = ( Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}).apply(tp.latest_mps).normalize(1.0) ) mpdm.compress_config = CompressConfig(threshold=5e-4) offset = mpdm.expectation(tentative_mpo) mpo = Mpo(mol_list, offset=Quantity(offset, "a.u.")) # do the evolution # nsteps = 90 # too many steps, may take hours to finish nsteps = 40 dt = 10.0 occ = [mpdm.e_occupations] for i in range(nsteps): mpdm = mpdm.evolve(mpo, dt) occ.append(mpdm.e_occupations) # make it compatible with std data occ = np.array(occ[:nsteps]).transpose() with open(os.path.join(cur_dir, "FT_occ" + str(n_dmrg_phs) + ".npy"), "rb") as f: std = np.load(f) assert np.allclose(occ[:, :nsteps], std[:, :nsteps], atol=1e-3, rtol=1e-3)
def init_b_mps(self): # get the right hand site vector b, Ax=b # b = -eta * dipole * \psi_0 # only support Holstine model 0/1 exciton manifold if self.spectratype == "abs": nexciton = 0 dipoletype = r"a^\dagger" elif self.spectratype == "emi": nexciton = 1 dipoletype = "a" # procedure for ground state calculation if self.procedure_gs is None: self.procedure_gs = \ [[10, 0.4], [20, 0.2], [30, 0.1], [40, 0], [40, 0]] # ground state calculation mps = Mps.random( self.model, nexciton, self.procedure_gs[0][0], percent=1.0) mps.optimize_config = OptimizeConfig(procedure=self.procedure_gs) mps.optimize_config.method = "2site" energies, mps = gs.optimize_mps(mps, self.h_mpo) e0 = min(energies) dipole_mpo = \ Mpo.onsite( self.model, dipoletype, dipole=True ) b_mps = dipole_mpo.apply(mps.scale(-self.eta)) return b_mps, e0
def create_electron_fc(self, gs_mp): center_mol_idx = self.mol_num // 2 creation_operator = Mpo.onsite( self.mol_list, r"a^\dagger", mol_idx_set={center_mol_idx} ) mps = creation_operator.apply(gs_mp) return mps
def test_dynamics(dissipation, dt, nsteps): tentative_mpo = Mpo(band_limit_mol_list) gs_mp = MpDm.max_entangled_gs(band_limit_mol_list) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(band_limit_mol_list, offset=energy) tp = ThermalProp(gs_mp, mpo, exact=True, space="GS") tp.evolve(None, 50, low_t.to_beta() / 2j) gs_mp = tp.latest_mps center_mol_idx = band_limit_mol_list.mol_num // 2 creation_operator = Mpo.onsite( band_limit_mol_list, r"a^\dagger", mol_idx_set={center_mol_idx} ) mpdm = creation_operator.apply(gs_mp) mpdm_full = MpDmFull.from_mpdm(mpdm) # As more compression is involved higher threshold is necessary mpdm_full.compress_config = CompressConfig(threshold=1e-4) liouville = SuperLiouville(mpo, dissipation) r_square_list = [calc_r_square(mpdm_full.e_occupations)] time_series = [0] for i in range(nsteps - 1): logger.info(mpdm_full) mpdm_full = mpdm_full.evolve(liouville, dt) r_square_list.append(calc_r_square(mpdm_full.e_occupations)) time_series.append(time_series[-1] + dt) time_series = np.array(time_series) if dissipation == 0: assert np.allclose(get_analytical_r_square(time_series), r_square_list, rtol=1e-2, atol=1e-3) else: # not much we can do, just basic sanity check assert (np.array(r_square_list)[1:] < get_analytical_r_square(time_series)[1:]).all()
def f(mol_list, run_qutip=True): tentative_mpo = Mpo(mol_list) init_mps = (Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}) @ Mps.gs( mol_list, False)).expand_bond_dimension(hint_mpo=tentative_mpo) init_mpdm = MpDm.from_mps(init_mps).expand_bond_dimension( hint_mpo=tentative_mpo) e = init_mps.expectation(tentative_mpo) mpo = Mpo(mol_list, offset=Quantity(e)) if run_qutip: # calculate result in ZT. FT result is exactly the same TIME_LIMIT = 10 QUTIP_STEP = 0.01 N_POINTS = TIME_LIMIT / QUTIP_STEP + 1 qutip_time_series = np.linspace(0, TIME_LIMIT, N_POINTS) init = qutip.Qobj(init_mps.full_wfn(), [qutip_h.dims[0], [1] * len(qutip_h.dims[0])]) # the result is not exact and the error scale is approximately 1e-5 res = qutip.sesolve(qutip_h - e, init, qutip_time_series, e_ops=[c.dag() * c for c in qutip_clist]) qutip_expectations = np.array(res.expect).T return qutip_expectations, QUTIP_STEP, init_mps, init_mpdm, mpo else: return init_mps, init_mpdm, mpo
def max_entangled_ex(cls, mol_list, normalize=True): """ T = \\infty maximum entangled EX state """ mps = Mps.gs(mol_list, max_entangled=True) # the creation operator \\sum_i a^\\dagger_i ex_mps = Mpo.onsite(mol_list, r"a^\dagger").apply(mps) if normalize: ex_mps.normalize(1.0) return cls.from_mps(ex_mps)
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 init_mps(self): if self.spectratype == "emi": operator = "a" else: operator = r"a^\dagger" dipole_mpo = Mpo.onsite(self.model, operator, dipole=True) a_ket_mps = dipole_mpo.apply(self.get_imps(), canonicalise=True) a_ket_mps.canonical_normalize() a_ket_mps.evolve_config = self.evolve_config a_bra_mps = a_ket_mps.copy() return BraKetPair(a_bra_mps, a_ket_mps)
def init_mps(self): beta = self.temperature.to_beta() self.h_mpo = Mpo(self.mol_list) if self.spectratype == "abs": dipole_mpo = Mpo.onsite(self.mol_list, r"a^\dagger", dipole=True) i_mpo = MpDm.max_entangled_gs(self.mol_list) tp = ThermalProp(i_mpo, self.h_mpo, exact=True, space='GS') tp.evolve(None, 1, beta / 2j) ket_mpo = tp.latest_mps else: impo = MpDm.max_entangled_ex(self.mol_list) dipole_mpo = Mpo.onsite(self.mol_list, "a", dipole=True) if self.job_name is None: job_name = None else: job_name = self.job_name + "_thermal_prop" impo.compress_config = self.compress_config tp = ThermalProp(impo, self.h_mpo, evolve_config=self.evolve_config, dump_dir=self.dump_dir, job_name=job_name) self._defined_output_path = tp._defined_output_path if tp._defined_output_path: try: logger.info( f"load density matrix from {self._thermal_dump_path}") ket_mpo = MpDm.load(self.mol_list, self._thermal_dump_path) logger.info(f"density matrix loaded: {ket_mpo}") except FileNotFoundError: logger.debug(f"no file found in {self._thermal_dump_path}") tp.evolve(None, self.insteps, beta / 2j) ket_mpo = tp.latest_mps ket_mpo.dump(self._thermal_dump_path) self.a_ket_mpo = dipole_mpo.apply(ket_mpo, canonicalise=True) self.cv_mpo = Mpo.finiteT_cv(self.mol_list, 1, self.m_max, self.spectratype, percent=1.0) self.cv_mps = self.cv_mpo
def max_entangled_ex(cls, model, normalize=True): """ T = \\infty locally maximal entangled EX state """ mps = Mps.ground_state(model, max_entangled=True) # the creation operator \\sum_i a^\\dagger_i ex_mpo = Mpo.onsite(model, r"a^\dagger") ex_mps = ex_mpo @ mps if normalize: ex_mps.normalize(1.0) return cls.from_mps(ex_mps)
def test_displacement(): def get_e_occu(idx): res = np.zeros(len(mol_list)) res[idx] = 1 return res gs = Mps.gs(mol_list, max_entangled=False) gs = Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}).apply(gs).compress() assert np.allclose(gs.e_occupations, get_e_occu(0)) gs = Mpo.displacement(mol_list, 0, 2).apply(gs) assert np.allclose(gs.e_occupations, get_e_occu(2)) gs = Mpo.displacement(mol_list, 2, 0).apply(gs) assert np.allclose(gs.e_occupations ,get_e_occu(0))
def init_mps_abs(self): dipole_mpo = Mpo.onsite(self.mol_list, r"a^\dagger", dipole=True) i_mpo = MpDm.max_entangled_gs(self.mol_list) beta = self.temperature.to_beta() tp = ThermalProp(i_mpo, self.h_mpo, exact=True, space="GS") tp.evolve(None, 1, beta / 2j) ket_mpo = tp.latest_mps ket_mpo.evolve_config = self.evolve_config a_ket_mpo = dipole_mpo.apply(ket_mpo, canonicalise=True) a_ket_mpo.canonical_normalize() a_bra_mpo = a_ket_mpo.copy() return BraKetPairAbsFiniteT(a_bra_mpo, a_ket_mpo)
def init_b_mpo(self): # get the right hand site vector b, Ax=b # b = -eta * dipole * \psi_0 # only support Holstien model 0/1 exciton manifold beta = self.temperature.to_beta() if self.spectratype == "abs": dipole_mpo = Mpo.onsite(self.model, r"a^\dagger", dipole=True) i_mpo = MpDm.max_entangled_gs(self.model) tp = ThermalProp(i_mpo, self.h_mpo, exact=True, space='GS') tp.evolve(None, 1, beta / 2j) ket_mpo = tp.latest_mps elif self.spectratype == "emi": dipole_mpo = Mpo.onsite(self.model, "a", dipole=True) if self._defined_output_path: ket_mpo = \ load_thermal_state(self.model, self._thermal_dump_path) else: ket_mpo = None if ket_mpo is None: impo = MpDm.max_entangled_ex(self.model) impo.compress_config = self.compress_config if self.job_name is None: job_name = None else: job_name = self.job_name + "_thermal_prop" tp = ThermalProp(impo, self.h_mpo, evolve_config=self.evolve_config, dump_dir=self.dump_dir, job_name=job_name) tp.evolve(None, self.insteps, beta / 2j) ket_mpo = tp.latest_mps if self._defined_output_path: ket_mpo.dump(self._thermal_dump_path) else: assert False ket_mpo = dipole_mpo.apply(ket_mpo.scale(-self.eta)) return ket_mpo, None
def test_save_load(): mps = Mpo.onsite(parameter.mol_list, "a^\dagger", mol_idx_set={0}).apply(Mps.gs(parameter.mol_list, False)) mpo = Mpo(parameter.mol_list) mps1 = mps.copy() for i in range(2): mps1 = mps1.evolve(mpo, 10) mps2 = mps.evolve(mpo, 10) fname = "test.npz" mps2.dump(fname) mps2 = Mps.load(parameter.mol_list, fname) mps2 = mps2.evolve(mpo, 10) assert np.allclose(mps1.e_occupations, mps2.e_occupations) os.remove(fname)
def init_mps_emi(self): dipole_mpo = Mpo.onsite(self.mol_list, "a", dipole=True) i_mpo = MpDm.max_entangled_ex(self.mol_list) # only propagate half beta tp = ThermalProp(i_mpo, self.h_mpo) tp.evolve(None, self.insteps, self.temperature.to_beta() / 2j) ket_mpo = tp.latest_mps ket_mpo.evolve_config = self.evolve_config # e^{\-beta H/2} \Psi dipole_mpo_dagger = dipole_mpo.conj_trans() dipole_mpo_dagger.build_empty_qn() a_ket_mpo = ket_mpo.apply(dipole_mpo_dagger, canonicalise=True) a_ket_mpo.canonical_normalize() a_bra_mpo = a_ket_mpo.copy() return BraKetPairEmiFiniteT(a_bra_mpo, a_ket_mpo)
def test_save_load(): mol_list = custom_mol_list(hartrees=[True, False]) mps = Mpo.onsite(mol_list, "a^\dagger", mol_idx_set={0}) @ Mps.gs( mol_list, False) mpo = Mpo(mol_list) mps1 = mps.copy() for i in range(2): mps1 = mps1.evolve(mpo, 10) mps2 = mps.evolve(mpo, 10) fname = "test.npz" mps2.dump(fname) mps2 = Mps.load(mol_list, fname) mps2 = mps2.evolve(mpo, 10) assert np.allclose(mps1.e_occupations, mps2.e_occupations) os.remove(fname)
def test_save_load(): model = holstein_model mps = Mpo.onsite(model, r"a^\dagger", dof_set={0}) @ Mps.ground_state( model, False) mpo = Mpo(model) mps1 = mps.copy() for i in range(2): mps1 = mps1.evolve(mpo, 10) mps2 = mps.evolve(mpo, 10) fname = "test.npz" mps2.dump(fname) mps2 = Mps.load(model, fname) mps2 = mps2.evolve(mpo, 10) assert np.allclose(mps1.e_occupations, mps2.e_occupations) os.remove(fname)
def test_intersite(scheme): local_mlist = holstein_model.switch_scheme(scheme) mpo1 = Mpo.intersite(local_mlist, {0: r"a^\dagger"}, {}, Quantity(1.0)) mpo2 = Mpo.onsite(local_mlist, r"a^\dagger", dof_set=[0]) assert mpo1.distance(mpo2) == pytest.approx(0, abs=1e-5) mpo3 = Mpo.intersite(local_mlist, {2: r"a^\dagger a"}, {}, Quantity(1.0)) mpo4 = Mpo.onsite(local_mlist, r"a^\dagger a", dof_set=[2]) assert mpo3.distance(mpo4) == pytest.approx(0, abs=1e-5) mpo5 = Mpo.intersite(local_mlist, {2: r"a^\dagger a"}, {}, Quantity(0.5)) assert mpo5.add(mpo5).distance(mpo4) == pytest.approx(0, abs=1e-5) mpo6 = Mpo.intersite(local_mlist, { 0: r"a^\dagger", 2: "a" }, {}, Quantity(1.0)) mpo7 = Mpo.onsite(local_mlist, "a", dof_set=[2]) assert mpo2.apply(mpo7).distance(mpo6) == pytest.approx(0, abs=1e-5) mpo8 = Mpo.intersite(local_mlist, { 0: r"a^\dagger", 2: "a" }, {}, Quantity(local_mlist.j_matrix[0, 2])) mpo9 = Mpo.intersite(local_mlist, { 2: r"a^\dagger", 0: "a" }, {}, Quantity(local_mlist.j_matrix[0, 2])) assert mpo9.conj_trans().distance(mpo8) == pytest.approx(0, abs=1e-6) ph_mpo1 = Mpo.ph_onsite(local_mlist, "b", 1, 1) ph_mpo2 = Mpo.intersite(local_mlist, {}, {(1, 1): "b"}) assert ph_mpo1.distance(ph_mpo2) == pytest.approx(0, abs=1e-6)
def create_electron_relaxed(self, gs_mp): assert np.allclose(gs_mp.bond_dims, np.ones_like(gs_mp.bond_dims)) center_mol_idx = self.mol_num // 2 center_mol = self.mol_list[center_mol_idx] # start from phonon for i, ph in enumerate(center_mol.dmrg_phs): idx = self.mol_list.ph_idx(center_mol_idx, i) mt = gs_mp[idx][0, ..., 0].array evecs = ph.get_displacement_evecs() mt = evecs.dot(mt) logger.debug(f"relaxed mt: {mt}") gs_mp[idx] = mt.reshape([1] + list(mt.shape) + [1]) creation_operator = Mpo.onsite( self.mol_list, r"a^\dagger", mol_idx_set={center_mol_idx} ) mps = creation_operator.apply(gs_mp) return mps
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_SCF_exact(): nexciton = 1 dmrg_mol_list = custom_mol_list(None, ph_phys_dim, dis=[Quantity(0), Quantity(0)]) # DMRG calculation procedure = [[40, 0.4], [40, 0.2], [40, 0.1], [40, 0], [40, 0]] mps, mpo = construct_mps_mpo_2(dmrg_mol_list, 40, nexciton) mps.optimize_config.procedure = procedure energy = optimize_mps(mps, mpo) dmrg_e = mps.expectation(mpo) # print occupation dmrg_occ = [] for i in [0, 1, 2]: mpo = Mpo.onsite(dmrg_mol_list, r"a^\dagger a", dipole=False, mol_idx_set={i}) dmrg_occ.append(mps.expectation(mpo)) print("dmrg_occ", dmrg_occ) hartree_mol_list = custom_mol_list(None, ph_phys_dim, dis=[Quantity(0), Quantity(0)], hartrees=[True, True]) WFN, Etot = tdh.SCF(hartree_mol_list, nexciton) assert Etot == pytest.approx(dmrg_e) fe, fv = 1, 6 HAM, Etot, A_el = tdh.construct_H_Ham(hartree_mol_list, nexciton, WFN, fe, fv, debug=True) assert Etot == pytest.approx(dmrg_e) assert np.allclose(A_el.flatten(), dmrg_occ, rtol=1e-4)
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 max_entangled_ex(cls, mol_list, normalize=True): """ T = \\infty locally maximal entangled EX state """ mps = Mps.gs(mol_list, max_entangled=True) # the creation operator \\sum_i a^\\dagger_i if isinstance(mol_list, MolList): ex_mpo = Mpo.onsite(mol_list, r"a^\dagger") else: model = {} for dof in mol_list.e_dofs: model[(dof, )] = [(Op("a^\dagger", 1), 1.0)] ex_mpo = Mpo.general_mpo( mol_list, model=model, model_translator=ModelTranslator.general_model) ex_mps = ex_mpo @ mps if normalize: ex_mps.normalize(1.0) return cls.from_mps(ex_mps)
def init_oper(self): if self.spectratype == "abs": self.nexciton = 0 dipoletype = r"a^\dagger" else: self.nexciton = 1 dipoletype = "a" dipole_mpo = \ Mpo.onsite( self.mol_list, dipoletype, dipole=True ) mps, self.mpo = \ construct_mps_mpo_2( self.mol_list, self.procedure_gs[0][0], self.nexciton ) # ground state calculation mps.optimize_config = OptimizeConfig(procedure=self.procedure_gs) mps.optimize_config.method = "2site" self.lowest_e = optimize_mps(mps, self.mpo) ket_mps = dipole_mpo.apply(mps, canonicalise=True) self.b_oper = ket_mps.scale(-self.eta)
def test_zt(n_dmrg_phs, scheme): mol_list = parameter_PBI.construct_mol(4, n_dmrg_phs, 10 - n_dmrg_phs).switch_scheme(scheme) mps = Mps.gs(mol_list, False) # create electron mps = Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set={0}).apply(mps).normalize(1.0) tentative_mpo = Mpo(mol_list) offset = mps.expectation(tentative_mpo) mpo = Mpo(mol_list, offset=Quantity(offset, "a.u.")) # do the evolution nsteps = 30 dt = 30.0 occ = [mps.e_occupations] for i in range(nsteps): mps = mps.evolve(mpo, dt) occ.append(mps.e_occupations) # make it compatible with std data occ = np.array(occ[:nsteps]).transpose() with open(os.path.join(cur_dir, "ZT_occ" + str(n_dmrg_phs) + ".npy"), "rb") as f: std = np.load(f) assert np.allclose(occ, std, rtol=1e-2, atol=1e-4)
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 init_mps_emi(self): dipole_mpo = Mpo.onsite(self.mol_list, "a", dipole=True) i_mpo = MpDm.max_entangled_ex(self.mol_list) i_mpo.compress_config = self.icompress_config if self.job_name is None: job_name = None else: job_name = self.job_name + "_thermal_prop" # only propagate half beta tp = ThermalProp(i_mpo, self.h_mpo, evolve_config=self.ievolve_config, dump_dir=self.dump_dir, job_name=job_name) if tp._defined_output_path: try: logger.info( f"load density matrix from {self._thermal_dump_path}") ket_mpo = MpDm.load(self.mol_list, self._thermal_dump_path) logger.info(f"density matrix loaded:{ket_mpo}") except FileNotFoundError: logger.debug(f"no file found in {self._thermal_dump_path}") tp.evolve(None, self.insteps, self.temperature.to_beta() / 2j) ket_mpo = tp.latest_mps ket_mpo.dump(self._thermal_dump_path) else: tp.evolve(None, self.insteps, self.temperature.to_beta() / 2j) ket_mpo = tp.latest_mps ket_mpo.evolve_config = self.evolve_config # e^{\-beta H/2} \Psi dipole_mpo_dagger = dipole_mpo.conj_trans() dipole_mpo_dagger.build_empty_qn() a_ket_mpo = ket_mpo.apply(dipole_mpo_dagger, canonicalise=True) a_ket_mpo.canonical_normalize() a_bra_mpo = a_ket_mpo.copy() return BraKetPairEmiFiniteT(a_bra_mpo, a_ket_mpo)
# -*- coding: utf-8 -*- import numpy as np import pytest from renormalizer.mps import Mps, Mpo from renormalizer.model import MolList2, ModelTranslator from renormalizer.utils.basis import BasisSHO, BasisMultiElectronVac, BasisMultiElectron, BasisSimpleElectron, Op from renormalizer.tests import parameter @pytest.mark.parametrize("mpos", ([ Mpo.onsite(parameter.mol_list, r"a^\dagger a", mol_idx_set={i}) for i in range(parameter.mol_list.mol_num) ], [ Mpo.intersite(parameter.mol_list, { i: "a", i + 1: r"a^\dagger" }, {}) for i in range(parameter.mol_list.mol_num - 1) ], [ Mpo.intersite(parameter.mol_list, { i: "a", i + 1: r"a^\dagger" }, {}) for i in range(parameter.mol_list.mol_num - 1) ] + [ Mpo.intersite(parameter.mol_list, {i: "a"}, {}) for i in range(parameter.mol_list.mol_num - 1) ])) def test_expectations(mpos): random = Mps.random(parameter.mol_list, 1, 20)