Beispiel #1
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    assert params.Dquad == params.Bquad
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    ST = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
    SB = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
    CT = Basis(params.N[2], 'C', quad=params.Dquad)
    ST0 = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad) # For 1D problem
    K0 = Basis(params.N[0], 'F', domain=(0, params.L[0]), dtype='D')
    K1 = Basis(params.N[1], 'F', domain=(0, params.L[1]), dtype='d')

    kw0 = {'threads':params.threads,
           'planner_effort':params.planner_effort["dct"],
           'slab': (params.decomposition == 'slab'),
           'collapse_fourier': collapse_fourier}
    FST = TensorProductSpace(comm, (K0, K1, ST), axes=(2, 0, 1), **kw0)    # Dirichlet
    FSB = TensorProductSpace(comm, (K0, K1, SB), axes=(2, 0, 1), **kw0)    # Biharmonic
    FCT = TensorProductSpace(comm, (K0, K1, CT), axes=(2, 0, 1), **kw0)    # Regular Chebyshev
    VFS = MixedTensorProductSpace([FST, FST, FSB])
    VFST = MixedTensorProductSpace([FST, FST, FST])
    VUG = MixedTensorProductSpace([FST, FSB])

    # Padded
    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
        SBp = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
        CTp = Basis(params.N[2], 'C', quad=params.Dquad)
    else:
        STp, SBp, CTp = ST, SB, CT
    K0p = Basis(params.N[0], 'F', dtype='D', domain=(0, params.L[0]), **kw)
    K1p = Basis(params.N[1], 'F', dtype='d', domain=(0, params.L[1]), **kw)
    FSTp = TensorProductSpace(comm, (K0p, K1p, STp), axes=(2, 0, 1), **kw0)
    FSBp = TensorProductSpace(comm, (K0p, K1p, SBp), axes=(2, 0, 1), **kw0)
    FCTp = TensorProductSpace(comm, (K0p, K1p, CTp), axes=(2, 0, 1), **kw0)
    VFSp = MixedTensorProductSpace([FSTp, FSTp, FSBp])

    Nu = params.N[2]-2   # Number of velocity modes in Shen basis
    Nb = params.N[2]-4   # Number of velocity modes in Shen biharmonic basis
    u_slice = slice(0, Nu)
    v_slice = slice(0, Nb)

    float, complex, mpitype = datatypes("double")

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    U = Array(VFS)
    U0 = Array(VFS)
    U_hat = Function(VFS)
    U_hat0 = Function(VFS)
    g = Function(FST)

    # primary variable
    u = (U_hat, g)

    H_hat = Function(VFST)
    H_hat0 = Function(VFST)
    H_hat1 = Function(VFST)

    dU = Function(VUG)
    hv = Function(FST)
    hg = Function(FST)
    Source = Array(VFS)
    Sk = Function(VFS)

    K2 = K[0]*K[0]+K[1]*K[1]
    K4 = K2**2

    # Set Nyquist frequency to zero on K that is used for odd derivatives in nonlinear terms
    Kx = FST.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    K_over_K2 = np.zeros((2,)+g.shape)
    for i in range(2):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    work = work_arrays()
    u_dealias = Array(VFSp)
    u0_hat = np.zeros((2, params.N[2]), dtype=complex)
    h0_hat = np.zeros((2, params.N[2]), dtype=complex)
    w = np.zeros((params.N[2], ), dtype=complex)
    w1 = np.zeros((params.N[2], ), dtype=complex)

    nu, dt, N = params.nu, params.dt, params.N

    # Collect all matrices
    mat = config.AttributeDict(
        dict(CDD=inner_product((ST, 0), (ST, 1)),
             CTD=inner_product((CT, 0), (ST, 1)),
             BTT=inner_product((CT, 0), (CT, 0)),
             AB=HelmholtzCoeff(N[2], 1.0, -(K2 - 2.0/nu/dt), 2, ST.quad),
             AC=BiharmonicCoeff(N[2], nu*dt/2., (1. - nu*dt*K2), -(K2 - nu*dt/2.*K4), 2, SB.quad),
             # Matrices for biharmonic equation
             CBD=inner_product((SB, 0), (ST, 1)),
             ABB=inner_product((SB, 0), (SB, 2)),
             BBB=inner_product((SB, 0), (SB, 0)),
             SBB=inner_product((SB, 0), (SB, 4)),
             # Matrices for Helmholtz equation
             ADD=inner_product((ST, 0), (ST, 2)),
             BDD=inner_product((ST, 0), (ST, 0)),
             BBD=inner_product((SB, 0), (ST, 0)),
             CDB=inner_product((ST, 0), (SB, 1)),
             ADD0=inner_product((ST0, 0), (ST0, 2)),
             BDD0=inner_product((ST0, 0), (ST0, 0))))

    la = config.AttributeDict(
        dict(HelmholtzSolverG=Helmholtz(mat.ADD, mat.BDD, -np.ones((1, 1, 1)),
                                        (K2+2.0/nu/dt)),
             BiharmonicSolverU=Biharmonic(mat.SBB, mat.ABB, mat.BBB, -nu*dt/2.*np.ones((1, 1, 1)),
                                          (1.+nu*dt*K2),
                                          (-(K2 + nu*dt/2.*K4))),
             HelmholtzSolverU0=Helmholtz(mat.ADD0, mat.BDD0, np.array([-1.]), np.array([2./nu/dt])),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0)))))

    hdf5file = KMMFile(config.params.solver,
                       checkpoint={'space': VFS,
                                   'data': {'0': {'U': [U_hat]},
                                            '1': {'U': [U_hat0]}}},
                       results={'space': VFS,
                                'data': {'U': [U]}})

    return config.AttributeDict(locals())
Beispiel #2
0
# Solve and transform to real space
u_hat = Function(T)           # Solution spectral space
u_hat = H(u_hat, f_hat)       # Solve
uq = T.backward(u_hat)

# Compare with analytical solution
uj = Array(T, buffer=ue)
print(abs(uj-uq).max())
assert np.allclose(uj, uq)
c = H.matvec(u_hat, Function(T))
assert np.allclose(c, f_hat)

if 'pytest' not in os.environ:
    import matplotlib.pyplot as plt
    plt.figure()
    X = T.local_mesh(True) # With broadcasting=True the shape of X is local_shape, even though the number of datapoints are still the same as in 1D
    plt.contourf(X[0], X[1], uq)
    plt.colorbar()

    plt.figure()
    plt.contourf(X[0], X[1], uj)
    plt.colorbar()

    plt.figure()
    plt.contourf(X[0], X[1], uq-uj)
    plt.colorbar()
    plt.title('Error')

    plt.show()
