示例#1
0
def VMC(dft_checkfile,
        output,
        nconfig=1000,
        start_from=None,
        S=None,
        client=None,
        npartitions=None,
        jastrow_kws=None,
        slater_kws=None,
        vmc_kws=None,
        accumulators=None):
    if vmc_kws is None:
        vmc_kws = {}
    mol, mf = pyqmc.recover_pyscf(dft_checkfile)
    if S is not None:
        mol = pyqmc.get_supercell(mol, np.asarray(S))

    wf, _ = pyqmc.generate_wf(mol,
                              mf,
                              jastrow_kws=jastrow_kws,
                              slater_kws=slater_kws)

    if start_from is not None:
        pyqmc.read_wf(wf, start_from)

    configs = pyqmc.initial_guess(mol, nconfig)

    pyqmc.vmc(wf,
              configs,
              accumulators=generate_accumulators(mol, mf, **accumulators),
              verbose=True,
              hdf_file=output,
              client=client,
              npartitions=npartitions,
              **vmc_kws)
示例#2
0
 def dmc(self, nconfig=1000, **kwargs):
     configs = pyqmc.initial_guess(self.mol, nconfig)
     if self.client is None:
         pyqmc.vmc(self.wf, configs, nsteps=10)
         pyqmc.rundmc(
             self.wf,
             configs,
             accumulators={"energy": pyqmc.EnergyAccumulator(self.mol)},
             **kwargs,
         )
     else:
         pyqmc.dasktools.distvmc(
             self.wf,
             configs,
             nsteps=10,
             client=self.client,
             npartitions=self.npartitions,
         )
         pyqmc.rundmc(
             self.wf,
             configs,
             accumulators={"energy": pyqmc.EnergyAccumulator(self.mol)},
             propagate=pyqmc.dasktools.distdmc_propagate,
             **kwargs,
             client=self.client,
             npartitions=self.npartitions,
         )
示例#3
0
def find_basis_evaluate(mfchk, hdf_opt, hdf_vmc, hdf_final):
    """Given a wave function in hdf_opt, compute the 1-RDM (stored in hdf_vmc) , generate a minimal atomic basis and compute the energy/OBDM/TBDM and store in hdf_final """
    from pyqmc.obdm import OBDMAccumulator
    from pyqmc.tbdm import TBDMAccumulator
    from pyqmc import EnergyAccumulator

    sys = pyqmc_from_hdf(mfchk)

    mol = sys["mol"]
    a = lo.orth_ao(mol, "lowdin")
    obdm_up = OBDMAccumulator(mol=mol, orb_coeff=a, spin=0)
    obdm_down = OBDMAccumulator(mol=mol, orb_coeff=a, spin=1)
    with h5py.File(hdf_opt, "r") as hdf_in:
        if f"wf" in hdf_in.keys():
            print("reading in wave function")
            grp = hdf_in[f"wf"]
            for k in grp.keys():
                sys["wf"].parameters[k] = np.array(grp[k])

    configs = pyqmc.initial_guess(sys["mol"], 1000)
    pyqmc.vmc(
        sys["wf"],
        configs,
        nsteps=500,
        hdf_file=hdf_vmc,
        accumulators={
            "obdm_up": obdm_up,
            "obdm_down": obdm_down
        },
    )

    with h5py.File(hdf_vmc, "r") as vmc_hdf:
        obdm_up = np.mean(np.array(vmc_hdf["obdm_upvalue"]), axis=0)
        obdm_down = np.mean(np.array(vmc_hdf["obdm_downvalue"]), axis=0)
    basis_up = gen_basis(mol, sys["mf"], obdm_up)
    basis_down = gen_basis(mol, sys["mf"], obdm_down)
    obdm_up_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_up, spin=0)
    obdm_down_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_down, spin=1)
    tbdm = TBDMAccumulator(mol, np.array([basis_up, basis_down]), spin=(0, 1))
    acc = {
        "energy": EnergyAccumulator(mol),
        "obdm_up": obdm_up_acc,
        "obdm_down": obdm_down_acc,
        "tbdm": tbdm,
    }

    configs = pyqmc.initial_guess(sys["mol"], 1000)
    pyqmc.vmc(sys["wf"],
              configs,
              nsteps=500,
              hdf_file=hdf_final,
              accumulators=acc)
