def init_mps(self): tentative_mpo = Mpo(self.mol_list) if self.temperature == 0: gs_mp = Mps.gs(self.mol_list, max_entangled=False) if self.dissipation != 0: gs_mp = MpDm.from_mps(gs_mp) else: gs_mp = MpDm.max_entangled_gs(self.mol_list) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(self.mol_list, offset=energy) tp = ThermalProp(gs_mp, mpo, exact=True, space="GS") tp.evolve(None, len(gs_mp), self.temperature.to_beta() / 2j) gs_mp = tp.latest_mps init_mp = self.create_electron(gs_mp) if self.dissipation != 0: init_mp = MpDmFull.from_mpdm(init_mp) energy = Quantity(init_mp.expectation(tentative_mpo)) self.mpo = Mpo(self.mol_list, offset=energy) logger.info(f"mpo bond dims: {self.mpo.bond_dims}") logger.info(f"mpo physical dims: {self.mpo.pbond_list}") if self.dissipation != 0: self.mpo = SuperLiouville(self.mpo, self.dissipation) init_mp.canonicalise() init_mp.evolve_config = self.evolve_config # init the compress config if not using threshold and not set if self.compress_config.criteria is not CompressCriteria.threshold\ and self.compress_config.max_dims is None: self.compress_config.set_bonddim(length=len(init_mp) + 1) init_mp.compress_config = self.compress_config # init_mp.invalidate_cache() return init_mp
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 init_mps(self): tentative_mpo = Mpo(self.model) if self.temperature == 0: gs_mp = Mps.ground_state(self.model, max_entangled=False) else: if self._defined_output_path: gs_mp = load_thermal_state(self.model, self._thermal_dump_path) else: gs_mp = None if gs_mp is None: gs_mp = MpDm.max_entangled_gs(self.model) # subtract the energy otherwise might cause numeric error because of large offset * dbeta energy = Quantity(gs_mp.expectation(tentative_mpo)) mpo = Mpo(self.model, offset=energy) tp = ThermalProp(gs_mp, mpo, exact=True, space="GS") tp.evolve(None, max(20, len(gs_mp)), self.temperature.to_beta() / 2j) gs_mp = tp.latest_mps if self._defined_output_path: gs_mp.dump(self._thermal_dump_path) init_mp = self.create_electron(gs_mp) energy = Quantity(init_mp.expectation(tentative_mpo)) self.mpo = Mpo(self.model, offset=energy) logger.info(f"mpo bond dims: {self.mpo.bond_dims}") logger.info(f"mpo physical dims: {self.mpo.pbond_list}") init_mp.evolve_config = self.evolve_config init_mp.compress_config = self.compress_config if self.evolve_config.is_tdvp: init_mp = init_mp.expand_bond_dimension(self.mpo) init_mp.canonicalise() return init_mp
def test_svd_compress(comp, mp): if mp == "mpo": mps = Mpo(holstein_model) M = 22 else: mps = Mps.random(holstein_model, 1, 10) if mp == "mpdm": mps = MpDm.from_mps(mps) mps.canonicalise().normalize() M = 36 if comp: mps = mps.to_complex(inplace=True) print(f"{mps}") mpo = Mpo(holstein_model) if comp: mpo = mpo.scale(-1.0j) print(f"{mpo.bond_dims}") std_mps = mpo.apply(mps, canonicalise=True).canonicalise() print(f"std_mps: {std_mps}") mps.compress_config.bond_dim_max_value = M mps.compress_config.criteria = CompressCriteria.fixed svd_mps = mpo.contract(mps) dis = svd_mps.distance(std_mps) / std_mps.dmrg_norm print(f"svd_mps: {svd_mps}, dis: {dis}") assert np.allclose(dis, 0.0, atol=1e-3) assert np.allclose(svd_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4)
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 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_phonon_onsite(): gs = Mps.gs(mol_list, max_entangled=False) assert not gs.ph_occupations.any() b2 = Mpo.ph_onsite(mol_list, r"b^\dagger", 0, 0) p1 = b2.apply(gs).normalize() assert np.allclose(p1.ph_occupations, [1, 0, 0, 0, 0, 0]) p2 = b2.apply(p1).normalize() assert np.allclose(p2.ph_occupations, [2, 0, 0, 0, 0, 0]) b = b2.conj_trans() assert b.distance(Mpo.ph_onsite(mol_list, r"b", 0, 0)) == 0 assert b.apply(p2).normalize().distance(p1) == pytest.approx(0, abs=1e-5)
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 test_general_mpo_MolList(mol_list, scheme): if scheme == 4: mol_list1 = mol_list.switch_scheme(4) else: mol_list1 = mol_list mol_list1.mol_list2_para() mpo = Mpo.general_mpo(mol_list1, const=Quantity(-mol_list1[0].gs_zpe * mol_list1.mol_num)) mpo_std = Mpo(mol_list1) check_result(mpo, mpo_std)
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 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_symbolic_mpo(nsites, nterms): possible_operators = ["sigma_+", "sigma_-", "sigma_z"] ham_terms = [] for i in range(nterms): op_list = [ Op(random.choice(possible_operators), j) for j in range(nsites) ] ham_terms.append(Op.product(op_list) * random.random()) basis = [BasisHalfSpin(i) for i in range(nsites)] model = Model(basis, ham_terms) mpo = Mpo(model) dense_mpo = mpo.full_operator() qutip_ham = get_spin_hamiltonian(ham_terms) assert np.allclose(dense_mpo, qutip_ham.data.todense())
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 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_pyr_4mode(multi_e, dvr): basis, ham_terms = construct_vibronic_model(multi_e, dvr) model = Model(basis, ham_terms) mpo = Mpo(model) logger.info(f"mpo_bond_dims:{mpo.bond_dims}") # same form whether multi_e is True or False init_condition = {"s2": 1} if dvr: for dof in model.v_dofs: idx = model.order[dof] init_condition[dof] = basis[idx].dvr_v[0] mps = Mps.hartree_product_state(model, condition=init_condition) compress_config = CompressConfig(CompressCriteria.fixed, max_bonddim=10) evolve_config = EvolveConfig(EvolveMethod.tdvp_ps) job = VibronicModelDynamics(model, mps0=mps, h_mpo=mpo, compress_config=compress_config, evolve_config=evolve_config, expand=True) time_step_fs = 2 job.evolve(evolve_dt=time_step_fs * fs2au, nsteps=60) from renormalizer.vibronic.tests.mctdh_data import mctdh_data assert np.allclose(mctdh_data[::round(time_step_fs / 0.5)][:61, 1:], job.e_occupations_array, atol=2e-2)
def __init__(self, mol_list, temperature: Quantity, insteps: int = None, ievolve_config=None, compress_config=None, evolve_config=None, dump_dir: str = None, job_name: str = None): self.mol_list = mol_list self.h_mpo = Mpo(mol_list) self.j_oper = self._construct_flux_operator() self.temperature = temperature # imaginary time evolution config if ievolve_config is None: self.ievolve_config = EvolveConfig() if insteps is None: self.ievolve_config.adaptive = True # start from a small step self.ievolve_config.evolve_dt = temperature.to_beta() / 1e5j self.ievolve_config.d_energy = 1 else: self.ievolve_config = ievolve_config self.insteps = insteps if compress_config is None: logger.debug("using default compress config") self.compress_config = CompressConfig() else: self.compress_config = compress_config self.impdm = None super().__init__(evolve_config, dump_dir, job_name)
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 test_pyr_4mode(multi_e, translator): order, basis, vibronic_model = construct_vibronic_model(multi_e) if translator is ModelTranslator.vibronic_model: model = vibronic_model elif translator is ModelTranslator.general_model: model = vibronic_to_general(vibronic_model) else: assert False mol_list2 = MolList2(order, basis, model, model_translator=translator) mpo = Mpo(mol_list2) logger.info(f"mpo_bond_dims:{mpo.bond_dims}") mps = Mps.hartree_product_state(mol_list2, condition={"e_1": 1}) # for multi-e case the `expand bond dimension` routine is currently not working # because creation operator is not defined yet mps.use_dummy_qn = True mps.build_empty_qn() compress_config = CompressConfig(CompressCriteria.fixed, max_bonddim=10) evolve_config = EvolveConfig(EvolveMethod.tdvp_ps) job = VibronicModelDynamics(mol_list2, mps0=mps, h_mpo=mpo, compress_config=compress_config, evolve_config=evolve_config) time_step_fs = 2 job.evolve(evolve_dt=time_step_fs * fs2au, nsteps=59) from renormalizer.vibronic.tests.mctdh_data import mctdh_data assert np.allclose(mctdh_data[::round(time_step_fs / 0.5)][:, 1:], job.e_occupations_array, atol=5e-2)
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 init_cv_mpo(self): cv_mpo = Mpo.finiteT_cv(self.model, 1, self.m_max, self.spectratype, percent=1.0) return cv_mpo
def test_exact_propagator(dt, space, shift): prop_mpo = Mpo.exact_propagator(holstein_model, -1.0j * dt, space, shift) with open(os.path.join(cur_dir, "test_exact_propagator.pickle"), "rb") as fin: std_dict = pickle.load(fin) std_mpo = std_dict[space] assert prop_mpo == std_mpo
def __init__( self, model, spectratype, m_max, eta, h_mpo = None, method = "1site", procedure_cv = None, rtol = 1e-5, b_mps = None, e0 = None, cv_mps = None, ): self.model = model assert spectratype in ["abs", "emi", None] self.spectratype = spectratype self.m_max = m_max self.eta = eta # Hamiltonian if h_mpo is None: self.h_mpo = Mpo(model) else: self.h_mpo = h_mpo assert method in ["1site", "2site"] self.method = method logger.info(f"cv optimize method: {method}") # percent used to update correction vector for each isweep process # see function mps.lib.select_basis if procedure_cv is None: procedure_cv = [0.4, 0.4, 0.2, 0.2, 0.1, 0.1] + [0] * 45 self.procedure_cv = procedure_cv self.rtol = rtol # ax=b b_mps and ground state energy e0 if b_mps is None: self.b_mps, self.e0 = self.init_b_mps() else: self.b_mps = b_mps # e0 is used in zero temperature case self.e0 = e0 # initial_guess cv_mps if cv_mps is None: self.cv_mps = self.init_cv_mps() else: self.cv_mps = cv_mps # results self.hop_time = [] self.macro_iteration_result = [] self.batch_run = False logger.info("DDMRG job created.")
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 __init__(self, model: Model, temperature: Quantity, distance_matrix: np.ndarray = None, insteps: int=1, ievolve_config=None, compress_config=None, evolve_config=None, dump_dir: str=None, job_name: str=None, properties: Property = None): self.model = model self.distance_matrix = distance_matrix self.h_mpo = Mpo(model) logger.info(f"Bond dim of h_mpo: {self.h_mpo.bond_dims}") self._construct_current_operator() if temperature == 0: raise ValueError("Can't set temperature to 0.") self.temperature = temperature # imaginary time evolution config if ievolve_config is None: self.ievolve_config = EvolveConfig() if insteps is None: self.ievolve_config.adaptive = True # start from a small step self.ievolve_config.guess_dt = temperature.to_beta() / 1e5j insteps = 1 else: self.ievolve_config = ievolve_config self.insteps = insteps if compress_config is None: logger.debug("using default compress config") self.compress_config = CompressConfig() else: self.compress_config = compress_config self.properties = properties self._auto_corr = [] self._auto_corr_deomposition = [] super().__init__(evolve_config=evolve_config, dump_dir=dump_dir, job_name=job_name)
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 check_reduced_density_matrix(basis): model = Model(basis, []) mps = Mps.random(model, 1, 20) rdm = mps.calc_edof_rdm().real assert np.allclose(np.diag(rdm), mps.e_occupations) # only test a sample. Should be enough. mpo = Mpo(model, Op(r"a^\dagger a", [0, 3])) assert rdm[-1][0] == pytest.approx(mps.expectation(mpo))
def test_mpo(): gs_dm = MpDm.max_entangled_gs(mol_list) beta = Quantity(10, "K").to_beta() tp = ThermalProp(gs_dm, Mpo(gs_dm.mol_list), exact=True, space="GS") tp.evolve(None, 500, beta / 1j) gs_dm = tp.latest_mps mp = creation_operator.apply(gs_dm) check_property(mp)
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(): 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