Beispiel #3
0
def get_context():
    """Set up context for classical (NS) solver"""
    float, complex, mpitype = datatypes(params.precision)
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    dim = len(params.N)
    dtype = lambda d: float if d == dim-1 else complex
    V = [Basis(params.N[i], 'F', domain=(0, params.L[i]),
               dtype=dtype(i)) for i in range(dim)]

    kw0 = {'threads': params.threads,
           'planner_effort': params.planner_effort['fft']}
    T = TensorProductSpace(comm, V, dtype=float,
                           slab=(params.decomposition == 'slab'),
                           collapse_fourier=collapse_fourier, **kw0)
    VT = VectorTensorProductSpace(T)

    # Different bases for nonlinear term, either 2/3-rule or 3/2-rule
    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}

    Vp = [Basis(params.N[i], 'F', domain=(0, params.L[i]),
                dtype=dtype(i), **kw) for i in range(dim)]

    Tp = TensorProductSpace(comm, Vp, dtype=float,
                            slab=(params.decomposition == 'slab'),
                            collapse_fourier=collapse_fourier, **kw0)
    VTp = VectorTensorProductSpace(Tp)

    # Mesh variables
    X = T.local_mesh(True)
    K = T.local_wavenumbers(scaled=True)
    for i in range(dim):
        X[i] = X[i].astype(float)
        K[i] = K[i].astype(float)
    K2 = np.zeros(T.shape(True), dtype=float)
    for i in range(dim):
        K2 += K[i]*K[i]

    # Set Nyquist frequency to zero on K that is, from now on, used for odd derivatives
    Kx = T.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    for i in range(dim):
        Kx[i] = Kx[i].astype(float)

    K_over_K2 = np.zeros(VT.shape(True), dtype=float)
    for i in range(dim):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    # Velocity and pressure. Use ndarray view for efficiency
    U = Array(VT)
    U_hat = Function(VT)
    P = Array(T)
    P_hat = Function(T)
    u_dealias = Array(VTp)

    # Primary variable
    u = U_hat

    # RHS array
    dU = Function(VT)
    curl = Array(VT)
    Source = Function(VT) # Possible source term initialized to zero
    work = work_arrays()

    hdf5file = NSFile(config.params.solver,
                      checkpoint={'space': VT,
                                  'data': {'0': {'U': [U_hat]}}},
                      results={'space': VT,
                               'data': {'U': [U], 'P': [P]}})

    return config.AttributeDict(locals())
Beispiel #4
0
def get_context():
    """Set up context for classical (NS) solver"""
    float, complex, mpitype = datatypes(params.precision)
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    dim = len(params.N)
    dtype = lambda d: float if d == dim - 1 else complex
    V = [
        Basis(params.N[i], 'F', domain=(0, params.L[i]), dtype=dtype(i))
        for i in range(dim)
    ]

    kw0 = {
        'threads': params.threads,
        'planner_effort': params.planner_effort['fft']
    }
    T = TensorProductSpace(comm,
                           V,
                           dtype=float,
                           slab=(params.decomposition == 'slab'),
                           collapse_fourier=collapse_fourier,
                           **kw0)
    VT = VectorTensorProductSpace(T)

    # Different bases for nonlinear term, either 2/3-rule or 3/2-rule
    kw = {
        'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
        'dealias_direct': params.dealias == '2/3-rule'
    }

    Vp = [
        Basis(params.N[i], 'F', domain=(0, params.L[i]), dtype=dtype(i), **kw)
        for i in range(dim)
    ]

    Tp = TensorProductSpace(comm,
                            Vp,
                            dtype=float,
                            slab=(params.decomposition == 'slab'),
                            collapse_fourier=collapse_fourier,
                            **kw0)
    VTp = VectorTensorProductSpace(Tp)

    mask = T.get_mask_nyquist() if params.mask_nyquist else None

    # Mesh variables
    X = T.local_mesh(True)
    K = T.local_wavenumbers(scaled=True)
    for i in range(dim):
        X[i] = X[i].astype(float)
        K[i] = K[i].astype(float)
    K2 = np.zeros(T.shape(True), dtype=float)
    for i in range(dim):
        K2 += K[i] * K[i]

    K_over_K2 = np.zeros(VT.shape(True), dtype=float)
    for i in range(dim):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    # Velocity and pressure. Use ndarray view for efficiency
    U = Array(VT)
    U_hat = Function(VT)
    P = Array(T)
    P_hat = Function(T)
    u_dealias = Array(VTp)

    # Primary variable
    u = U_hat

    # RHS array
    dU = Function(VT)
    curl = Array(VT)
    Source = Function(VT)  # Possible source term initialized to zero
    work = work_arrays()

    hdf5file = NSFile(config.params.solver,
                      checkpoint={
                          'space': VT,
                          'data': {
                              '0': {
                                  'U': [U_hat]
                              }
                          }
                      },
                      results={
                          'space': VT,
                          'data': {
                              'U': [U],
                              'P': [P]
                          }
                      })

    return config.AttributeDict(locals())
Beispiel #5
0
uq = T.backward(u_hat, uq, fast_transform=True)

uj = Array(T, buffer=ue)
assert np.allclose(uj, uq)

# Test eval at point
point = np.array([[0.1, 0.5], [0.5, 0.6]])
p = T.eval(point, u_hat)
ul = lambdify((x, y), ue)
assert np.allclose(p, ul(*point))
p2 = u_hat.eval(point)
assert np.allclose(p2, ul(*point))
print(np.sqrt(dx((uj - uq)**2)))

if 'pytest' not in os.environ:
    import matplotlib.pyplot as plt
    plt.figure()
    X = T.local_mesh(True)
    plt.contourf(X[0], X[1], uq)
    plt.colorbar()

    plt.figure()
    plt.contourf(X[0], X[1], uj)
    plt.colorbar()

    plt.figure()
    plt.contourf(X[0], X[1], uq - uj)
    plt.colorbar()
    plt.title('Error')
    plt.show()