示例#4
0
def VMC(
    dft_checkfile,
    output,
    nconfig=1000,
    ci_checkfile=None,
    start_from=None,
    S=None,
    client=None,
    npartitions=None,
    jastrow_kws=None,
    slater_kws=None,
    vmc_kws=None,
    accumulators=None,
):
    if vmc_kws is None:
        vmc_kws = {}

    target_root = 0
    if ci_checkfile is None:
        mol, mf = pyqmc.recover_pyscf(dft_checkfile)
        mc = None
    else:
        mol, mf, mc = pyqmc.recover_pyscf(dft_checkfile,
                                          ci_checkfile=ci_checkfile)
        mc.ci = mc.ci[target_root]

    if S is not None:
        print("S", S)
        mol = pyqmc.get_supercell(mol, np.asarray(S))

    if accumulators is None:
        accumulators = {}

    wf, _ = pyqmc.generate_wf(mol,
                              mf,
                              mc=mc,
                              jastrow_kws=jastrow_kws,
                              slater_kws=slater_kws)

    if start_from is not None:
        pyqmc.read_wf(wf, start_from)

    configs = pyqmc.initial_guess(mol, nconfig)

    pyqmc.vmc(wf,
              configs,
              accumulators=generate_accumulators(mol, mf, **accumulators),
              verbose=True,
              hdf_file=output,
              client=client,
              npartitions=npartitions,
              **vmc_kws)
示例#5
0
def evaluate_big1rdm(mc_calc, output, nconfig =1000, **kwargs):
    mol = mc_calc['mol']
    a = pyscf.lo.orth_ao(mol, 'lowdin')
    obdm_up = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=a, spin=0)
    obdm_down = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=a, spin=1)

    configs = pyqmc.initial_guess(mol, 1000)
    pyqmc.vmc(mc_calc['wf'], configs, hdf_file=output,
                accumulators = {
                    'obdm_up':obdm_up,
                    'obdm_down':obdm_down
                },
                **kwargs
    )
示例#6
0
def evaluate_smallbasis(mc_calc, smallbasis_hdf, nconfig=1000, **kwargs):
    with h5py.File(smallbasis_hdf,'r') as f:
        basis_up = f['basis_up'][...]
        basis_down = f['basis_down'][...]
    mol = mc_calc['mol']
    obdm_up_acc = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=basis_up, spin=0)
    obdm_down_acc = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=basis_down, spin=1)
    tbdm = pyqmc.tbdm.TBDMAccumulator(mol, np.array([basis_up,basis_down]), spin=(0,1))
    acc = {'energy': pyqmc.EnergyAccumulator(mol),
        'obdm_up':obdm_up_acc,
        'obdm_down':obdm_down_acc,
        'tbdm': tbdm } 

    configs = pyqmc.initial_guess(mc_calc['mol'], nconfig)
    pyqmc.vmc(mc_calc['wf'], configs, accumulators = acc, **kwargs)
