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_2dirichlet(quad): x, y = symbols("x,y") ue = (cos(4*y)*sin(2*x))*(1-x**2)*(1-y**2) sizes = (18, 17) D0 = lbases.ShenDirichlet(sizes[0], quad=quad) D1 = lbases.ShenDirichlet(sizes[1], quad=quad) B0 = lbases.Orthogonal(sizes[0], quad=quad) B1 = lbases.Orthogonal(sizes[1], quad=quad) DD = TensorProductSpace(comm, (D0, D1)) BD = TensorProductSpace(comm, (B0, D1)) DB = TensorProductSpace(comm, (D0, B1)) BB = TensorProductSpace(comm, (B0, B1)) X = DD.local_mesh(True) uh = Function(DD, buffer=ue) dudx_hat = project(Dx(uh, 0, 1), BD) dx = Function(BD, buffer=ue.diff(x, 1)) assert np.allclose(dx, dudx_hat, 0, 1e-5) dudy = project(Dx(uh, 1, 1), DB).backward() duedy = Array(DB, buffer=ue.diff(y, 1)) assert np.allclose(duedy, dudy, 0, 1e-5) us_hat = Function(BB) uq = uh.backward() us = project(uq, BB, output_array=us_hat).backward() assert np.allclose(us, uq, 0, 1e-5) dudxy = project(Dx(us_hat, 0, 1) + Dx(us_hat, 1, 1), BB).backward() dxy = Array(BB, buffer=ue.diff(x, 1) + ue.diff(y, 1)) assert np.allclose(dxy, dudxy, 0, 1e-5), np.linalg.norm(dxy-dudxy)
def standardConvection(rhs, u_dealias, u_hat, K, VFSp, FSTp, FCTp, work, mat, la): rhs[:] = 0 U = u_dealias Uc = work[(U, 1, True)] Uc2 = work[(U, 2, True)] # dudx = 0 on walls from continuity equation. Use Shen Dirichlet basis # Use regular Chebyshev basis for dvdx and dwdx dudx = project(Dx(u_hat[0], 0, 1), FSTp).backward() dvdx = project(Dx(u_hat[1], 0, 1), FCTp).backward() dwdx = project(Dx(u_hat[2], 0, 1), FCTp).backward() dudy = Uc2[0] = FSTp.backward(1j * K[1] * u_hat[0], Uc2[0]) dudz = Uc2[1] = FSTp.backward(1j * K[2] * u_hat[0], Uc2[1]) rhs[0] = FSTp.forward(U[0] * dudx + U[1] * dudy + U[2] * dudz, rhs[0]) Uc2[:] = 0 dvdy = Uc2[0] = FSTp.backward(1j * K[1] * u_hat[1], Uc2[0]) dvdz = Uc2[1] = FSTp.backward(1j * K[2] * u_hat[1], Uc2[1]) rhs[1] = FSTp.forward(U[0] * dvdx + U[1] * dvdy + U[2] * dvdz, rhs[1]) Uc2[:] = 0 dwdy = Uc2[0] = FSTp.backward(1j * K[1] * u_hat[2], Uc2[0]) dwdz = Uc2[1] = FSTp.backward(1j * K[2] * u_hat[2], Uc2[1]) rhs[2] = FSTp.forward(U[0] * dwdx + U[1] * dwdy + U[2] * dwdz, rhs[2]) return rhs
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_curl2(): # Test projection of curl K0 = FunctionSpace(N[0], 'C', bc=(0, 0)) K1 = FunctionSpace(N[1], 'F', dtype='D') K2 = FunctionSpace(N[2], 'F', dtype='d') K3 = FunctionSpace(N[0], 'C') T = TensorProductSpace(comm, (K0, K1, K2)) TT = TensorProductSpace(comm, (K3, K1, K2)) X = T.local_mesh(True) K = T.local_wavenumbers(False) Tk = VectorSpace(T) TTk = VectorSpace([T, T, TT]) U = Array(Tk) U_hat = Function(Tk) curl_hat = Function(TTk) curl_ = Array(TTk) # Initialize a Taylor Green vortex U[0] = np.sin(X[0]) * np.cos(X[1]) * np.cos(X[2]) * (1 - X[0]**2) U[1] = -np.cos(X[0]) * np.sin(X[1]) * np.cos(X[2]) * (1 - X[0]**2) U[2] = 0 U_hat = Tk.forward(U, U_hat) Uc = U_hat.copy() U = Tk.backward(U_hat, U) U_hat = Tk.forward(U, U_hat) assert allclose(U_hat, Uc) # Compute curl first by computing each term individually curl_hat[0] = 1j * (K[1] * U_hat[2] - K[2] * U_hat[1]) curl_[0] = T.backward( curl_hat[0], curl_[0]) # No x-derivatives, still in Dirichlet space dwdx_hat = project(Dx(U_hat[2], 0, 1), TT) # Need to use space without bc dvdx_hat = project(Dx(U_hat[1], 0, 1), TT) # Need to use space without bc dwdx = Array(TT) dvdx = Array(TT) dwdx = TT.backward(dwdx_hat, dwdx) dvdx = TT.backward(dvdx_hat, dvdx) curl_hat[1] = 1j * K[2] * U_hat[0] curl_hat[2] = -1j * K[1] * U_hat[0] curl_[1] = T.backward(curl_hat[1], curl_[1]) curl_[2] = T.backward(curl_hat[2], curl_[2]) curl_[1] -= dwdx curl_[2] += dvdx # Now do it with project w_hat = project(curl(U_hat), TTk) w = Array(TTk) w = TTk.backward(w_hat, w) assert allclose(w, curl_)
def test_project_2dirichlet(quad): x, y = symbols("x,y") ue = (cos(4 * y) * sin(2 * x)) * (1 - x**2) * (1 - y**2) sizes = (25, 24) D0 = lbases.ShenDirichletBasis(sizes[0], quad=quad) D1 = lbases.ShenDirichletBasis(sizes[1], quad=quad) B0 = lbases.Basis(sizes[0], quad=quad) B1 = lbases.Basis(sizes[1], quad=quad) DD = TensorProductSpace(comm, (D0, D1)) BD = TensorProductSpace(comm, (B0, D1)) DB = TensorProductSpace(comm, (D0, B1)) BB = TensorProductSpace(comm, (B0, B1)) X = DD.local_mesh(True) ul = lambdify((x, y), ue, 'numpy') uq = Array(DD) uq[:] = ul(*X) uh = Function(DD) uh = DD.forward(uq, uh) dudx_hat = project(Dx(uh, 0, 1), BD) dudx = Array(BD) dudx = BD.backward(dudx_hat, dudx) duedx = ue.diff(x, 1) duxl = lambdify((x, y), duedx, 'numpy') dx = duxl(*X) assert np.allclose(dx, dudx) dudy_hat = project(Dx(uh, 1, 1), DB) dudy = Array(DB) dudy = DB.backward(dudy_hat, dudy) duedy = ue.diff(y, 1) duyl = lambdify((x, y), duedy, 'numpy') dy = duyl(*X) assert np.allclose(dy, dudy) us_hat = Function(BB) us_hat = project(uq, BB, output_array=us_hat) us = Array(BB) us = BB.backward(us_hat, us) assert np.allclose(us, uq) dudxy_hat = project(Dx(us_hat, 0, 1) + Dx(us_hat, 1, 1), BB) dudxy = Array(BB) dudxy = BB.backward(dudxy_hat, dudxy) duedxy = ue.diff(x, 1) + ue.diff(y, 1) duxyl = lambdify((x, y), duedxy, 'numpy') dxy = duxyl(*X) assert np.allclose(dxy, dudxy)
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_eval_expression(): import sympy as sp from shenfun import div, grad x, y, z = sp.symbols('x,y,z') B0 = Basis(16, 'C') B1 = Basis(17, 'C') B2 = Basis(20, 'F', dtype='d') TB = TensorProductSpace(comm, (B0, B1, B2)) f = sp.sin(x)+sp.sin(y)+sp.sin(z) dfx = f.diff(x, 2) + f.diff(y, 2) + f.diff(z, 2) fa = Array(TB, buffer=f).forward() dfe = div(grad(fa)) dfa = project(dfe, TB) xyz = np.array([[0.25, 0.5, 0.75], [0.25, 0.5, 0.75], [0.25, 0.5, 0.75]]) f0 = lambdify((x, y, z), dfx)(*xyz) f1 = dfe.eval(xyz) f2 = dfa.eval(xyz) assert np.allclose(f0, f1, 1e-7) assert np.allclose(f1, f2, 1e-7)
def test_tensor2(): B0 = shenfun.FunctionSpace(8, 'C') T = shenfun.TensorProductSpace(comm, (B0, B0)) x, y = sp.symbols('x,y') ue = x**2 + y**2 ua = shenfun.Array(T, buffer=ue) uh = ua.forward() M = shenfun.VectorSpace(T) gradu = shenfun.project(grad(uh), M) V = shenfun.TensorSpace(T) gradgradu = shenfun.project(grad(grad(uh)), V) g = gradgradu.backward() assert np.allclose(g.v[0], 2) assert np.allclose(g.v[1], 0) assert np.allclose(g.v[2], 0) assert np.allclose(g.v[3], 2)
def test_curl_cc(): theta, phi = sp.symbols('x,y', real=True, positive=True) psi = (theta, phi) r = 1 rv = (r * sp.sin(theta) * sp.cos(phi), r * sp.sin(theta) * sp.sin(phi), r * sp.cos(theta)) # Manufactured solution sph = sp.functions.special.spherical_harmonics.Ynm ue = sph(6, 3, theta, phi) N, M = 16, 12 L0 = FunctionSpace(N, 'C', domain=(0, np.pi)) F1 = FunctionSpace(M, 'F', dtype='D') T = TensorProductSpace(comm, (L0, F1), coordinates=(psi, rv)) u_hat = Function(T, buffer=ue) du = curl(grad(u_hat)) du.terms() == [[]] r, theta, z = psi = sp.symbols('x,y,z', real=True, positive=True) rv = (r * sp.cos(theta), r * sp.sin(theta), z) # Manufactured solution ue = (r * (1 - r) * sp.cos(4 * theta) - 1 * (r - 1)) * sp.cos(4 * z) N = 12 F0 = FunctionSpace(N, 'F', dtype='D') F1 = FunctionSpace(N, 'F', dtype='d') L = FunctionSpace(N, 'L', bc='Dirichlet', domain=(0, 1)) T = TensorProductSpace(comm, (L, F0, F1), coordinates=(psi, rv)) T1 = T.get_orthogonal() V = VectorSpace(T1) u_hat = Function(T, buffer=ue) du = project(curl(grad(u_hat)), V) assert np.linalg.norm(du) < 1e-10
def divergenceConvection(rhs, u_dealias, u_hat, K, VFSp, FSTp, FSBp, FCTp, work, mat, la, add=False): """c_i = div(u_i u_j)""" if not add: rhs.fill(0) F_tmp = Function(VFSp, buffer=work[(rhs, 0, True)]) F_tmp2 = Function(VFSp, buffer=work[(rhs, 1, True)]) U = u_dealias F_tmp[0] = FSTp.forward(U[0]*U[0], F_tmp[0]) F_tmp[1] = FSTp.forward(U[0]*U[1], F_tmp[1]) F_tmp[2] = FSTp.forward(U[0]*U[2], F_tmp[2]) F_tmp2 = project(Dx(F_tmp, 0, 1), VFSp, output_array=F_tmp2) rhs += F_tmp2 F_tmp2[0] = FSTp.forward(U[0]*U[1], F_tmp2[0]) F_tmp2[1] = FSTp.forward(U[0]*U[2], F_tmp2[1]) rhs[0] += 1j*K[1]*F_tmp2[0] # duvdy rhs[0] += 1j*K[2]*F_tmp2[1] # duwdz F_tmp[0] = FSTp.forward(U[1]*U[1], F_tmp[0]) F_tmp[1] = FSTp.forward(U[1]*U[2], F_tmp[1]) F_tmp[2] = FSTp.forward(U[2]*U[2], F_tmp[2]) rhs[1] += 1j*K[1]*F_tmp[0] # dvvdy rhs[1] += 1j*K[2]*F_tmp[1] # dvwdz rhs[2] += 1j*K[1]*F_tmp[1] # dvwdy rhs[2] += 1j*K[2]*F_tmp[2] # dwwdz return rhs
def get_divergence(U_hat, FST, mask, **context): div_hat = project(div(U_hat), FST) if mask is not None: div_hat.mask_nyquist(mask) div_ = Array(FST) div_ = div_hat.backward(div_) return div_
def compute_cauchy_stresses(self, u_hat): assert isinstance(u_hat, sf.Function) space = u_hat[0].function_space().get_orthogonal() dim = len(space.bases) # number of dofs for each component N = [u_hat.function_space().spaces[0].bases[i].N for i in range(dim)] lmbda, mu = self._material_parameters # displacement gradient H = np.empty(shape=(dim, dim, *N)) for i in range(dim): for j in range(dim): H[i, j] = sf.project(Dx(u_hat[i], j), space).backward() # linear strain tensor E = 0.5 * (H + np.swapaxes(H, 0, 1)) # trace of linear strain tensor trE = np.trace(E) # create block with identity matrices on diagonal identity = np.zeros_like(H) for i in range(dim): identity[i, i] = np.ones(N) # Cauchy stress tensor T = 2.0 * mu * E + lmbda * trE * identity return T, space
def test_project_1D(basis): ue = sin(2*np.pi*x)*(1-x**2) T = basis(12) u = shenfun.TrialFunction(T) v = shenfun.TestFunction(T) u_tilde = shenfun.Function(T) X = T.mesh() ua = shenfun.Array(T, buffer=ue) u_tilde = shenfun.inner(v, ua, output_array=u_tilde) M = shenfun.inner(u, v) u_p = shenfun.Function(T) u_p = M.solve(u_tilde, u=u_p) u_0 = shenfun.Function(T) u_0 = shenfun.project(ua, T) assert np.allclose(u_0, u_p) u_1 = shenfun.project(ue, T) assert np.allclose(u_1, u_p)
def test_tensor2(): B0 = shenfun.FunctionSpace(8, 'C') T = shenfun.TensorProductSpace(comm, (B0, B0)) x, y = sp.symbols('x,y') ue = x**2 + y**2 ua = shenfun.Array(T, buffer=ue) uh = ua.forward() M = shenfun.VectorSpace(T) gradu = shenfun.project(grad(uh), M)
def test_curl(typecode): K0 = Basis(N[0], 'F', dtype=typecode.upper()) K1 = Basis(N[1], 'F', dtype=typecode.upper()) K2 = Basis(N[2], 'F', dtype=typecode) T = TensorProductSpace(comm, (K0, K1, K2), dtype=typecode) X = T.local_mesh(True) K = T.local_wavenumbers() Tk = VectorTensorProductSpace(T) u = TrialFunction(Tk) v = TestFunction(Tk) U = Array(Tk) U_hat = Function(Tk) curl_hat = Function(Tk) curl_ = Array(Tk) # Initialize a Taylor Green vortex U[0] = np.sin(X[0]) * np.cos(X[1]) * np.cos(X[2]) U[1] = -np.cos(X[0]) * np.sin(X[1]) * np.cos(X[2]) U[2] = 0 U_hat = Tk.forward(U, U_hat) Uc = U_hat.copy() U = Tk.backward(U_hat, U) U_hat = Tk.forward(U, U_hat) assert allclose(U_hat, Uc) divu_hat = project(div(U_hat), T) divu = Array(T) divu = T.backward(divu_hat, divu) assert allclose(divu, 0) curl_hat[0] = 1j * (K[1] * U_hat[2] - K[2] * U_hat[1]) curl_hat[1] = 1j * (K[2] * U_hat[0] - K[0] * U_hat[2]) curl_hat[2] = 1j * (K[0] * U_hat[1] - K[1] * U_hat[0]) curl_ = Tk.backward(curl_hat, curl_) w_hat = Function(Tk) w_hat = inner(v, curl(U_hat), output_array=w_hat) A = inner(v, u) for i in range(3): w_hat[i] = A[i].solve(w_hat[i]) w = Array(Tk) w = Tk.backward(w_hat, w) #from IPython import embed; embed() assert allclose(w, curl_) u_hat = Function(Tk) u_hat = inner(v, U, output_array=u_hat) for i in range(3): u_hat[i] = A[i].solve(u_hat[i]) uu = Array(Tk) uu = Tk.backward(u_hat, uu) assert allclose(u_hat, U_hat)
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 compute_hyper_stresses(self, u_hat): assert isinstance(u_hat, sf.Function) space = u_hat[0].function_space() dim = len(space.bases) c1, c2, c3, c4, c5 = self._material_parameters[2:] N = [u_hat.function_space().spaces[0].bases[i].N for i in range(dim)] Laplace = np.zeros(shape=(dim, *N)) for i in range(dim): for j in range(dim): Laplace[i] += sf.project(Dx(u_hat[i], j, 2), space).backward() GradDiv = np.zeros(shape=(dim, *N)) for i in range(dim): for j in range(dim): GradDiv[i] += sf.project( Dx(Dx(u_hat[j], j), i), space ).backward() GradGrad = np.empty(shape=(dim, dim, dim, *N)) for i in range(dim): for j in range(dim): for k in range(dim): GradGrad[i, j, k] = sf.project( Dx(Dx(u_hat[i], j), k), space ).backward() identity = np.identity(dim) # hyper stresses T = c1 * np.swapaxes(np.tensordot(identity, Laplace, axes=0), 0, 2) \ + c2 / 2.0 * (np.tensordot(identity, Laplace, axes=0) + np.swapaxes(np.tensordot(identity, Laplace, axes=0), 1, 2) ) \ + c3 / 2.0 * (np.tensordot(identity, GradDiv, axes=0) + np.swapaxes(np.tensordot(identity, GradDiv, axes=0), 1, 2) ) \ + c4 * GradGrad \ + c5 / 2.0 * (np.swapaxes(GradGrad, 0, 1) + np.swapaxes(GradGrad, 0, 2)) return T, space
def test_CDDmat(quad): M = 48 SD = cbases.ShenDirichlet(M, quad=quad) u = (1-x**2)*sin(np.pi*6*x) dudx = u.diff(x, 1) dudx_hat = shenfun.Function(SD, buffer=dudx) u_hat = shenfun.Function(SD, buffer=u) ducdx_hat = shenfun.project(shenfun.Dx(u_hat, 0, 1), SD) assert np.linalg.norm(ducdx_hat-dudx_hat)/M < 1e-10, np.linalg.norm(ducdx_hat-dudx_hat)/M # Multidimensional version SD0 = cbases.ShenDirichlet(8, quad=quad) SD1 = cbases.ShenDirichlet(M, quad=quad) T = shenfun.TensorProductSpace(shenfun.comm, (SD0, SD1)) u = (1-y**2)*sin(np.pi*6*y) dudy = u.diff(y, 1) dudy_hat = shenfun.Function(T, buffer=dudy) u_hat = shenfun.Function(T, buffer=u) ducdy_hat = shenfun.project(shenfun.Dx(u_hat, 1, 1), T) assert np.linalg.norm(ducdy_hat-dudy_hat)/M < 1e-10, np.linalg.norm(ducdy_hat-dudy_hat)/M
def test_backward2D(): T = FunctionSpace(N, 'C') L = FunctionSpace(N, 'L') F = FunctionSpace(N, 'F', dtype='d') TT = TensorProductSpace(comm, (T, F)) TL = TensorProductSpace(comm, (L, F)) uT = Function(TT, buffer=f) uL = Function(TL, buffer=f) u2 = uL.backward(kind=TT) uT2 = project(u2, TT) assert np.linalg.norm(uT2 - uT) TT = TensorProductSpace(comm, (F, T)) TL = TensorProductSpace(comm, (F, L)) uT = Function(TT, buffer=f) uL = Function(TL, buffer=f) u2 = uL.backward(kind=TT) uT2 = project(u2, TT) assert np.linalg.norm(uT2 - uT)
def test_backward2ND(): T0 = FunctionSpace(N, 'C') L0 = FunctionSpace(N, 'L') T1 = FunctionSpace(N, 'C') L1 = FunctionSpace(N, 'L') TT = TensorProductSpace(comm, (T0, T1)) LL = TensorProductSpace(comm, (L0, L1)) uT = Function(TT, buffer=h) uL = Function(LL, buffer=h) u2 = uL.backward(kind=TT) uT2 = project(u2, TT) assert np.linalg.norm(uT2 - uT)
def test_backward3D(): T = FunctionSpace(N, 'C') L = FunctionSpace(N, 'L') F0 = FunctionSpace(N, 'F', dtype='D') F1 = FunctionSpace(N, 'F', dtype='d') TT = TensorProductSpace(comm, (F0, T, F1)) TL = TensorProductSpace(comm, (F0, L, F1)) uT = Function(TT, buffer=h) uL = Function(TL, buffer=h) u2 = uL.backward(kind=TT) uT2 = project(u2, TT) assert np.linalg.norm(uT2 - uT)
def standardConvection(rhs, u_dealias, u_hat, K, VFSp, FSTp, FSBp, FCTp, work, mat, la): rhs[:] = 0 U = u_dealias Uc = work[(U, 1, True)] Uc2 = work[(U, 2, True)] F_tmp = work[(rhs, 0, True)] # dudx = 0 from continuity equation. Use Shen Dirichlet basis # Use regular Chebyshev basis for dvdx and dwdx #F_tmp[0] = mat.CDB.matvec(u_hat[0], F_tmp[0]) #F_tmp[0] = la.TDMASolverD(F_tmp[0]) #dudx = Uc[0] = FSTp.backward(F_tmp[0], Uc[0]) #LUsolve.Mult_CTD_3D(params.N[0], u_hat[1], u_hat[2], F_tmp[1], F_tmp[2]) #dvdx = Uc[1] = FCTp.backward(F_tmp[1], Uc[1]) #dwdx = Uc[2] = FCTp.backward(F_tmp[2], Uc[2]) dudx = project(Dx(u_hat[0], 0, 1), FSTp).backward() dvdx = project(Dx(u_hat[1], 0, 1), FCTp).backward() dwdx = project(Dx(u_hat[2], 0, 1), FCTp).backward() dudy = Uc2[0] = FSBp.backward(1j*K[1]*u_hat[0], Uc2[0]) dudz = Uc2[1] = FSBp.backward(1j*K[2]*u_hat[0], Uc2[1]) rhs[0] = FSTp.forward(U[0]*dudx + U[1]*dudy + U[2]*dudz, rhs[0]) Uc2[:] = 0 dvdy = Uc2[0] = FSTp.backward(1j*K[1]*u_hat[1], Uc2[0]) dvdz = Uc2[1] = FSTp.backward(1j*K[2]*u_hat[1], Uc2[1]) rhs[1] = FSTp.forward(U[0]*dvdx + U[1]*dvdy + U[2]*dvdz, rhs[1]) Uc2[:] = 0 dwdy = Uc2[0] = FSTp.backward(1j*K[1]*u_hat[2], Uc2[0]) dwdz = Uc2[1] = FSTp.backward(1j*K[2]*u_hat[2], Uc2[1]) rhs[2] = FSTp.forward(U[0]*dwdx + U[1]*dwdy + U[2]*dwdz, rhs[2]) return rhs
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_backward(): T = FunctionSpace(N, 'C') L = FunctionSpace(N, 'L') uT = Function(T, buffer=f) uL = Function(L, buffer=f) uLT = uL.backward(kind=T) uT2 = project(uLT, T) assert np.linalg.norm(uT2 - uT) < 1e-8 uTL = uT.backward(kind=L) uL2 = project(uTL, L) assert np.linalg.norm(uL2 - uL) < 1e-8 T2 = FunctionSpace(N, 'C', bc=(f.subs(x, -1), f.subs(x, 1))) L = FunctionSpace(N, 'L') uT = Function(T2, buffer=f) uL = Function(L, buffer=f) uLT = uL.backward(kind=T2) uT2 = project(uLT, T2) assert np.linalg.norm(uT2 - uT) < 1e-8
def test_to_ortho(basis, quad): N = 10 if basis.family() == 'legendre': B1 = lBasis[0](N, quad) #B3 = lBasis[0](N, quad) elif basis.family() == 'chebyshev': if basis.short_name() == 'DU': B1 = cBasisGC[0](N, quad) else: B1 = cBasis[0](N, quad) #B3 = cBasis[0](N, quad) elif basis.family() == 'laguerre': B1 = laBasis[0](N, quad) #B3 = laBasis[0](N, quad) B0 = basis(N, quad=quad) a = shenfun.Array(B0) a_hat = shenfun.Function(B0) b0_hat = shenfun.Function(B1) b1_hat = shenfun.Function(B1) a[:] = np.random.random(a.shape) a_hat = a.forward(a_hat) b0_hat = shenfun.project(a_hat, B1, output_array=b0_hat, fill=False, use_to_ortho=True) b1_hat = shenfun.project(a_hat, B1, output_array=b1_hat, fill=False, use_to_ortho=False) assert np.linalg.norm(b0_hat-b1_hat) < 1e-10 #B2 = basis(N, quad=quad) TD = shenfun.TensorProductSpace(shenfun.comm, (B0, B0)) TC = shenfun.TensorProductSpace(shenfun.comm, (B1, B1)) a = shenfun.Array(TD) a_hat = shenfun.Function(TD) b0_hat = shenfun.Function(TC) b1_hat = shenfun.Function(TC) a[:] = np.random.random(a.shape) a_hat = a.forward(a_hat) b0_hat = shenfun.project(a_hat, TC, output_array=b0_hat, fill=False, use_to_ortho=True) b1_hat = shenfun.project(a_hat, TC, output_array=b1_hat, fill=False, use_to_ortho=False) assert np.linalg.norm(b0_hat-b1_hat) < 1e-10 F0 = shenfun.FunctionSpace(N, 'F') TD = shenfun.TensorProductSpace(shenfun.comm, (B0, F0)) TC = shenfun.TensorProductSpace(shenfun.comm, (B1, F0)) a = shenfun.Array(TD) a_hat = shenfun.Function(TD) b0_hat = shenfun.Function(TC) b1_hat = shenfun.Function(TC) a[:] = np.random.random(a.shape) a_hat = a.forward(a_hat) b0_hat = shenfun.project(a_hat, TC, output_array=b0_hat, fill=False, use_to_ortho=True) b1_hat = shenfun.project(a_hat, TC, output_array=b1_hat, fill=False, use_to_ortho=False) assert np.linalg.norm(b0_hat-b1_hat) < 1e-10
def check_with_pde(self, u_hat, material_parameters, body_forces): assert isinstance(u_hat, sf.Function) assert len(material_parameters) == self._n_material_parameters for comp in body_forces: assert isinstance(comp, (sp.Expr, float, int)) lambd, mu = material_parameters V = u_hat.function_space().get_orthogonal() # left hand side of pde lhs = (lambd + mu) * grad(div(u_hat)) + mu * div(grad(u_hat)) error_array = sf.Array(V, buffer=body_forces) error_array += sf.project(lhs, V).backward() error = np.sqrt(inner((1, 1), error_array ** 2)) # scale by magnitude of solution scale = np.sqrt(inner((1, 1), u_hat.backward() ** 2)) return error / scale
def to_ortho(self, input_array, output_array=None): """Project to orthogonal basis Parameters ---------- input_array : array Expansion coefficients of input basis output_array : array, optional Expansion coefficients in orthogonal basis Returns ------- array output_array """ from shenfun import project T = self.get_orthogonal() output_array = project(input_array, T, output_array=output_array, use_to_ortho=False) return output_array
def test_CXXmat(test, trial): test = test(N) trial = trial(N) CT = cBasis[0](N) Cm = inner_product((test, 0), (trial, 1)) S2 = Cm.trialfunction[0] S1 = Cm.testfunction[0] fj = shenfun.Array(S2, buffer=np.random.randn(N)) # project to S2 f_hat = fj.forward() fj = f_hat.backward(fj) # Check S1.scalar_product(f) equals Cm*S2.forward(f) f_hat = S2.forward(fj, f_hat) cs = np.zeros_like(f_hat) cs = Cm.matvec(f_hat, cs) df = shenfun.project(shenfun.grad(f_hat), CT).backward() cs2 = np.zeros(N) cs2 = S1.scalar_product(df, cs2) s = S1.slice() assert np.allclose(cs[s], cs2[s], rtol=1e-5, atol=1e-6) # Multidimensional version f_hat = f_hat.repeat(4 * 4).reshape( (N, 4, 4)) + 1j * f_hat.repeat(4 * 4).reshape((N, 4, 4)) df = df.repeat(4 * 4).reshape((N, 4, 4)) + 1j * df.repeat(4 * 4).reshape( (N, 4, 4)) cs = np.zeros_like(f_hat) cs = Cm.matvec(f_hat, cs) cs2 = np.zeros((N, 4, 4), dtype=np.complex) S1.tensorproductspace = ABC(3, S1.coors) S1.plan((N, 4, 4), 0, np.complex, {}) cs2 = S1.scalar_product(df, cs2) assert np.allclose(cs[s], cs2[s], rtol=1e-5, atol=1e-6)