Beispiel #6
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    assert params.Dquad == params.Bquad
    ST = ShenDirichletBasis(params.N[0], quad=params.Dquad)
    SB = ShenBiharmonicBasis(params.N[0], quad=params.Bquad)
    CT = Basis(params.N[0], quad=params.Dquad)
    ST0 = ShenDirichletBasis(params.N[0], quad=params.Dquad, plan=True) # For 1D problem
    K0 = C2CBasis(params.N[1], domain=(0, params.L[1]))
    K1 = R2CBasis(params.N[2], domain=(0, params.L[2]))

    FST = TensorProductSpace(comm, (ST, K0, K1), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})    # Dirichlet
    FSB = TensorProductSpace(comm, (SB, K0, K1), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})    # Biharmonic
    FCT = TensorProductSpace(comm, (CT, K0, K1), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})    # Regular Chebyshev
    VFS = VectorTensorProductSpace([FSB, FST, FST])

    # Padded
    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = ShenDirichletBasis(params.N[0], quad=params.Dquad)
        SBp = ShenBiharmonicBasis(params.N[0], quad=params.Bquad)
        CTp = Basis(params.N[0], quad=params.Dquad)
    else:
        STp, SBp, CTp = ST, SB, CT

    K0p = C2CBasis(params.N[1], domain=(0, params.L[1]), **kw)
    K1p = R2CBasis(params.N[2], domain=(0, params.L[2]), **kw)
    FSTp = TensorProductSpace(comm, (STp, K0p, K1p), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})
    FSBp = TensorProductSpace(comm, (SBp, K0p, K1p), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})
    FCTp = TensorProductSpace(comm, (CTp, K0p, K1p), **{'threads':params.threads, 'planner_effort':params.planner_effort["dct"]})
    VFSp = VectorTensorProductSpace([FSBp, FSTp, FSTp])

    Nu = params.N[0]-2   # Number of velocity modes in Shen basis
    Nb = params.N[0]-4   # Number of velocity modes in Shen biharmonic basis
    u_slice = slice(0, Nu)
    v_slice = slice(0, Nb)

    float, complex, mpitype = datatypes("double")

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    U = Array(VFS, False)
    U0 = Array(VFS, False)
    U_hat = Array(VFS)
    U_hat0 = Array(VFS)
    g = Array(FST)

    # primary variable
    u = (U_hat, g)

    H_hat = Array(VFS)
    H_hat0 = Array(VFS)
    H_hat1 = Array(VFS)

    dU = Array(VFS)
    hv = Array(FST)
    hg = Array(FST)
    Source = Array(VFS, False)
    Sk = Array(VFS)

    K2 = K[1]*K[1]+K[2]*K[2]
    K4 = K2**2

    # Set Nyquist frequency to zero on K that is used for odd derivatives in nonlinear terms
    Kx = FST.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    K_over_K2 = np.zeros((2,)+g.shape)
    for i in range(2):
        K_over_K2[i] = K[i+1] / np.where(K2 == 0, 1, K2)

    work = work_arrays()

    nu, dt, N = params.nu, params.dt, params.N

    alfa = K2[0] - 2.0/nu/dt
    # Collect all matrices
    mat = config.AttributeDict(
        dict(CDD=inner_product((ST, 0), (ST, 1)),
             AB=HelmholtzCoeff(N[0], 1.0, -alfa, ST.quad),
             AC=BiharmonicCoeff(N[0], nu*dt/2., (1. - nu*dt*K2[0]), -(K2[0] - nu*dt/2.*K4[0]), quad=SB.quad),
             # Matrices for biharmonic equation
             CBD=inner_product((SB, 0), (ST, 1)),
             ABB=inner_product((SB, 0), (SB, 2)),
             BBB=inner_product((SB, 0), (SB, 0)),
             SBB=inner_product((SB, 0), (SB, 4)),
             # Matrices for Helmholtz equation
             ADD=inner_product((ST, 0), (ST, 2)),
             BDD=inner_product((ST, 0), (ST, 0)),
             BBD=inner_product((SB, 0), (ST, 0)),
             CDB=inner_product((ST, 0), (SB, 1)),
             ADD0=inner_product((ST0, 0), (ST0, 2)),
             BDD0=inner_product((ST0, 0), (ST0, 0)),))

    ## Collect all linear algebra solvers
    #la = config.AttributeDict(dict(
        #HelmholtzSolverG = old_Helmholtz(N[0], np.sqrt(K2[0]+2.0/nu/dt), ST),
        #BiharmonicSolverU = old_Biharmonic(N[0], -nu*dt/2., 1.+nu*dt*K2[0],
                                    #-(K2[0] + nu*dt/2.*K4[0]), quad=SB.quad,
                                    #solver="cython"),
        #HelmholtzSolverU0 = old_Helmholtz(N[0], np.sqrt(2./nu/dt), ST),
        #TDMASolverD = TDMA(inner_product((ST, 0), (ST, 0)))
        #)
    #)

    mat.ADD.axis = 0
    mat.BDD.axis = 0
    mat.SBB.axis = 0

    la = config.AttributeDict(
        dict(HelmholtzSolverG=Helmholtz(mat.ADD, mat.BDD, -np.ones((1, 1, 1)),
                                        (K2[0]+2.0/nu/dt)[np.newaxis, :, :]),
             BiharmonicSolverU=Biharmonic(mat.SBB, mat.ABB, mat.BBB, -nu*dt/2.*np.ones((1, 1, 1)),
                                          (1.+nu*dt*K2[0])[np.newaxis, :, :],
                                          (-(K2[0] + nu*dt/2.*K4[0]))[np.newaxis, :, :]),
             HelmholtzSolverU0=old_Helmholtz(N[0], np.sqrt(2./nu/dt), ST),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0)))))

    hdf5file = KMMWriter({"U":U[0], "V":U[1], "W":U[2]},
                         chkpoint={'current':{'U':U}, 'previous':{'U':U0}},
                         filename=params.solver+".h5",
                         mesh={"x": x0, "y": x1, "z": x2})

    return config.AttributeDict(locals())
