示例#1
0
def test_manual_slater(H2_ccecp_rhf, epsilon=1e-5):
    mol, mf = H2_ccecp_rhf

    determinants = [(1.0, [[0], [0]]), (-0.2, [[1], [1]])]
    wf = Slater(mol, mf, determinants=determinants)
    configs = pyq.initial_guess(mol, 10)
    run_tests(wf, configs, epsilon)
示例#2
0
def test_constraints(H2_ccecp_casci_s0):
    mol, mf, mc = H2_ccecp_casci_s0

    wf, to_opt = pyq.generate_wf(mol, mf, mc=mc)

    old_parms = copy.deepcopy(wf.parameters)
    lt = LinearTransform(wf.parameters, to_opt)

    # Test serialize parameters
    x0 = lt.serialize_parameters(wf.parameters)
    x0 += np.random.normal(size=x0.shape)
    for k, it in lt.deserialize(wf, x0).items():
        assert wf.parameters[k].shape == it.shape
        wf.parameters[k] = it

    # to_opt is supposed to be false for both of these.
    assert wf.parameters["wf1det_coeff"][0] == old_parms["wf1det_coeff"][0]
    assert np.sum(wf.parameters["wf2bcoeff"][0] -
                  old_parms["wf2bcoeff"][0]) == 0
    # While this one is supposed to change.
    assert np.sum(wf.parameters["wf2bcoeff"][1] -
                  old_parms["wf2bcoeff"][1]) != 0

    # Test serialize gradients
    configs = pyq.initial_guess(mol, 10)
    wf.recompute(configs)
    pgrad = wf.pgradient()
    pgrad_serial = lt.serialize_gradients(pgrad)

    # Pgrad should be walkers, configs
    assert pgrad_serial.shape[1] == x0.shape[0]
示例#3
0
def info_functions(mol, wf, accumulators):
    accumulators["energy"] = accumulators["pgrad"].enacc
    configs = pyq.initial_guess(mol, 100)
    wf.recompute(configs)
    for k, acc in accumulators.items():
        shapes = acc.shapes()
        keys = acc.keys()
        assert shapes.keys() == keys, "keys: {0}\nshapes: {1}".format(keys, shapes)
        avg = acc.avg(configs, wf)
        assert avg.keys() == keys, (k, avg.keys(), keys)
        for ka in keys:
            assert shapes[ka] == avg[ka].shape, "{0} {1}".format(ka, avg[ka].shape)
示例#4
0
def run_optimization_best_practice_2states(**kwargs):
    """
    First optimize the ground state and then optimize the excited
    states while fixing the 
    """

    mol, mf, mc = H2_casci()
    import copy
    mf.output = None
    mol.output = None
    mc.output = None
    mc.stdout = None
    mol.stdout = None
    mc.stdout = None
    nstates = 2
    mcs = [copy.copy(mc) for i in range(nstates)]
    for i in range(nstates):
        mcs[i].ci = mc.ci[i]

    wfs = []
    to_opts = []
    for i in range(nstates):
        wf, to_opt = pyq.generate_wf(
            mol, mf, mc=mcs[i], slater_kws=dict(optimize_determinants=True))
        wfs.append(wf)
        to_opts.append(to_opt)
    configs = pyq.initial_guess(mol, 1000)

    pgrad1 = pyq.gradient_generator(mol, wfs[0], to_opt=to_opts[0])
    wfs[0], _ = pyq.line_minimization(wfs[0],
                                      configs,
                                      pgrad1,
                                      verbose=True,
                                      max_iterations=10)

    for k in to_opts[0]:
        to_opts[0][k] = np.zeros_like(to_opts[0][k])
    to_opts[0]['wf1det_coeff'][0] = True  #Bug workaround for linear transform
    for to_opt in to_opts[1:]:
        to_opt['wf1det_coeff'] = np.ones_like(to_opt['wf1det_coeff'])

    transforms = [
        pyqmc.accumulators.LinearTransform(wf.parameters, to_opt)
        for wf, to_opt in zip(wfs, to_opts)
    ]
    for wf in wfs[1:]:
        for k in wf.parameters.keys():
            if 'wf2' in k:
                wf.parameters[k] = wfs[0].parameters[k].copy()
    _, configs = pyq.vmc(wfs[0], configs)
    energy = pyq.EnergyAccumulator(mol)
    return optimize(wfs, configs, energy, transforms, **kwargs)
