예제 #1
0
def get_kernel_term(kernel_name, hyps_mask, hyps):
    hyps, cutoffs, hyps_mask = Parameters.get_component_mask(hyps_mask,
                                                             kernel_name,
                                                             hyps=hyps)
    kernel, _, ek, efk, _, _, _ = str_to_kernel_set([kernel_name], "mc",
                                                    hyps_mask)
    return (ek, cutoffs, hyps, hyps_mask)
예제 #2
0
def test_force(kernels, diff_cutoff):
    """Check that the analytical force kernel matches finite difference of
    energy kernel."""

    d1 = 1
    d2 = 2
    tol = 1e-3
    cell = 1e7 * np.eye(3)
    delta = 1e-4
    cutoffs = np.ones(3) * 1.2

    np.random.seed(10)

    cutoffs, hyps, hm = generate_diff_hm(kernels, diff_cutoff)
    kernel, kg, en_kernel, fek, _, _, _ = str_to_kernel_set(kernels, "mc", hm)

    nterm = 0
    for term in ["twobody", "threebody", "manybody"]:
        if term in kernels:
            nterm += 1

    np.random.seed(10)
    env1 = generate_mb_envs(cutoffs, cell, delta, d1, hm)
    env2 = generate_mb_envs(cutoffs, cell, delta, d2, hm)

    # check force kernel
    kern_finite_diff = 0
    if "manybody" in kernels and len(kernels) == 1:
        _, _, enm_kernel, _, _, _, _ = str_to_kernel_set(["manybody"], "mc", hm)
        mhyps, mcutoffs, mhyps_mask = Parameters.get_component_mask(
            hm, "manybody", hyps=hyps
        )
        margs = from_mask_to_args(mhyps, mcutoffs, mhyps_mask)
        cal = 0
        for i in range(3):
            for j in range(len(env1[0])):
                cal += enm_kernel(env1[1][i], env2[1][j], *margs)
                cal += enm_kernel(env1[2][i], env2[2][j], *margs)
                cal -= enm_kernel(env1[1][i], env2[2][j], *margs)
                cal -= enm_kernel(env1[2][i], env2[1][j], *margs)
        kern_finite_diff += cal / (4 * delta ** 2)
    elif "manybody" in kernels:
        # TODO: Establish why 2+3+MB fails (numerical error?)
        return

    if "twobody" in kernels:
        ntwobody = 1
        _, _, en2_kernel, _, _, _, _ = str_to_kernel_set(["twobody"], "mc", hm)
        bhyps, bcutoffs, bhyps_mask = Parameters.get_component_mask(
            hm, "twobody", hyps=hyps
        )
        args2 = from_mask_to_args(bhyps, bcutoffs, bhyps_mask)

        calc1 = en2_kernel(env1[1][0], env2[1][0], *args2)
        calc2 = en2_kernel(env1[2][0], env2[2][0], *args2)
        calc3 = en2_kernel(env1[1][0], env2[2][0], *args2)
        calc4 = en2_kernel(env1[2][0], env2[1][0], *args2)
        kern_finite_diff += 4 * (calc1 + calc2 - calc3 - calc4) / (4 * delta ** 2)
    else:
        ntwobody = 0

    if "threebody" in kernels:
        _, _, en3_kernel, _, _, _, _ = str_to_kernel_set(["threebody"], "mc", hm)

        thyps, tcutoffs, thyps_mask = Parameters.get_component_mask(
            hm, "threebody", hyps=hyps
        )
        args3 = from_mask_to_args(thyps, tcutoffs, thyps_mask)

        calc1 = en3_kernel(env1[1][0], env2[1][0], *args3)
        calc2 = en3_kernel(env1[2][0], env2[2][0], *args3)
        calc3 = en3_kernel(env1[1][0], env2[2][0], *args3)
        calc4 = en3_kernel(env1[2][0], env2[1][0], *args3)
        kern_finite_diff += 9 * (calc1 + calc2 - calc3 - calc4) / (4 * delta ** 2)

    args = from_mask_to_args(hyps, cutoffs, hm)
    kern_analytical = kernel(env1[0][0], env2[0][0], d1, d2, *args)

    assert isclose(kern_finite_diff, kern_analytical, rtol=tol)