Пример #1
0
def check_distance(a: Mps, b: Mps):
    d1 = (a - b).dmrg_norm
    d2 = a.distance(b)
    a_array = a.full_wfn().array
    b_array = b.full_wfn().array
    d3 = np.linalg.norm(a_array - b_array)
    assert d1 == pytest.approx(d2) == pytest.approx(d3)
Пример #2
0
def optimize_mps(mps: Mps, mpo: Mpo):
    energies = optimize_mps_dmrg(mps, mpo)
    if not mps.hybrid_tdh:
        return energies[-1]
    # from matplotlib import pyplot as plt
    # plt.plot(energies); plt.show()

    HAM = []

    for mol in mps.mol_list:
        for ph in mol.hartree_phs:
            HAM.append(ph.h_indep)

    optimize_mps_hartree(mps, HAM)

    for itera in range(mps.optimize_config.niterations):
        logging.info("Loop: %d" % itera)
        MPO, HAM, Etot = mps.construct_hybrid_Ham(mpo)

        MPS_old = mps.copy()
        optimize_mps_dmrg(mps, MPO)
        optimize_mps_hartree(mps, HAM)

        # check convergence
        dmrg_converge = abs(mps.angle(MPS_old) -
                            1) < mps.optimize_config.dmrg_thresh
        hartree_converge = np.all(
            mps.hartree_wfn_diff(MPS_old) < mps.optimize_config.hartree_thresh)
        if dmrg_converge and hartree_converge:
            logger.info("SCF converge!")
            break
    return Etot
Пример #3
0
def test_distance():
    model = custom_model(n_phys_dim=(2, 2))
    a = Mps.random(model, 1, 10)
    b = Mps.random(model, 1, 10)
    check_distance(a, b)
    h = Mpo(model)
    for i in range(100):
        a = a.evolve(h, 10)
        b = b.evolve(h, 10)
        check_distance(a, b)
Пример #4
0
def test_distance():
    mol_list = parameter.custom_mol_list(n_phys_dim=(2, 2))
    a = Mps.random(mol_list, 1, 10)
    b = Mps.random(mol_list, 1, 10)
    check_distance(a, b)
    h = Mpo(mol_list)
    for i in range(100):
        a = a.evolve(h, 10)
        b = b.evolve(h, 10)
        check_distance(a, b)
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
def find_highest_energy(h_mpo: Mpo, nexciton, Mmax):
    logger.debug("begin finding highest energy")
    model = h_mpo.model
    mps = Mps.random(model, nexciton, Mmax)
    mps.optimize_config.inverse = -1.0
    energies, _ = optimize_mps(mps, h_mpo)
    return -energies[-1]
Пример #9
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)
Пример #10
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)
Пример #11
0
def test_clear():
    gs_mps = Mps.gs(mol_list, max_entangled=False)
    mps = creation_operator.apply(gs_mps)
    new_mps = mps.copy()
    new_mps.clear_memory()
    assert new_mps.total_bytes < mps.total_bytes
    check_property(new_mps)
Пример #12
0
def test_expectations(mpos):
    random = Mps.random(parameter.holstein_model, 1, 20)

    e1 = random.expectations(mpos)
    e2 = random.expectations(mpos, opt=False)

    assert np.allclose(e1, e2)
Пример #13
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
Пример #14
0
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)
Пример #15
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
Пример #16
0
def test_expectations(mpos):
    random = Mps.random(parameter.mol_list, 1, 20)

    e1 = random.expectations(mpos)
    e2 = random.expectations(mpos, opt=False)

    assert np.allclose(e1, e2)
Пример #17
0
    def load_wfn(self, model):
        r"""Load tda wavefunction
        """
        mps_l_cano = Mps.load(model, "mps_l_cano.npz")
        mps_r_cano = Mps.load(model, "mps_r_cano.npz")
        tangent_u_dict = np.load("tangent_u.npz")
        tangent_u = [tangent_u_dict[str(i)] if str(i) in tangent_u_dict.keys()
                else None for i in range(mps_l_cano.site_num)]
        tda_coeff_list = []
        for iroot in range(self.nroots):
            tda_coeff_dict = np.load(f"tda_coeff_{iroot}.npz")
            tda_coeff = [tda_coeff_dict[str(i)] if str(i) in tda_coeff_dict.keys()
                else None for i in range(mps_l_cano.site_num)]
            tda_coeff_list.append(tda_coeff)

        self.wfn = [mps_l_cano, mps_r_cano, tangent_u, tda_coeff_list]
Пример #18
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
Пример #19
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)
Пример #20
0
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)
Пример #21
0
    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
Пример #22
0
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))
Пример #23
0
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)
Пример #24
0
def find_lowest_energy(h_mpo: Mpo, nexciton, Mmax, with_hartree=True):
    logger.debug("begin finding lowest energy")
    if with_hartree:
        mol_list = h_mpo.mol_list
    else:
        mol_list = h_mpo.mol_list.get_pure_dmrg_mollist()
    mps = Mps.random(mol_list, nexciton, Mmax)
    energy = optimize_mps(mps, h_mpo)
    return energy.min()
Пример #25
0
    def init_cv_mps(self):
        # random guess of cv_mps with same qn as b_mps
        assert self.b_mps is not None
        # initialize guess of cv_mps
        cv_mps = Mps.random(
            self.model, self.b_mps.qntot, self.m_max, percent=1.0)
        logger.info(f"cv_mps random guess qntot: {cv_mps.qntot}")

        return cv_mps
Пример #26
0
def test_environ():
    mps = Mps.random(holstein_model, 1, 10)
    mpo = Mpo(holstein_model)
    mps = mps.evolve(mpo, 10)
    environ = Environ(mps, mpo)
    for i in range(len(mps) - 1):
        l = environ.read("L", i)
        r = environ.read("R", i + 1)
        e = complex(tensordot(l, r, axes=((0, 1, 2), (0, 1, 2)))).real
        assert pytest.approx(e) == mps.expectation(mpo)
Пример #27
0
 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)
Пример #28
0
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)
Пример #29
0
def test_csvd():
    np.random.seed(0)
    mps1, mpo = construct_mps_mpo_2(mol_list, procedure[0][0], nexciton)
    mps1.threshold = 1e-6
    mps1.optimize_config.procedure = procedure
    optimize_mps(mps1, mpo)
    mps1.compress()
    mps2 = Mps.load(mol_list, os.path.join(cur_dir, "test_svd_qn.npz"))
    d = pytest.approx(mps1.distance(mps2), abs=1e-4)
    # the same direction or opposite direction
    assert d == 0 or d == 2
Пример #30
0
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))