Beispiel #7
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    assert params.Dquad == params.Bquad
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    ST = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
    SB = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
    CT = Basis(params.N[2], 'C', quad=params.Dquad)
    ST0 = Basis(params.N[2], 'C', bc=(0, 0),
                quad=params.Dquad)  # For 1D problem
    K0 = Basis(params.N[0], 'F', domain=(0, params.L[0]), dtype='D')
    K1 = Basis(params.N[1], 'F', domain=(0, params.L[1]), dtype='d')

    kw0 = {
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"],
        'slab': (params.decomposition == 'slab'),
        'collapse_fourier': collapse_fourier
    }
    FST = TensorProductSpace(comm, (K0, K1, ST), axes=(2, 0, 1),
                             **kw0)  # Dirichlet
    FSB = TensorProductSpace(comm, (K0, K1, SB), axes=(2, 0, 1),
                             **kw0)  # Biharmonic
    FCT = TensorProductSpace(comm, (K0, K1, CT), axes=(2, 0, 1),
                             **kw0)  # Regular Chebyshev
    VFS = MixedTensorProductSpace([FST, FST, FSB])
    VFST = MixedTensorProductSpace([FST, FST, FST])
    VUG = MixedTensorProductSpace([FST, FSB])

    mask = FST.get_mask_nyquist() if params.mask_nyquist else None

    # Padded
    kw = {
        'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
        'dealias_direct': params.dealias == '2/3-rule'
    }
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = Basis(params.N[2], 'C', bc=(0, 0), quad=params.Dquad)
        SBp = Basis(params.N[2], 'C', bc='Biharmonic', quad=params.Bquad)
        CTp = Basis(params.N[2], 'C', quad=params.Dquad)
    else:
        STp, SBp, CTp = ST, SB, CT
    K0p = Basis(params.N[0], 'F', dtype='D', domain=(0, params.L[0]), **kw)
    K1p = Basis(params.N[1], 'F', dtype='d', domain=(0, params.L[1]), **kw)
    FSTp = TensorProductSpace(comm, (K0p, K1p, STp), axes=(2, 0, 1), **kw0)
    FSBp = TensorProductSpace(comm, (K0p, K1p, SBp), axes=(2, 0, 1), **kw0)
    FCTp = TensorProductSpace(comm, (K0p, K1p, CTp), axes=(2, 0, 1), **kw0)
    VFSp = MixedTensorProductSpace([FSTp, FSTp, FSBp])

    float, complex, mpitype = datatypes("double")

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    U = Array(VFS)
    U0 = Array(VFS)
    U_hat = Function(VFS)
    U_hat0 = Function(VFS)
    g = Function(FST)

    # primary variable
    u = (U_hat, g)

    H_hat = Function(VFST)
    H_hat0 = Function(VFST)
    H_hat1 = Function(VFST)

    dU = Function(VUG)
    hv = Function(FST)
    hg = Function(FST)
    Source = Array(VFS)
    Sk = Function(VFS)

    K2 = K[0] * K[0] + K[1] * K[1]
    K4 = K2**2

    # Set Nyquist frequency to zero on K that is used for odd derivatives in nonlinear terms
    Kx = FST.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    K_over_K2 = np.zeros((2, ) + g.shape)
    for i in range(2):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    for i in range(3):
        K[i] = K[i].astype(float)
        Kx[i] = Kx[i].astype(float)

    Kx2 = Kx[1] * Kx[1] + Kx[2] * Kx[2]
    work = work_arrays()
    u_dealias = Array(VFSp)
    u0_hat = np.zeros((2, params.N[2]), dtype=complex)
    h0_hat = np.zeros((2, params.N[2]), dtype=complex)
    w = np.zeros((params.N[2], ), dtype=complex)
    w1 = np.zeros((params.N[2], ), dtype=complex)

    nu, dt, N = params.nu, params.dt, params.N

    # Collect all matrices
    mat = config.AttributeDict(
        dict(
            CDD=inner_product((ST, 0), (ST, 1)),
            CTD=inner_product((CT, 0), (ST, 1)),
            BTT=inner_product((CT, 0), (CT, 0)),
            AB=HelmholtzCoeff(N[2], 1.0, -(K2 - 2.0 / nu / dt), 2, ST.quad),
            AC=BiharmonicCoeff(N[2], nu * dt / 2., (1. - nu * dt * K2),
                               -(K2 - nu * dt / 2. * K4), 2, SB.quad),
            # Matrices for biharmonic equation
            CBD=inner_product((SB, 0), (ST, 1)),
            ABB=inner_product((SB, 0), (SB, 2)),
            BBB=inner_product((SB, 0), (SB, 0)),
            SBB=inner_product((SB, 0), (SB, 4)),
            # Matrices for Helmholtz equation
            ADD=inner_product((ST, 0), (ST, 2)),
            BDD=inner_product((ST, 0), (ST, 0)),
            BBD=inner_product((SB, 0), (ST, 0)),
            CDB=inner_product((ST, 0), (SB, 1)),
            ADD0=inner_product((ST0, 0), (ST0, 2)),
            BDD0=inner_product((ST0, 0), (ST0, 0))))

    la = config.AttributeDict(
        dict(HelmholtzSolverG=Helmholtz(mat.ADD, mat.BDD, -np.ones((1, 1, 1)),
                                        (K2 + 2.0 / nu / dt)),
             BiharmonicSolverU=Biharmonic(mat.SBB, mat.ABB, mat.BBB,
                                          -nu * dt / 2. * np.ones(
                                              (1, 1, 1)), (1. + nu * dt * K2),
                                          (-(K2 + nu * dt / 2. * K4))),
             HelmholtzSolverU0=Helmholtz(mat.ADD0, mat.BDD0, np.array([-1.]),
                                         np.array([2. / nu / dt])),
             TDMASolverD=TDMA(inner_product((ST, 0), (ST, 0)))))

    hdf5file = KMMFile(config.params.solver,
                       checkpoint={
                           'space': VFS,
                           'data': {
                               '0': {
                                   'U': [U_hat]
                               },
                               '1': {
                                   'U': [U_hat0]
                               }
                           }
                       },
                       results={
                           'space': VFS,
                           'data': {
                               'U': [U]
                           }
                       })

    return config.AttributeDict(locals())
