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 _construct_flux_operator(self): # construct flux operator logger.info("constructing 1-d Holstein model flux operator ") if isinstance(self.mol_list, MolList): if self.mol_list.periodic: itera = range(len(self.mol_list)) else: itera = range(len(self.mol_list) - 1) j_list = [] for i in itera: conne = (i + 1) % len(self.mol_list) # connect site index j1 = Mpo.intersite(self.mol_list, { i: r"a", conne: r"a^\dagger" }, {}, Quantity(self.mol_list.j_matrix[i, conne])) j1.compress_config.threshold = 1e-8 j2 = j1.conj_trans().scale(-1) j_list.extend([j1, j2]) j_oper = compressed_sum(j_list, batchsize=10) elif isinstance(self.mol_list, MolList2): e_nsite = self.mol_list.n_edofs model = {} for i in range(e_nsite): conne = (i + 1) % e_nsite # connect site index model[(f"e_{i}", f"e_{conne}")] = [ (Op(r"a^\dagger", 1), Op("a", -1), -self.mol_list.j_matrix[i, conne]), (Op(r"a", -1), Op(r"a^\dagger", 1), self.mol_list.j_matrix[conne, i]) ] j_oper = Mpo.general_mpo( self.mol_list, model=model, model_translator=ModelTranslator.general_model) else: assert False logger.debug(f"flux operator bond dim: {j_oper.bond_dims}") return j_oper
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)
ph_phys_dim = 5 omega = [Quantity(omega_value), Quantity(omega_value)] D = [Quantity(0.), Quantity(D_value)] ph = Phonon(omega, D, ph_phys_dim) model = HolsteinModel( [Mol(Quantity(elocalex), [ph], dipole_abs)] * nmols, j_matrix, ) # periodic nearest-neighbour interaction mpo = Mpo(model) periodic = Mpo.intersite(model, { 0: r"a^\dagger", nmols - 1: "a" }, {}, Quantity(j_value)) mpo = mpo.add(periodic).add(periodic.conj_trans()) @pytest.mark.parametrize("periodic", (True, False)) def test_thermal_equilibrium(periodic): if periodic: # define properties # periodic case prop_mpos = ops.e_ph_static_correlation(model, periodic=True) prop_strs = list(prop_mpos.keys()) prop_strs.append("e_rdm") prop = Property(prop_strs, prop_mpos) else:
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) e1 = random.expectations(mpos) e2 = random.expectations(mpos, opt=False)
def e_ph_static_correlation(mol_list: MolList, imol:int =0, jph:int =0, periodic:bool =False, name:str="S"): ''' construct the electron-phonon static correlation operator in polaron problem The details of the definition, see Qiang Shi et al. J. Chem. Phys. 142, 174103 (2015) or Romero et al. Journal of Luminescence 83-84 (1999) 147-153 if periodic: # D is the displacement between different PES of each mode S_(m, jph) = \frac{1}{D_m+n,jph} \sum_n \langle x_{m+n,jph} a_n^\dagger a_n \rangle operator name = "_".join([name, str(m), str(jph)]) m stands for distance if periodic else: S_(n,m,jph) = \frac{1}{D_m,jph} \langle x_{m, jph} a_n^\dagger a_n \rangle operator name: "_".join([name, str(n), str(m), str(jph)]) Parameters: mol_list : MolList the molecular information imol : int electron site index (default:0) if periodic is True, imol is omitted. jph : int phonon site index periodic : bool if homogenous periodic system name: str the name of the operator Note: Only one mode Holstein Model has been tested ''' if mol_list.scheme == 4: raise NotImplementedError prop_mpos = {} nmols = mol_list.mol_num if not periodic: # each jmol site is calculated separately for jmol in range(nmols): op_name = "_".join([name, str(imol), str(jmol), str(jph)]) prop_mpos[op_name] = Mpo.intersite(mol_list, {imol:r"a^\dagger a"}, {(jmol, jph):r"b^\dagger + b"}, scale=Quantity(np.sqrt(1./2.0/mol_list[jmol].dmrg_phs[jph].omega[0])/mol_list[jmol].dmrg_phs[jph].dis[1])) # normalized by the displacement D else: # each distance is calculated seperately for dis in range(nmols): dis_list = [] for jmol in range(nmols): kmol = (jmol+dis) % nmols dis_list.append(Mpo.intersite(mol_list, {jmol:r"a^\dagger a"}, {(kmol, jph):r"b^\dagger + b"}, scale=Quantity(np.sqrt(1./2.0/mol_list[kmol].dmrg_phs[jph].omega[0])/mol_list[kmol].dmrg_phs[jph].dis[1]))) for item in dis_list[1:]: dis_list[0] = dis_list[0].add(item) op_name = "_".join([name, str(dis), str(jph)]) prop_mpos[op_name] = dis_list[0] return prop_mpos
def test_general_mpo_others(): mol_list2 = MolList2.MolList_to_MolList2(mol_list) # onsite mpo_std = Mpo.onsite(mol_list, r"a^\dagger", mol_idx_set=[0]) mpo = Mpo.onsite(mol_list2, r"a^\dagger", mol_idx_set=[0]) check_result(mpo, mpo_std) # general method mpo = Mpo.general_mpo(mol_list2, model={("e_0", ): [(Op(r"a^\dagger", 0), 1.0)]}, model_translator=ModelTranslator.general_model) check_result(mpo, mpo_std) mpo_std = Mpo.onsite(mol_list, r"a^\dagger a", dipole=True) mpo = Mpo.onsite(mol_list2, r"a^\dagger a", dipole=True) check_result(mpo, mpo_std) mpo = Mpo.general_mpo(mol_list2, model={ ("e_0", ): [(Op(r"a^\dagger a", 0), mol_list2.dipole[("e_0", )])], ("e_1", ): [(Op(r"a^\dagger a", 0), mol_list2.dipole[("e_1", )])], ("e_2", ): [(Op(r"a^\dagger a", 0), mol_list2.dipole[("e_2", )])] }, model_translator=ModelTranslator.general_model) check_result(mpo, mpo_std) # intersite mpo_std = Mpo.intersite(mol_list, { 0: r"a^\dagger", 2: "a" }, {(0, 1): "b^\dagger"}, Quantity(2.0)) mpo = Mpo.intersite(mol_list2, { 0: r"a^\dagger", 2: "a" }, {(0, 1): r"b^\dagger"}, Quantity(2.0)) check_result(mpo, mpo_std) mpo = Mpo.general_mpo(mol_list2, model={ ("e_0", "e_2", "v_1"): [(Op(r"a^\dagger", 1), Op(r"a", -1), Op(r"b^\dagger", 0), 2.0)] }, model_translator=ModelTranslator.general_model) check_result(mpo, mpo_std) # phsite mpo_std = Mpo.ph_onsite(mol_list, r"b^\dagger", 0, 0) mpo = Mpo.ph_onsite(mol_list2, r"b^\dagger", 0, 0) check_result(mpo, mpo_std) mpo = Mpo.general_mpo(mol_list2, model={ (mol_list2.map[(0, 0)], ): [(Op(r"b^\dagger", 0), 1.0)] }, model_translator=ModelTranslator.general_model) check_result(mpo, mpo_std)
import numpy as np import pytest from renormalizer.model import Model from renormalizer.model.basis import BasisSHO, BasisMultiElectronVac, BasisMultiElectron, BasisSimpleElectron from renormalizer.model.op import Op from renormalizer.mps import Mps, Mpo from renormalizer.tests import parameter @pytest.mark.parametrize("mpos", ([ Mpo.onsite(parameter.holstein_model, r"a^\dagger a", dof_set={i}) for i in range(parameter.holstein_model.mol_num) ], [ Mpo.intersite(parameter.holstein_model, { i: "a", i + 1: r"a^\dagger" }, {}) for i in range(parameter.holstein_model.mol_num - 1) ], [ Mpo.intersite(parameter.holstein_model, { i: "a", i + 1: r"a^\dagger" }, {}) for i in range(parameter.holstein_model.mol_num - 1) ] + [ Mpo.intersite(parameter.holstein_model, {i: "a"}, {}) for i in range(parameter.holstein_model.mol_num - 1) ])) def test_expectations(mpos): random = Mps.random(parameter.holstein_model, 1, 20) e1 = random.expectations(mpos) e2 = random.expectations(mpos, opt=False)