示例#5
0
def test_transform(LiH_sto3g_rhf):
    """Tests that the shapes are ok"""
    mol, mf = LiH_sto3g_rhf
    wf, to_opt = pyq.generate_wf(mol, mf)
    transform = LinearTransform(wf.parameters)
    x = transform.serialize_parameters(wf.parameters)
    nconfig = 10
    configs = pyq.initial_guess(mol, nconfig)
    wf.recompute(configs)
    pgrad = wf.pgradient()
    gradtrans = transform.serialize_gradients(pgrad)
    assert gradtrans.shape[1] == len(x)
    assert gradtrans.shape[0] == nconfig
def test_sampler(H2_casci):

    mol, mf, mc = H2_casci

    ci_energies= mc.e_tot
    mc1 = copy.copy(mc)
    mc2 = copy.copy(mc)
    mc1.ci = mc.ci[0]
    mc2.ci = (mc.ci[0]+mc.ci[1])/np.sqrt(2)

    wf1, to_opt1 = pyq.generate_slater(mol, mf,mc=mc1, optimize_determinants=True)
    wf2, to_opt2 = pyq.generate_slater(mol, mf, mc=mc2, optimize_determinants=True)
    for to_opt in [to_opt1, to_opt2]:
        to_opt['det_coeff'] = np.ones_like(to_opt['det_coeff'],dtype=bool)

    transform1 = pyqmc.accumulators.LinearTransform(wf1.parameters,to_opt1)
    transform2 = pyqmc.accumulators.LinearTransform(wf2.parameters,to_opt2)
    configs = pyq.initial_guess(mol, 2000)
    _, configs = pyq.vmc(wf1, configs)
    energy =pyq.EnergyAccumulator(mol)
    data_weighted, data_unweighted, configs = sample_overlap_worker([wf1,wf2],configs, energy, [transform1,transform2], nsteps=40, nblocks=20)
    avg, error = average(data_weighted, data_unweighted)
    print(avg, error)

    ref_energy1 = 0.5*(ci_energies[0] + ci_energies[1])
    assert abs(avg['total'][1,1] - ref_energy1) < 3*error['total'][1][1]

    ref_energy01 = ci_energies[0]/np.sqrt(2)
    assert abs(avg['total'][0,1] - ref_energy01) < 3*error['total'][0,1]

    overlap_tolerance = 0.2# magic number..be careful.
    terms = collect_terms(avg,error)

    norm = [np.sum(np.abs(m.ci)**2) for m in [mc1,mc2]]
    norm_ref = norm
    assert np.all( np.abs(norm_ref - terms['norm']) < overlap_tolerance) 

    norm_derivative_ref = 2*np.real(mc2.ci).flatten() 
    print(terms[('dp_norm',1)].shape, norm_derivative_ref.shape)
    assert np.all(np.abs(norm_derivative_ref - terms[('dp_norm',1)])<overlap_tolerance)

    overlap_ref = np.sum(mc1.ci*mc2.ci) 
    print('overlap test', overlap_ref, terms['overlap'][0,1])
    assert abs(overlap_ref - terms['overlap'][0,1]) < overlap_tolerance

    overlap_derivative_ref = (mc1.ci.flatten() - 0.5*overlap_ref * norm_derivative_ref) 
    assert np.all( np.abs(overlap_derivative_ref - terms[('dp_overlap',1)][:,0,1]) < overlap_tolerance)

    en_derivative = take_derivative_casci_energy(mc, mc2.ci)
    assert(np.all(abs(terms[('dp_energy',1)][:,1,1].reshape(mc2.ci.shape)-en_derivative) -overlap_tolerance) )
    derivative = objective_function_derivative(terms,1.0, norm_relative_penalty=1.0, offdiagonal_energy_penalty=0.1)
示例#7
0
def test_linemin(H2_ccecp_uhf):
    """Optimize a Slater-Jastrow wave function and check that it's better than Hartree-Fock"""
    mol, mf = H2_ccecp_uhf

    wf, to_opt = generate_wf(mol, mf)
    nconf = 100
    wf, dfgrad = line_minimization(
        wf, initial_guess(mol, nconf), gradient_generator(mol, wf, to_opt)
    )

    dfgrad = pd.DataFrame(dfgrad)
    mfen = mf.energy_tot()
    enfinal = dfgrad["energy"].values[-1]
    enfinal_err = dfgrad["energy_error"].values[-1]
    assert mfen > enfinal
