def test_hessian(): from pyiga.approx import interpolate # 2D test kvs = 2 * (make_knots(3, 0.0, 1.0, 4),) grid = 2 * (np.linspace(0, 1, 7),) u = BSplineFunc(kvs, interpolate(kvs, lambda x,y: x**2 + 4*x*y + 3*y**2)) hess = u.grid_hessian(grid) assert np.allclose(hess, [2.0, 4.0, 6.0]) # (xx, xy, yy) # 3D test kvs = 3 * (make_knots(3, 0.0, 1.0, 4),) grid = 3 * (np.linspace(0, 1, 5),) u = BSplineFunc(kvs, interpolate(kvs, lambda x,y,z: x**2 + 3*x*z + 2*y*z)) hess = u.grid_hessian(grid) assert np.allclose(hess, [2.0, 0.0, 3.0, 0.0, 2.0, 0.0]) # (xx, xy, xz, yy, yz, zz) # 2D vector test kvs = 2 * (make_knots(3, 0.0, 1.0, 4),) grid = 2 * (np.linspace(0, 1, 7),) u = BSplineFunc(kvs, interpolate(kvs, lambda x,y: (x**2 + 4*x*y, 3*y**2))) hess = u.grid_hessian(grid) assert np.allclose(hess, [[2.0, 4.0, 0.0], [0.0, 0.0, 6.0]]) # (xx, xy, yy) # 3D vector test kvs = 3 * (make_knots(3, 0.0, 1.0, 4),) grid = 3 * (np.linspace(0, 1, 5),) u = BSplineFunc(kvs, interpolate(kvs, lambda x,y,z: (x**2, 3*x*z, 2*y*z))) hess = u.grid_hessian(grid) assert np.allclose(hess, # (xx, xy, xz, yy, yz, zz) [[2.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 3.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 2.0, 0.0]])
def test_assemble_asym(): kv1 = bspline.make_knots(4, 0.0, 1.0, 10) kv2 = bspline.make_knots(1, 0.0, 1.0, 20) K_12 = bsp_mixed_deriv_biform_1d_asym(kv1, kv2, 1, 0, quadgrid=kv2.mesh) assert(K_12.shape[0] == kv2.numdofs) assert(K_12.shape[1] == kv1.numdofs) u = interpolate(kv1, lambda x: x**4) v = interpolate(kv2, lambda x: 1.0) itg = K_12.dot(u).dot(v) assert abs(itg - 1.0) < 1e-10 # int(4*x^3, 0, 1) = 1
def test_interpolation(): kv = make_knots(3, 0.0, 1.0, 10) # create random spline coeffs = np.random.rand(kv.numdofs) def f(x): return ev(kv, coeffs, x) # interpolate it at Gréville points and check that result is the same result = interpolate(kv, f) assert np.allclose(coeffs, result) ## # test for p=0 kv = make_knots(0, 0.0, 1.0, 10) coeffs = np.random.rand(kv.numdofs) def f(x): return ev(kv, coeffs, x) # interpolate it at Gréville points and check that result is the same result = interpolate(kv, f) assert np.allclose(coeffs, result)
def test_animate_field(): kvs = 2 * (bspline.make_knots(2, 0.0, 1.0, 5),) fields = [ bspline.BSplineFunc(kvs, approx.interpolate(kvs, lambda x,y: np.sin(t+x) * np.exp(y))) for t in range(3) ] anim = animate_field(fields, geo=geometry.bspline_quarter_annulus(), res=10) anim.to_jshtml()
def test_divdiv_geo_2d(): kv = bspline.make_knots(3, 0.0, 1.0, 15) geo = geometry.bspline_quarter_annulus() A = divdiv((kv,kv), geo, layout='packed') # construct divergence-free function from pyiga.approx import interpolate u = interpolate((kv,kv), lambda x,y: (x,-y), geo=geo).ravel() assert abs(A.dot(u)).max() < 1e-12
def test_trf_gradient(): geo = bspline_quarter_annulus() u_coeffs = approx.interpolate(geo.kvs, lambda x, y: x - y, geo=geo) u = BSplineFunc(geo.kvs, u_coeffs) u_grad = u.transformed_jacobian(geo) grd = 2 * (np.linspace(0, 1, 10), ) grads = u_grad.grid_eval(grd) assert np.allclose(grads[:, :, 0], 1) and np.allclose(grads[:, :, 1], -1)
def test_mixed_deriv_biform(): kv = bspline.make_knots(4, 0.0, 1.0, 20) DxxD0 = bsp_mixed_deriv_biform_1d(kv, 2, 0) DxxDx = bsp_mixed_deriv_biform_1d(kv, 2, 1) u = interpolate(kv, lambda x: x) # second derivative of linear function x -> x is 0 assert abs(DxxD0.dot(u)).max() < 1e-10 assert abs(DxxDx.dot(u)).max() < 1e-10
def test_plot_field(): def f(x, y): return np.sin(x) * np.exp(y) geo = geometry.quarter_annulus() plot_field(f, physical=True, geo=geo, res=10) # kvs = 2 * (bspline.make_knots(2, 0.0, 1.0, 5),) u = bspline.BSplineFunc(kvs, approx.interpolate(kvs, f)) plot_field(u, res=10) plot_field(u, geo=geo, res=10)
def test_mass_asym(): kv1 = bspline.make_knots(4, 0.0, 1.0, 10) kv2 = bspline.make_knots(1, 0.0, 1.0, 20) M_12 = bsp_mass_1d_asym(kv1, kv2, quadgrid=kv2.mesh) assert(M_12.shape[0] == kv2.numdofs) assert(M_12.shape[1] == kv1.numdofs) u = interpolate(kv1, lambda x: x**4) itg = M_12.dot(u).dot(np.ones(kv2.numdofs)) assert abs(itg - 1.0/5) < 1e-10 # int(x^4, 0, 1) = 1/5
def test_solution_1d(): # solve -u''(x) = 1, u(0) = 0, u(1) = 1 kv = bspline.make_knots(2, 0.0, 1.0, 10) A = stiffness(kv) f = inner_products(kv, lambda x: 1.0) LS = RestrictedLinearSystem(A, f, [(0,kv.numdofs-1), (0.0,1.0)]) u = LS.complete(np.linalg.solve(LS.A.A, LS.b)) u_ex = interpolate(kv, lambda x: 0.5*x*(3-x)) assert np.linalg.norm(u - u_ex) < 1e-12
def test_divdiv_geo_2d(): kv = bspline.make_knots(3, 0.0, 1.0, 15) geo = geometry.bspline_quarter_annulus() A = divdiv((kv,kv), geo, layout='packed', format='bsr') # construct divergence-free function u = interpolate((kv,kv), lambda x,y: (x,-y), geo=geo) assert abs(A.dot(u.ravel())).max() < 1e-12 # test blocked layout A = divdiv((kv,kv), geo, layout='blocked') u_blocked = np.moveaxis(u, -1, 0) # move last axis to the front assert abs(A.dot(u_blocked.ravel())).max() < 1e-12
def test_deriv(): # create linear spline kv = make_knots(4, 0.0, 1.0, 25) coeffs = interpolate(kv, lambda x: 1.0 + 2.5*x) # check that derivative is 2.5 x = np.linspace(0.0, 1.0, 100) drv = deriv(kv, coeffs, 1, x) assert np.linalg.norm(drv - 2.5) < 1e-10 # create random spline coeffs = np.random.rand(kv.numdofs) # compare derivatives by two methods derivs1 = deriv(kv, coeffs, 1, x) derivs2 = deriv(kv, coeffs, 2, x) allders = collocation_derivs(kv, x, derivs=2) assert np.linalg.norm(derivs1 - allders[1].dot(coeffs), np.inf) < 1e-10 assert np.linalg.norm(derivs2 - allders[2].dot(coeffs), np.inf) < 1e-10
def test_assemble_nonsym_vec(): kvs = 2 * (bspline.make_knots(2, 0.0, 1.0, 5),) geo = geometry.quarter_annulus() problem = 'inner(as_matrix([[2,1],[0,0]]).dot(u), v) * dx' A = assemble(problem, kvs, geo=geo, bfuns=[('u',2), ('v',2)], layout='packed', format='bsr') u = interpolate(kvs, lambda x, y: (x*y, -2*x*y), geo=geo) assert np.allclose(A @ u.ravel(), 0) # test the blockwise assembling using multi_blocks asm = instantiate_assembler(problem, kvs, args={'geo': geo}, bfuns=[('u',2), ('v',2)]) blocks = np.array(asm.multi_blocks([(0,0), (0,1), (2,1)])) AA = A.A # bsr does not support slicing assert np.array_equal(blocks[0], AA[0:2, 0:2]) assert np.array_equal(blocks[1], AA[0:2, 2:4]) assert np.array_equal(blocks[2], AA[4:6, 2:4]) # test blocked layout A = assemble(problem, kvs, geo=geo, bfuns=[('u',2), ('v',2)], layout='blocked') u_blocked = np.moveaxis(u, -1, 0) # move last axis to the front assert np.allclose(A @ u_blocked.ravel(), 0)