예제 #1
0
 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
예제 #2
0
 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
예제 #3
0
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()
예제 #4
0
 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)
예제 #5
0
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
예제 #6
0
def test_from_mps():
    gs = Mps.random(parameter.holstein_model, 1, 20)
    gs_mpdm = MpDm.from_mps(gs)
    assert np.allclose(gs.e_occupations, gs_mpdm.e_occupations)
    gs = gs.canonicalise()
    gs_mpdm = gs_mpdm.canonicalise()
    assert np.allclose(gs.e_occupations, gs_mpdm.e_occupations)
예제 #7
0
    def __init__(
        self,
        init_mpdm: MpDm,
        h_mpo: Mpo,
        exact: bool = False,
        space: str = "GS",
        evolve_config: EvolveConfig = None,
        dump_mps: bool = False,
        dump_dir: str = None,
        job_name: str = None,
        properties: Property = None,
        auto_expand: bool = True,
    ):
        self.init_mpdm: MpDm = init_mpdm.canonicalise()
        self.h_mpo = h_mpo
        self.exact = exact
        assert space in ["GS", "EX"]
        self.space = space
        self.energies = []
        self._e_occupations_array = []
        self._ph_occupations_array = []
        self._vn_entropy_array = []
        self.properties = properties
        self.auto_expand = auto_expand

        super().__init__(evolve_config=evolve_config,
                         dump_mps=dump_mps,
                         dump_dir=dump_dir,
                         job_name=job_name)
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)
예제 #9
0
    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)
예제 #10
0
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)
예제 #11
0
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)
예제 #12
0
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])
예제 #13
0
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)
예제 #14
0
 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
예제 #15
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)
예제 #16
0
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)
예제 #17
0
    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
예제 #18
0
 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)
예제 #19
0
def test_environ_multi_mpo(mpdm):
    mps = Mps.random(holstein_model, 1, 10)
    if mpdm:
        mps = MpDm.from_mps(mps)
    mpo = Mpo(holstein_model)
    mps = mps.evolve(mpo, 10)
    environ = Environ(mps, mpo)
    environ_multi_mpo = Environ(mps, [mpo])
    for i in range(len(mps) - 1):
        l = environ.read("L", i)
        r = environ.read("R", i + 1)
        l2 = environ_multi_mpo.read("L", i)
        r2 = environ_multi_mpo.read("R", i + 1)
        assert np.allclose(asnumpy(l), asnumpy(l2))
        assert np.allclose(asnumpy(r), asnumpy(r2))
예제 #20
0
 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)
예제 #21
0
 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)
예제 #22
0
def test_variational_compress(comp, mp):

    if mp == "mpo":
        mps = Mpo(holstein_model)
        M = 20
    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}")

    # 2site algorithm
    mps.compress_config.vprocedure = [[M, 1.0], [M, 0.2], [M, 0.1]] + [
        [M, 0],
    ] * 10
    mps.compress_config.vmethod = "2site"
    var_mps = mps.variational_compress(mpo, guess=None)
    dis = var_mps.distance(std_mps) / std_mps.dmrg_norm
    print(f"var2_mps: {var_mps}, dis: {dis}")
    assert np.allclose(dis, 0.0, atol=1e-4)
    assert np.allclose(var_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4)

    # 1site algorithm with 2site result as a guess
    # 1site algorithm is easy to be trapped in a local minimum
    var_mps.compress_config.vprocedure = [
        [M, 0],
    ] * 10
    var_mps.compress_config.vmethod = "1site"
    var_mps = mps.variational_compress(mpo, guess=var_mps)
    dis = var_mps.distance(std_mps) / std_mps.dmrg_norm
    print(f"var1_mps: {var_mps}, dis: {dis}")
    assert np.allclose(dis, 0.0, atol=1e-4)
    assert np.allclose(var_mps.dmrg_norm, std_mps.dmrg_norm, atol=1e-4)
예제 #23
0
def load_thermal_state(mol_list, path: str):
    """
    Load thermal propagated state from disk. Return None if the file is not found.

    Args:
        mol_list (:class:`MolList`): system information
        path (str): the path to load thermal state from. Should be an `npz` file.
    Returns: Loaded MpDm
    """
    try:
        logger.info(f"Try load from {path}")
        mpdm = MpDm.load(mol_list, path)
        logger.info(f"Init mpdm loaded: {mpdm}")
    except FileNotFoundError:
        logger.info(f"No file found in {path}")
        mpdm = None

    return mpdm
예제 #24
0
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)
예제 #25
0
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)
예제 #26
0
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)
예제 #27
0
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)
예제 #28
0
def test_ft():
    model = get_model()
    mpo = Mpo(model)
    impdm = MpDm.max_entangled_gs(model)
    impdm.compress_config = CompressConfig(threshold=1e-6)
    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(model, Op("sigma_x", "spin")).contract(mpdm)
    mpdm.evolve_config = EvolveConfig(adaptive=True, guess_dt=0.1)
    time_series = [0]
    sigma_z_oper = Mpo(model, Op("sigma_z", "spin"))
    spin = [mpdm.expectation(sigma_z_oper)]
    for i in range(29):
        dt = mpdm.evolve_config.guess_dt
        mpdm = mpdm.evolve(mpo, evolve_dt=dt)
        time_series.append(time_series[-1] + dt)
        spin.append(mpdm.expectation(sigma_z_oper))
    qutip_res = get_qutip_ft(model, temperature, time_series)
    assert np.allclose(qutip_res, spin, atol=1e-3)
예제 #29
0
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)