示例#7
0
def test_pbc_wfs():
    """
    Ensure that the wave function objects are consistent in several situations.
    """

    from pyscf.pbc import lib, gto, scf
    from pyqmc.supercell import get_supercell
    from pyqmc.slater import Slater
    from pyqmc.multiplywf import MultiplyWF
    from pyqmc import default_jastrow
    import pyqmc

    mol = gto.M(
        atom="H 0. 0. 0.; H 1. 1. 1.",
        basis="sto-3g",
        unit="bohr",
        a=(np.ones((3, 3)) - np.eye(3)) * 4,
    )
    mf = scf.KRKS(mol, mol.make_kpts((2, 2, 2))).run()
    # mf_rohf = scf.KROKS(mol).run()
    # mf_uhf = scf.KUKS(mol).run()
    epsilon = 1e-5
    nconf = 10
    supercell = get_supercell(mol, S=(np.ones((3, 3)) - 2 * np.eye(3)))
    epos = pyqmc.initial_guess(supercell, nconf)
    # For multislaterpbc
    # kinds = 0, 3, 5, 6  # G, X, Y, Z
    # d1 = {kind: [0] for kind in kinds}
    # d2 = d1.copy()
    # d2.update({0: [], 3: [0, 1]})
    # detwt = [2 ** 0.5, 2 ** 0.5]
    # occup = [[d1, d2], [d1]]
    # map_dets = [[0, 1], [0, 0]]
    for wf in [
        MultiplyWF(Slater(supercell, mf), default_jastrow(supercell)[0]),
        Slater(supercell, mf),
    ]:
        for k in wf.parameters:
            if "mo_coeff" not in k and k != "det_coeff":
                wf.parameters[k] = np.random.rand(*wf.parameters[k].shape)

        _, epos = pyqmc.vmc(wf, epos, nblocks=1, nsteps=2, tstep=1)  # move off node

        for fname, func in zip(
            ["gradient", "laplacian", "pgradient"],
            [
                testwf.test_wf_gradient,
                testwf.test_wf_laplacian,
                testwf.test_wf_pgradient,
            ],
        ):
            err = []
            for delta in [1e-4, 1e-5, 1e-6, 1e-7, 1e-8]:
                err.append(func(wf, epos, delta))
            print(type(wf), fname, min(err))
            assert min(err) < epsilon

        for k, item in testwf.test_updateinternals(wf, epos).items():
            print(k, item)
            assert item < epsilon
示例#8
0
文件: coord.py 项目: sapatha2/pyqmc
def test():
    from pyscf.pbc import gto, scf
    import pyqmc
    import pandas as pd

    L = 4
    mol = gto.M(
        atom="""H     {0}      {0}      {0}""".format(0.0),
        basis="sto-3g",
        a=np.eye(3) * L,
        spin=1,
        unit="bohr",
    )
    mf = scf.UKS(mol)
    mf.xc = "pbe"
    mf = mf.density_fit().run()
    wf = pyqmc.PySCFSlaterUHF(mol, mf)

    #####################################
    ## evaluate KE in PySCF
    #####################################
    ke_mat = mol.pbc_intor("int1e_kin", hermi=1, kpts=np.array([0, 0, 0]))
    dm = mf.make_rdm1()
    pyscfke = np.einsum("ij,ji", ke_mat, dm[0])
    print("PySCF kinetic energy: {0}".format(pyscfke))

    #####################################
    ## evaluate KE integral on grid
    #####################################
    X = np.linspace(0, 1, 20, endpoint=False)
    XYZ = np.meshgrid(X, X, X, indexing="ij")
    pts = [np.outer(p.ravel(), mol.a[i]) for i, p in enumerate(XYZ)]
    coords = np.sum(pts, axis=0).reshape((-1, 1, 3))

    phase, logdet = wf.recompute(coords)
    psi = phase * np.exp(logdet)
    lap = wf.laplacian(0, coords.reshape((-1, 3)))
    gridke = np.sum(-0.5 * lap * psi ** 2) / np.sum(psi ** 2)
    print("grid kinetic energy: {0}".format(gridke))

    #####################################
    ## evaluate KE integral with VMC
    #####################################
    coords = pyqmc.initial_guess(mol, 600, 0.7)
    coords = PeriodicConfigs(coords, mol.a)
    warmup = 10
    df, coords = pyqmc.vmc(
        wf,
        coords,
        nsteps=128 + warmup,
        tstep=L * 0.6,
        accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)},
    )
    df = pd.DataFrame(df)
    reblocked = pyqmc.reblock.optimally_reblocked(df["energyke"][warmup:])
    print(
        "VMC kinetic energy: {0} $\pm$ {1}".format(
            reblocked["mean"], reblocked["standard error"]
        )
    )