def test_correlated_sampling(H2_casci):

    mol, mf, mc = H2_casci

    ci_energies= mc.e_tot
    import copy
    mc1 = copy.copy(mc)
    mc2 = copy.copy(mc)
    mc1.ci = mc.ci[0]
    mc2.ci = mc.ci[1]

    wf1, to_opt1 = pyq.generate_slater(mol, mf,mc=mc1, optimize_determinants=True)
    wf2, to_opt2 = pyq.generate_slater(mol, mf, mc=mc2, optimize_determinants=True)
    for to_opt in [to_opt1, to_opt2]:
        to_opt['det_coeff'] = np.ones_like(to_opt['det_coeff'],dtype=bool)

    transform1 = pyqmc.accumulators.LinearTransform(wf1.parameters,to_opt1)
    transform2 = pyqmc.accumulators.LinearTransform(wf2.parameters,to_opt2)
    configs = pyq.initial_guess(mol, 1000)
    _, configs = pyq.vmc(wf1, configs)
    energy =pyq.EnergyAccumulator(mol)
    data_weighted, data_unweighted, configs = sample_overlap_worker([wf1,wf2],configs, energy, [transform1,transform2], nsteps=10, nblocks=10)

    parameters1 = transform1.serialize_parameters(wf1.parameters)
    parameters2 = transform1.serialize_parameters(wf2.parameters)
    sample_parameters = []
    energies_reference = []
    overlap_reference = []
    for theta in np.linspace(0,np.pi/2, 4):
        a = np.cos(theta)
        b = np.sin(theta)
        sample_parameters.append([a*parameters1 + b*parameters2, a*parameters1 - b*parameters2])
        energies_reference.append([a**2*ci_energies[0] + b**2*ci_energies[1]]*2)
        overlap_reference.append([[1.0, a**2-b**2], [a**2-b**2,1.0]]  )
    energies_reference=np.asarray(energies_reference)
    overlap_reference=np.asarray(overlap_reference)
    correlated_results = correlated_sampling([wf1,wf2], configs,energy, [transform1,transform2], sample_parameters )
    print(correlated_results)
    energy_sample = correlated_results['energy']/correlated_results['overlap']
    print('energy reference',energies_reference)
    print('energy sample', energy_sample)

    assert np.all(np.abs(energy_sample.diagonal(axis1=1,axis2=2) - energies_reference) < 0.1)

    print('overlap sample', correlated_results['overlap'])

    print('overlap reference', overlap_reference)
    assert np.all(np.abs(correlated_results['overlap']-overlap_reference)<0.1)
示例#9
0
def test_shci_wf_is_better(H2_ccecp_hci):
    mol, mf, cisolver = H2_ccecp_hci

    configs = pyq.initial_guess(mol, 1000)
    wf = Slater(mol, mf, cisolver, tol=0.0)
    data, configs = pyq.vmc(
        wf,
        configs,
        nblocks=40,
        verbose=True,
        accumulators={"energy": pyq.EnergyAccumulator(mol)},
    )
    en, err = avg(data["energytotal"][1:])
    nsigma = 4
    assert len(wf.parameters["det_coeff"]) == len(cisolver.ci)
    assert en - nsigma * err < mf.e_tot
    assert en + nsigma * err > cisolver.energy
示例#10
0
def runtest(mol, mf, kind=0):
    kpt = mf.kpts[kind]
    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
    #####################################
    wf = Slater(mol, mf)
    coords = pyq.initial_guess(mol, 1200, 0.7)
    warmup = 10
    start = time.time()
    df, coords = pyq.vmc(
        wf,
        coords,
        nsteps=100 + warmup,
        tstep=1,
        accumulators={"energy": pyq.EnergyAccumulator(mol)},
        verbose=False,
        hdf_file=str(uuid.uuid4()),
    )
    print("VMC time", time.time() - start)

    df = pd.DataFrame(df)
    dfke = pyq.avg_reblock(df["energyke"][warmup:], 10)
    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
    )
