def test_identity(): geo = identity([(3.0, 4.0), (5.0, 6.0)]) assert geo.dim == geo.sdim == 2 assert np.allclose(geo.eval(5, 3), (5, 3)) assert np.allclose(geo.eval(6, 4), (6, 4)) assert np.allclose(geo.eval(5.87, 3.21), (5.87, 3.21)) geo2 = identity([ bspline.make_knots(3, 3.0, 4.0, 10), bspline.make_knots(3, 5.0, 6.0, 5) ]) assert geos_roughly_equal(geo, geo2)
def test_nurbs(): kv = bspline.make_knots(2, 0.0, 1.0, 1) r = 2.0 # construct quarter circle using NURBS coeffs = np.array([[r, 0.0, 1.0], [r, r, 1.0 / np.sqrt(2.0)], [0.0, r, 1.0]]) grid = (np.linspace(0.0, 1.0, 20), ) nurbs = NurbsFunc((kv, ), coeffs.copy(), weights=None) vals = nurbs.grid_eval(grid) assert abs(r - np.linalg.norm(vals, axis=-1)).max() < 1e-12 nurbs = NurbsFunc((kv, ), coeffs[:, :2], weights=coeffs[:, -1]) vals = nurbs.grid_eval(grid) assert abs(r - np.linalg.norm(vals, axis=-1)).max() < 1e-12 assert nurbs.output_shape() == (2, ) assert nurbs.is_vector() nurbsx = nurbs[0] assert nurbsx.output_shape() == () assert nurbsx.is_scalar() assert nurbsx.grid_eval(grid).shape[1:] == () assert nurbsx.grid_jacobian(grid).shape[1:] == (1, ) assert nurbsx.grid_hessian(grid).shape[1:] == (1, )
def test_parse(): from pyiga import bspline, geometry kvs = 2 * (bspline.make_knots(2, 0.0, 1.0, 5), ) vf = parse_vf('u * v * dx', kvs, bfuns=[('u', 1), ('v', 1)]) assert vf.hash() == mass_vf(2).hash() f = bspline.BSplineFunc(kvs, np.ones(bspline.numdofs(kvs))) vf = parse_vf('f * v * dx', kvs, {'f': f}) assert vf.hash() == L2functional_vf(2, physical=False).hash() f = lambda x, y: 1.0 vf = parse_vf('f * v * dx', kvs, {'f': f}) assert vf.hash() == L2functional_vf(2, physical=True).hash() vf = parse_vf('div(u) * div(v) * dx', kvs, bfuns=[('u', 2), ('v', 2)]) assert vf.hash() == divdiv_vf(2).hash() # some other features vf = parse_vf('f * v * ds', kvs[:1], {'f': geometry.circular_arc(1.4)[0]}) vf = parse_vf('inner(f, v) * ds', kvs, bfuns=[('v', 2)], args={ 'f': lambda x, y: (-y, x) })
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_incidence(): kv = bspline.make_knots(2, 0.0, 1.0, 4) hs = HSpace((kv, )) hs.refine_region(0, lambda x: 1. / 4 < x < 3. / 4) hs.refine_region(1, lambda x: 3. / 8 < x < 5. / 8) Z = hs.incidence_matrix().A naf = tuple(len(A) for A in hs.active_indices()) # (6, 2, 2) nac = tuple(len(A) for A in hs.active_cells()) # (2, 2, 4) assert Z.shape == (sum(naf), sum(nac)) # rows: functions, columns: cells assert np.array_equal( Z, ###################### level 0 [ [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 1, 0, 1, 1, 0, 0], [1, 0, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1], [0, 1, 0, 1, 0, 0, 1, 1], [0, 1, 0, 0, 0, 0, 0, 0], ###################### level 1 [0, 0, 1, 0, 1, 1, 1, 1], [0, 0, 0, 1, 1, 1, 1, 1], ###################### level 2 [0, 0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 0, 0, 1, 1, 1] ])
def test_exact_poly(): for p in range(1, 5): for mult in range(1, p + 1): kv = bspline.make_knots(p, 0.0, 1.0, 5, mult=mult) f = lambda x: (x + 1)**p u = project_L2(kv, f) x = np.linspace(0, 1, 25) assert np.allclose(f(x), bspline.ev(kv, u, x))
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_twogrid(): kv_c = bspline.make_knots(3, 0.0, 1.0, 50) kv = kv_c.refine() P = bspline.prolongation(kv_c, kv) A = assemble.mass(kv) + assemble.stiffness(kv) f = bspline.load_vector(kv, lambda x: 1.0) S = SequentialSmoother( (GaussSeidelSmoother(), OperatorSmoother(1e-6 * np.eye(len(f))))) x = twogrid(A, f, P, S) assert np.linalg.norm(f - A.dot(x)) < 1e-6
def test_fastdiag_solver(): kvs = [ bspline.make_knots(4, 0.0, 1.0, 3), bspline.make_knots(3, 0.0, 1.0, 4), bspline.make_knots(2, 0.0, 1.0, 5) ] # compute Dirichlet matrices KM = [(assemble.stiffness(kv)[1:-1, 1:-1].A, assemble.mass(kv)[1:-1, 1:-1].A) for kv in kvs] solver = fastdiag_solver(KM) def multikron(*Xs): return reduce(np.kron, Xs) A = (multikron(KM[0][0], KM[1][1], KM[2][1]) + multikron(KM[0][1], KM[1][0], KM[2][1]) + multikron(KM[0][1], KM[1][1], KM[2][0])) f = np.random.rand(A.shape[0]) assert np.allclose(f, solver.dot(A.dot(f)))
def test_compare_intproj(): f = lambda x,y: np.cos(x)*np.exp(y) kvs = 2 * (bspline.make_knots(3, 0.0, 1.0, 50),) x1 = interpolate(kvs, f) x2 = project_L2(kvs, f) assert abs(x1-x2).max() < 1e-5 geo = geometry.bspline_quarter_annulus() x1 = interpolate(kvs, f, geo=geo) x2 = project_L2(kvs, f, f_physical=True, geo=geo) assert abs(x1-x2).max() < 1e-5
def test_tensorproduct(): kv = bspline.make_knots(2, 0.0, 1.0, 1) Gy = NurbsFunc(kv, np.reshape([0, .5, 1], (3, 1)), [1, 3, 1]) Gx = NurbsFunc(kv, np.reshape([0, .5, 1], (3, 1)), [1, 1.0 / 3.0, 1]) G = tensor_product(Gy, Gx) assert G.sdim == Gy.sdim + Gx.sdim assert G.dim == Gy.dim + Gx.dim Y, X = np.linspace(0, 1, 7), np.linspace(0, 1, 7) Vy, Vx = Gy.grid_eval((Y, )), Gx.grid_eval((X, )) V = G.grid_eval((Y, X)) for i in range(len(Y)): for j in range(len(X)): assert np.allclose(V[i, j], np.concatenate((Vx[j], Vy[i])))
def _test_approx(approx_fun, extra_dims): kvs = [bspline.make_knots(p, 0.0, 1.0, 8+p) for p in range(3,6)] N = [kv.numdofs for kv in kvs] coeffs = np.random.random_sample(N + extra_dims) func = geometry.BSplineFunc(kvs, coeffs) result = approx_fun(kvs, func) assert np.allclose(coeffs, result) # try also with direct function call def f(X, Y, Z): return func.grid_eval([np.squeeze(w) for w in (Z,Y,X)]) result = approx_fun(kvs, f) assert np.allclose(coeffs, result)
def test_nurbs(): kv = bspline.make_knots(2, 0.0, 1.0, 1) r = 2.0 # construct quarter circle using NURBS coeffs = np.array([[r, 0.0, 1.0], [r, r, 1.0 / np.sqrt(2.0)], [0.0, r, 1.0]]) grid = (np.linspace(0.0, 1.0, 20), ) nurbs = NurbsFunc((kv, ), coeffs.copy(), weights=None) vals = nurbs.grid_eval(grid) assert abs(r - np.linalg.norm(vals, axis=-1)).max() < 1e-12 nurbs = NurbsFunc((kv, ), coeffs[:, :2], weights=coeffs[:, -1]) vals = nurbs.grid_eval(grid) assert abs(r - np.linalg.norm(vals, axis=-1)).max() < 1e-12
def create_example_hspace(p, dim, n0, disparity=np.inf, truncate=False, num_levels=3): bdspecs = [(0, 0), (0, 1), (1, 0), (1, 1)] if dim == 2 else [(0, 0), (0, 1)] hs = HSpace(dim * (bspline.make_knots(p, 0.0, 1.0, n0), ), truncate=truncate, disparity=disparity, bdspecs=bdspecs) # perform local refinement delta = 0.5 for lv in range(num_levels): hs.refine_region(lv, lambda *X: min(X) > 1 - delta**(lv + 1)) return hs
def test_ls(): from pyiga import bspline, assemble kv = bspline.make_knots(3, 0.0, 1.0, 10) K = assemble.stiffness(kv)[1:-1, 1:-1] M = assemble.mass(kv)[1:-1, 1:-1] A = [(K, M, M), (M, K, M), (M, M, K)] n = K.shape[0] F = CanonicalTensor.ones((n, n, n)) # X = CanonicalTensor(als1_ls(A, F)) Y = CanonicalTensor(als1_ls(A, F, spd=True)) assert X.shape == F.shape assert Y.shape == F.shape assert fro_norm(X - Y) < 0.1 * fro_norm(X) # T1 = gta_ls(A, F, 5) T2 = gta_ls(A, F, 5, spd=True) assert T1.shape == F.shape assert T2.shape == F.shape assert fro_norm(T1 - T2) < 0.01 * fro_norm(T1) A_op = CanonicalOperator(A) assert fro_norm(A_op.apply(T2) - F) < 0.01 * fro_norm(F) # check relative residual
def test_poisson_2d(): kvs = 2 * (bspline.make_knots(3, 0.0, 1.0, 10), ) geo = geometry.quarter_annulus() def g(x, y): # exact solution / boundary data return np.cos(x + y) + np.exp(y - x) def f(x, y): # right-hand side (-Laplace of g) return 2 * (np.cos(x + y) - np.exp(y - x)) # pure Dirichlet boundary conditions bcs = assemble.compute_dirichlet_bcs(kvs, geo, ('all', g)) # compute right-hand side from function f rhs = assemble.inner_products(kvs, f, f_physical=True, geo=geo).ravel() A = assemble.stiffness(kvs, geo=geo) LS = assemble.RestrictedLinearSystem(A, rhs, bcs) u_sol = solvers.make_solver(LS.A, spd=True).dot(LS.b) u = LS.complete(u_sol) u_ex = approx.project_L2(kvs, g, f_physical=True, geo=geo).ravel() rms_err = np.sqrt(np.mean((u - u_ex)**2)) assert rms_err < 5e-5 # error: about 4.83e-05
def test_interpolate_physical(): f = lambda x,y,z: np.cos(x)*np.sin(y)*np.exp(z) kvs = 3 * (bspline.make_knots(3, 0.0, 1.0, 10),) x1 = interpolate(kvs, f) x2 = interpolate(kvs, f, geo=geometry.unit_cube()) assert np.allclose(x1, x2)
def test_project_L2_geo(): f = lambda x,y,z: np.cos(x)*np.sin(y)*np.exp(z) kvs = 3 * (bspline.make_knots(3, 0.0, 1.0, 10),) x1 = project_L2(kvs, f) x2 = project_L2(kvs, f, geo=geometry.unit_cube()) assert np.allclose(x1, x2)
def _make_hs(p=3, n=3): kv = bspline.make_knots(p, 0.0, 1.0, n) return HSpace((kv, kv))