示例#9
0
def runtest(mol, mf, kind=0, do_mc=False):
    if do_mc:
        from pyscf import mcscf

        mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1))
        mc.kernel()
        wf = pyqmc.default_msj(mol, mf, mc)[0]
        kpt = mf.kpt
        dm = mc.make_rdm1()
        if len(dm.shape) == 4:
            dm = np.sum(dm, axis=0)
    else:
        kpt = mf.kpts[kind]
        wf = pyqmc.Slater(mol, mf)
        dm = mf.make_rdm1()
        print("original dm shape", dm.shape)
        if len(dm.shape) == 4:
            dm = np.sum(dm, axis=0)
        dm = dm[kind]

    #####################################
    ## evaluate KE in PySCF
    #####################################
    ke_mat = mol.pbc_intor("int1e_kin", hermi=1, kpts=np.array(kpt))
    print("ke_mat", ke_mat.shape)
    print("dm", dm.shape)
    pyscfke = np.real(np.einsum("ij,ji->", ke_mat, dm))
    print("PySCF kinetic energy: {0}".format(pyscfke))

    #####################################
    ## evaluate KE integral with VMC
    #####################################
    coords = pyqmc.initial_guess(mol, 1200, 0.7)
    warmup = 10
    start = time.time()
    df, coords = pyqmc.vmc(
        wf,
        coords,
        nsteps=100 + warmup,
        tstep=1,
        accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)},
        verbose=False,
        hdf_file=str(uuid.uuid4()),
    )
    print("VMC time", time.time() - start)
    df = pd.DataFrame(df)
    dfke = reblock(df["energyke"][warmup:], 10)
    dfke /= mol.scale
    vmcke, err = dfke.mean(), dfke.sem()
    print("VMC kinetic energy: {0} +- {1}".format(vmcke, err))

    assert (
        np.abs(vmcke - pyscfke) < 5 * err
    ), "energy diff not within 5 sigma ({0:.6f}): energies \n{1} \n{2}".format(
        5 * err, vmcke, pyscfke)
示例#10
0
def test_updateinternals(wf, configs):
    """
    Parameters:
    wf: a wave function object to be tested
    configs: nconf x nelec x 3 position array

    Returns:
    tuple which

    """
    from pyqmc import vmc

    nconf, ne, ndim = configs.configs.shape
    delta = 1e-2

    iscomplex = 1j if wf.iscomplex else 1
    updatevstest = np.zeros((ne, nconf)) * iscomplex
    recomputevstest = np.zeros((ne, nconf)) * iscomplex
    recomputevsupdate = np.zeros((ne, nconf)) * iscomplex
    wfcopy = copy.copy(wf)
    val1 = wf.recompute(configs)
    for e in range(ne):
        # val1 = wf.recompute(configs)
        epos = configs.make_irreducible(e, configs.configs[:, e, :] + delta)
        ratio = wf.testvalue(e, epos)
        wf.updateinternals(e, epos)
        update = wf.value()
        configs.move(e, epos, [True] * nconf)
        recompute = wfcopy.recompute(configs)
        updatevstest[
            e, :] = update[0] / val1[0] * np.exp(update[1] - val1[1]) - ratio
        recomputevsupdate[e, :] = update[0] / val1[0] * np.exp(
            update[1] -
            val1[1]) - recompute[0] / val1[0] * np.exp(recompute[1] - val1[1])
        recomputevstest[e, :] = (
            recompute[0] / val1[0] * np.exp(recompute[1] - val1[1]) - ratio)
        val1 = recompute

    # Test mask and pgrad
    _, configs = vmc(wf, configs, nblocks=1, nsteps_per_block=1, tstep=2)
    pgradupdate = wf.pgradient()
    wf.recompute(configs)
    pgrad = wf.pgradient()
    pgdict = {
        k: np.max(np.abs(pgu - pgrad[k]))
        for k, pgu in pgradupdate.items()
    }
    return {
        "updatevstest": np.max(np.abs(updatevstest)),
        "recomputevstest": np.max(np.abs(recomputevstest)),
        "recomputevsupdate": np.max(np.abs(recomputevsupdate)),
        **pgdict,
    }
