15a21df39Svaleriabarra# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 25a21df39Svaleriabarra# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 35a21df39Svaleriabarra# reserved. See files LICENSE and NOTICE for details. 45a21df39Svaleriabarra# 55a21df39Svaleriabarra# This file is part of CEED, a collection of benchmarks, miniapps, software 65a21df39Svaleriabarra# libraries and APIs for efficient high-order finite element and spectral 75a21df39Svaleriabarra# element discretizations for exascale applications. For more information and 85a21df39Svaleriabarra# source code availability see http://github.com/ceed. 95a21df39Svaleriabarra# 105a21df39Svaleriabarra# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 115a21df39Svaleriabarra# a collaborative effort of two U.S. Department of Energy organizations (Office 125a21df39Svaleriabarra# of Science and the National Nuclear Security Administration) responsible for 135a21df39Svaleriabarra# the planning and preparation of a capable exascale ecosystem, including 145a21df39Svaleriabarra# software, applications, hardware, advanced system engineering and early 155a21df39Svaleriabarra# testbed platforms, in support of the nation's exascale computing imperative. 165a21df39Svaleriabarra 175a21df39Svaleriabarrafrom _ceed_cffi import ffi, lib 185a21df39Svaleriabarraimport tempfile 195a21df39Svaleriabarraimport numpy as np 205a21df39Svaleriabarrafrom abc import ABC 215a21df39Svaleriabarrafrom .ceed_constants import TRANSPOSE, NOTRANSPOSE 225a21df39Svaleriabarra 235a21df39Svaleriabarra# ------------------------------------------------------------------------------ 247a7b0fa3SJed Brown 257a7b0fa3SJed Brown 265a21df39Svaleriabarraclass Basis(ABC): 275a21df39Svaleriabarra """Ceed Basis: finite element basis objects.""" 285a21df39Svaleriabarra 295a21df39Svaleriabarra # Attributes 305a21df39Svaleriabarra _ceed = ffi.NULL 315a21df39Svaleriabarra _pointer = ffi.NULL 325a21df39Svaleriabarra 335a21df39Svaleriabarra # Representation 345a21df39Svaleriabarra def __repr__(self): 355a21df39Svaleriabarra return "<CeedBasis instance at " + hex(id(self)) + ">" 365a21df39Svaleriabarra 375a21df39Svaleriabarra # String conversion for print() to stdout 385a21df39Svaleriabarra def __str__(self): 395a21df39Svaleriabarra """View a Basis via print().""" 405a21df39Svaleriabarra 415a21df39Svaleriabarra # libCEED call 425a21df39Svaleriabarra with tempfile.NamedTemporaryFile() as key_file: 435a21df39Svaleriabarra with open(key_file.name, 'r+') as stream_file: 445a21df39Svaleriabarra stream = ffi.cast("FILE *", stream_file) 455a21df39Svaleriabarra 46477729cfSJeremy L Thompson err_code = lib.CeedBasisView(self._pointer[0], stream) 47477729cfSJeremy L Thompson self._ceed._check_error(err_code) 485a21df39Svaleriabarra 495a21df39Svaleriabarra stream_file.seek(0) 505a21df39Svaleriabarra out_string = stream_file.read() 515a21df39Svaleriabarra 525a21df39Svaleriabarra return out_string 535a21df39Svaleriabarra 545a21df39Svaleriabarra # Apply Basis 555a21df39Svaleriabarra def apply(self, nelem, emode, u, v, tmode=NOTRANSPOSE): 565a21df39Svaleriabarra """Apply basis evaluation from nodes to quadrature points or vice versa. 575a21df39Svaleriabarra 585a21df39Svaleriabarra Args: 595a21df39Svaleriabarra nelem: the number of elements to apply the basis evaluation to; 605a21df39Svaleriabarra the backend will specify the ordering in a 615a21df39Svaleriabarra BlockedElemRestriction 625a21df39Svaleriabarra emode: basis evaluation mode 635a21df39Svaleriabarra u: input vector 645a21df39Svaleriabarra v: output vector 655a21df39Svaleriabarra **tmode: CEED_NOTRANSPOSE to evaluate from nodes to quadrature 665a21df39Svaleriabarra points, CEED_TRANSPOSE to apply the transpose, mapping 675a21df39Svaleriabarra from quadrature points to nodes; default CEED_NOTRANSPOSE""" 685a21df39Svaleriabarra 695a21df39Svaleriabarra # libCEED call 70477729cfSJeremy L Thompson err_code = lib.CeedBasisApply(self._pointer[0], nelem, tmode, emode, 715a21df39Svaleriabarra u._pointer[0], v._pointer[0]) 72477729cfSJeremy L Thompson self._ceed._check_error(err_code) 735a21df39Svaleriabarra 745a21df39Svaleriabarra # Transpose a Basis 755a21df39Svaleriabarra @property 765a21df39Svaleriabarra def T(self): 775a21df39Svaleriabarra """Transpose a Basis.""" 785a21df39Svaleriabarra 795a21df39Svaleriabarra return TransposeBasis(self) 805a21df39Svaleriabarra 815a21df39Svaleriabarra # Transpose a Basis 825a21df39Svaleriabarra @property 835a21df39Svaleriabarra def transpose(self): 845a21df39Svaleriabarra """Transpose a Basis.""" 855a21df39Svaleriabarra 865a21df39Svaleriabarra return TransposeBasis(self) 875a21df39Svaleriabarra 885a21df39Svaleriabarra # Get number of nodes 895a21df39Svaleriabarra def get_num_nodes(self): 905a21df39Svaleriabarra """Get total number of nodes (in dim dimensions) of a Basis. 915a21df39Svaleriabarra 925a21df39Svaleriabarra Returns: 935a21df39Svaleriabarra num_nodes: total number of nodes""" 945a21df39Svaleriabarra 955a21df39Svaleriabarra # Setup argument 965a21df39Svaleriabarra p_pointer = ffi.new("CeedInt *") 975a21df39Svaleriabarra 985a21df39Svaleriabarra # libCEED call 99477729cfSJeremy L Thompson err_code = lib.CeedBasisGetNumNodes(self._pointer[0], p_pointer) 100477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1015a21df39Svaleriabarra 1025a21df39Svaleriabarra return p_pointer[0] 1035a21df39Svaleriabarra 1045a21df39Svaleriabarra # Get number of quadrature points 1055a21df39Svaleriabarra def get_num_quadrature_points(self): 1065a21df39Svaleriabarra """Get total number of quadrature points (in dim dimensions) of a Basis. 1075a21df39Svaleriabarra 1085a21df39Svaleriabarra Returns: 1095a21df39Svaleriabarra num_qpts: total number of quadrature points""" 1105a21df39Svaleriabarra 1115a21df39Svaleriabarra # Setup argument 1125a21df39Svaleriabarra q_pointer = ffi.new("CeedInt *") 1135a21df39Svaleriabarra 1145a21df39Svaleriabarra # libCEED call 115477729cfSJeremy L Thompson err_code = lib.CeedBasisGetNumQuadraturePoints( 116477729cfSJeremy L Thompson self._pointer[0], q_pointer) 117477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1185a21df39Svaleriabarra 1195a21df39Svaleriabarra return q_pointer[0] 1205a21df39Svaleriabarra 1215a21df39Svaleriabarra # Gauss quadrature 1225a21df39Svaleriabarra @staticmethod 1235a21df39Svaleriabarra def gauss_quadrature(q): 1245a21df39Svaleriabarra """Construct a Gauss-Legendre quadrature. 1255a21df39Svaleriabarra 1265a21df39Svaleriabarra Args: 1275a21df39Svaleriabarra Q: number of quadrature points (integrates polynomials of 1285a21df39Svaleriabarra degree 2*Q-1 exactly) 1295a21df39Svaleriabarra 1305a21df39Svaleriabarra Returns: 1315a21df39Svaleriabarra (qref1d, qweight1d): array of length Q to hold the abscissa on [-1, 1] 1325a21df39Svaleriabarra and array of length Q to hold the weights""" 1335a21df39Svaleriabarra 1345a21df39Svaleriabarra # Setup arguments 1355a21df39Svaleriabarra qref1d = np.empty(q, dtype="float64") 136fc2a3161SJed Brown qweight1d = np.empty(q, dtype="float64") 1375a21df39Svaleriabarra 1385a21df39Svaleriabarra qref1d_pointer = ffi.new("CeedScalar *") 1397a7b0fa3SJed Brown qref1d_pointer = ffi.cast( 1407a7b0fa3SJed Brown "CeedScalar *", 1417a7b0fa3SJed Brown qref1d.__array_interface__['data'][0]) 1425a21df39Svaleriabarra 1435a21df39Svaleriabarra qweight1d_pointer = ffi.new("CeedScalar *") 1447a7b0fa3SJed Brown qweight1d_pointer = ffi.cast( 1457a7b0fa3SJed Brown "CeedScalar *", 1467a7b0fa3SJed Brown qweight1d.__array_interface__['data'][0]) 1475a21df39Svaleriabarra 1485a21df39Svaleriabarra # libCEED call 149477729cfSJeremy L Thompson err_code = lib.CeedGaussQuadrature(q, qref1d_pointer, qweight1d_pointer) 150477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1515a21df39Svaleriabarra 1525a21df39Svaleriabarra return qref1d, qweight1d 1535a21df39Svaleriabarra 1545a21df39Svaleriabarra # Lobatto quadrature 1555a21df39Svaleriabarra @staticmethod 1565a21df39Svaleriabarra def lobatto_quadrature(q): 1575a21df39Svaleriabarra """Construct a Gauss-Legendre-Lobatto quadrature. 1585a21df39Svaleriabarra 1595a21df39Svaleriabarra Args: 1605a21df39Svaleriabarra q: number of quadrature points (integrates polynomials of 1615a21df39Svaleriabarra degree 2*Q-3 exactly) 1625a21df39Svaleriabarra 1635a21df39Svaleriabarra Returns: 1645a21df39Svaleriabarra (qref1d, qweight1d): array of length Q to hold the abscissa on [-1, 1] 1655a21df39Svaleriabarra and array of length Q to hold the weights""" 1665a21df39Svaleriabarra 1675a21df39Svaleriabarra # Setup arguments 1685a21df39Svaleriabarra qref1d = np.empty(q, dtype="float64") 1695a21df39Svaleriabarra qref1d_pointer = ffi.new("CeedScalar *") 1707a7b0fa3SJed Brown qref1d_pointer = ffi.cast( 1717a7b0fa3SJed Brown "CeedScalar *", 1727a7b0fa3SJed Brown qref1d.__array_interface__['data'][0]) 1735a21df39Svaleriabarra 174fc2a3161SJed Brown qweight1d = np.empty(q, dtype="float64") 1755a21df39Svaleriabarra qweight1d_pointer = ffi.new("CeedScalar *") 1767a7b0fa3SJed Brown qweight1d_pointer = ffi.cast( 1777a7b0fa3SJed Brown "CeedScalar *", 1787a7b0fa3SJed Brown qweight1d.__array_interface__['data'][0]) 1795a21df39Svaleriabarra 1805a21df39Svaleriabarra # libCEED call 181477729cfSJeremy L Thompson err_code = lib.CeedLobattoQuadrature( 182477729cfSJeremy L Thompson q, qref1d_pointer, qweight1d_pointer) 183477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1845a21df39Svaleriabarra 1855a21df39Svaleriabarra return qref1d, qweight1d 1865a21df39Svaleriabarra 1875a21df39Svaleriabarra # QR factorization 1885a21df39Svaleriabarra @staticmethod 1895a21df39Svaleriabarra def qr_factorization(ceed, mat, tau, m, n): 1905a21df39Svaleriabarra """Return QR Factorization of a matrix. 1915a21df39Svaleriabarra 1925a21df39Svaleriabarra Args: 1935a21df39Svaleriabarra ceed: Ceed context currently in use 1945a21df39Svaleriabarra *mat: Numpy array holding the row-major matrix to be factorized in place 1955a21df39Svaleriabarra *tau: Numpy array to hold the vector of lengt m of scaling factors 1965a21df39Svaleriabarra m: number of rows 1975a21df39Svaleriabarra n: numbef of columns""" 1985a21df39Svaleriabarra 1995a21df39Svaleriabarra # Setup arguments 2005a21df39Svaleriabarra mat_pointer = ffi.new("CeedScalar *") 2017a7b0fa3SJed Brown mat_pointer = ffi.cast( 2027a7b0fa3SJed Brown "CeedScalar *", 2037a7b0fa3SJed Brown mat.__array_interface__['data'][0]) 2045a21df39Svaleriabarra 2055a21df39Svaleriabarra tau_pointer = ffi.new("CeedScalar *") 2067a7b0fa3SJed Brown tau_pointer = ffi.cast( 2077a7b0fa3SJed Brown "CeedScalar *", 2087a7b0fa3SJed Brown tau.__array_interface__['data'][0]) 2095a21df39Svaleriabarra 2105a21df39Svaleriabarra # libCEED call 2117a7b0fa3SJed Brown lib.CeedQRFactorization( 2127a7b0fa3SJed Brown ceed._pointer[0], mat_pointer, tau_pointer, m, n) 2135a21df39Svaleriabarra 2145a21df39Svaleriabarra return mat, tau 2155a21df39Svaleriabarra 2165a21df39Svaleriabarra # Symmetric Schur decomposition 2175a21df39Svaleriabarra @staticmethod 2185a21df39Svaleriabarra def symmetric_schur_decomposition(ceed, mat, n): 2195a21df39Svaleriabarra """Return symmetric Schur decomposition of a symmetric matrix 2205a21df39Svaleriabarra via symmetric QR factorization. 2215a21df39Svaleriabarra 2225a21df39Svaleriabarra Args: 2235a21df39Svaleriabarra ceed: Ceed context currently in use 2245a21df39Svaleriabarra *mat: Numpy array holding the row-major matrix to be factorized in place 2255a21df39Svaleriabarra n: number of rows/columns 2265a21df39Svaleriabarra 2275a21df39Svaleriabarra Returns: 2285a21df39Svaleriabarra lbda: Numpy array of length n holding eigenvalues""" 2295a21df39Svaleriabarra 2305a21df39Svaleriabarra # Setup arguments 2315a21df39Svaleriabarra mat_pointer = ffi.new("CeedScalar *") 2327a7b0fa3SJed Brown mat_pointer = ffi.cast( 2337a7b0fa3SJed Brown "CeedScalar *", 2347a7b0fa3SJed Brown mat.__array_interface__['data'][0]) 2355a21df39Svaleriabarra 2365a21df39Svaleriabarra lbda = np.empty(n, dtype="float64") 2375a21df39Svaleriabarra l_pointer = ffi.new("CeedScalar *") 2387a7b0fa3SJed Brown l_pointer = ffi.cast( 2397a7b0fa3SJed Brown "CeedScalar *", 2407a7b0fa3SJed Brown lbda.__array_interface__['data'][0]) 2415a21df39Svaleriabarra 2425a21df39Svaleriabarra # libCEED call 2437a7b0fa3SJed Brown lib.CeedSymmetricSchurDecomposition( 2447a7b0fa3SJed Brown ceed._pointer[0], mat_pointer, l_pointer, n) 2455a21df39Svaleriabarra 2465a21df39Svaleriabarra return lbda 2475a21df39Svaleriabarra 2485a21df39Svaleriabarra # Simultaneous Diagonalization 2495a21df39Svaleriabarra @staticmethod 2505a21df39Svaleriabarra def simultaneous_diagonalization(ceed, matA, matB, n): 2515a21df39Svaleriabarra """Return Simultaneous Diagonalization of two matrices. 2525a21df39Svaleriabarra 2535a21df39Svaleriabarra Args: 2545a21df39Svaleriabarra ceed: Ceed context currently in use 2555a21df39Svaleriabarra *matA: Numpy array holding the row-major matrix to be factorized with 2565a21df39Svaleriabarra eigenvalues 2575a21df39Svaleriabarra *matB: Numpy array holding the row-major matrix to be factorized to identity 2585a21df39Svaleriabarra n: number of rows/columns 2595a21df39Svaleriabarra 2605a21df39Svaleriabarra Returns: 2615a21df39Svaleriabarra (x, lbda): Numpy array holding the row-major orthogonal matrix and 2625a21df39Svaleriabarra Numpy array holding the vector of length n of generalized 2635a21df39Svaleriabarra eigenvalues""" 2645a21df39Svaleriabarra 2655a21df39Svaleriabarra # Setup arguments 2665a21df39Svaleriabarra matA_pointer = ffi.new("CeedScalar *") 2677a7b0fa3SJed Brown matA_pointer = ffi.cast( 2687a7b0fa3SJed Brown "CeedScalar *", 2697a7b0fa3SJed Brown matA.__array_interface__['data'][0]) 2705a21df39Svaleriabarra 2715a21df39Svaleriabarra matB_pointer = ffi.new("CeedScalar *") 2727a7b0fa3SJed Brown matB_pointer = ffi.cast( 2737a7b0fa3SJed Brown "CeedScalar *", 2747a7b0fa3SJed Brown matB.__array_interface__['data'][0]) 2755a21df39Svaleriabarra 2765a21df39Svaleriabarra lbda = np.empty(n, dtype="float64") 2775a21df39Svaleriabarra l_pointer = ffi.new("CeedScalar *") 2787a7b0fa3SJed Brown l_pointer = ffi.cast( 2797a7b0fa3SJed Brown "CeedScalar *", 2807a7b0fa3SJed Brown lbda.__array_interface__['data'][0]) 2815a21df39Svaleriabarra 2825a21df39Svaleriabarra x = np.empty(n * n, dtype="float64") 2835a21df39Svaleriabarra x_pointer = ffi.new("CeedScalar *") 2845a21df39Svaleriabarra x_pointer = ffi.cast("CeedScalar *", x.__array_interface__['data'][0]) 2855a21df39Svaleriabarra 2865a21df39Svaleriabarra # libCEED call 2875a21df39Svaleriabarra lib.CeedSimultaneousDiagonalization(ceed._pointer[0], matA_pointer, matB_pointer, 2885a21df39Svaleriabarra x_pointer, l_pointer, n) 2895a21df39Svaleriabarra 2905a21df39Svaleriabarra return x, lbda 2915a21df39Svaleriabarra 2925a21df39Svaleriabarra # Destructor 2935a21df39Svaleriabarra def __del__(self): 2945a21df39Svaleriabarra # libCEED call 295477729cfSJeremy L Thompson err_code = lib.CeedBasisDestroy(self._pointer) 296477729cfSJeremy L Thompson self._ceed._check_error(err_code) 2975a21df39Svaleriabarra 2985a21df39Svaleriabarra# ------------------------------------------------------------------------------ 2997a7b0fa3SJed Brown 3007a7b0fa3SJed Brown 3015a21df39Svaleriabarraclass BasisTensorH1(Basis): 3025a21df39Svaleriabarra """Ceed Tensor H1 Basis: finite element tensor-product basis objects for 3035a21df39Svaleriabarra H^1 discretizations.""" 3045a21df39Svaleriabarra 3055a21df39Svaleriabarra # Constructor 3065a21df39Svaleriabarra def __init__(self, ceed, dim, ncomp, P1d, Q1d, interp1d, grad1d, 3075a21df39Svaleriabarra qref1d, qweight1d): 3085a21df39Svaleriabarra 3095a21df39Svaleriabarra # Setup arguments 3105a21df39Svaleriabarra self._pointer = ffi.new("CeedBasis *") 3115a21df39Svaleriabarra 3125a21df39Svaleriabarra self._ceed = ceed 3135a21df39Svaleriabarra 3145a21df39Svaleriabarra interp1d_pointer = ffi.new("CeedScalar *") 3157a7b0fa3SJed Brown interp1d_pointer = ffi.cast( 3167a7b0fa3SJed Brown "CeedScalar *", 3177a7b0fa3SJed Brown interp1d.__array_interface__['data'][0]) 3185a21df39Svaleriabarra 3195a21df39Svaleriabarra grad1d_pointer = ffi.new("CeedScalar *") 3207a7b0fa3SJed Brown grad1d_pointer = ffi.cast( 3217a7b0fa3SJed Brown "CeedScalar *", 3227a7b0fa3SJed Brown grad1d.__array_interface__['data'][0]) 3235a21df39Svaleriabarra 3245a21df39Svaleriabarra qref1d_pointer = ffi.new("CeedScalar *") 3257a7b0fa3SJed Brown qref1d_pointer = ffi.cast( 3267a7b0fa3SJed Brown "CeedScalar *", 3277a7b0fa3SJed Brown qref1d.__array_interface__['data'][0]) 3285a21df39Svaleriabarra 3295a21df39Svaleriabarra qweight1d_pointer = ffi.new("CeedScalar *") 3307a7b0fa3SJed Brown qweight1d_pointer = ffi.cast( 3317a7b0fa3SJed Brown "CeedScalar *", 3327a7b0fa3SJed Brown qweight1d.__array_interface__['data'][0]) 3335a21df39Svaleriabarra 3345a21df39Svaleriabarra # libCEED call 335477729cfSJeremy L Thompson err_code = lib.CeedBasisCreateTensorH1(self._ceed._pointer[0], dim, ncomp, 336477729cfSJeremy L Thompson P1d, Q1d, interp1d_pointer, 337477729cfSJeremy L Thompson grad1d_pointer, qref1d_pointer, 3385a21df39Svaleriabarra qweight1d_pointer, self._pointer) 339477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3405a21df39Svaleriabarra 341*d99fa3c5SJeremy L Thompson # 342*d99fa3c5SJeremy L Thompson def get_interp1d(self): 343*d99fa3c5SJeremy L Thompson """Return 1D interpolation matrix of a tensor product Basis. 344*d99fa3c5SJeremy L Thompson 345*d99fa3c5SJeremy L Thompson Returns: 346*d99fa3c5SJeremy L Thompson *array: Numpy array""" 347*d99fa3c5SJeremy L Thompson 348*d99fa3c5SJeremy L Thompson # Compute the length of the array 349*d99fa3c5SJeremy L Thompson nnodes_pointer = ffi.new("CeedInt *") 350*d99fa3c5SJeremy L Thompson lib.CeedBasisGetNumNodes1D(self._pointer[0], nnodes_pointer) 351*d99fa3c5SJeremy L Thompson nqpts_pointer = ffi.new("CeedInt *") 352*d99fa3c5SJeremy L Thompson lib.CeedBasisGetNumQuadraturePoints1D(self._pointer[0], nqpts_pointer) 353*d99fa3c5SJeremy L Thompson length = nnodes_pointer[0] * nqpts_pointer[0] 354*d99fa3c5SJeremy L Thompson 355*d99fa3c5SJeremy L Thompson # Setup the pointer's pointer 356*d99fa3c5SJeremy L Thompson array_pointer = ffi.new("CeedScalar **") 357*d99fa3c5SJeremy L Thompson 358*d99fa3c5SJeremy L Thompson # libCEED call 359*d99fa3c5SJeremy L Thompson lib.CeedBasisGetInterp1D(self._pointer[0], array_pointer) 360*d99fa3c5SJeremy L Thompson 361*d99fa3c5SJeremy L Thompson # Return array created from buffer 362*d99fa3c5SJeremy L Thompson # Create buffer object from returned pointer 363*d99fa3c5SJeremy L Thompson buff = ffi.buffer( 364*d99fa3c5SJeremy L Thompson array_pointer[0], 365*d99fa3c5SJeremy L Thompson ffi.sizeof("CeedScalar") * 366*d99fa3c5SJeremy L Thompson length) 367*d99fa3c5SJeremy L Thompson # return read only Numpy array 368*d99fa3c5SJeremy L Thompson ret = np.frombuffer(buff, dtype="float64") 369*d99fa3c5SJeremy L Thompson ret.flags['WRITEABLE'] = False 370*d99fa3c5SJeremy L Thompson return ret 371*d99fa3c5SJeremy L Thompson 372*d99fa3c5SJeremy L Thompson 3735a21df39Svaleriabarra# ------------------------------------------------------------------------------ 3747a7b0fa3SJed Brown 3757a7b0fa3SJed Brown 376*d99fa3c5SJeremy L Thompsonclass BasisTensorH1Lagrange(BasisTensorH1): 3775a21df39Svaleriabarra """Ceed Tensor H1 Lagrange Basis: finite element tensor-product Lagrange basis 3785a21df39Svaleriabarra objects for H^1 discretizations.""" 3795a21df39Svaleriabarra 3805a21df39Svaleriabarra # Constructor 3815a21df39Svaleriabarra def __init__(self, ceed, dim, ncomp, P, Q, qmode): 3825a21df39Svaleriabarra 3835a21df39Svaleriabarra # Setup arguments 3845a21df39Svaleriabarra self._pointer = ffi.new("CeedBasis *") 3855a21df39Svaleriabarra 3865a21df39Svaleriabarra self._ceed = ceed 3875a21df39Svaleriabarra 3885a21df39Svaleriabarra # libCEED call 389477729cfSJeremy L Thompson err_code = lib.CeedBasisCreateTensorH1Lagrange(self._ceed._pointer[0], dim, 390477729cfSJeremy L Thompson ncomp, P, Q, qmode, self._pointer) 391477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3925a21df39Svaleriabarra 3935a21df39Svaleriabarra# ------------------------------------------------------------------------------ 3947a7b0fa3SJed Brown 3957a7b0fa3SJed Brown 3965a21df39Svaleriabarraclass BasisH1(Basis): 3975a21df39Svaleriabarra """Ceed H1 Basis: finite element non tensor-product basis for H^1 discretizations.""" 3985a21df39Svaleriabarra 3995a21df39Svaleriabarra # Constructor 4007a7b0fa3SJed Brown def __init__(self, ceed, topo, ncomp, nnodes, 4017a7b0fa3SJed Brown nqpts, interp, grad, qref, qweight): 4025a21df39Svaleriabarra 4035a21df39Svaleriabarra # Setup arguments 4045a21df39Svaleriabarra self._pointer = ffi.new("CeedBasis *") 4055a21df39Svaleriabarra 4065a21df39Svaleriabarra self._ceed = ceed 4075a21df39Svaleriabarra 4085a21df39Svaleriabarra interp_pointer = ffi.new("CeedScalar *") 4097a7b0fa3SJed Brown interp_pointer = ffi.cast( 4107a7b0fa3SJed Brown "CeedScalar *", 4117a7b0fa3SJed Brown interp.__array_interface__['data'][0]) 4125a21df39Svaleriabarra 4135a21df39Svaleriabarra grad_pointer = ffi.new("CeedScalar *") 4147a7b0fa3SJed Brown grad_pointer = ffi.cast( 4157a7b0fa3SJed Brown "CeedScalar *", 4167a7b0fa3SJed Brown grad.__array_interface__['data'][0]) 4175a21df39Svaleriabarra 4185a21df39Svaleriabarra qref_pointer = ffi.new("CeedScalar *") 4197a7b0fa3SJed Brown qref_pointer = ffi.cast( 4207a7b0fa3SJed Brown "CeedScalar *", 4217a7b0fa3SJed Brown qref.__array_interface__['data'][0]) 4225a21df39Svaleriabarra 4235a21df39Svaleriabarra qweight_pointer = ffi.new("CeedScalar *") 4247a7b0fa3SJed Brown qweight_pointer = ffi.cast( 4257a7b0fa3SJed Brown "CeedScalar *", 4267a7b0fa3SJed Brown qweight.__array_interface__['data'][0]) 4275a21df39Svaleriabarra 4285a21df39Svaleriabarra # libCEED call 429477729cfSJeremy L Thompson err_code = lib.CeedBasisCreateH1(self._ceed._pointer[0], topo, ncomp, 430477729cfSJeremy L Thompson nnodes, nqpts, interp_pointer, 431477729cfSJeremy L Thompson grad_pointer, qref_pointer, 4325a21df39Svaleriabarra qweight_pointer, self._pointer) 4335a21df39Svaleriabarra 4345a21df39Svaleriabarra# ------------------------------------------------------------------------------ 4357a7b0fa3SJed Brown 4367a7b0fa3SJed Brown 4375a21df39Svaleriabarraclass TransposeBasis(): 4385a21df39Svaleriabarra """Transpose Ceed Basis: transpose of finite element tensor-product basis objects.""" 4395a21df39Svaleriabarra 4405a21df39Svaleriabarra # Attributes 4415a21df39Svaleriabarra _basis = None 4425a21df39Svaleriabarra 4435a21df39Svaleriabarra # Constructor 4445a21df39Svaleriabarra def __init__(self, basis): 4455a21df39Svaleriabarra 4465a21df39Svaleriabarra # Reference basis 4475a21df39Svaleriabarra self._basis = basis 4485a21df39Svaleriabarra 4495a21df39Svaleriabarra # Representation 4505a21df39Svaleriabarra def __repr__(self): 4515a21df39Svaleriabarra return "<Transpose CeedBasis instance at " + hex(id(self)) + ">" 4525a21df39Svaleriabarra 4535a21df39Svaleriabarra # Apply Transpose Basis 4545a21df39Svaleriabarra def apply(self, nelem, emode, u, v): 4555a21df39Svaleriabarra """Apply basis evaluation from quadrature points to nodes. 4565a21df39Svaleriabarra 4575a21df39Svaleriabarra Args: 4585a21df39Svaleriabarra nelem: the number of elements to apply the basis evaluation to; 4595a21df39Svaleriabarra the backend will specify the ordering in a 4605a21df39Svaleriabarra Blocked ElemRestriction 4615a21df39Svaleriabarra **emode: basis evaluation mode 4625a21df39Svaleriabarra u: input vector 4635a21df39Svaleriabarra v: output vector""" 4645a21df39Svaleriabarra 4655a21df39Svaleriabarra # libCEED call 4665a21df39Svaleriabarra self._basis.apply(nelem, emode, u, v, tmode=TRANSPOSE) 4675a21df39Svaleriabarra 4685a21df39Svaleriabarra# ------------------------------------------------------------------------------ 469