def test_project_hermite(typecode, dim, ST, quad): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (20, 19) funcs = { (1, 0): (cos(4*y)*sin(2*x))*exp(-x**2/2), (1, 1): (cos(4*x)*sin(2*y))*exp(-y**2/2), (2, 0): (sin(3*z)*cos(4*y)*sin(2*x))*exp(-x**2/2), (2, 1): (sin(2*z)*cos(4*x)*sin(2*y))*exp(-y**2/2), (2, 2): (sin(2*x)*cos(4*y)*sin(2*z))*exp(-z**2/2) } 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)) for axis in range(dim+1): ST0 = ST(3*shape[-1], quad=quad) bases.insert(axis, ST0) fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis]) X = fft.local_mesh(True) ue = funcs[(dim, axis)] u_h = project(ue, fft) ul = lambdify(syms[dim], ue, 'numpy') uq = ul(*X).astype(typecode) uf = u_h.backward() assert np.linalg.norm(uq-uf) < 1e-5 bases.pop(axis) fft.destroy()
def test_shentransform(typecode, dim, ST, quad): 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) fft = TensorProductSpace(comm, bases, dtype=typecode) U = random_like(fft.forward.input_array) F = fft.forward(U) Fc = F.copy() V = fft.backward(F) F = fft.forward(U) assert allclose(F, Fc) bases.pop(axis) fft.destroy()
def test_project_hermite(typecode, dim): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (20, 19) funcs = { (1, 0): (cos(4*y)*sin(2*x))*exp(-x**2/2), (1, 1): (cos(4*x)*sin(2*y))*exp(-y**2/2), (2, 0): (sin(3*z)*cos(4*y)*sin(2*x))*exp(-x**2/2), (2, 1): (sin(2*z)*cos(4*x)*sin(2*y))*exp(-y**2/2), (2, 2): (sin(2*x)*cos(4*y)*sin(2*z))*exp(-z**2/2) } xs = {0:x, 1:y, 2:z} for shape in product(*([sizes]*dim)): 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): ST0 = hBasis[0](3*shape[-1]) bases.insert(axis, ST0) fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis]) X = fft.local_mesh(True) ue = funcs[(dim, axis)] due = ue.diff(xs[0], 1) u_h = project(ue, fft) du_h = project(due, fft) du2 = project(Dx(u_h, 0, 1), fft) assert np.linalg.norm(du_h-du2) < 1e-5 bases.pop(axis) fft.destroy()
def test_project(typecode, dim, ST, quad): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (25, 24) funcs = { (1, 0): (cos(4 * y) * sin(2 * np.pi * x)) * (1 - x**2), (1, 1): (cos(4 * x) * sin(2 * np.pi * y)) * (1 - y**2), (2, 0): (sin(6 * z) * cos(4 * y) * sin(2 * np.pi * x)) * (1 - x**2), (2, 1): (sin(2 * z) * cos(4 * x) * sin(2 * np.pi * y)) * (1 - y**2), (2, 2): (sin(2 * x) * cos(4 * y) * sin(2 * np.pi * z)) * (1 - z**2) } 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) 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) for ax in (x for x in range(dim + 1) if x is not axis): due = ue.diff(xs[axis], 1, xs[ax], 1) dul = lambdify(syms[dim], due, 'numpy') duq = dul(*X).astype(typecode) uf = project(Dx(Dx(uh, axis, 1), ax, 1), fft) uy = Array(fft) uy = fft.backward(uf, uy) assert np.allclose(uy, duq, 0, 1e-6) bases.pop(axis) fft.destroy()
def test_project2(typecode, dim, ST, quad): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (18, 17) 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(3*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)) 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-3) # 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-3) bases.pop(axis) fft.destroy()
def test_project(typecode, dim, ST, quad): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (20, 19) funcs = { (1, 0): (cos(1*y)*sin(1*np.pi*x))*(1-x**2), (1, 1): (cos(1*x)*sin(1*np.pi*y))*(1-y**2), (2, 0): (sin(1*z)*cos(1*y)*sin(1*np.pi*x))*(1-x**2), (2, 1): (sin(1*z)*cos(1*x)*sin(1*np.pi*y))*(1-y**2), (2, 2): (sin(1*x)*cos(1*y)*sin(1*np.pi*z))*(1-z**2) } xs = {0:x, 1:y, 2:z} for shape in product(*([sizes]*dim)): 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): ST0 = ST(shape[-1], quad=quad) bases.insert(axis, ST0) fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis]) dfft = fft.get_orthogonal() X = fft.local_mesh(True) ue = funcs[(dim, axis)] uq = Array(fft, buffer=ue) uh = Function(fft) uh = fft.forward(uq, uh) due = ue.diff(xs[axis], 1) duq = Array(fft, buffer=due) uf = project(Dx(uh, axis, 1), dfft).backward() assert np.linalg.norm(uf-duq) < 1e-5 for ax in (x for x in range(dim+1) if x is not axis): due = ue.diff(xs[axis], 1, xs[ax], 1) duq = Array(fft, buffer=due) uf = project(Dx(Dx(uh, axis, 1), ax, 1), dfft).backward() assert np.linalg.norm(uf-duq) < 1e-5 bases.pop(axis) fft.destroy() dfft.destroy()
def test_shentransform(typecode, dim, ST, quad): for shape in product(*([sizes]*dim)): 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): ST0 = ST(shape[-1], quad=quad) bases.insert(axis, ST0) fft = TensorProductSpace(comm, bases, dtype=typecode) U = random_like(fft.forward.input_array) F = fft.forward(U) Fc = F.copy() V = fft.backward(F) F = fft.forward(U) assert allclose(F, Fc) bases.pop(axis) fft.destroy()
def test_project_lag(typecode, dim): # Using sympy to compute an analytical solution x, y, z = symbols("x,y,z") sizes = (20, 17) funcs = { (1, 0): (cos(4*y)*sin(2*x))*exp(-x), (1, 1): (cos(4*x)*sin(2*y))*exp(-y), (2, 0): (sin(3*z)*cos(4*y)*sin(2*x))*exp(-x), (2, 1): (sin(2*z)*cos(4*x)*sin(2*y))*exp(-y), (2, 2): (sin(2*x)*cos(4*y)*sin(2*z))*exp(-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)) for axis in range(dim+1): ST1 = lagBasis[1](3*shape[-1]) bases.insert(axis, ST1) fft = TensorProductSpace(comm, bases, dtype=typecode, axes=axes[dim][axis]) dfft = fft.get_orthogonal() X = fft.local_mesh(True) ue = funcs[(dim, axis)] due = ue.diff(xs[0], 1) u_h = project(ue, fft) du_h = project(due, dfft) du2 = project(Dx(u_h, 0, 1), dfft) uf = u_h.backward() assert np.linalg.norm(du2-du_h) < 1e-3 bases.pop(axis) fft.destroy() dfft.destroy()
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 = (22, 21) 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) } 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) } 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) } funcs = { (1, 0): cos(2 * y) * funcx[ST.boundary_condition()], (1, 1): cos(2 * x) * funcy[ST.boundary_condition()], (2, 0): sin(6 * 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(Basis(n, 'F', dtype=typecode.upper())) bases.append(Basis(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') uu = ul(*X).astype(typecode) uq = ul(*points).astype(typecode) u_hat = Function(fft) u_hat = fft.forward(uu, u_hat) t0 = time() result = fft.eval(points, u_hat, method=0) t_0 += time() - t0 assert np.allclose(uq, result, 0, 1e-6) t0 = time() result = fft.eval(points, u_hat, method=1) t_1 += time() - t0 assert np.allclose(uq, result, 0, 1e-6) t0 = time() result = fft.eval(points, u_hat, method=2) t_2 += time() - t0 print(uq) assert np.allclose(uq, result, 0, 1e-6), uq / result 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() print('method=0', t_0) print('method=1', t_1) print('method=2', t_2)
def test_transform(typecode, dim): s = (True, ) if comm.Get_size() > 2 and dim > 2: s = (True, False) for slab in s: 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)) fft = TensorProductSpace(comm, bases, dtype=typecode, slab=slab) if comm.rank == 0: grid = [c.size for c in fft.subcomm] print('grid:{} shape:{} typecode:{}'.format( grid, shape, typecode)) U = random_like(fft.forward.input_array) F = fft.forward(U) V = fft.backward(F) assert allclose(V, U) # Alternative method fft.forward.input_array[...] = U fft.forward(fast_transform=False) fft.backward(fast_transform=False) V = fft.backward.output_array assert allclose(V, U) TT = VectorTensorProductSpace(fft) U = Array(TT) V = Array(TT) F = Function(TT) U[:] = random_like(U) F = TT.forward(U, F) V = TT.backward(F, V) assert allclose(V, U) TM = MixedTensorProductSpace([fft, fft]) U = Array(TM) V = Array(TM) F = Function(TM) U[:] = random_like(U) F = TM.forward(U, F) V = TM.backward(F, V) assert allclose(V, U) fft.destroy() padding = 1.5 bases = [] for n in shape[:-1]: bases.append( Basis(n, 'F', dtype=typecode.upper(), padding_factor=padding)) bases.append( Basis(shape[-1], 'F', dtype=typecode, padding_factor=padding)) fft = TensorProductSpace(comm, bases, dtype=typecode) if comm.rank == 0: grid = [c.size for c in fft.subcomm] print('grid:{} shape:{} typecode:{}'.format( grid, shape, typecode)) U = random_like(fft.forward.input_array) F = fft.forward(U) Fc = F.copy() V = fft.backward(F) F = fft.forward(V) assert allclose(F, Fc) # Alternative method fft.backward.input_array[...] = F fft.backward() fft.forward() V = fft.forward.output_array assert allclose(F, V) fft.destroy()
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()