示例#11
0
def test_wfs():
    """
    Ensure that the wave function objects are consistent in several situations.
    """

    from pyscf import lib, gto, scf
    from pyqmc.slater import PySCFSlater
    from pyqmc.jastrowspin import JastrowSpin
    from pyqmc.multiplywf import MultiplyWF
    from pyqmc.manybody_jastrow import J3
    import pyqmc

    mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5", basis="sto-3g", unit="bohr")
    mf = scf.RHF(mol).run()
    mf_rohf = scf.ROHF(mol).run()
    mf_uhf = scf.UHF(mol).run()
    epsilon = 1e-5
    nconf = 10
    epos = pyqmc.initial_guess(mol, nconf)
    for wf in [
            JastrowSpin(mol),
            J3(mol),
            MultiplyWF(PySCFSlater(mol, mf), JastrowSpin(mol)),
            MultiplyWF(PySCFSlater(mol, mf), JastrowSpin(mol), J3(mol)),
            PySCFSlater(mol, mf_uhf),
            PySCFSlater(mol, mf),
            PySCFSlater(mol, mf_rohf),
    ]:
        for k in wf.parameters:
            if k != "mo_coeff":
                wf.parameters[k] = np.random.rand(*wf.parameters[k].shape)
        for k, item in testwf.test_updateinternals(wf, epos).items():
            print(k, item)
            assert item < epsilon

        testwf.test_mask(wf, 0, epos)

        _, epos = pyqmc.vmc(wf, epos, nblocks=1, nsteps=2,
                            tstep=1)  # move off node

        for fname, func in zip(
            ["gradient", "laplacian", "pgradient"],
            [
                testwf.test_wf_gradient,
                testwf.test_wf_laplacian,
                testwf.test_wf_pgradient,
            ],
        ):
            err = []
            for delta in [1e-4, 1e-5, 1e-6, 1e-7, 1e-8]:
                err.append(func(wf, epos, delta)[0])
            print(type(wf), fname, min(err))
            assert min(err) < epsilon, "epsilon {0}".format(epsilon)
示例#12
0
def runtest(mol, mf, kind):
    kpt = mf.kpts[kind]
    wf = pyqmc.PySCFSlaterUHF(mol, mf, twist=np.dot(kpt, mol.a.T / np.pi))

    #####################################
    ## evaluate KE in PySCF
    #####################################
    ke_mat = mol.pbc_intor('int1e_kin', hermi=1, kpts=np.array(kpt))
    dm = mf.make_rdm1()
    if len(dm.shape) == 4:
        dm = np.sum(dm, axis=0)
    pyscfke = np.real(np.einsum('ij,ji->', ke_mat, dm[kind]))
    print('PySCF kinetic energy: {0}'.format(pyscfke))

    #####################################
    ## evaluate KE integral with VMC
    #####################################
    coords = pyqmc.initial_guess(mol, 1200, .7)
    warmup = 10
    start = time.time()
    df, coords = pyqmc.vmc(
        wf,
        coords,
        nsteps=32 + warmup,
        tstep=1,
        accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)},
        verbose=False,
    )
    print("VMC time", time.time() - start)
    df = pd.DataFrame(df)
    dfke = reblock(df["energyke"][warmup:], 8)
    vmcke, err = dfke.mean(), dfke.sem()
    print('VMC kinetic energy: {0} +- {1}'.format(vmcke, err))

    assert np.abs(vmcke-pyscfke) < 5 * err, \
        "energy diff not within 5 sigma ({0:.6f}): energies \n{1} \n{2}".format(5 * err, vmcke, pyscfke)
示例#13
0
def test_shci_wf():
    mol = pyscf.gto.M(
        atom="O 0. 0. 0.; H 0. 0. 2.0",
        basis="ccecpccpvtz",
        ecp="ccecp",
        unit="bohr",
        charge=-1,
    )
    mf = pyscf.scf.RHF(mol)
    mf.kernel()
    e_hf = mf.energy_tot()
    cisolver = pyscf.hci.SCI(mol)
    cisolver.select_cutoff = 0.1
    nmo = mf.mo_coeff.shape[1]
    nelec = mol.nelec
    h1 = mf.mo_coeff.T.dot(mf.get_hcore()).dot(mf.mo_coeff)
    h2 = pyscf.ao2mo.full(mol, mf.mo_coeff)
    e, civec = cisolver.kernel(h1, h2, nmo, nelec, verbose=4)
    cisolver.ci = civec[0]
    ci_energy = mf.energy_nuc() + e

    tol = 0.0
    configs = pyqmc.initial_guess(mol, 1000)
    wf = pyqmc.Slater(mol, mf, cisolver, tol=tol)
    data, configs = pyqmc.vmc(
        wf,
        configs,
        nblocks=40,
        verbose=True,
        accumulators={"energy": pyqmc.EnergyAccumulator(mol)},
    )
    en, err = avg(data["energytotal"][1:])
    nsigma = 4
    assert len(wf.parameters["det_coeff"]) == len(cisolver.ci)
    assert en - nsigma * err < e_hf
    assert en + nsigma * err > ci_energy
