Пример #1
0
def dx(u, FST, axis=0):
    """Compute integral of u over domain for channel solvers"""
    sx = list(range(3))
    sx.pop(axis)
    uu = np.sum(u, axis=tuple(sx))
    sl = FST.local_slice(False)[axis]
    M = FST.shape()[axis]
    c = aligned(M, fill=0)
    cc = aligned(M, fill=0)
    cc[sl] = uu
    FST.comm.Reduce(cc, c, op=MPI.SUM, root=0)
    quad = FST.bases[axis].quad
    if FST.comm.Get_rank() == 0:
        if quad == 'GL':
            ak = aligned_like(c)
            dct = dctn(aligned_like(c), axes=(0, ), type=1)
            ak = dct(c, ak)
            ak /= (M - 1)
            w = np.arange(0, M, 1, dtype=float)
            w[2:] = 2. / (1 - w[2:]**2)
            w[0] = 1
            w[1::2] = 0
            return sum(ak * w) * np.prod(
                np.take(config.params.L / config.params.N, sx))

        assert quad == 'GC'
        d = aligned(M, fill=0)
        k = 2 * (1 + np.arange((M - 1) // 2))
        d[::2] = (2. / M) / np.hstack((1., 1. - k * k))
        w = aligned_like(d)
        dct = dctn(w, axes=(0, ), type=3)
        w = dct(d, w)
        return np.sum(c * w) * np.prod(
            np.take(config.params.L / config.params.N, sx))
    return 0
Пример #2
0
def dx(u, FST, axis=0):
    """Compute integral of u over domain for channel solvers"""
    sx = list(range(3))
    sx.pop(axis)
    uu = np.sum(u, axis=tuple(sx))
    sl = FST.local_slice(False)[axis]
    M = FST.shape()[axis]
    c = aligned(M, fill=0)
    cc = aligned(M, fill=0)
    cc[sl] = uu
    FST.comm.Reduce(cc, c, op=MPI.SUM, root=0)
    quad = FST.bases[axis].quad
    if FST.comm.Get_rank() == 0:
        if quad == 'GL':
            ak = aligned_like(c)
            dct = dctn(aligned_like(c), axes=(0,), type=1)
            ak = dct(c, ak)
            ak /= (M-1)
            w = np.arange(0, M, 1, dtype=float)
            w[2:] = 2./(1-w[2:]**2)
            w[0] = 1
            w[1::2] = 0
            return sum(ak*w)*np.prod(np.take(config.params.L/config.params.N, sx))

        assert quad == 'GC'
        d = aligned(M, fill=0)
        k = 2*(1 + np.arange((M-1)//2))
        d[::2] = (2./M)/np.hstack((1., 1.-k*k))
        w = aligned_like(d)
        dct = dctn(w, axes=(0,), type=3)
        w = dct(d, w)
        return np.sum(c*w)*np.prod(np.take(config.params.L/config.params.N, sx))
    return 0
Пример #3
0
def test_r2r():
    N = (5, 6, 7, 8, 9)
    assert MPI.COMM_WORLD.Get_size() < 6
    dctn = functools.partial(fftw.dctn, type=3)
    idctn = functools.partial(fftw.idctn, type=3)
    dstn = functools.partial(fftw.dstn, type=3)
    idstn = functools.partial(fftw.idstn, type=3)
    fft = PFFT(MPI.COMM_WORLD, N, axes=((0,), (1, 2), (3, 4)), grid=(-1,),
               transforms={(1, 2): (dctn, idctn), (3, 4): (dstn, idstn)})

    A = newDistArray(fft, forward_output=False)
    A[:] = np.random.random(A.shape)
    C = fftw.aligned_like(A)
    B = fft.forward(A)
    C = fft.backward(B, C)
    assert np.allclose(A, C)
Пример #4
0
def main(N, alpha, method, tau):
    # Bases
    c = coords.Coordinate('x')
    d = distributor.Distributor((c,))
    xb = basis.ChebyshevT(c, size=N, bounds=(-1, 1))
    x = xb.local_grid(1)
    # Fields
    u = field.Field(name='u', dist=d, bases=(xb,), dtype=np.float64)
    ux = field.Field(name='ux', dist=d, bases=(xb,), dtype=np.float64)
    f = field.Field(name='f', dist=d, bases=(xb,), dtype=np.float64)
    t1 = field.Field(name='t1', dist=d, dtype=np.float64)
    t2 = field.Field(name='t2', dist=d, dtype=np.float64)
    pi, sin, cos = np.pi, np.sin, np.cos
    f['g'] = 64*pi**3*(4*pi*sin(4*pi*x)**2*sin(4*pi*cos(4*pi*x)) + cos(4*pi*x)*cos(4*pi*cos(4*pi*x))) + alpha*sin(4*pi*cos(4*pi*x))
    # Tau polynomials
    xb1 = xb._new_a_b(xb.a+1, xb.b+1)
    xb2 = xb._new_a_b(xb.a+2, xb.b+2)
    if tau == 0:
        # First-order classical Chebyshev tau: T[-1], dx(T[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    elif tau == 1:
        # First-order ultraspherical tau: U[-1], dx(U[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb1,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb1,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    # Problem
    dx = lambda A: operators.Differentiate(A, c)
    problem = problems.LBVP([u, ux, t1, t2])
    problem.add_equation((alpha*u - dx(ux) + t1*p1, f))
    problem.add_equation((ux - dx(u) + t2*p2, 0))
    problem.add_equation((u(x=-1), 0))
    problem.add_equation((u(x=+1), 0))
    solver = solvers.LinearBoundaryValueSolver(problem)
    # Methods
    if method == 0:
        # Condition number
        L_exp = solver.subproblems[0].L_exp
        result = np.linalg.cond(L_exp.A)
    elif method == 1:
        # Roundtrip roundoff with uniform u
        A = solver.subproblems[0].L_exp
        v = np.random.rand(A.shape[1])
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    elif method == 2:
        # Manufactured solution
        from mpi4py_fft import fftw as mpi4py_fftw
        solver.solve()
        ue = np.sin(4*np.pi*np.cos(4*np.pi*x))
        d = mpi4py_fftw.aligned(N, fill=0)
        k = 2*(1 + np.arange((N-1)//2))
        d[::2] = (2./N)/np.hstack((1., 1.-k*k))
        w = mpi4py_fftw.aligned_like(d)
        dct = mpi4py_fftw.dctn(w, axes=(0,), type=3)
        weights = dct(d, w)
        result = np.sqrt(np.sum(weights*(u['g']-ue)**2))
    elif method == 3:
        # Roundtrip roundoff with uniform f
        A = solver.subproblems[0].L_exp
        g = np.random.rand(A.shape[0])
        v = solver.subproblem_matsolvers[solver.subproblems[0]].solve(g)
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    return result