Пример #1
0
def test_fmm_force_ewald_2():

    R = 3
    eps = 10.**-6
    free_space = True

    N = 2
    E = 4.
    rc = E / 8

    A = state.State()
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    ASYNC = False
    DIRECT = True if MPISIZE == 1 else False

    DIRECT = True
    EWALD = True

    fmm = PyFMM(domain=A.domain, r=R, eps=eps, free_space=free_space)

    A.npart = N

    rng = np.random.RandomState(seed=1234)

    A.P = data.PositionDat(ncomp=3)
    A.F = data.ParticleDat(ncomp=3)
    A.FE = data.ParticleDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)

    A.crr = data.ScalarArray(ncomp=1)
    A.cri = data.ScalarArray(ncomp=1)
    A.crs = data.ScalarArray(ncomp=1)

    if N == 4:
        ra = 0.25 * E
        nra = -0.25 * E

        A.P[0, :] = (0.21, 0.21, 0.00)
        A.P[1, :] = (-0.21, 0.21, 0.00)
        A.P[2, :] = (-0.21, -0.21, 0.00)
        A.P[3, :] = (0.21, -0.21, 0.00)

        #A.P[0,:] = ( 0.00,  0.21, 0.21)
        #A.P[1,:] = ( 0.00,  0.21,-0.21)
        #A.P[2,:] = ( 0.00, -0.21,-0.21)
        #A.P[3,:] = ( 0.00, -0.21, 0.21)

        #A.P[0,:] = ( 1.01,  1.01, 0.00)
        #A.P[1,:] = (-1.01,  1.01, 0.00)
        #A.P[2,:] = (-1.01, -1.01, 0.00)
        #A.P[3,:] = ( 1.01, -1.01, 0.00)

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.
        A.Q[2, 0] = -1.
        A.Q[3, 0] = 1.

    elif N == 1:
        A.P[0, :] = (0.25 * E, 0.25 * E, 0.25 * E)
        A.P[0, :] = (10.**-6, 10.**-6, 10.**-6)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.

        A.Q[0, 0] = 1.

    elif N == 2:
        #A.P[0,:] = ( 0.25*E, 0.25*E, 0.25*E)
        #A.P[1,:] = ( -0.25*E, -0.25*E, 0)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.
        ra = 0.25 * E
        nra = -0.25 * E

        eps = 0.00

        epsx = 0
        epsy = 0
        epsz = 0

        A.P[0, :] = (1.999999, 0., 0.)
        A.P[1, :] = (0., 0., 0.)

        #A.P[:2:,:] = rng.uniform(low=-0.4999*E, high=0.4999*E, size=(N,3))

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.

    elif N == 8:
        for px in range(8):
            phi = (float(px) / 8) * 2. * math.pi
            pxr = 0.25 * E
            pxx = pxr * math.cos(phi)
            pxy = pxr * math.sin(phi)

            A.P[px, :] = (pxx, pxy, 0)
            A.Q[px, 0] = 1. - 2. * (px % 2)
            #A.Q[px, 0] = -1.

        #A.P[0,:] += eps

        eps = 0.00001
        #A.P[0:N:2,0] += eps
        #A.P[0,0] -= eps
        A.P[4, 0] -= eps
        A.P[:, 2] -= 0.200
        A.P[:, 1] -= 0.200

        #A.Q[0,0] = 0.
        A.Q[1, 0] = 0.
        A.Q[4, 0] = 0.
        A.Q[3, 0] = 0.
        A.Q[5, 0] = 0.
        A.Q[6, 0] = 0.
        A.Q[7, 0] = 0.

    else:
        assert N % 2 == 0
        for px in range(N // 2):
            pos = rng.uniform(low=-0.4999 * E, high=0.4999 * E, size=(1, 3))
            cha = rng.uniform(low=-1., high=1.)

            A.P[px, :] = pos
            A.Q[px, 0] = cha

            A.P[-1 * (px + 1), :] = -1.0 * pos
            A.Q[-1 * (px + 1), 0] = cha

        bias = np.sum(A.Q[:])
        A.Q[:, 0] -= bias / N

    dipole = np.zeros(3)
    for px in range(N):
        dipole[:] += A.P[px, :] * A.Q[px, 0]

    bias = np.sum(A.Q[:])

    print("DIPOLE:\t", dipole, "TOTAL CHARGE:\t", bias)

    A.scatter_data_from(0)

    print("boundary", A.domain.boundary)

    t0 = time.time()
    phi_py = fmm(A.P, A.Q, forces=A.F, execute_async=ASYNC)
    t1 = time.time()

    if MPIRANK == 0 and DEBUG:
        print("\n")
        #print(60*"-")
        #opt.print_profile()
        #print(60*"-")
        print("TIME FMM:\t", t1 - t0)
        print("ENERGY FMM:\t", phi_py)

    A.gather_data_on(0)
    if MPIRANK == 0:
        for px in range(N):

            print("PX:", px)
            print("\t\tFORCE FMM:", A.F[px, :])

    fmm.free()
Пример #2
0
def test_fmm_force_direct_3():

    R = 3
    L = 12
    free_space = True

    N = 2
    E = 4.
    rc = E / 4

    A = state.State()
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    ASYNC = False
    DIRECT = True if MPISIZE == 1 else False

    DIRECT = True
    EWALD = True

    fmm = PyFMM(domain=A.domain, r=R, eps=None, l=L, free_space=free_space)

    A.npart = N

    rng = np.random.RandomState(seed=1234)

    A.P = data.PositionDat(ncomp=3)
    A.F = data.ParticleDat(ncomp=3)
    A.FE = data.ParticleDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)

    A.crr = data.ScalarArray(ncomp=1)
    A.cri = data.ScalarArray(ncomp=1)
    A.crs = data.ScalarArray(ncomp=1)

    if N == 2:

        eps = 0.00

        epsx = 0
        epsy = 0
        epsz = 0

        A.P[0, :] = (-0.0001, 0.0001, 1.0001)
        A.P[1, :] = (-0.0001, 0.0001, -0.0001)

        A.Q[0, 0] = 1.
        A.Q[1, 0] = 1.

    A.scatter_data_from(0)

    t0 = time.time()
    #phi_py = fmm._test_call(A.P, A.Q, execute_async=ASYNC)
    phi_py = fmm(A.P, A.Q, forces=A.F, execute_async=ASYNC)
    t1 = time.time()

    direct_forces = np.zeros((N, 3))

    if DIRECT:
        #print("WARNING 0-th PARTICLE ONLY")
        phi_direct = 0.0

        # compute phi from image and surrounding 26 cells

        for ix in range(N):

            phi_part = 0.0
            for jx in range(ix + 1, N):
                rij = np.linalg.norm(A.P[jx, :] - A.P[ix, :])
                phi_direct += A.Q[ix, 0] * A.Q[jx, 0] / rij
                phi_part += A.Q[ix, 0] * A.Q[jx, 0] / rij

                direct_forces[ix,:] -= A.Q[ix, 0] * A.Q[jx, 0] * \
                                       (A.P[jx,:] - A.P[ix,:]) / (rij**3.)
                direct_forces[jx,:] += A.Q[ix, 0] * A.Q[jx, 0] * \
                                       (A.P[jx,:] - A.P[ix,:]) / (rij**3.)
            if free_space == '27':
                for ofx in cube_offsets:
                    cube_mid = np.array(ofx) * E
                    for jx in range(N):
                        rij = np.linalg.norm(A.P[jx, :] + cube_mid -
                                             A.P[ix, :])
                        phi_direct += 0.5 * A.Q[ix, 0] * A.Q[jx, 0] / rij
                        phi_part += 0.5 * A.Q[ix, 0] * A.Q[jx, 0] / rij

                        direct_forces[ix,:] -= A.Q[ix, 0] * A.Q[jx, 0] * \
                                           (A.P[jx,:] - A.P[ix,:] + cube_mid) \
                                               / (rij**3.)

    local_err = abs(phi_py - phi_direct)
    if local_err > eps: serr = red(local_err)
    else: serr = green(local_err)

    if MPIRANK == 0 and DEBUG:
        print("\n")
        #print(60*"-")
        #opt.print_profile()
        #print(60*"-")
        print("TIME FMM:\t", t1 - t0)
        print("ENERGY DIRECT:\t{:.20f}".format(phi_direct))
        print("ENERGY FMM:\t", phi_py)
        print("ERR:\t\t", serr)

    for px in range(N):
        cell = A._fmm_cell[px, 0]
        stride = fmm.tree_plain[0].shape[-1]
        ss = fmm.tree_plain[R - 1].shape[0:3:]

        cx = cell % ss[2]
        cy = ((cell - cx) // ss[2]) % ss[1]
        cz = (((cell - cx) // ss[2]) - cy) // ss[1]

        mom = fmm.tree_plain[fmm.R - 1][cz, cy, cx, :]
        mid = (0.5 * E / 2.**
               (R - 1)) * np.ones(3) + (E / 2.**(R - 1)) * np.array(
                   (cx, cy, cz)) - 0.5 * E * np.ones(3)

        disp_cart = A.P[px, :] - mid
        disp = spherical(disp_cart)

        print(cell, "|", cx, cy, cz, "|", mid)

        fpy = force_from_multipole(mom, fmm, disp.reshape(1, 3), A.Q[px, 0])

        err_re_c = red_tol(
            np.linalg.norm(direct_forces[px, :] - A.F[px, :], ord=np.inf),
            10.**-6)
        err_re_p = red_tol(
            np.linalg.norm(direct_forces[px, :] - fpy, ord=np.inf), 10.**-6)

        print("PX:", px)
        print("\t\tFORCE DIR :", direct_forces[px, :])
        print("\t\tFORCE FMMC:", A.F[px, :], err_re_c)
        print("\t\tFORCE py  :", fpy, err_re_p)

    fmm.free()
Пример #3
0
def test_fmm_force_ewald_1():

    R = 3
    eps = 10.**-8
    free_space = False

    N = 32
    E = 4.

    #N = 10000
    #E = 100.

    rc = E / 8

    A = state.State()
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    ASYNC = False

    CUDA = False

    fmm = PyFMM(domain=A.domain, r=R, l=22, free_space=free_space, cuda=CUDA)

    A.npart = N

    rng = np.random.RandomState(seed=1234)
    rng = np.random.RandomState(seed=95235)

    A.P = data.PositionDat(ncomp=3)
    A.F = data.ParticleDat(ncomp=3)
    A.FE = data.ParticleDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)

    A.crr = data.ScalarArray(ncomp=1)
    A.cri = data.ScalarArray(ncomp=1)
    A.crs = data.ScalarArray(ncomp=1)

    if N == 4:
        ra = 0.25 * E
        nra = -0.25 * E

        A.P[0, :] = (0.21, 0.21, 0.00)
        A.P[1, :] = (-0.21, 0.21, 0.00)
        A.P[2, :] = (-0.21, -0.21, 0.00)
        A.P[3, :] = (0.21, -0.21, 0.00)

        #A.P[0,:] = ( 0.00,  0.21, 0.21)
        #A.P[1,:] = ( 0.00,  0.21,-0.21)
        #A.P[2,:] = ( 0.00, -0.21,-0.21)
        #A.P[3,:] = ( 0.00, -0.21, 0.21)

        #A.P[0,:] = ( 1.01,  1.01, 0.00)
        #A.P[1,:] = (-1.01,  1.01, 0.00)
        #A.P[2,:] = (-1.01, -1.01, 0.00)
        #A.P[3,:] = ( 1.01, -1.01, 0.00)

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.
        A.Q[2, 0] = -1.
        A.Q[3, 0] = 1.

    elif N == 1:
        A.P[0, :] = (0.25 * E, 0.25 * E, 0.25 * E)
        A.P[0, :] = (10.**-6, 10.**-6, 10.**-6)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.

        A.Q[0, 0] = 1.

    elif N == 2:
        #A.P[0,:] = ( 0.25*E, 0.25*E, 0.25*E)
        #A.P[1,:] = ( -0.25*E, -0.25*E, 0)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.
        ra = 0.25 * E
        nra = -0.25 * E

        epsx = 0
        epsy = 0
        epsz = 0

        A.P[0, :] = (0.001, 0.001, 1.001)
        A.P[1, :] = (0.001, 0.001, -1.001)

        #A.P[:2:,:] = rng.uniform(low=-0.4999*E, high=0.4999*E, size=(N,3))

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.

    elif N == 8:
        for px in range(8):
            phi = (float(px) / 8) * 2. * math.pi
            pxr = 0.25 * E
            pxx = pxr * math.cos(phi)
            pxy = pxr * math.sin(phi)

            A.P[px, :] = (pxx, pxy, 0)
            A.Q[px, 0] = 1. - 2. * (px % 2)
            #A.Q[px, 0] = -1.

        #A.P[0,:] += eps

        #A.P[0:N:2,0] += eps
        #A.P[0,0] -= eps
        A.P[4, 0] -= eps
        A.P[:, 2] -= 0.200
        A.P[:, 1] -= 0.200

        #A.Q[0,0] = 0.
        A.Q[1, 0] = 0.
        A.Q[4, 0] = 0.
        A.Q[3, 0] = 0.
        A.Q[5, 0] = 0.
        A.Q[6, 0] = 0.
        A.Q[7, 0] = 0.

    else:
        assert N % 2 == 0
        for px in range(N // 2):
            pos = rng.uniform(low=-0.4999 * E, high=0.4999 * E, size=(1, 3))
            cha = rng.uniform(low=-1., high=1.)

            A.P[px, :] = pos
            A.Q[px, 0] = cha

            A.P[-1 * (px + 1), :] = -1.0 * pos
            A.Q[-1 * (px + 1), 0] = cha

        bias = np.sum(A.Q[:])
        A.Q[:, 0] -= bias / N

    dipole = np.zeros(3)
    for px in range(N):
        dipole[:] += A.P[px, :] * A.Q[px, 0]

    bias = np.sum(A.Q[:])

    Q = np.sum(np.abs(A.Q[:N:, 0]))

    A.scatter_data_from(0)

    t0 = time.time()
    phi_py = fmm(A.P, A.Q, forces=A.F, execute_async=ASYNC)
    t1 = time.time()

    ewald = EwaldOrthoganalHalf(domain=A.domain,
                                real_cutoff=rc,
                                eps=eps,
                                shared_memory=SHARED_MEMORY)

    t2 = time.time()
    ewald.evaluate_contributions(positions=A.P, charges=A.Q)
    A.cri[0] = 0.0
    ewald.extract_forces_energy_reciprocal(A.P, A.Q, A.FE, A.cri)
    A.crr[0] = 0.0
    ewald.extract_forces_energy_real(A.P, A.Q, A.FE, A.crr)
    A.crs[0] = 0.0
    ewald.evaluate_self_interactions(A.Q, A.crs)

    t3 = time.time()

    phi_ewald = A.cri[0] + A.crr[0] + A.crs[0]

    local_err = abs(phi_py - phi_ewald) / Q
    if local_err > eps: serr = red(local_err)
    else: serr = green(local_err)

    for px in range(A.npart_local):

        assert np.linalg.norm(A.FE[px, :] - A.F[px, :], ord=np.inf) < 10.**-6

    if MPIRANK == 0 and DEBUG:
        print("\n")
        #print(60*"-")
        #opt.print_profile()
        #print(60*"-")
        print("TIME EWALD:\t", t3 - t2)
        print("TIME FMM:\t", t1 - t0)
        print("ENERGY EWALD:\t{:.20f}".format(phi_ewald))
        print("ENERGY FMM:\t", phi_py)
        print("ERR:\t\t", serr)

    # run the same again
    A.F[:] = 0.0
    t0 = time.time()
    phi_py = fmm(A.P, A.Q, forces=A.F, execute_async=ASYNC)
    t1 = time.time()

    local_err = abs(phi_py - phi_ewald) / Q
    if local_err > eps: serr = red(local_err)
    else: serr = green(local_err)

    A.gather_data_on(0)
    if MPIRANK == 0:
        for px in range(N):

            err_re_c = red_tol(
                np.linalg.norm(A.FE[px, :] - A.F[px, :], ord=np.inf), 10.**-6)

            assert np.linalg.norm(A.FE[px, :] - A.F[px, :],
                                  ord=np.inf) < 10.**-6

    if MPIRANK == 0 and DEBUG:
        print("TIME FMM:\t", t1 - t0)
        print("ENERGY FMM:\t", phi_py)
        print("ERR:\t\t", serr)

    fmm.free()
Пример #4
0
def test_fmm_force_direct_1():

    R = 3
    eps = 10.**-6
    free_space = '27'

    N = 4
    E = 4.
    rc = E / 4

    A = state.State()
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    ASYNC = False
    DIRECT = True if MPISIZE == 1 else False

    DIRECT = True
    EWALD = True

    fmm = PyFMM(domain=A.domain, r=R, eps=eps, free_space=free_space)

    A.npart = N

    rng = np.random.RandomState(seed=1234)

    A.P = data.PositionDat(ncomp=3)
    A.F = data.ParticleDat(ncomp=3)
    A.FE = data.ParticleDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)

    A.crr = data.ScalarArray(ncomp=1)
    A.cri = data.ScalarArray(ncomp=1)
    A.crs = data.ScalarArray(ncomp=1)

    if N == 4:
        ra = 0.25 * E
        nra = -0.25 * E

        A.P[0, :] = (1.01, 1.01, 0.0)
        A.P[1, :] = (-1.01, 1.01, 0.0)
        A.P[2, :] = (-1.01, -1.01, 0.0)
        A.P[3, :] = (1.01, -1.01, 0.0)

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.
        A.Q[2, 0] = -1.
        A.Q[3, 0] = 1.

    elif N == 1:
        A.P[0, :] = (0.25 * E, 0.25 * E, 0.25 * E)
        A.P[0, :] = (10.**-6, 10.**-6, 10.**-6)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.

        A.Q[0, 0] = 1.

    elif N == 2:
        #A.P[0,:] = ( 0.25*E, 0.25*E, 0.25*E)
        #A.P[1,:] = ( -0.25*E, -0.25*E, 0)

        #A.P[0,:] = (0, -0.25*E, 0)
        #A.P[1,:] = (0, 0.25*E, 0)
        #A.P[0,:] = (0, 0, -0.25*E)
        #A.P[1,:] = (0, 0, 0.25*E)

        #A.Q[:,0] = 1.
        ra = 0.25 * E
        nra = -0.25 * E

        eps = 0.00

        epsx = 0
        epsy = 0
        epsz = 0

        A.P[0, :] = (1.000, 0.001, 0.001)
        A.P[1, :] = (-1.001, 0.001, 0.001)

        #A.P[:2:,:] = rng.uniform(low=-0.4999*E, high=0.4999*E, size=(N,3))

        A.Q[0, 0] = -1.
        A.Q[1, 0] = 1.

    elif N == 8:
        for px in range(8):
            phi = (float(px) / 8) * 2. * math.pi
            pxr = 0.25 * E
            pxx = pxr * math.cos(phi)
            pxy = pxr * math.sin(phi)

            A.P[px, :] = (pxx, pxy, 0)
            A.Q[px, 0] = 1. - 2. * (px % 2)
            #A.Q[px, 0] = -1.

        #A.P[0,:] += eps

        eps = 0.00001
        #A.P[0:N:2,0] += eps
        #A.P[0,0] -= eps
        A.P[4, 0] -= eps
        A.P[:, 2] -= 0.200
        A.P[:, 1] -= 0.200

        #A.Q[0,0] = 0.
        A.Q[1, 0] = 0.
        A.Q[4, 0] = 0.
        A.Q[3, 0] = 0.
        A.Q[5, 0] = 0.
        A.Q[6, 0] = 0.
        A.Q[7, 0] = 0.

    else:
        assert N % 2 == 0
        for px in range(N // 2):
            pos = rng.uniform(low=-0.4999 * E, high=0.4999 * E, size=(1, 3))
            cha = rng.uniform(low=-1., high=1.)

            A.P[px, :] = pos
            A.Q[px, 0] = cha

            A.P[-1 * (px + 1), :] = -1.0 * pos
            A.Q[-1 * (px + 1), 0] = cha

        bias = np.sum(A.Q[:])
        A.Q[:, 0] -= bias / N

        dipole = np.zeros(3)
        for px in range(N):
            dipole[:] += A.P[px, :] * A.Q[px, 0]

        bias = np.sum(A.Q[:])

        print("DIPOLE:\t", dipole, "TOTAL CHARGE:\t", bias)

    A.scatter_data_from(0)

    t0 = time.time()
    #phi_py = fmm._test_call(A.P, A.Q, execute_async=ASYNC)
    phi_py = fmm(A.P, A.Q, forces=A.F, execute_async=ASYNC)
    t1 = time.time()

    direct_forces = np.zeros((N, 3))

    if DIRECT:
        #print("WARNING 0-th PARTICLE ONLY")
        phi_direct = 0.0

        # compute phi from image and surrounding 26 cells

        for ix in range(N):

            phi_part = 0.0
            for jx in range(ix + 1, N):
                rij = np.linalg.norm(A.P[jx, :] - A.P[ix, :])
                phi_direct += A.Q[ix, 0] * A.Q[jx, 0] / rij
                phi_part += A.Q[ix, 0] * A.Q[jx, 0] / rij

                direct_forces[ix,:] -= A.Q[ix, 0] * A.Q[jx, 0] * \
                                       (A.P[jx,:] - A.P[ix,:]) / (rij**3.)
                direct_forces[jx,:] += A.Q[ix, 0] * A.Q[jx, 0] * \
                                       (A.P[jx,:] - A.P[ix,:]) / (rij**3.)
            if free_space == '27':
                for ofx in cube_offsets:
                    cube_mid = np.array(ofx) * E
                    for jx in range(N):
                        rij = np.linalg.norm(A.P[jx, :] + cube_mid -
                                             A.P[ix, :])
                        phi_direct += 0.5 * A.Q[ix, 0] * A.Q[jx, 0] / rij
                        phi_part += 0.5 * A.Q[ix, 0] * A.Q[jx, 0] / rij

                        direct_forces[ix,:] -= A.Q[ix, 0] * A.Q[jx, 0] * \
                                           (A.P[jx,:] - A.P[ix,:] + cube_mid) \
                                               / (rij**3.)

    local_err = abs(phi_py - phi_direct)
    if local_err > eps: serr = red(local_err)
    else: serr = green(local_err)

    if MPIRANK == 0 and DEBUG:
        print("\n")
        #print(60*"-")
        #opt.print_profile()
        #print(60*"-")
        print("TIME FMM:\t", t1 - t0)
        print("ENERGY DIRECT:\t{:.20f}".format(phi_direct))
        print("ENERGY FMM:\t", phi_py)
        print("ERR:\t\t", serr)

    for px in range(N):

        err_re_c = red_tol(
            np.linalg.norm(direct_forces[px, :] - A.F[px, :], ord=np.inf),
            10.**-6)

        print("PX:", px)
        print("\t\tFORCE DIR :", direct_forces[px, :])
        print("\t\tFORCE FMMC:", A.F[px, :], err_re_c)

    fmm.free()
Пример #5
0
def test_fmm_sim_1():

    input_data = np.load(get_res_file_path('coulomb/CO2cuboid.npy'))
    N = input_data.shape[0]

    E = 50.

    A = state.State()
    A.npart = N
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    eps = 10.**-6

    fmm = PyFMM(domain=A.domain, r=3, N=N, eps=eps, free_space=True)

    A.P = data.PositionDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)

    if MPIRANK == 0:
        A.P[:] = input_data[:, 0:3:]
        A.Q[:, 0] = input_data[:, 3]
    A.scatter_data_from(0)

    if MPISIZE == 1:
        # compute potential energy to point across all charges directly
        P2 = data.PositionDat(npart=N, ncomp=3)
        Q2 = data.ParticleDat(npart=N, ncomp=1)
        P2[:, :] = A.P[:N:, :]
        Q2[:, :] = A.Q[:N:, :]
        phi_ga = data.ScalarArray(ncomp=1, dtype=ctypes.c_double)
        src = """
        const double d0 = P.j[0] - P.i[0];
        const double d1 = P.j[1] - P.i[1];
        const double d2 = P.j[2] - P.i[2];
        phi[0] += 0.5 * Q.i[0] * Q.j[0] / sqrt(d0*d0 + d1*d1 + d2*d2);
        """
        phi_kernel = kernel.Kernel('all_to_all_phi',
                                   src,
                                   headers=(kernel.Header('math.h'), ))

        phi_loop = pairloop.AllToAllNS(kernel=phi_kernel,
                                       dat_dict={
                                           'P': P2(access.READ),
                                           'Q': Q2(access.READ),
                                           'phi': phi_ga(access.INC_ZERO)
                                       })
        phi_loop.execute()
        phi_direct = phi_ga[0]
    else:
        phi_direct = None

    t0 = time.time()
    phi_fmm = fmm(A.P, A.Q)
    t1 = time.time()

    if DEBUG and MPIRANK == 0:
        print("Time:", t1 - t0)
        print("MPISIZE", MPISIZE)
        print("phi_fmm", phi_fmm)
        if MPISIZE == 1:
            print("phi_direct: {:.30f}".format(phi_direct))
            print("phi_fmm", phi_fmm)
            print("ERROR:", abs(phi_direct - phi_fmm))

    fmm.free()
Пример #6
0
def test_fmm_init_2_1():

    E = 20.

    A = state.State()
    A.domain = domain.BaseDomainHalo(extent=(E, E, E))
    A.domain.boundary_condition = domain.BoundaryTypePeriodic()

    eps = 10.**-3

    fmm = PyFMM(domain=A.domain, r=3, eps=eps, free_space=True)

    ncubeside = 2**(fmm.R - 1)
    N = ncubeside**3
    N = 100
    A.npart = N

    rng = np.random.RandomState(seed=1234)
    #rng = np.random

    A.P = data.PositionDat(ncomp=3)
    A.Q = data.ParticleDat(ncomp=1)
    A.U = data.ParticleDat(ncomp=1)
    A.F = data.ParticleDat(ncomp=3)

    A.P[:] = rng.uniform(low=-0.5 * E, high=0.5 * E, size=(N, 3))

    A.Q[:] = rng.uniform(low=-0.5 * E, high=0.5 * E, size=(N, 1))

    bias = np.sum(A.Q[:]) / N
    A.Q[:] -= bias

    #A.Q[:] = 1.0
    #A.Q[0:-2] = 0.0

    #A.P[2,:] = (-7.5, -7.5,  2.5)
    #A.Q[2, 0] = -1.

    #A.P[0,:] = (-6., 2., -1.)
    #A.P[1,:] = (5.000000001, 5.000000001, -4.5)
    #A.Q[0, 0] = 1.0
    #A.Q[1, 0] = -1.0

    A.scatter_data_from(0)

    maxt = 5
    for tx in itertools.product(range(-1 * maxt, maxt + 1),
                                range(-1 * maxt, maxt + 1),
                                range(-1 * maxt, maxt + 1)):

        dispt = (tx[0] * E, tx[1] * E, tx[2] * E)
        dispt_sph = spherical(dispt)
        dispt_fmm = fmm._image_to_sph(tx)
        assert abs(dispt_sph[0] - dispt_fmm[0]) < 10.**-16, "bad radius"
        assert abs(dispt_sph[2] - dispt_fmm[1]) < 10.**-16, "bad phi"
        assert abs(dispt_sph[1] - dispt_fmm[2]) < 10.**-16, "bad theta"

    fmm._check_aux_dat(A.P)
    fmm._compute_cube_contrib(A.P, A.Q, A._fmm_cell)

    # compute potential energy to point across all charges directly
    P2 = data.PositionDat(npart=N, ncomp=3)
    Q2 = data.ParticleDat(npart=N, ncomp=1)
    U2 = data.ParticleDat(npart=N, ncomp=1)
    P2[:, :] = A.P[:N:, :]
    Q2[:, :] = A.Q[:N:, :]
    phi_ga = data.ScalarArray(ncomp=1, dtype=ctypes.c_double)

    src = """
    const double d0 = P.j[0] - P.i[0];
    const double d1 = P.j[1] - P.i[1];
    const double d2 = P.j[2] - P.i[2];
    const double contrib = Q.i[0] * Q.j[0] / sqrt(d0*d0 + d1*d1 + d2*d2);
    phi[0] += 0.5 * contrib;
    U.i[0] += contrib;
    """
    phi_kernel = kernel.Kernel('all_to_all_phi',
                               src,
                               headers=(kernel.Header('math.h'), ))

    phi_loop = pairloop.AllToAllNS(kernel=phi_kernel,
                                   dat_dict={
                                       'P': P2(access.READ),
                                       'Q': Q2(access.READ),
                                       'phi': phi_ga(access.INC_ZERO),
                                       'U': U2(access.INC_ZERO)
                                   })
    phi_loop.execute()

    if DEBUG:
        phi_py = 0.0
        for ix in range(N):
            for jx in range(ix + 1, N):
                r2 = np.linalg.norm(A.P[jx, :] - A.P[ix, :])
                phi_py += A.Q[ix, 0] * A.Q[jx, 0] / r2

        print("Direct", phi_ga[0], phi_py)

    extent = A.domain.extent
    cube_ilen = 2**(fmm.R - 1) / extent[:]
    cube_half_len = 0.5 * extent[:] / (2**(fmm.R - 1))
    shift_pos = A.P[:] + 0.5 * extent[:]
    shift_pos[:, 0] = shift_pos[:, 0] * cube_ilen[0]
    shift_pos[:, 1] = shift_pos[:, 1] * cube_ilen[1]
    shift_pos[:, 2] = shift_pos[:, 2] * cube_ilen[2]
    shift_pos = np.array(shift_pos, dtype='int')

    phi_local = fmm._compute_local_interaction(A.P, A.Q)
    #print("phi_local:", phi_local)
    #print("------------------------------------------------")
    phi_local_pair = fmm._compute_local_interaction_pairloop(A.P, A.Q)
    #print("correct  :", phi_local)

    assert abs(phi_local - phi_local_pair) < 10.**-12

    level = fmm.R - 1

    phi_sph_re = 0.0
    phi_sph_im = 0.0

    lsize = fmm.tree_plain[level][:, :, :, 0].shape

    sep = A.domain.extent[0] / float(2.**level)
    start_point = -0.5 * E + 0.5 * sep

    for px in range(N):
        point = A.P[px, :]
        charge = A.Q[px, 0]
        if DEBUG:
            print(px, point, charge, shift_pos[px, :])
        cubex = shift_pos[px, :]

        for momx in itertools.product(range(lsize[0]), range(lsize[1]),
                                      range(lsize[2])):

            dist = ((momx[2] - cubex[0])**2 + (momx[1] - cubex[1])**2 +
                    (momx[0] - cubex[2])**2)
            if dist > 3:

                center = np.array((start_point + (momx[2]) * sep,
                                   start_point + (momx[1]) * sep,
                                   start_point + (momx[0]) * sep))

                disp = point - center
                moments = fmm.tree_halo[level][momx[0] + 2, momx[1] + 2,
                                               momx[2] + 2, :]
                disp_sph = spherical(np.reshape(disp, (1, 3)))

                phi_sph_re1, phi_sph_im1 = compute_phi(fmm.L, moments,
                                                       disp_sph)
                phi_sph_re += phi_sph_re1 * charge * 0.5
                phi_sph_im += phi_sph_im1 * charge * 0.5

    if DEBUG:
        print("direct:", phi_ga[0])
        print("multipole:", phi_sph_re + phi_local, "local:", phi_local,
              "expansions:", phi_sph_re)
    assert abs(phi_ga[0] - phi_sph_re - phi_local) < eps, "bad real part"

    phi_py2 = fmm(A.P, A.Q, forces=A.F, potential=A.U)

    for px in range(A.npart_local):
        assert abs(U2[px, 0] - A.U[px, 0]) < eps

    fmm.free()
Пример #7
0
 def _direct():
     _phi_direct = fmm(positions=B.P, charges=B.Q)
     return _phi_direct