def init_mps(self): # first try to load if self._defined_output_path: mpdm = load_thermal_state(self.model, self._thermal_dump_path) else: mpdm = None # then try to calculate if mpdm is None: i_mpdm = MpDm.max_entangled_ex(self.model) i_mpdm.compress_config = self.compress_config if self.job_name is None: job_name = None else: job_name = self.job_name + "_thermal_prop" tp = ThermalProp(i_mpdm, self.h_mpo, evolve_config=self.ievolve_config, dump_dir=self.dump_dir, job_name=job_name) # only propagate half beta tp.evolve(None, self.insteps, self.temperature.to_beta() / 2j) mpdm = tp.latest_mps if self._defined_output_path: mpdm.dump(self._thermal_dump_path) mpdm.compress_config = self.compress_config e = mpdm.expectation(self.h_mpo) self.h_mpo = Mpo(self.model, offset=Quantity(e)) mpdm.evolve_config = self.evolve_config logger.debug("Applying current operator") ket_mpdm = self.j_oper.contract(mpdm).canonical_normalize() bra_mpdm = mpdm.copy() if self.j_oper2 is None: return BraKetPair(bra_mpdm, ket_mpdm, self.j_oper) else: logger.debug("Applying the second current operator") ket_mpdm2 = self.j_oper2.contract(mpdm).canonical_normalize() return BraKetPair(bra_mpdm, ket_mpdm, self.j_oper), BraKetPair(bra_mpdm, ket_mpdm2, self.j_oper2)
def test_thermal_prop(adaptive, evolve_method): model = parameter.holstein_model init_mps = MpDm.max_entangled_ex(model) mpo = Mpo(model) beta = Quantity(298, "K").to_beta() evolve_time = beta / 2j evolve_config = EvolveConfig(evolve_method, adaptive=adaptive, guess_dt=0.1 / 1j) if adaptive: nsteps = 1 else: nsteps = 100 if evolve_method == EvolveMethod.tdvp_mu_vmf: nsteps = 20 evolve_config.ivp_rtol = 1e-3 evolve_config.ivp_atol = 1e-6 evolve_config.reg_epsilon = 1e-8 init_mps.compress_config.bond_dim_max_value = 12 dbeta = evolve_time / nsteps tp = ThermalProp(init_mps, mpo, evolve_config=evolve_config) tp.evolve(evolve_dt=dbeta, nsteps=nsteps) # MPO, HAM, Etot, A_el = mps.construct_hybrid_Ham(mpo, debug=True) # exact A_el: 0.20896541050347484, 0.35240029674394463, 0.4386342927525734 # exact internal energy: 0.0853388060014744 etot_std = 0.0853388 + parameter.holstein_model.gs_zpe occ_std = [0.20896541050347484, 0.35240029674394463, 0.4386342927525734] rtol = 5e-3 assert np.allclose(tp.e_occupations_array[-1], occ_std, rtol=rtol) assert np.allclose(tp.energies[-1], etot_std, rtol=rtol)
def test_thermal_equilibrium(periodic): if periodic: # define properties # periodic case prop_mpos = ops.e_ph_static_correlation(mol_list, periodic=True) prop_strs = list(prop_mpos.keys()) prop_strs.append("e_rdm") prop = Property(prop_strs, prop_mpos) else: # non-periodic case (though actually periodic) prop_mpos = {} for imol in range(nmols): prop_mpo = ops.e_ph_static_correlation(mol_list, imol=imol) prop_mpos.update(prop_mpo) prop_strs = list(prop_mpos.keys()) prop_strs.append("e_rdm") prop = Property(prop_strs, prop_mpos) beta = Quantity(1500., "K").to_beta() logger.info(f"beta:{beta}") nsteps = 1 dbeta = beta / nsteps / 2j evolve_config = EvolveConfig(method=EvolveMethod.prop_and_compress, adaptive=True, adaptive_rtol=1e-4, guess_dt=0.1/1j) init_mpdm = MpDm.max_entangled_ex(mol_list) #init_mpdm.compress_config.bond_dim_max_value=10 init_mpdm.compress_config.threshold = 1e-4 td = ThermalProp(init_mpdm, mpo, evolve_config=evolve_config, dump_dir=dump_dir, job_name=job_name, properties=prop) td.evolve(dbeta, nsteps=nsteps) if periodic: def combine(local_prop): res = [] for dis in range(nmols): res.append(local_prop.prop_res["S_"+str(dis)+"_0"][-1]) return res else: def combine(local_prop): e_ph_static_corr = [] for dis in range(nmols): res = 0. for i in range(nmols): res = res + np.array(local_prop.prop_res["S_"+str(i)+"_"+str((i+dis)%nmols)+"_0"][-1]) e_ph_static_corr.append(res) return e_ph_static_corr assert np.allclose(td.properties.prop_res["e_rdm"][-1], thermal_std["e_rdm"]) assert np.allclose(combine(td.properties), thermal_std["e_ph_static_corr"]) # directly calculate properties mpdm = td.latest_mps prop.calc_properties(mpdm, None) assert np.allclose(prop.prop_res["e_rdm"][-1], prop.prop_res["e_rdm"][-2])
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 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 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 test_thermal_prop(mol_list, etot_std, occ_std, nsteps, evolve_method, use_rk, rtol): init_mps = MpDm.max_entangled_ex(mol_list) mpo = Mpo(mol_list) beta = Quantity(298, "K").to_beta() evolve_time = beta / 2j if nsteps is None: evolve_config = EvolveConfig(evolve_method, adaptive=True, evolve_dt=beta / 100j) else: evolve_config = EvolveConfig(evolve_method) if evolve_method is EvolveMethod.tdvp_ps: evolve_config.tdvp_ps_rk4 = use_rk tp = ThermalProp(init_mps, mpo, evolve_config=evolve_config) tp.evolve(nsteps=nsteps, evolve_time=evolve_time) mps = tp.latest_mps MPO, HAM, Etot, A_el = mps.construct_hybrid_Ham(mpo, debug=True) assert np.allclose(Etot, etot_std, rtol=rtol) assert np.allclose(A_el, occ_std, rtol=rtol)
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 init_mps(self): # first try to load if self._defined_output_path: try: logger.info(f"Try load from {self._thermal_dump_path}") mpdm = MpDm.load(self.mol_list, self._thermal_dump_path) logger.info(f"Init mpdm loaded: {mpdm}") mpdm.compress_config = self.compress_config except FileNotFoundError: logger.debug(f"No file found in {self._thermal_dump_path}") mpdm = None else: mpdm = None # then try to calculate if mpdm is None: i_mpdm = MpDm.max_entangled_ex(self.mol_list) i_mpdm.compress_config = self.compress_config if self.job_name is None: job_name = None else: job_name = self.job_name + "_thermal_prop" tp = ThermalProp(i_mpdm, self.h_mpo, evolve_config=self.ievolve_config, dump_dir=self.dump_dir, job_name=job_name) # only propagate half beta tp.evolve(None, self.insteps, self.temperature.to_beta() / 2j) mpdm = tp.latest_mps if self._defined_output_path: mpdm.dump(self._thermal_dump_path) self.impdm = mpdm e = mpdm.expectation(self.h_mpo) self.h_mpo = Mpo(self.mol_list, offset=Quantity(e)) mpdm.evolve_config = self.evolve_config ket_mpdm = self.j_oper.contract(mpdm).canonical_normalize() bra_mpdm = mpdm.copy() return BraKetPair(bra_mpdm, ket_mpdm, self.j_oper)
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)