示例#11
0
def test_manual_pbcs_correct(H_pbc_sto3g_kuks, epsilon=1e-5, nconf=10):
    """
    This test makes sure that the number of k-points must match the number of k-points
    in the mf object.
    """
    from pyqmc.determinant_tools import create_pbc_determinant

    mol, mf = H_pbc_sto3g_kuks
    supercell = np.identity(3, dtype=int)
    supercell[0, 0] = 2
    mol = pyq.get_supercell(mol, supercell)

    determinants = [
        (1.0, create_pbc_determinant(mol, mf, [])),
        (-0.2, create_pbc_determinant(mol, mf, [(0, 0, 0, 0, 1)])),
    ]
    wf = Slater(mol, mf, determinants=determinants)
    configs = pyq.initial_guess(mol, 10)
    run_tests(wf, configs, epsilon)
示例#12
0
def test_overlap_derivative(H2_ccecp_uhf, epsilon=1e-8):
    mol, mf = H2_ccecp_uhf
    mf = copy.copy(mf)

    wf0 = slater.Slater(mol, mf)
    mf.mo_coeff[0][:, 0] = np.mean(mf.mo_coeff[0][:, :2], axis=1)
    wf1, to_opt = wftools.generate_slater(mol, mf, optimize_orbitals=True)

    pgrad = pyq.gradient_generator(mol, wf1, to_opt)
    configs = pyq.initial_guess(mol, 2000)

    wf0.recompute(configs)
    wf1.recompute(configs)
    wfs = [wf0, wf1]

    print("warming up", flush=True)
    block_avg, configs = oo.sample_overlap_worker(wfs,
                                                  configs,
                                                  pgrad,
                                                  20,
                                                  tstep=1.5)

    print("computing gradients and normalization", flush=True)
    data = get_data(wfs, configs, pgrad)
    parameters = pgrad.transform.serialize_parameters(wfs[-1].parameters)
    N = compute_normalization(wfs, [parameters], pgrad.transform, configs)
    print(np.stack([data["N"], N]))

    print("computing numerical gradients", flush=True)
    error = {"N": [], "S": []}
    deltas = [1e-4, 1e-5, 1e-6]
    numgrad = numerical_gradient(wfs, configs, pgrad, deltas)
    for k, ng in numgrad.items():
        pgerr = data[k + "_derivative"].T[:, np.newaxis] - ng
        error[k] = pgerr

    print("computing errors", flush=True)
    for k, er in error.items():
        error[k] = np.amin(er, axis=1)
        print(k)
        print(error[k])
        assert np.all(error[k] < epsilon)
示例#13
0
def test_casci_energy(H2_ccecp_casci_s0):
    """
    Checks that VMC energy matches energy calculated in PySCF
    """
    nsteps = 200
    warmup = 10

    mol, mf, mc = H2_ccecp_casci_s0
    wf = Slater(mol, mf, mc)
    nconf = 1000
    coords = pyq.initial_guess(mol, nconf)
    df, coords = pyq.vmc(
        wf, coords, nsteps=nsteps, accumulators={"energy": EnergyAccumulator(mol)}
    )

    df = pd.DataFrame(df)
    df = pyq.avg_reblock(df["energytotal"][warmup:], 20)
    en = df.mean()
    err = df.sem()
    assert en - mc.e_tot < 5 * err
示例#14
0
def test_pbc_wfs(H_pbc_sto3g_krks, epsilon=1e-5, nconf=10):
    """
    Ensure that the wave function objects are consistent in several situations.
    """
    mol, mf = H_pbc_sto3g_krks

    supercell = pyq.get_supercell(mol, S=(np.ones((3, 3)) - 2 * np.eye(3)))
    epos = pyq.initial_guess(supercell, nconf)
    for wf in [
            MultiplyWF(Slater(supercell, mf),
                       generate_jastrow(supercell)[0]),
            Slater(supercell, mf),
    ]:
        for k in wf.parameters:
            if "mo_coeff" not in k and k != "det_coeff":
                wf.parameters[k] = cp.asarray(
                    np.random.rand(*wf.parameters[k].shape))

        _, epos = pyq.vmc(wf, epos, nblocks=1, nsteps=2,
                          tstep=1)  # move off node
        run_tests(wf, epos, epsilon)