Beispiel #8
0
def get_context():
    """Set up context for solver"""

    # Get points and weights for Chebyshev weighted integrals
    assert params.Dquad == params.Bquad
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    ST = FunctionSpace(params.N[0], 'C', bc=(0, 0), quad=params.Dquad)
    CT = FunctionSpace(params.N[0], 'C', quad=params.Dquad)
    CP = FunctionSpace(params.N[0], 'C', quad=params.Dquad)
    K0 = FunctionSpace(params.N[1], 'F', domain=(0, params.L[1]), dtype='D')
    K1 = FunctionSpace(params.N[2], 'F', domain=(0, params.L[2]), dtype='d')
    CP.slice = lambda: slice(0, CT.N)

    kw0 = {
        'threads': params.threads,
        'planner_effort': params.planner_effort["dct"],
        'slab': (params.decomposition == 'slab'),
        'collapse_fourier': collapse_fourier
    }
    FST = TensorProductSpace(comm, (ST, K0, K1), **kw0)  # Dirichlet
    FCT = TensorProductSpace(comm, (CT, K0, K1), **kw0)  # Regular Chebyshev N
    FCP = TensorProductSpace(comm, (CP, K0, K1),
                             **kw0)  # Regular Chebyshev N-2
    VFS = VectorTensorProductSpace(FST)
    VCT = VectorTensorProductSpace(FCT)
    VQ = MixedTensorProductSpace([VFS, FCP])

    mask = FST.get_mask_nyquist() if params.mask_nyquist else None

    # Padded
    kw = {
        'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
        'dealias_direct': params.dealias == '2/3-rule'
    }
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = FunctionSpace(params.N[0], 'C', bc=(0, 0), quad=params.Dquad)
        CTp = FunctionSpace(params.N[0], 'C', quad=params.Dquad)
    else:
        STp, CTp = ST, CT
    K0p = FunctionSpace(params.N[1],
                        'F',
                        dtype='D',
                        domain=(0, params.L[1]),
                        **kw)
    K1p = FunctionSpace(params.N[2],
                        'F',
                        dtype='d',
                        domain=(0, params.L[2]),
                        **kw)
    FSTp = TensorProductSpace(comm, (STp, K0p, K1p), **kw0)
    FCTp = TensorProductSpace(comm, (CTp, K0p, K1p), **kw0)
    VFSp = VectorTensorProductSpace(FSTp)
    VCp = MixedTensorProductSpace([FSTp, FCTp, FCTp])

    float, complex, mpitype = datatypes("double")

    constraints = ((3, 0, 0), (3, params.N[0] - 1, 0))

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    UP_hat = Function(VQ)
    UP_hat0 = Function(VQ)
    U_hat, P_hat = UP_hat
    U_hat0, P_hat0 = UP_hat0

    UP = Array(VQ)
    UP0 = Array(VQ)
    U, P = UP
    U0, P0 = UP0

    # primary variable
    u = UP_hat

    H_hat = Function(VFS)
    H_hat0 = Function(VFS)
    H_hat1 = Function(VFS)

    dU = Function(VQ)
    Source = Array(
        VFS)  # Note - not using VQ. Only used for constant pressure gradient
    Sk = Function(VFS)

    K2 = K[1] * K[1] + K[2] * K[2]

    for i in range(3):
        K[i] = K[i].astype(float)

    work = work_arrays()
    u_dealias = Array(VFSp)
    curl_hat = Function(VCp)
    curl_dealias = Array(VCp)

    nu, dt, N = params.nu, params.dt, params.N

    up = TrialFunction(VQ)
    vq = TestFunction(VQ)

    ut, pt = up
    vt, qt = vq

    alfa = 2. / nu / dt
    a0 = inner(vt, (2. / nu / dt) * ut - div(grad(ut)))
    a1 = inner(vt, (2. / nu) * grad(pt))
    a2 = inner(qt, (2. / nu) * div(ut))

    M = BlockMatrix(a0 + a1 + a2)

    # Collect all matrices
    mat = config.AttributeDict(
        dict(
            CDD=inner_product((ST, 0), (ST, 1)),
            AB=HelmholtzCoeff(N[0], 1., alfa - K2, 0, ST.quad),
        ))

    la = None

    hdf5file = CoupledFile(config.params.solver,
                           checkpoint={
                               'space': VQ,
                               'data': {
                                   '0': {
                                       'UP': [UP_hat]
                                   },
                                   '1': {
                                       'UP': [UP_hat0]
                                   }
                               }
                           },
                           results={
                               'space': VFS,
                               'data': {
                                   'U': [U]
                               }
                           })

    return config.AttributeDict(locals())
Beispiel #9
0
fe = ue.diff(x, 2) + ue.diff(y, 2) + ue.diff(z, 2)

# Lambdify for faster evaluation
ul = lambdify((x, y, z), ue, 'numpy')
fl = lambdify((x, y, z), fe, 'numpy')

# Size of discretization
N = int(sys.argv[-2])
N = [N, N + 1, N + 2]
#N = (14, 15, 16)

SD = Basis(N[0], family=family, bc=(a, b))
K1 = Basis(N[1], family='F', dtype='D')
K2 = Basis(N[2], family='F', dtype='d')
T = TensorProductSpace(comm, (K1, K2, SD), axes=(0, 1, 2), slab=True)
X = T.local_mesh()
u = TrialFunction(T)
v = TestFunction(T)

K = T.local_wavenumbers()

# Get f on quad points
fj = Array(T, buffer=fl(*X))

# Compute right hand side of Poisson equation
f_hat = inner(v, fj)
if family == 'legendre':
    f_hat *= -1.

# Get left hand side of Poisson equation
if family == 'chebyshev':
Beispiel #10
0
def get_context():
    """Set up context for solver"""

    collapse_fourier = False if params.dealias == '3/2-rule' else True
    family = 'C'
    ST = Basis(params.N[0], family, bc=(0, 0), quad=params.Dquad)
    CT = Basis(params.N[0], family, quad=params.Dquad)
    CP = Basis(params.N[0], family, quad=params.Dquad)
    K0 = Basis(params.N[1], 'F', domain=(0, params.L[1]), dtype='D')
    K1 = Basis(params.N[2], 'F', domain=(0, params.L[2]), dtype='d')
    #CP.slice = lambda: slice(0, CP.N-2)

    constraints = ((3, 0, 0),
                   (3, params.N[0]-1, 0))

    kw0 = {'threads': params.threads,
           'planner_effort': params.planner_effort["dct"],
           'slab': (params.decomposition == 'slab'),
           'collapse_fourier': collapse_fourier}
    FST = TensorProductSpace(comm, (ST, K0, K1), **kw0)    # Dirichlet
    FCT = TensorProductSpace(comm, (CT, K0, K1), **kw0)    # Regular Chebyshev N
    FCP = TensorProductSpace(comm, (CP, K0, K1), **kw0)    # Regular Chebyshev N-2
    VFS = VectorTensorProductSpace(FST)
    VCT = VectorTensorProductSpace(FCT)
    VQ = MixedTensorProductSpace([VFS, FCP])

    mask = FST.get_mask_nyquist() if params.mask_nyquist else None

    # Padded
    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}
    if params.dealias == '3/2-rule':
        # Requires new bases due to planning and transforms on different size arrays
        STp = Basis(params.N[0], family, bc=(0, 0), quad=params.Dquad)
        CTp = Basis(params.N[0], family, quad=params.Dquad)
    else:
        STp, CTp = ST, CT
    K0p = Basis(params.N[1], 'F', dtype='D', domain=(0, params.L[1]), **kw)
    K1p = Basis(params.N[2], 'F', dtype='d', domain=(0, params.L[2]), **kw)
    FSTp = TensorProductSpace(comm, (STp, K0p, K1p), **kw0)
    FCTp = TensorProductSpace(comm, (CTp, K0p, K1p), **kw0)
    VFSp = VectorTensorProductSpace(FSTp)
    VCp = MixedTensorProductSpace([FSTp, FCTp, FCTp])

    float, complex, mpitype = datatypes("double")

    # Mesh variables
    X = FST.local_mesh(True)
    x0, x1, x2 = FST.mesh()
    K = FST.local_wavenumbers(scaled=True)

    # Solution variables
    UP_hat = Function(VQ)
    UP_hat0 = Function(VQ)
    U_hat, P_hat = UP_hat
    U_hat0, P_hat0 = UP_hat0

    UP = Array(VQ)
    UP0 = Array(VQ)
    U, P = UP
    U0, P0 = UP0

    # RK parameters
    a = (8./15., 5./12., 3./4.)
    b = (0.0, -17./60., -5./12.)

    # primary variable
    u = UP_hat

    H_hat = Function(VFS)

    dU = Function(VQ)
    hv = np.zeros((2,)+H_hat.shape, dtype=np.complex)

    Source = Array(VFS) # Note - not using VQ. Only used for constant pressure gradient
    Sk = Function(VFS)

    K2 = K[1]*K[1]+K[2]*K[2]

    for i in range(3):
        K[i] = K[i].astype(float)

    work = work_arrays()
    u_dealias = Array(VFSp)
    curl_hat = Function(VCp)
    curl_dealias = Array(VCp)

    nu, dt, N = params.nu, params.dt, params.N

    up = TrialFunction(VQ)
    vq = TestFunction(VQ)

    ut, pt = up
    vt, qt = vq

    M = []
    for rk in range(3):
        a0 = inner(vt, (2./nu/dt/(a[rk]+b[rk]))*ut-div(grad(ut)))
        a1 = inner(vt, (2./nu/(a[rk]+b[rk]))*grad(pt))
        a2 = inner(qt, (2./nu/(a[rk]+b[rk]))*div(ut))
        M.append(BlockMatrix(a0+a1+a2))

    # Collect all matrices
    if ST.family() == 'chebyshev':
        mat = config.AttributeDict(
            dict(AB=[HelmholtzCoeff(N[0], 1., -(K2 - 2./nu/dt/(a[rk]+b[rk])), 0, ST.quad) for rk in range(3)],))
    else:
        mat = config.AttributeDict(
            dict(ADD=inner_product((ST, 0), (ST, 2)),
                 BDD=inner_product((ST, 0), (ST, 0)))
        )

    la = None

    hdf5file = CoupledRK3File(config.params.solver,
                        checkpoint={'space': VQ,
                                    'data': {'0': {'UP': [UP_hat]}}},
                        results={'space': VFS,
                                 'data': {'U': [U]}})

    del rk
    return config.AttributeDict(locals())
