10ef72598Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 20ef72598Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 30ef72598Sjeremylt# reserved. See files LICENSE and NOTICE for details. 40ef72598Sjeremylt# 50ef72598Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software 60ef72598Sjeremylt# libraries and APIs for efficient high-order finite element and spectral 70ef72598Sjeremylt# element discretizations for exascale applications. For more information and 80ef72598Sjeremylt# source code availability see http://github.com/ceed. 90ef72598Sjeremylt# 100ef72598Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 110ef72598Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office 120ef72598Sjeremylt# of Science and the National Nuclear Security Administration) responsible for 130ef72598Sjeremylt# the planning and preparation of a capable exascale ecosystem, including 140ef72598Sjeremylt# software, applications, hardware, advanced system engineering and early 150ef72598Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative. 160ef72598Sjeremylt 170ef72598Sjeremylt# @file 180ef72598Sjeremylt# Test Ceed Basis functionality 190ef72598Sjeremylt 200ef72598Sjeremyltimport os 210ef72598Sjeremyltimport math 220ef72598Sjeremyltimport libceed 230ef72598Sjeremyltimport numpy as np 240ef72598Sjeremyltimport buildmats as bm 250ef72598Sjeremyltimport check 260ef72598Sjeremylt 270ef72598SjeremyltTOL = np.finfo(float).eps * 256 280ef72598Sjeremylt 290ef72598Sjeremylt# ------------------------------------------------------------------------------- 300ef72598Sjeremylt# Utilities 310ef72598Sjeremylt# ------------------------------------------------------------------------------- 320ef72598Sjeremylt 330ef72598Sjeremylt 340ef72598Sjeremyltdef eval(dim, x): 350ef72598Sjeremylt result, center = 1, 0.1 360ef72598Sjeremylt for d in range(dim): 370ef72598Sjeremylt result *= math.tanh(x[d] - center) 380ef72598Sjeremylt center += 0.1 390ef72598Sjeremylt return result 400ef72598Sjeremylt 410ef72598Sjeremylt 420ef72598Sjeremyltdef feval(x1, x2): 430ef72598Sjeremylt return x1 * x1 + x2 * x2 + x1 * x2 + 1 440ef72598Sjeremylt 450ef72598Sjeremylt 460ef72598Sjeremyltdef dfeval(x1, x2): 470ef72598Sjeremylt return 2 * x1 + x2 480ef72598Sjeremylt 490ef72598Sjeremylt# ------------------------------------------------------------------------------- 500ef72598Sjeremylt# Test creation and distruction of a H1Lagrange basis 510ef72598Sjeremylt# ------------------------------------------------------------------------------- 520ef72598Sjeremylt 530ef72598Sjeremylt 540ef72598Sjeremyltdef test_300(ceed_resource, capsys): 550ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 560ef72598Sjeremylt 570ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(1, 1, 4, 4, libceed.GAUSS_LOBATTO) 580ef72598Sjeremylt print(b) 590ef72598Sjeremylt del b 600ef72598Sjeremylt 610ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(1, 1, 4, 4, libceed.GAUSS) 620ef72598Sjeremylt print(b) 630ef72598Sjeremylt del b 640ef72598Sjeremylt 650ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 660ef72598Sjeremylt assert not stderr 670ef72598Sjeremylt assert stdout == ref_stdout 680ef72598Sjeremylt 690ef72598Sjeremylt# ------------------------------------------------------------------------------- 700ef72598Sjeremylt# Test QR factorization 710ef72598Sjeremylt# ------------------------------------------------------------------------------- 720ef72598Sjeremylt 730ef72598Sjeremylt 740ef72598Sjeremyltdef test_301(ceed_resource, capsys): 750ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 760ef72598Sjeremylt 770ef72598Sjeremylt qr = np.array([1, -1, 4, 1, 4, -2, 1, 4, 2, 1, -1, 0], dtype="float64") 780ef72598Sjeremylt tau = np.empty(3, dtype="float64") 790ef72598Sjeremylt 800ef72598Sjeremylt qr, tau = ceed.qr_factorization(qr, tau, 4, 3) 810ef72598Sjeremylt 820ef72598Sjeremylt for i in range(len(qr)): 830ef72598Sjeremylt if qr[i] <= TOL and qr[i] >= -TOL: 840ef72598Sjeremylt qr[i] = 0 850ef72598Sjeremylt print("%12.8f" % qr[i]) 860ef72598Sjeremylt 870ef72598Sjeremylt for i in range(len(tau)): 880ef72598Sjeremylt if tau[i] <= TOL and tau[i] >= -TOL: 890ef72598Sjeremylt tau[i] = 0 900ef72598Sjeremylt print("%12.8f" % tau[i]) 910ef72598Sjeremylt 920ef72598Sjeremylt stdout, stderr, ref_stdout = check.output(capsys) 930ef72598Sjeremylt assert not stderr 940ef72598Sjeremylt assert stdout == ref_stdout 950ef72598Sjeremylt 960ef72598Sjeremylt# ------------------------------------------------------------------------------- 970ef72598Sjeremylt# Test Symmetric Schur Decomposition 980ef72598Sjeremylt# ------------------------------------------------------------------------------- 990ef72598Sjeremylt 1000ef72598Sjeremylt 1010ef72598Sjeremyltdef test_304(ceed_resource, capsys): 1020ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1030ef72598Sjeremylt 104*673160d7Sjeremylt A = np.array([0.2, 0.0745355993, -0.0745355993, 0.0333333333, 105*673160d7Sjeremylt 0.0745355993, 1., 0.1666666667, -0.0745355993, 106*673160d7Sjeremylt -0.0745355993, 0.1666666667, 1., 0.0745355993, 107*673160d7Sjeremylt 0.0333333333, -0.0745355993, 0.0745355993, 0.2], dtype="float64") 1080ef72598Sjeremylt 109*673160d7Sjeremylt Q = A.copy() 1100ef72598Sjeremylt 111*673160d7Sjeremylt lam = ceed.symmetric_schur_decomposition(Q, 4) 112*673160d7Sjeremylt Q = Q.reshape(4, 4) 113*673160d7Sjeremylt lam = np.diag(lam) 1140ef72598Sjeremylt 115*673160d7Sjeremylt Q_lambda_Qt = np.matmul(np.matmul(Q, lam), Q.T) 116*673160d7Sjeremylt assert np.max(Q_lambda_Qt - A.reshape(4, 4)) < 1E-14 1170ef72598Sjeremylt 1180ef72598Sjeremylt# ------------------------------------------------------------------------------- 1190ef72598Sjeremylt# Test Simultaneous Diagonalization 1200ef72598Sjeremylt# ------------------------------------------------------------------------------- 1210ef72598Sjeremylt 1220ef72598Sjeremylt 1230ef72598Sjeremyltdef test_305(ceed_resource, capsys): 1240ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1250ef72598Sjeremylt 126*673160d7Sjeremylt M = np.array([0.2, 0.0745355993, -0.0745355993, 0.0333333333, 127*673160d7Sjeremylt 0.0745355993, 1., 0.1666666667, -0.0745355993, 128*673160d7Sjeremylt -0.0745355993, 0.1666666667, 1., 0.0745355993, 129*673160d7Sjeremylt 0.0333333333, -0.0745355993, 0.0745355993, 0.2], dtype="float64") 130*673160d7Sjeremylt K = np.array([3.0333333333, -3.4148928136, 0.4982261470, -0.1166666667, 131*673160d7Sjeremylt -3.4148928136, 5.8333333333, -2.9166666667, 0.4982261470, 132*673160d7Sjeremylt 0.4982261470, -2.9166666667, 5.8333333333, -3.4148928136, 133*673160d7Sjeremylt -0.1166666667, 0.4982261470, -3.4148928136, 3.0333333333], dtype="float64") 1340ef72598Sjeremylt 135*673160d7Sjeremylt X, lam = ceed.simultaneous_diagonalization(K, M, 4) 136*673160d7Sjeremylt X = X.reshape(4, 4) 137*673160d7Sjeremylt np.diag(lam) 1380ef72598Sjeremylt 139*673160d7Sjeremylt M = M.reshape(4, 4) 140*673160d7Sjeremylt K = K.reshape(4, 4) 1410ef72598Sjeremylt 142*673160d7Sjeremylt Xt_M_X = np.matmul(X.T, np.matmul(M, X)) 143*673160d7Sjeremylt assert np.max(Xt_M_X - np.identity(4)) < 1E-14 1440ef72598Sjeremylt 145*673160d7Sjeremylt Xt_K_X = np.matmul(X.T, np.matmul(K, X)) 146*673160d7Sjeremylt assert np.max(Xt_K_X - lam) < 1E-14 1470ef72598Sjeremylt 1480ef72598Sjeremylt# ------------------------------------------------------------------------------- 1490ef72598Sjeremylt# Test GetNumNodes and GetNumQuadraturePoints for basis 1500ef72598Sjeremylt# ------------------------------------------------------------------------------- 1510ef72598Sjeremylt 1520ef72598Sjeremylt 1530ef72598Sjeremyltdef test_306(ceed_resource): 1540ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1550ef72598Sjeremylt 1560ef72598Sjeremylt b = ceed.BasisTensorH1Lagrange(3, 1, 4, 5, libceed.GAUSS_LOBATTO) 1570ef72598Sjeremylt 1580ef72598Sjeremylt p = b.get_num_nodes() 1590ef72598Sjeremylt q = b.get_num_quadrature_points() 1600ef72598Sjeremylt 1610ef72598Sjeremylt assert p == 64 1620ef72598Sjeremylt assert q == 125 1630ef72598Sjeremylt 1640ef72598Sjeremylt# ------------------------------------------------------------------------------- 1650ef72598Sjeremylt# Test interpolation in multiple dimensions 1660ef72598Sjeremylt# ------------------------------------------------------------------------------- 1670ef72598Sjeremylt 1680ef72598Sjeremylt 1690ef72598Sjeremyltdef test_313(ceed_resource): 1700ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 1710ef72598Sjeremylt 1720ef72598Sjeremylt for dim in range(1, 4): 1730ef72598Sjeremylt Q = 10 1740ef72598Sjeremylt Qdim = Q**dim 1750ef72598Sjeremylt Xdim = 2**dim 1760ef72598Sjeremylt x = np.empty(Xdim * dim, dtype="float64") 1770ef72598Sjeremylt uq = np.empty(Qdim, dtype="float64") 1780ef72598Sjeremylt 1790ef72598Sjeremylt for d in range(dim): 1800ef72598Sjeremylt for i in range(Xdim): 1810ef72598Sjeremylt x[d * Xdim + i] = 1 if (i % 1820ef72598Sjeremylt (2**(dim - d))) // (2**(dim - d - 1)) else -1 1830ef72598Sjeremylt 1840ef72598Sjeremylt X = ceed.Vector(Xdim * dim) 1850ef72598Sjeremylt X.set_array(x, cmode=libceed.USE_POINTER) 1860ef72598Sjeremylt Xq = ceed.Vector(Qdim * dim) 1870ef72598Sjeremylt Xq.set_value(0) 1880ef72598Sjeremylt U = ceed.Vector(Qdim) 1890ef72598Sjeremylt U.set_value(0) 1900ef72598Sjeremylt Uq = ceed.Vector(Qdim) 1910ef72598Sjeremylt 1920ef72598Sjeremylt bxl = ceed.BasisTensorH1Lagrange(dim, dim, 2, Q, libceed.GAUSS_LOBATTO) 1930ef72598Sjeremylt bul = ceed.BasisTensorH1Lagrange(dim, 1, Q, Q, libceed.GAUSS_LOBATTO) 1940ef72598Sjeremylt 1950ef72598Sjeremylt bxl.apply(1, libceed.EVAL_INTERP, X, Xq) 1960ef72598Sjeremylt 1970ef72598Sjeremylt with Xq.array_read() as xq: 1980ef72598Sjeremylt for i in range(Qdim): 1990ef72598Sjeremylt xx = np.empty(dim, dtype="float64") 2000ef72598Sjeremylt for d in range(dim): 2010ef72598Sjeremylt xx[d] = xq[d * Qdim + i] 2020ef72598Sjeremylt uq[i] = eval(dim, xx) 2030ef72598Sjeremylt 2040ef72598Sjeremylt Uq.set_array(uq, cmode=libceed.USE_POINTER) 2050ef72598Sjeremylt 2060ef72598Sjeremylt # This operation is the identity because the quadrature is collocated 2070ef72598Sjeremylt bul.T.apply(1, libceed.EVAL_INTERP, Uq, U) 2080ef72598Sjeremylt 2090ef72598Sjeremylt bxg = ceed.BasisTensorH1Lagrange(dim, dim, 2, Q, libceed.GAUSS) 2100ef72598Sjeremylt bug = ceed.BasisTensorH1Lagrange(dim, 1, Q, Q, libceed.GAUSS) 2110ef72598Sjeremylt 2120ef72598Sjeremylt bxg.apply(1, libceed.EVAL_INTERP, X, Xq) 2130ef72598Sjeremylt bug.apply(1, libceed.EVAL_INTERP, U, Uq) 2140ef72598Sjeremylt 2150ef72598Sjeremylt with Xq.array_read() as xq, Uq.array_read() as u: 2160ef72598Sjeremylt for i in range(Qdim): 2170ef72598Sjeremylt xx = np.empty(dim, dtype="float64") 2180ef72598Sjeremylt for d in range(dim): 2190ef72598Sjeremylt xx[d] = xq[d * Qdim + i] 2200ef72598Sjeremylt fx = eval(dim, xx) 2210ef72598Sjeremylt assert math.fabs(u[i] - fx) < 1E-4 2220ef72598Sjeremylt 2230ef72598Sjeremylt# ------------------------------------------------------------------------------- 2240ef72598Sjeremylt# Test grad in multiple dimensions 2250ef72598Sjeremylt# ------------------------------------------------------------------------------- 2260ef72598Sjeremylt 2270ef72598Sjeremylt 2280ef72598Sjeremyltdef test_314(ceed_resource): 2290ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2300ef72598Sjeremylt 2310ef72598Sjeremylt for dim in range(1, 4): 2320ef72598Sjeremylt P, Q = 8, 10 2330ef72598Sjeremylt Pdim = P**dim 2340ef72598Sjeremylt Qdim = Q**dim 2350ef72598Sjeremylt Xdim = 2**dim 2360ef72598Sjeremylt sum1 = sum2 = 0 2370ef72598Sjeremylt x = np.empty(Xdim * dim, dtype="float64") 2380ef72598Sjeremylt u = np.empty(Pdim, dtype="float64") 2390ef72598Sjeremylt 2400ef72598Sjeremylt for d in range(dim): 2410ef72598Sjeremylt for i in range(Xdim): 2420ef72598Sjeremylt x[d * Xdim + i] = 1 if (i % 2430ef72598Sjeremylt (2**(dim - d))) // (2**(dim - d - 1)) else -1 2440ef72598Sjeremylt 2450ef72598Sjeremylt X = ceed.Vector(Xdim * dim) 2460ef72598Sjeremylt X.set_array(x, cmode=libceed.USE_POINTER) 2470ef72598Sjeremylt Xq = ceed.Vector(Pdim * dim) 2480ef72598Sjeremylt Xq.set_value(0) 2490ef72598Sjeremylt U = ceed.Vector(Pdim) 2500ef72598Sjeremylt Uq = ceed.Vector(Qdim * dim) 2510ef72598Sjeremylt Uq.set_value(0) 2520ef72598Sjeremylt Ones = ceed.Vector(Qdim * dim) 2530ef72598Sjeremylt Ones.set_value(1) 2540ef72598Sjeremylt Gtposeones = ceed.Vector(Pdim) 2550ef72598Sjeremylt Gtposeones.set_value(0) 2560ef72598Sjeremylt 2570ef72598Sjeremylt # Get function values at quadrature points 2580ef72598Sjeremylt bxl = ceed.BasisTensorH1Lagrange(dim, dim, 2, P, libceed.GAUSS_LOBATTO) 2590ef72598Sjeremylt bxl.apply(1, libceed.EVAL_INTERP, X, Xq) 2600ef72598Sjeremylt 2610ef72598Sjeremylt with Xq.array_read() as xq: 2620ef72598Sjeremylt for i in range(Pdim): 2630ef72598Sjeremylt xx = np.empty(dim, dtype="float64") 2640ef72598Sjeremylt for d in range(dim): 2650ef72598Sjeremylt xx[d] = xq[d * Pdim + i] 2660ef72598Sjeremylt u[i] = eval(dim, xx) 2670ef72598Sjeremylt 2680ef72598Sjeremylt U.set_array(u, cmode=libceed.USE_POINTER) 2690ef72598Sjeremylt 2700ef72598Sjeremylt # Calculate G u at quadrature points, G' * 1 at dofs 2710ef72598Sjeremylt bug = ceed.BasisTensorH1Lagrange(dim, 1, P, Q, libceed.GAUSS) 2720ef72598Sjeremylt bug.apply(1, libceed.EVAL_GRAD, U, Uq) 2730ef72598Sjeremylt bug.T.apply(1, libceed.EVAL_GRAD, Ones, Gtposeones) 2740ef72598Sjeremylt 2750ef72598Sjeremylt # Check if 1' * G * u = u' * (G' * 1) 2760ef72598Sjeremylt with Gtposeones.array_read() as gtposeones, Uq.array_read() as uq: 2770ef72598Sjeremylt for i in range(Pdim): 2780ef72598Sjeremylt sum1 += gtposeones[i] * u[i] 2790ef72598Sjeremylt for i in range(dim * Qdim): 2800ef72598Sjeremylt sum2 += uq[i] 2810ef72598Sjeremylt 2820ef72598Sjeremylt assert math.fabs(sum1 - sum2) < 1E-10 2830ef72598Sjeremylt 2840ef72598Sjeremylt# ------------------------------------------------------------------------------- 2850ef72598Sjeremylt# Test creation and destruction of a 2D Simplex non-tensor H1 basis 2860ef72598Sjeremylt# ------------------------------------------------------------------------------- 2870ef72598Sjeremylt 2880ef72598Sjeremylt 2890ef72598Sjeremyltdef test_320(ceed_resource): 2900ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 2910ef72598Sjeremylt 2920ef72598Sjeremylt P, Q, dim = 6, 4, 2 2930ef72598Sjeremylt 2940ef72598Sjeremylt in_array = np.empty(P, dtype="float64") 2950ef72598Sjeremylt qref = np.empty(dim * Q, dtype="float64") 2960ef72598Sjeremylt qweight = np.empty(Q, dtype="float64") 2970ef72598Sjeremylt 2980ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 2990ef72598Sjeremylt 3000ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 3010ef72598Sjeremylt 3020ef72598Sjeremylt print(b) 3030ef72598Sjeremylt del b 3040ef72598Sjeremylt 3050ef72598Sjeremylt# ------------------------------------------------------------------------------- 3060ef72598Sjeremylt# Test integration with a 2D Simplex non-tensor H1 basis 3070ef72598Sjeremylt# ------------------------------------------------------------------------------- 3080ef72598Sjeremylt 3090ef72598Sjeremylt 3100ef72598Sjeremyltdef test_322(ceed_resource): 3110ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 3120ef72598Sjeremylt 3130ef72598Sjeremylt P, Q, dim = 6, 4, 2 3140ef72598Sjeremylt 3150ef72598Sjeremylt xr = np.array([0., 0.5, 1., 0., 0.5, 0., 0., 0., 3160ef72598Sjeremylt 0., 0.5, 0.5, 1.], dtype="float64") 3170ef72598Sjeremylt in_array = np.empty(P, dtype="float64") 3180ef72598Sjeremylt qref = np.empty(dim * Q, dtype="float64") 3190ef72598Sjeremylt qweight = np.empty(Q, dtype="float64") 3200ef72598Sjeremylt 3210ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 3220ef72598Sjeremylt 3230ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 3240ef72598Sjeremylt 3250ef72598Sjeremylt # Interpolate function to quadrature points 3260ef72598Sjeremylt for i in range(P): 3270ef72598Sjeremylt in_array[i] = feval(xr[0 * P + i], xr[1 * P + i]) 3280ef72598Sjeremylt 3290ef72598Sjeremylt in_vec = ceed.Vector(P) 3300ef72598Sjeremylt in_vec.set_array(in_array, cmode=libceed.USE_POINTER) 3310ef72598Sjeremylt out_vec = ceed.Vector(Q) 3320ef72598Sjeremylt out_vec.set_value(0) 3330ef72598Sjeremylt weights_vec = ceed.Vector(Q) 3340ef72598Sjeremylt weights_vec.set_value(0) 3350ef72598Sjeremylt 3360ef72598Sjeremylt b.apply(1, libceed.EVAL_INTERP, in_vec, out_vec) 3370ef72598Sjeremylt b.apply(1, libceed.EVAL_WEIGHT, libceed.VECTOR_NONE, weights_vec) 3380ef72598Sjeremylt 3390ef72598Sjeremylt # Check values at quadrature points 3400ef72598Sjeremylt with out_vec.array_read() as out_array, weights_vec.array_read() as weights_array: 3410ef72598Sjeremylt sum = 0 3420ef72598Sjeremylt for i in range(Q): 3430ef72598Sjeremylt sum += out_array[i] * weights_array[i] 3440ef72598Sjeremylt assert math.fabs(sum - 17. / 24.) < 1E-10 3450ef72598Sjeremylt 3460ef72598Sjeremylt# ------------------------------------------------------------------------------- 3470ef72598Sjeremylt# Test grad with a 2D Simplex non-tensor H1 basis 3480ef72598Sjeremylt# ------------------------------------------------------------------------------- 3490ef72598Sjeremylt 3500ef72598Sjeremylt 3510ef72598Sjeremyltdef test_323(ceed_resource): 3520ef72598Sjeremylt ceed = libceed.Ceed(ceed_resource) 3530ef72598Sjeremylt 3540ef72598Sjeremylt P, Q, dim = 6, 4, 2 3550ef72598Sjeremylt 3560ef72598Sjeremylt xq = np.array([0.2, 0.6, 1. / 3., 0.2, 0.2, 0.2, 3570ef72598Sjeremylt 1. / 3., 0.6], dtype="float64") 3580ef72598Sjeremylt xr = np.array([0., 0.5, 1., 0., 0.5, 0., 0., 0., 3590ef72598Sjeremylt 0., 0.5, 0.5, 1.], dtype="float64") 3600ef72598Sjeremylt in_array = np.empty(P, dtype="float64") 3610ef72598Sjeremylt qref = np.empty(dim * Q, dtype="float64") 3620ef72598Sjeremylt qweight = np.empty(Q, dtype="float64") 3630ef72598Sjeremylt 3640ef72598Sjeremylt interp, grad = bm.buildmats(qref, qweight) 3650ef72598Sjeremylt 3660ef72598Sjeremylt b = ceed.BasisH1(libceed.TRIANGLE, 1, P, Q, interp, grad, qref, qweight) 3670ef72598Sjeremylt 3680ef72598Sjeremylt # Interpolate function to quadrature points 3690ef72598Sjeremylt for i in range(P): 3700ef72598Sjeremylt in_array[i] = feval(xr[0 * P + i], xr[1 * P + i]) 3710ef72598Sjeremylt 3720ef72598Sjeremylt in_vec = ceed.Vector(P) 3730ef72598Sjeremylt in_vec.set_array(in_array, cmode=libceed.USE_POINTER) 3740ef72598Sjeremylt out_vec = ceed.Vector(Q * dim) 3750ef72598Sjeremylt out_vec.set_value(0) 3760ef72598Sjeremylt 3770ef72598Sjeremylt b.apply(1, libceed.EVAL_GRAD, in_vec, out_vec) 3780ef72598Sjeremylt 3790ef72598Sjeremylt # Check values at quadrature points 3800ef72598Sjeremylt with out_vec.array_read() as out_array: 3810ef72598Sjeremylt for i in range(Q): 3820ef72598Sjeremylt value = dfeval(xq[0 * Q + i], xq[1 * Q + i]) 3830ef72598Sjeremylt assert math.fabs(out_array[0 * Q + i] - value) < 1E-10 3840ef72598Sjeremylt 3850ef72598Sjeremylt value = dfeval(xq[1 * Q + i], xq[0 * Q + i]) 3860ef72598Sjeremylt assert math.fabs(out_array[1 * Q + i] - value) < 1E-10 3870ef72598Sjeremylt 3880ef72598Sjeremylt# ------------------------------------------------------------------------------- 389