示例#15
0
def test_superpose_wf(H2_casci,
                      coeffs=[1 / np.sqrt(2), 1 / np.sqrt(2)],
                      epsilon=1e-5,
                      nconf=10):
    """
    This test makes sure that the superposewf passes all the wftests, when adding two casci wave functions.
    """

    mol, mf, mc = H2_casci
    ci0, ci1 = mc.ci[0], mc.ci[1]

    mc.ci = ci0
    wf0 = Slater(mol, mf, mc, tol=0.0)

    mc.ci = ci1
    wf1 = Slater(mol, mf, mc, tol=0.0)

    wfs = [wf0, wf1]
    wf = AddWF(coeffs, wfs)
    configs = pyq.initial_guess(mol, nconf)
    run_tests(wf, configs, epsilon)
示例#16
0
def test_dmc_restarts(H_pbc_sto3g_krks, nconf=10):
    """For PBCs, check to make sure there are no
    errors on restart."""
    mol, mf = H_pbc_sto3g_krks
    nconf = 10
    fname = "test_dmc_restart_" + str(uuid.uuid4())

    configs = pyq.initial_guess(mol, nconf)
    wf, _ = pyq.generate_wf(mol, mf, jastrow_kws=dict(na=0, nb=0))
    enacc = pyq.EnergyAccumulator(mol)
    pyq.rundmc(wf,
               configs,
               nsteps=20,
               hdf_file=fname,
               accumulators={"energy": enacc})
    pyq.rundmc(wf,
               configs,
               nsteps=20,
               hdf_file=fname,
               accumulators={"energy": enacc})
    os.remove(fname)
示例#17
0
def test():
    """ Ensure that DMC obtains the exact result for a hydrogen atom """
    from pyscf import gto, scf
    from pyqmc.dmc import limdrift
    import pandas as pd

    mol = gto.M(atom="H 0. 0. 0.", basis="sto-3g", unit="bohr", spin=1)
    mf = scf.UHF(mol).run()
    nconf = 1000
    configs = pyq.initial_guess(mol, nconf)
    wf, _ = pyq.generate_wf(mol, mf, jastrow_kws=dict(na=0, nb=0))
    enacc = pyq.EnergyAccumulator(mol)

    warmup = 200
    branchtime = 5
    dfdmc, configs_, weights_ = pyq.rundmc(
        wf,
        configs,
        nsteps=4000 + warmup * branchtime,
        branchtime=branchtime,
        accumulators={"energy": enacc},
        ekey=("energy", "total"),
        tstep=0.01,
        verbose=True,
    )

    dfdmc = pd.DataFrame(dfdmc)
    dfdmc.sort_values("step", inplace=True)

    dfprod = dfdmc[dfdmc.step >= warmup]

    rb_summary = reblock.reblock_summary(dfprod[["energytotal", "energyei"]],
                                         20,
                                         weights=dfprod["weight"])
    energy, err = [
        rb_summary[v]["energytotal"] for v in ("mean", "standard error")
    ]
    assert (np.abs(energy + 0.5) <
            5 * err), "energy not within {0} of -0.5: energy {1}".format(
                5 * err, np.mean(energy))
示例#18
0
def test_complex_linemin(H2_ccecp_rhf, optfile="linemin.hdf5"):
    """Test linemin for the case of complex orbital coefficients.
    We check whether it completes successfully and whether the energy has decreased.
    """
    mol, mf = H2_ccecp_rhf
    mf = copy.copy(mf)
    noise = (np.random.random(mf.mo_coeff.shape) - 0.5) * 0.2
    mf.mo_coeff = mf.mo_coeff * 1j + noise

    slater_kws = {"optimize_orbitals": True}
    wf, to_opt = pyq.generate_wf(mol, mf, slater_kws=slater_kws)

    configs = pyq.initial_guess(mol, 100)
    acc = pyq.gradient_generator(mol, wf, to_opt)
    pyq.line_minimization(
        wf, configs, acc, verbose=True, hdf_file=optfile, max_iterations=5
    )
    assert os.path.isfile(optfile)
    with h5py.File(optfile, "r") as f:
        en = f["energy"][()]
    assert en[0] > en[-1]
    os.remove(optfile)