Beispiel #11
0
def test_eval_tensor(typecode, dim, ST, quad):
    # Using sympy to compute an analytical solution
    # Testing for Dirichlet and regular basis
    x, y, z = symbols("x,y,z")
    sizes = (16, 15)

    funcx = {'': (1-x**2)*sin(np.pi*x),
             'Dirichlet': (1-x**2)*sin(np.pi*x),
             'Neumann': (1-x**2)*sin(np.pi*x),
             'Biharmonic': (1-x**2)*sin(2*np.pi*x),
             '6th order': (1-x**2)**3*sin(np.pi*x),
             'BiPolar': (1-x**2)*sin(2*np.pi*x),
             'BiPolar0': (1-x**2)*sin(2*np.pi*x),
             'UpperDirichlet': (1-x)*sin(np.pi*x),
             'DirichletNeumann': (1-x**2)*sin(2*np.pi*x),
             'NeumannDirichlet': (1-x**2)*sin(2*np.pi*x)}
    funcy = {'': (1-y**2)*sin(np.pi*y),
             'Dirichlet': (1-y**2)*sin(np.pi*y),
             'Neumann': (1-y**2)*sin(np.pi*y),
             'Biharmonic': (1-y**2)*sin(2*np.pi*y),
             '6th order': (1-y**2)**3*sin(np.pi*y),
             'BiPolar': (1-y**2)*sin(2*np.pi*y),
             'BiPolar0': (1-y**2)*sin(2*np.pi*y),
             'UpperDirichlet': (1-y)*sin(np.pi*y),
             'DirichletNeumann': (1-y**2)*sin(2*np.pi*y),
             'NeumannDirichlet': (1-y**2)*sin(2*np.pi*y)}
    funcz = {'': (1-z**2)*sin(np.pi*z),
             'Dirichlet': (1-z**2)*sin(np.pi*z),
             'Neumann': (1-z**2)*sin(np.pi*z),
             'Biharmonic': (1-z**2)*sin(2*np.pi*z),
             '6th order': (1-z**2)**3*sin(np.pi*z),
             'BiPolar': (1-z**2)*sin(2*np.pi*z),
             'BiPolar0': (1-z**2)*sin(2*np.pi*z),
             'UpperDirichlet': (1-z)*sin(np.pi*z),
             'DirichletNeumann': (1-z**2)*sin(2*np.pi*z),
             'NeumannDirichlet': (1-z**2)*sin(2*np.pi*z)}

    funcs = {
        (1, 0): cos(2*y)*funcx[ST.boundary_condition()],
        (1, 1): cos(2*x)*funcy[ST.boundary_condition()],
        (2, 0): sin(3*z)*cos(4*y)*funcx[ST.boundary_condition()],
        (2, 1): sin(2*z)*cos(4*x)*funcy[ST.boundary_condition()],
        (2, 2): sin(2*x)*cos(4*y)*funcz[ST.boundary_condition()]
        }
    syms = {1: (x, y), 2:(x, y, z)}
    points = None
    if comm.Get_rank() == 0:
        points = np.random.random((dim+1, 4))
    points = comm.bcast(points)
    t_0 = 0
    t_1 = 0
    t_2 = 0
    for shape in product(*([sizes]*dim)):
        #for shape in ((64, 64),):
        bases = []
        for n in shape[:-1]:
            bases.append(FunctionSpace(n, 'F', dtype=typecode.upper()))
        bases.append(FunctionSpace(shape[-1], 'F', dtype=typecode))

        for axis in range(dim+1):
            #for axis in (0,):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            # Spectral space must be aligned in nonperiodic direction, hence axes
            fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis])
            #print('axes', axes[dim][axis])
            #print('bases', bases)
            #print(bases[0].axis, bases[1].axis)
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            ul = lambdify(syms[dim], ue, 'numpy')
            uq = ul(*points).astype(typecode)
            u_hat = Function(fft, buffer=ue)
            t0 = time()
            result = fft.eval(points, u_hat, method=0)
            t_0 += time()-t0
            assert np.allclose(uq, result, 0, 1e-3)
            t0 = time()
            result = fft.eval(points, u_hat, method=1)
            t_1 += time()-t0
            assert np.allclose(uq, result, 0, 1e-3)
            t0 = time()
            result = fft.eval(points, u_hat, method=2)
            t_2 += time()-t0
            assert np.allclose(uq, result, 0, 1e-3), uq/result
            result = u_hat.eval(points)
            assert np.allclose(uq, result, 0, 1e-3)

            bases.pop(axis)
            fft.destroy()
    print('method=0', t_0)
    print('method=1', t_1)
    print('method=2', t_2)