示例#14
0
    # Initialize energy accumulator (and Ewald)
    pgrad = pyqmc.gradient_generator(supercell, wf, to_opt=to_opt)

    # Optimize jastrow
    wf, lm_df = pyqmc.line_minimization(wf,
                                        configs,
                                        pgrad,
                                        hdf_file="pbc_he_linemin.hdf",
                                        verbose=True)

    # Run VMC
    df, configs = pyqmc.vmc(
        wf,
        configs,
        nblocks=100,
        accumulators={"energy": pgrad.enacc},
        hdf_file="pbc_he_vmc.hdf",
        verbose=True,
    )

    # Run DMC
    pyqmc.rundmc(
        wf,
        configs,
        nsteps=1000,
        accumulators={"energy": pgrad.enacc},
        hdf_file="pbc_he_dmc.hdf",
        verbose=True,
    )
示例#15
0
 pgrad_acc = pyqmc.gradient_generator(mol, wf, to_opt)
 configs = pyqmc.initial_guess(mol, nconfig)
 line_minimization(
     wf,
     configs,
     pgrad_acc,
     hdf_file="h2o_opt.hdf",
     client=client,
     npartitions=ncore,
     verbose=True,
 )
 df, configs = vmc(
     wf,
     configs,
     hdf_file="h2o_vmc.hdf",
     accumulators={"energy": pgrad_acc.enacc},
     client=client,
     npartitions=ncore,
     verbose=True,
 )
 dfdmc, configs, weights = rundmc(
     wf,
     configs,
     hdf_file="h2o_dmc.hdf",
     nsteps=1000,
     accumulators={"energy": pgrad_acc.enacc},
     ekey=("energy", "total"),
     tstep=0.02,
     verbose=True,
     client=client,
     npartitions=ncore,
示例#16
0
        jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array(
            [-0.25, -0.50, -0.25])
        freeze = {}
        freeze["wf2acoeff"] = np.zeros(
            jastrow.parameters["acoeff"].shape).astype(bool)
        freeze["wf2bcoeff"] = np.zeros(
            jastrow.parameters["bcoeff"].shape).astype(bool)
        freeze["wf2bcoeff"][0, [0, 1, 2]] = True  # Cusp conditions
        to_opt = ["wf2acoeff", "wf2bcoeff"]

        # Multiply
        wf = MultiplyWF(slater, jastrow)
        configs = pyqmc.initial_guess(supercell, nconfig)

        # Warm up VMC
        df, configs = pyqmc.vmc(wf, configs, nsteps=5, verbose=True)

        # Initialize energy accumulator (and Ewald)
        pgrad = pyqmc.gradient_generator(supercell,
                                         wf,
                                         to_opt=to_opt,
                                         freeze=freeze)

        # Optimize jastrow
        hdf_file = "linemin_nk{0}.hdf".format(nk)
        wf, lm_df = line_minimization(wf,
                                      configs,
                                      pgrad,
                                      hdf_file=hdf_file,
                                      verbose=True)
        jastrow = wf.wf2
示例#17
0
        "excited1_final": "excited1_final.hdf5",
        "excited2_final": "excited2_final.hdf5",
    }

    for k, it in savefiles.items():
        if os.path.isfile(it):
            os.remove(it)

    # Run
    setuph2(savefiles["mf"], "test")
    sys = pyqmc_from_hdf(savefiles["mf"])

    df, coords = vmc(
        sys["wf"],
        pyqmc.initial_guess(sys["mol"], nconfig),
        client=client,
        nsteps=10,
        npartitions=ncore,
    )

    line_minimization(
        sys["wf"],
        coords,
        sys["pgrad"],
        hdf_file=savefiles["linemin"],
        client=client,
        npartitions=ncore,
        verbose=True,
    )

    # First excited state