1*3d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors 2*3d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 30ef72598Sjeremylt# 4*3d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 50ef72598Sjeremylt# 6*3d8e8822SJeremy L Thompson# This file is part of CEED: http://github.com/ceed 70ef72598Sjeremylt 80ef72598Sjeremylt# @file 90ef72598Sjeremylt# Test Ceed Basis functionality 100ef72598Sjeremylt 110ef72598Sjeremyltimport os 120ef72598Sjeremyltimport math 130ef72598Sjeremyltimport libceed 140ef72598Sjeremyltimport numpy as np 150ef72598Sjeremyltimport buildmats as bm 160ef72598Sjeremyltimport check 170ef72598Sjeremylt 1880a9ef05SNatalie BeamsTOL = libceed.EPSILON * 256 190ef72598Sjeremylt 200ef72598Sjeremylt# ------------------------------------------------------------------------------- 210ef72598Sjeremylt# Utilities 220ef72598Sjeremylt# ------------------------------------------------------------------------------- 230ef72598Sjeremylt 240ef72598Sjeremylt 250ef72598Sjeremyltdef eval(dim, x): 260ef72598Sjeremylt result, center = 1, 0.1 270ef72598Sjeremylt for d in range(dim): 280ef72598Sjeremylt result *= math.tanh(x[d] - center) 290ef72598Sjeremylt center += 0.1 300ef72598Sjeremylt return result 310ef72598Sjeremylt 320ef72598Sjeremylt 330ef72598Sjeremyltdef feval(x1, x2): 340ef72598Sjeremylt return x1 * x1 + x2 * x2 + x1 * x2 + 1 350ef72598Sjeremylt 360ef72598Sjeremylt 370ef72598Sjeremyltdef dfeval(x1, x2): 380ef72598Sjeremylt return 2 * x1 + x2 390ef72598Sjeremylt 400ef72598Sjeremylt# ------------------------------------------------------------------------------- 410ef72598Sjeremylt# Test creation and distruction of a H1Lagrange basis 420ef72598Sjeremylt# ------------------------------------------------------------------------------- 430ef72598Sjeremylt 440ef72598Sjeremylt 450ef72598Sjeremyltdef test_300(ceed_resource, capsys): 460ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 470ef72598Sjeremylt 480ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(1, 1, 4, 4, libceed.GAUSS_LOBATTO) 490ef72598Sjeremylt print(b) 500ef72598Sjeremylt del b 510ef72598Sjeremylt 520ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(1, 1, 4, 4, libceed.GAUSS) 530ef72598Sjeremylt print(b) 540ef72598Sjeremylt del b 550ef72598Sjeremylt 5680a9ef05SNatalie Beams # Only run this test in double precision 5780a9ef05SNatalie Beams if libceed.lib.CEED_SCALAR_TYPE == libceed.SCALAR_FP64: 580ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 590ef72598Sjeremylt assert not stderr 600ef72598Sjeremylt assert stdout == ref_stdout 610ef72598Sjeremylt 620ef72598Sjeremylt# ------------------------------------------------------------------------------- 630ef72598Sjeremylt# Test QR factorization 640ef72598Sjeremylt# ------------------------------------------------------------------------------- 650ef72598Sjeremylt 660ef72598Sjeremylt 67c3a5a609SJeremy L Thompsondef test_301(ceed_resource): 680ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 690ef72598Sjeremylt 70c3a5a609SJeremy L Thompson m = 4 71c3a5a609SJeremy L Thompson n = 3 7280a9ef05SNatalie Beams a = np.array([1, -1, 4, 1, 4, -2, 1, 4, 2, 1, -1, 0], 7380a9ef05SNatalie Beams dtype=ceed.scalar_type()) 7480a9ef05SNatalie Beams qr = np.array([1, -1, 4, 1, 4, -2, 1, 4, 2, 1, -1, 0], 7580a9ef05SNatalie Beams dtype=ceed.scalar_type()) 7680a9ef05SNatalie Beams tau = np.empty(3, dtype=ceed.scalar_type()) 770ef72598Sjeremylt 78c3a5a609SJeremy L Thompson qr, tau = ceed.qr_factorization(qr, tau, m, n) 79c3a5a609SJeremy L Thompson np_qr, np_tau = np.linalg.qr(a.reshape(m, n), mode="raw") 800ef72598Sjeremylt 81c3a5a609SJeremy L Thompson for i in range(n): 8280a9ef05SNatalie Beams assert abs(tau[i] - np_tau[i]) < TOL 830ef72598Sjeremylt 84c3a5a609SJeremy L Thompson qr = qr.reshape(m, n) 85c3a5a609SJeremy L Thompson for i in range(m): 86c3a5a609SJeremy L Thompson for j in range(n): 8780a9ef05SNatalie Beams assert abs(qr[i, j] - np_qr[j, i]) < TOL 880ef72598Sjeremylt 890ef72598Sjeremylt# ------------------------------------------------------------------------------- 900ef72598Sjeremylt# Test Symmetric Schur Decomposition 910ef72598Sjeremylt# ------------------------------------------------------------------------------- 920ef72598Sjeremylt 930ef72598Sjeremylt 94c3a5a609SJeremy L Thompsondef test_304(ceed_resource): 950ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 960ef72598Sjeremylt 97673160d7Sjeremylt A = np.array([0.2, 0.0745355993, -0.0745355993, 0.0333333333, 98673160d7Sjeremylt 0.0745355993, 1., 0.1666666667, -0.0745355993, 99673160d7Sjeremylt -0.0745355993, 0.1666666667, 1., 0.0745355993, 10080a9ef05SNatalie Beams 0.0333333333, -0.0745355993, 0.0745355993, 0.2], 10180a9ef05SNatalie Beams dtype=ceed.scalar_type()) 1020ef72598Sjeremylt 103673160d7Sjeremylt Q = A.copy() 1040ef72598Sjeremylt 105673160d7Sjeremylt lam = ceed.symmetric_schur_decomposition(Q, 4) 106673160d7Sjeremylt Q = Q.reshape(4, 4) 107673160d7Sjeremylt lam = np.diag(lam) 1080ef72598Sjeremylt 109673160d7Sjeremylt Q_lambda_Qt = np.matmul(np.matmul(Q, lam), Q.T) 11080a9ef05SNatalie Beams assert np.max(Q_lambda_Qt - A.reshape(4, 4)) < TOL 1110ef72598Sjeremylt 1120ef72598Sjeremylt# ------------------------------------------------------------------------------- 1130ef72598Sjeremylt# Test Simultaneous Diagonalization 1140ef72598Sjeremylt# ------------------------------------------------------------------------------- 1150ef72598Sjeremylt 1160ef72598Sjeremylt 117c3a5a609SJeremy L Thompsondef test_305(ceed_resource): 1180ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1190ef72598Sjeremylt 120673160d7Sjeremylt M = np.array([0.2, 0.0745355993, -0.0745355993, 0.0333333333, 121673160d7Sjeremylt 0.0745355993, 1., 0.1666666667, -0.0745355993, 122673160d7Sjeremylt -0.0745355993, 0.1666666667, 1., 0.0745355993, 12380a9ef05SNatalie Beams 0.0333333333, -0.0745355993, 0.0745355993, 0.2], 12480a9ef05SNatalie Beams dtype=ceed.scalar_type()) 125673160d7Sjeremylt K = np.array([3.0333333333, -3.4148928136, 0.4982261470, -0.1166666667, 126673160d7Sjeremylt -3.4148928136, 5.8333333333, -2.9166666667, 0.4982261470, 127673160d7Sjeremylt 0.4982261470, -2.9166666667, 5.8333333333, -3.4148928136, 12880a9ef05SNatalie Beams -0.1166666667, 0.4982261470, -3.4148928136, 3.0333333333], 12980a9ef05SNatalie Beams dtype=ceed.scalar_type()) 1300ef72598Sjeremylt 131673160d7Sjeremylt X, lam = ceed.simultaneous_diagonalization(K, M, 4) 132673160d7Sjeremylt X = X.reshape(4, 4) 133673160d7Sjeremylt np.diag(lam) 1340ef72598Sjeremylt 135673160d7Sjeremylt M = M.reshape(4, 4) 136673160d7Sjeremylt K = K.reshape(4, 4) 1370ef72598Sjeremylt 138673160d7Sjeremylt Xt_M_X = np.matmul(X.T, np.matmul(M, X)) 13980a9ef05SNatalie Beams assert np.max(Xt_M_X - np.identity(4)) < TOL 1400ef72598Sjeremylt 141673160d7Sjeremylt Xt_K_X = np.matmul(X.T, np.matmul(K, X)) 14280a9ef05SNatalie Beams assert np.max(Xt_K_X - lam) < TOL 1430ef72598Sjeremylt 1440ef72598Sjeremylt# ------------------------------------------------------------------------------- 1450ef72598Sjeremylt# Test GetNumNodes and GetNumQuadraturePoints for basis 1460ef72598Sjeremylt# ------------------------------------------------------------------------------- 1470ef72598Sjeremylt 1480ef72598Sjeremylt 1490ef72598Sjeremyltdef test_306(ceed_resource): 1500ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1510ef72598Sjeremylt 1520ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(3, 1, 4, 5, libceed.GAUSS_LOBATTO) 1530ef72598Sjeremylt 1540ef72598Sjeremylt p = b.get_num_nodes() 1550ef72598Sjeremylt q = b.get_num_quadrature_points() 1560ef72598Sjeremylt 1570ef72598Sjeremylt assert p == 64 1580ef72598Sjeremylt assert q == 125 1590ef72598Sjeremylt 1600ef72598Sjeremylt# ------------------------------------------------------------------------------- 1610ef72598Sjeremylt# Test interpolation in multiple dimensions 1620ef72598Sjeremylt# ------------------------------------------------------------------------------- 1630ef72598Sjeremylt 1640ef72598Sjeremylt 1650ef72598Sjeremyltdef test_313(ceed_resource): 1660ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1670ef72598Sjeremylt 1680ef72598Sjeremylt for dim in range(1, 4): 1690ef72598Sjeremylt Q = 10 1700ef72598Sjeremylt Qdim = Q**dim 1710ef72598Sjeremylt Xdim = 2**dim 17280a9ef05SNatalie Beams x = np.empty(Xdim * dim, dtype=ceed.scalar_type()) 17380a9ef05SNatalie Beams uq = np.empty(Qdim, dtype=ceed.scalar_type()) 1740ef72598Sjeremylt 1750ef72598Sjeremylt for d in range(dim): 1760ef72598Sjeremylt for i in range(Xdim): 1770ef72598Sjeremylt x[d * Xdim + i] = 1 if (i % 1780ef72598Sjeremylt (2**(dim - d))) // (2**(dim - d - 1)) else -1 1790ef72598Sjeremylt 1800ef72598Sjeremylt X = ceed.Vector(Xdim * dim) 1810ef72598Sjeremylt X.set_array(x, cmode=libceed.USE_POINTER) 1820ef72598Sjeremylt Xq = ceed.Vector(Qdim * dim) 1830ef72598Sjeremylt Xq.set_value(0) 1840ef72598Sjeremylt U = ceed.Vector(Qdim) 1850ef72598Sjeremylt U.set_value(0) 1860ef72598Sjeremylt Uq = ceed.Vector(Qdim) 1870ef72598Sjeremylt 1880ef72598Sjeremylt bxl = ceed.BasisTensorH1Lagrange(dim, dim, 2, Q, libceed.GAUSS_LOBATTO) 1890ef72598Sjeremylt bul = ceed.BasisTensorH1Lagrange(dim, 1, Q, Q, libceed.GAUSS_LOBATTO) 1900ef72598Sjeremylt 1910ef72598Sjeremylt bxl.apply(1, libceed.EVAL_INTERP, X, Xq) 1920ef72598Sjeremylt 1930ef72598Sjeremylt with Xq.array_read() as xq: 1940ef72598Sjeremylt for i in range(Qdim): 19580a9ef05SNatalie Beams xx = np.empty(dim, dtype=ceed.scalar_type()) 1960ef72598Sjeremylt for d in range(dim): 1970ef72598Sjeremylt xx[d] = xq[d * Qdim + i] 1980ef72598Sjeremylt uq[i] = eval(dim, xx) 1990ef72598Sjeremylt 2000ef72598Sjeremylt Uq.set_array(uq, cmode=libceed.USE_POINTER) 2010ef72598Sjeremylt 2020ef72598Sjeremylt # This operation is the identity because the quadrature is collocated 2030ef72598Sjeremylt bul.T.apply(1, libceed.EVAL_INTERP, Uq, U) 2040ef72598Sjeremylt 2050ef72598Sjeremylt bxg = ceed.BasisTensorH1Lagrange(dim, dim, 2, Q, libceed.GAUSS) 2060ef72598Sjeremylt bug = ceed.BasisTensorH1Lagrange(dim, 1, Q, Q, libceed.GAUSS) 2070ef72598Sjeremylt 2080ef72598Sjeremylt bxg.apply(1, libceed.EVAL_INTERP, X, Xq) 2090ef72598Sjeremylt bug.apply(1, libceed.EVAL_INTERP, U, Uq) 2100ef72598Sjeremylt 2110ef72598Sjeremylt with Xq.array_read() as xq, Uq.array_read() as u: 2120ef72598Sjeremylt for i in range(Qdim): 21380a9ef05SNatalie Beams xx = np.empty(dim, dtype=ceed.scalar_type()) 2140ef72598Sjeremylt for d in range(dim): 2150ef72598Sjeremylt xx[d] = xq[d * Qdim + i] 2160ef72598Sjeremylt fx = eval(dim, xx) 2170ef72598Sjeremylt assert math.fabs(u[i] - fx) < 1E-4 2180ef72598Sjeremylt 2190ef72598Sjeremylt# ------------------------------------------------------------------------------- 2200ef72598Sjeremylt# Test grad in multiple dimensions 2210ef72598Sjeremylt# ------------------------------------------------------------------------------- 2220ef72598Sjeremylt 2230ef72598Sjeremylt 2240ef72598Sjeremyltdef test_314(ceed_resource): 2250ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2260ef72598Sjeremylt 2270ef72598Sjeremylt for dim in range(1, 4): 2280ef72598Sjeremylt P, Q = 8, 10 2290ef72598Sjeremylt Pdim = P**dim 2300ef72598Sjeremylt Qdim = Q**dim 2310ef72598Sjeremylt Xdim = 2**dim 2320ef72598Sjeremylt sum1 = sum2 = 0 23380a9ef05SNatalie Beams x = np.empty(Xdim * dim, dtype=ceed.scalar_type()) 23480a9ef05SNatalie Beams u = np.empty(Pdim, dtype=ceed.scalar_type()) 2350ef72598Sjeremylt 2360ef72598Sjeremylt for d in range(dim): 2370ef72598Sjeremylt for i in range(Xdim): 2380ef72598Sjeremylt x[d * Xdim + i] = 1 if (i % 2390ef72598Sjeremylt (2**(dim - d))) // (2**(dim - d - 1)) else -1 2400ef72598Sjeremylt 2410ef72598Sjeremylt X = ceed.Vector(Xdim * dim) 2420ef72598Sjeremylt X.set_array(x, cmode=libceed.USE_POINTER) 2430ef72598Sjeremylt Xq = ceed.Vector(Pdim * dim) 2440ef72598Sjeremylt Xq.set_value(0) 2450ef72598Sjeremylt U = ceed.Vector(Pdim) 2460ef72598Sjeremylt Uq = ceed.Vector(Qdim * dim) 2470ef72598Sjeremylt Uq.set_value(0) 2480ef72598Sjeremylt Ones = ceed.Vector(Qdim * dim) 2490ef72598Sjeremylt Ones.set_value(1) 2500ef72598Sjeremylt Gtposeones = ceed.Vector(Pdim) 2510ef72598Sjeremylt Gtposeones.set_value(0) 2520ef72598Sjeremylt 2530ef72598Sjeremylt # Get function values at quadrature points 2540ef72598Sjeremylt bxl = ceed.BasisTensorH1Lagrange(dim, dim, 2, P, libceed.GAUSS_LOBATTO) 2550ef72598Sjeremylt bxl.apply(1, libceed.EVAL_INTERP, X, Xq) 2560ef72598Sjeremylt 2570ef72598Sjeremylt with Xq.array_read() as xq: 2580ef72598Sjeremylt for i in range(Pdim): 25980a9ef05SNatalie Beams xx = np.empty(dim, dtype=ceed.scalar_type()) 2600ef72598Sjeremylt for d in range(dim): 2610ef72598Sjeremylt xx[d] = xq[d * Pdim + i] 2620ef72598Sjeremylt u[i] = eval(dim, xx) 2630ef72598Sjeremylt 2640ef72598Sjeremylt U.set_array(u, cmode=libceed.USE_POINTER) 2650ef72598Sjeremylt 2660ef72598Sjeremylt # Calculate G u at quadrature points, G' * 1 at dofs 2670ef72598Sjeremylt bug = ceed.BasisTensorH1Lagrange(dim, 1, P, Q, libceed.GAUSS) 2680ef72598Sjeremylt bug.apply(1, libceed.EVAL_GRAD, U, Uq) 2690ef72598Sjeremylt bug.T.apply(1, libceed.EVAL_GRAD, Ones, Gtposeones) 2700ef72598Sjeremylt 2710ef72598Sjeremylt # Check if 1' * G * u = u' * (G' * 1) 2720ef72598Sjeremylt with Gtposeones.array_read() as gtposeones, Uq.array_read() as uq: 2730ef72598Sjeremylt for i in range(Pdim): 2740ef72598Sjeremylt sum1 += gtposeones[i] * u[i] 2750ef72598Sjeremylt for i in range(dim * Qdim): 2760ef72598Sjeremylt sum2 += uq[i] 2770ef72598Sjeremylt 27880a9ef05SNatalie Beams assert math.fabs(sum1 - sum2) < 10. * TOL 2790ef72598Sjeremylt 2800ef72598Sjeremylt# ------------------------------------------------------------------------------- 2810ef72598Sjeremylt# Test creation and destruction of a 2D Simplex non-tensor H1 basis 2820ef72598Sjeremylt# ------------------------------------------------------------------------------- 2830ef72598Sjeremylt 2840ef72598Sjeremylt 2850ef72598Sjeremyltdef test_320(ceed_resource): 2860ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2870ef72598Sjeremylt 2880ef72598Sjeremylt P, Q, dim = 6, 4, 2 2890ef72598Sjeremylt 29080a9ef05SNatalie Beams in_array = np.empty(P, dtype=ceed.scalar_type()) 29180a9ef05SNatalie Beams qref = np.empty(dim * Q, dtype=ceed.scalar_type()) 29280a9ef05SNatalie Beams qweight = np.empty(Q, dtype=ceed.scalar_type()) 2930ef72598Sjeremylt 29480a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 29580a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 2960ef72598Sjeremylt 2970ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 2980ef72598Sjeremylt 2990ef72598Sjeremylt print(b) 3000ef72598Sjeremylt del b 3010ef72598Sjeremylt 3020ef72598Sjeremylt# ------------------------------------------------------------------------------- 3030ef72598Sjeremylt# Test integration with a 2D Simplex non-tensor H1 basis 3040ef72598Sjeremylt# ------------------------------------------------------------------------------- 3050ef72598Sjeremylt 3060ef72598Sjeremylt 3070ef72598Sjeremyltdef test_322(ceed_resource): 3080ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 3090ef72598Sjeremylt 3100ef72598Sjeremylt P, Q, dim = 6, 4, 2 3110ef72598Sjeremylt 3120ef72598Sjeremylt xr = np.array([0., 0.5, 1., 0., 0.5, 0., 0., 0., 31380a9ef05SNatalie Beams 0., 0.5, 0.5, 1.], dtype=ceed.scalar_type()) 31480a9ef05SNatalie Beams in_array = np.empty(P, dtype=ceed.scalar_type()) 31580a9ef05SNatalie Beams qref = np.empty(dim * Q, dtype=ceed.scalar_type()) 31680a9ef05SNatalie Beams qweight = np.empty(Q, dtype=ceed.scalar_type()) 3170ef72598Sjeremylt 31880a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 31980a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 3200ef72598Sjeremylt 3210ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 3220ef72598Sjeremylt 3230ef72598Sjeremylt # Interpolate function to quadrature points 3240ef72598Sjeremylt for i in range(P): 3250ef72598Sjeremylt in_array[i] = feval(xr[0 * P + i], xr[1 * P + i]) 3260ef72598Sjeremylt 3270ef72598Sjeremylt in_vec = ceed.Vector(P) 3280ef72598Sjeremylt in_vec.set_array(in_array, cmode=libceed.USE_POINTER) 3290ef72598Sjeremylt out_vec = ceed.Vector(Q) 3300ef72598Sjeremylt out_vec.set_value(0) 3310ef72598Sjeremylt weights_vec = ceed.Vector(Q) 3320ef72598Sjeremylt weights_vec.set_value(0) 3330ef72598Sjeremylt 3340ef72598Sjeremylt b.apply(1, libceed.EVAL_INTERP, in_vec, out_vec) 3350ef72598Sjeremylt b.apply(1, libceed.EVAL_WEIGHT, libceed.VECTOR_NONE, weights_vec) 3360ef72598Sjeremylt 3370ef72598Sjeremylt # Check values at quadrature points 3380ef72598Sjeremylt with out_vec.array_read() as out_array, weights_vec.array_read() as weights_array: 3390ef72598Sjeremylt sum = 0 3400ef72598Sjeremylt for i in range(Q): 3410ef72598Sjeremylt sum += out_array[i] * weights_array[i] 34280a9ef05SNatalie Beams assert math.fabs(sum - 17. / 24.) < 10. * TOL 3430ef72598Sjeremylt 3440ef72598Sjeremylt# ------------------------------------------------------------------------------- 3450ef72598Sjeremylt# Test grad with a 2D Simplex non-tensor H1 basis 3460ef72598Sjeremylt# ------------------------------------------------------------------------------- 3470ef72598Sjeremylt 3480ef72598Sjeremylt 3490ef72598Sjeremyltdef test_323(ceed_resource): 3500ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 3510ef72598Sjeremylt 3520ef72598Sjeremylt P, Q, dim = 6, 4, 2 3530ef72598Sjeremylt 3540ef72598Sjeremylt xq = np.array([0.2, 0.6, 1. / 3., 0.2, 0.2, 0.2, 35580a9ef05SNatalie Beams 1. / 3., 0.6], dtype=ceed.scalar_type()) 3560ef72598Sjeremylt xr = np.array([0., 0.5, 1., 0., 0.5, 0., 0., 0., 35780a9ef05SNatalie Beams 0., 0.5, 0.5, 1.], dtype=ceed.scalar_type()) 35880a9ef05SNatalie Beams in_array = np.empty(P, dtype=ceed.scalar_type()) 35980a9ef05SNatalie Beams qref = np.empty(dim * Q, dtype=ceed.scalar_type()) 36080a9ef05SNatalie Beams qweight = np.empty(Q, dtype=ceed.scalar_type()) 3610ef72598Sjeremylt 36280a9ef05SNatalie Beams interp, grad = bm.buildmats(qref, qweight, libceed.scalar_types[ 36380a9ef05SNatalie Beams libceed.lib.CEED_SCALAR_TYPE]) 3640ef72598Sjeremylt 3650ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 3660ef72598Sjeremylt 3670ef72598Sjeremylt # Interpolate function to quadrature points 3680ef72598Sjeremylt for i in range(P): 3690ef72598Sjeremylt in_array[i] = feval(xr[0 * P + i], xr[1 * P + i]) 3700ef72598Sjeremylt 3710ef72598Sjeremylt in_vec = ceed.Vector(P) 3720ef72598Sjeremylt in_vec.set_array(in_array, cmode=libceed.USE_POINTER) 3730ef72598Sjeremylt out_vec = ceed.Vector(Q * dim) 3740ef72598Sjeremylt out_vec.set_value(0) 3750ef72598Sjeremylt 3760ef72598Sjeremylt b.apply(1, libceed.EVAL_GRAD, in_vec, out_vec) 3770ef72598Sjeremylt 3780ef72598Sjeremylt # Check values at quadrature points 3790ef72598Sjeremylt with out_vec.array_read() as out_array: 3800ef72598Sjeremylt for i in range(Q): 3810ef72598Sjeremylt value = dfeval(xq[0 * Q + i], xq[1 * Q + i]) 38280a9ef05SNatalie Beams assert math.fabs(out_array[0 * Q + i] - value) < 10. * TOL 3830ef72598Sjeremylt 3840ef72598Sjeremylt value = dfeval(xq[1 * Q + i], xq[0 * Q + i]) 38580a9ef05SNatalie Beams assert math.fabs(out_array[1 * Q + i] - value) < 10. * TOL 3860ef72598Sjeremylt 3870ef72598Sjeremylt# ------------------------------------------------------------------------------- 388