Beispiel #12
0
def get_context():
    float, complex, mpitype = datatypes(params.precision)
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    dim = len(params.N)
    dtype = lambda d: float if d == dim-1 else complex
    V = [Basis(params.N[i], 'F', domain=(0, params.L[i]),
               dtype=dtype(i)) for i in range(dim)]

    kw0 = {'threads': params.threads,
           'planner_effort': params.planner_effort['fft']}
    T = TensorProductSpace(comm, V, dtype=float,
                           slab=(params.decomposition == 'slab'),
                           collapse_fourier=collapse_fourier, **kw0)
    VT = VectorTensorProductSpace(T)
    VM = MixedTensorProductSpace([T]*2*dim)

    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}

    Vp = [Basis(params.N[i], 'F', domain=(0, params.L[i]),
                dtype=dtype(i), **kw) for i in range(dim)]

    Tp = TensorProductSpace(comm, Vp, dtype=float,
                            slab=(params.decomposition == 'slab'),
                            collapse_fourier=collapse_fourier, **kw0)
    VTp = VectorTensorProductSpace(Tp)
    VMp = MixedTensorProductSpace([Tp]*2*dim)

    # Mesh variables
    X = T.local_mesh(True)
    K = T.local_wavenumbers(scaled=True)
    for i in range(dim):
        X[i] = X[i].astype(float)
        K[i] = K[i].astype(float)
    K2 = np.zeros(T.shape(True), dtype=float)
    for i in range(dim):
        K2 += K[i]*K[i]

    # Set Nyquist frequency to zero on K that is, from now on, used for odd derivatives
    Kx = T.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    for i in range(dim):
        Kx[i] = Kx[i].astype(float)

    K_over_K2 = np.zeros(VT.shape(True), dtype=float)
    for i in range(dim):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    UB = Array(VM)
    P = Array(T)
    curl = Array(VT)
    UB_hat = Function(VM)
    P_hat = Function(T)
    dU = Function(VM)
    Source = Array(VM)
    ub_dealias = Array(VMp)
    ZZ_hat = np.zeros((3, 3) + Tp.shape(True), dtype=complex) # Work array

    # Create views into large data structures
    U = UB[:3]
    U_hat = UB_hat[:3]
    B = UB[3:]
    B_hat = UB_hat[3:]

    # Primary variable
    u = UB_hat

    hdf5file = MHDFile(config.params.solver,
                       checkpoint={'space': VM,
                                   'data': {'0': {'UB': [UB_hat]}}},
                       results={'space': VM,
                                'data': {'UB': [UB]}})

    return config.AttributeDict(locals())
Beispiel #13
0
def get_context():
    float, complex, mpitype = datatypes(params.precision)
    collapse_fourier = False if params.dealias == '3/2-rule' else True
    dim = len(params.N)
    dtype = lambda d: float if d == dim-1 else complex
    V = [FunctionSpace(params.N[i], 'F', domain=(0, params.L[i]),
                       dtype=dtype(i)) for i in range(dim)]

    kw0 = {'threads': params.threads,
           'planner_effort': params.planner_effort['fft']}
    T = TensorProductSpace(comm, V, dtype=float,
                           slab=(params.decomposition == 'slab'),
                           collapse_fourier=collapse_fourier, **kw0)
    VT = VectorTensorProductSpace(T)
    VM = MixedTensorProductSpace([T]*2*dim)

    mask = T.get_mask_nyquist() if params.mask_nyquist else None

    kw = {'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
          'dealias_direct': params.dealias == '2/3-rule'}

    Vp = [FunctionSpace(params.N[i], 'F', domain=(0, params.L[i]),
                        dtype=dtype(i), **kw) for i in range(dim)]

    Tp = TensorProductSpace(comm, Vp, dtype=float,
                            slab=(params.decomposition == 'slab'),
                            collapse_fourier=collapse_fourier, **kw0)
    VTp = VectorTensorProductSpace(Tp)
    VMp = MixedTensorProductSpace([Tp]*2*dim)

    # Mesh variables
    X = T.local_mesh(True)
    K = T.local_wavenumbers(scaled=True)
    for i in range(dim):
        X[i] = X[i].astype(float)
        K[i] = K[i].astype(float)
    K2 = np.zeros(T.shape(True), dtype=float)
    for i in range(dim):
        K2 += K[i]*K[i]

    K_over_K2 = np.zeros(VT.shape(True), dtype=float)
    for i in range(dim):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    UB = Array(VM)
    P = Array(T)
    curl = Array(VT)
    UB_hat = Function(VM)
    P_hat = Function(T)
    dU = Function(VM)
    Source = Array(VM)
    ub_dealias = Array(VMp)
    ZZ_hat = np.zeros((3, 3) + Tp.shape(True), dtype=complex) # Work array

    # Create views into large data structures
    U = UB[:3]
    U_hat = UB_hat[:3]
    B = UB[3:]
    B_hat = UB_hat[3:]

    # Primary variable
    u = UB_hat

    hdf5file = MHDFile(config.params.solver,
                       checkpoint={'space': VM,
                                   'data': {'0': {'UB': [UB_hat]}}},
                       results={'space': VM,
                                'data': {'UB': [UB]}})

    return config.AttributeDict(locals())