示例#19
0
def test_obc_wfs(LiH_sto3g_rhf, epsilon=1e-5, nconf=10):
    """
    Ensure that the wave function objects are consistent in several situations.
    """

    mol, mf = LiH_sto3g_rhf
    for wf in [
            generate_jastrow(mol)[0],
            J3(mol),
            MultiplyWF(Slater(mol, mf),
                       generate_jastrow(mol)[0]),
            MultiplyWF(Slater(mol, mf),
                       generate_jastrow(mol)[0], J3(mol)),
            Slater(mol, mf),
    ]:
        for k in wf.parameters:
            if k != "mo_coeff":
                wf.parameters[k] = cp.asarray(
                    np.random.rand(*wf.parameters[k].shape))

        epos = pyq.initial_guess(mol, nconf)
        run_tests(wf, epos, epsilon)
示例#20
0
def test_casci_s2(H2_ccecp_casci_s2, epsilon=1e-5):
    mol, mf, cisolver = H2_ccecp_casci_s2
    configs = pyq.initial_guess(mol, 10)
    wf = Slater(mol, mf, cisolver, tol=0.0)
    run_tests(wf, configs, epsilon)
示例#21
0
def test_rohf(C_ccecp_rohf, epsilon=1e-5):
    mol, mf = C_ccecp_rohf
    configs = pyq.initial_guess(mol, 10)
    wf = Slater(mol, mf)
    run_tests(wf, configs, epsilon)
示例#22
0
def runtest(mol, mf, kind=0):
    kpt = mf.kpts[kind]
    twist = np.dot(kpt, mol.lattice_vectors().T / (2 * np.pi))

    wf0 = Slater(mol, mf)
    wft = Slater(mol, mf, twist=twist)

    #####################################
    ## compare values across boundary
    ## psi, KE, ecp,
    #####################################
    nconfig = 50
    coords = pyq.initial_guess(mol, nconfig, 1)
    epos, wrap = enforce_pbc(coords.lvecs, coords.configs)
    coords = PeriodicConfigs(epos, coords.lvecs)

    shift_ = np.random.randint(10, size=coords.configs.shape) - 5
    phase = np.exp(2j * np.pi * np.einsum("ijk,k->ij", shift_, twist))

    shift = np.dot(shift_, mol.lattice_vectors())
    epos, wrap = enforce_pbc(coords.lvecs, epos + shift)
    newcoords = PeriodicConfigs(epos, coords.lvecs, wrap=wrap)

    assert np.linalg.norm(newcoords.configs - coords.configs) < 1e-12

    ph0, val0 = wf0.recompute(coords)
    pht, valt = wft.recompute(coords)
    enacc = pyq.EnergyAccumulator(mol, threshold=np.inf)
    np.random.seed(0)
    en0 = enacc(coords, wf0)
    np.random.seed(0)
    ent = enacc(coords, wft)

    e = 0
    rat0 = wf0.testvalue(e, newcoords.electron(e))
    assert np.linalg.norm(rat0 - 1) < 1e-9, rat0 - 1
    ratt = wft.testvalue(e, newcoords.electron(e))
    rattdiff = ratt - phase[:, e]
    print("phase", phase[:, e])
    assert np.linalg.norm(rattdiff) < 1e-9, [
        np.round(rattdiff, 10),
        np.amax(np.abs(rattdiff)),
    ]

    ph0new, val0new = wf0.recompute(newcoords)
    phtnew, valtnew = wft.recompute(newcoords)
    np.random.seed(0)
    en0new = enacc(newcoords, wf0)
    np.random.seed(0)
    entnew = enacc(newcoords, wft)

    assert np.linalg.norm(ph0 - ph0new) < 1e-11
    assert np.linalg.norm(pht * phase.prod(axis=1) - phtnew) < 1e-11, (
        pht * phase.prod(axis=1) - phtnew)
    assert np.linalg.norm(val0 - val0new) < 1e-11, np.linalg.norm(val0 -
                                                                  val0new)
    assert np.linalg.norm(valt - valtnew) < 1e-11, np.linalg.norm(valt -
                                                                  valtnew)

    for k in en0.keys():
        diff0 = en0[k] - en0new[k]
        difft = ent[k] - entnew[k]
        if k == "ecp":
            for l, diff in [("0", diff0), ("t", difft)]:
                mad = np.mean(np.abs(diff))
                if True:  # mad > 1e-12:
                    print("ecp%s diff" % l, mad, np.linalg.norm(diff))
                    assert mad < 1e-3, diff
        else:
            assert np.mean(np.abs(diff0)) < 1e-6, diff0
            assert np.mean(np.abs(difft)) < 1e-6, difft