Beispiel #14
0
def get_context():
    """Set up context for classical (NS) solver"""
    V0 = C2CBasis(params.N[0], domain=(0, params.L[0]))
    V1 = C2CBasis(params.N[1], domain=(0, params.L[1]))
    V2 = R2CBasis(params.N[2], domain=(0, params.L[2]))
    T = TensorProductSpace(comm, (V0, V1, V2), **{'threads': params.threads})
    VT = VectorTensorProductSpace([T] * 3)

    kw = {
        'padding_factor': 1.5 if params.dealias == '3/2-rule' else 1,
        'dealias_direct': params.dealias == '2/3-rule'
    }
    V0p = C2CBasis(params.N[0], domain=(0, params.L[0]), **kw)
    V1p = C2CBasis(params.N[1], domain=(0, params.L[1]), **kw)
    V2p = R2CBasis(params.N[2], domain=(0, params.L[2]), **kw)
    Tp = TensorProductSpace(comm, (V0p, V1p, V2p),
                            **{'threads': params.threads})
    VTp = VectorTensorProductSpace([Tp] * 3)

    float, complex, mpitype = datatypes(params.precision)
    FFT = T  # For compatibility - to be removed

    # Mesh variables
    X = T.local_mesh(True)
    K = T.local_wavenumbers(scaled=True)
    K2 = K[0] * K[0] + K[1] * K[1] + K[2] * K[2]

    # Set Nyquist frequency to zero on K that is, from now on, used for odd derivatives
    Kx = T.local_wavenumbers(scaled=True, eliminate_highest_freq=True)
    K_over_K2 = np.zeros((3, ) + VT.local_shape())
    for i in range(3):
        K_over_K2[i] = K[i] / np.where(K2 == 0, 1, K2)

    # Velocity and pressure
    U = Array(VT, False)
    U_hat = Array(VT)
    P = Array(T, False)
    P_hat = Array(T)

    # Primary variable
    u = U_hat

    # RHS array
    dU = Array(VT)
    curl = Array(VT, False)
    Source = Array(VT)  # Possible source term initialized to zero
    work = work_arrays()

    hdf5file = NSWriter({
        "U": U[0],
        "V": U[1],
        "W": U[2],
        "P": P
    },
                        chkpoint={
                            "current": {
                                "U": U,
                                "P": P
                            },
                            "previous": {}
                        },
                        filename=params.h5filename + ".h5")

    return config.AttributeDict(locals())
Beispiel #15
0
def test_eval_tensor(typecode, dim, ST, quad):
    # Using sympy to compute an analytical solution
    # Testing for Dirichlet and regular basis
    x, y, z = symbols("x,y,z")
    sizes = (25, 24)

    funcx = (x**2 - 1) * cos(2 * np.pi * x)
    funcy = (y**2 - 1) * cos(2 * np.pi * y)
    funcz = (z**2 - 1) * cos(2 * np.pi * z)

    funcs = {
        (1, 0): cos(4 * y) * funcx,
        (1, 1): cos(4 * x) * funcy,
        (2, 0): (sin(6 * z) + cos(4 * y)) * funcx,
        (2, 1): (sin(2 * z) + cos(4 * x)) * funcy,
        (2, 2): (sin(2 * x) + cos(4 * y)) * funcz
    }
    syms = {1: (x, y), 2: (x, y, z)}
    points = np.array([[0.1] * (dim + 1), [0.01] * (dim + 1),
                       [0.4] * (dim + 1), [0.5] * (dim + 1)])

    for shape in product(*([sizes] * dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        if dim < 3:
            n = min(shape)
            if typecode in 'fdg':
                n //= 2
                n += 1
            if n < comm.size:
                continue
        for axis in range(dim + 1):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            # Spectral space must be aligned in nonperiodic direction, hence axes
            fft = TensorProductSpace(comm,
                                     bases,
                                     dtype=typecode,
                                     axes=axes[dim][axis])
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            ul = lambdify(syms[dim], ue, 'numpy')
            uu = ul(*X).astype(typecode)
            uq = ul(*points.T).astype(typecode)
            u_hat = Function(fft)
            u_hat = fft.forward(uu, u_hat)
            result = fft.eval(points, u_hat, cython=True)
            assert np.allclose(uq, result, 0, 1e-6)
            result = fft.eval(points, u_hat, cython=False)
            assert np.allclose(uq, result, 0, 1e-6)
            result = u_hat.eval(points)
            assert np.allclose(uq, result, 0, 1e-6)
            ua = u_hat.backward()
            assert np.allclose(uu, ua, 0, 1e-6)
            ua = Array(fft)
            ua = u_hat.backward(ua)
            assert np.allclose(uu, ua, 0, 1e-6)

            bases.pop(axis)
            fft.destroy()
Beispiel #16
0
def test_project2(typecode, dim, ST, quad):
    # Using sympy to compute an analytical solution
    x, y, z = symbols("x,y,z")
    sizes = (25, 24)

    funcx = ((2 * np.pi**2 * (x**2 - 1) - 1) * cos(2 * np.pi * x) -
             2 * np.pi * x * sin(2 * np.pi * x)) / (4 * np.pi**3)
    funcy = ((2 * np.pi**2 * (y**2 - 1) - 1) * cos(2 * np.pi * y) -
             2 * np.pi * y * sin(2 * np.pi * y)) / (4 * np.pi**3)
    funcz = ((2 * np.pi**2 * (z**2 - 1) - 1) * cos(2 * np.pi * z) -
             2 * np.pi * z * sin(2 * np.pi * z)) / (4 * np.pi**3)

    funcs = {
        (1, 0): cos(4 * y) * funcx,
        (1, 1): cos(4 * x) * funcy,
        (2, 0): sin(6 * z) * cos(4 * y) * funcx,
        (2, 1): sin(2 * z) * cos(4 * x) * funcy,
        (2, 2): sin(2 * x) * cos(4 * y) * funcz
    }
    syms = {1: (x, y), 2: (x, y, z)}
    xs = {0: x, 1: y, 2: z}

    for shape in product(*([sizes] * dim)):
        bases = []
        for n in shape[:-1]:
            bases.append(Basis(n, 'F', dtype=typecode.upper()))
        bases.append(Basis(shape[-1], 'F', dtype=typecode))

        if dim < 3:
            n = min(shape)
            if typecode in 'fdg':
                n //= 2
                n += 1
            if n < comm.size:
                continue
        for axis in range(dim + 1):
            ST0 = ST(shape[-1], quad=quad)
            bases.insert(axis, ST0)
            # Spectral space must be aligned in nonperiodic direction, hence axes
            fft = TensorProductSpace(comm,
                                     bases,
                                     dtype=typecode,
                                     axes=axes[dim][axis])
            X = fft.local_mesh(True)
            ue = funcs[(dim, axis)]
            ul = lambdify(syms[dim], ue, 'numpy')
            uq = ul(*X).astype(typecode)
            uh = Function(fft)
            uh = fft.forward(uq, uh)
            due = ue.diff(xs[axis], 1)
            dul = lambdify(syms[dim], due, 'numpy')
            duq = dul(*X).astype(typecode)
            uf = project(Dx(uh, axis, 1), fft)
            uy = Array(fft)
            uy = fft.backward(uf, uy)
            assert np.allclose(uy, duq, 0, 1e-6)

            # Test also several derivatives
            for ax in (x for x in range(dim + 1) if x is not axis):
                due = ue.diff(xs[ax], 1, xs[axis], 1)
                dul = lambdify(syms[dim], due, 'numpy')
                duq = dul(*X).astype(typecode)
                uf = project(Dx(Dx(uh, ax, 1), axis, 1), fft)
                uy = Array(fft)
                uy = fft.backward(uf, uy)
                assert np.allclose(uy, duq, 0, 1e-6)
            bases.pop(axis)
            fft.destroy()