xref: /libCEED/python/ceed.py (revision e15f9bd09af0280c89b79924fa9af7dd2e3e30be)
139b2de37Sjeremylt# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
239b2de37Sjeremylt# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
339b2de37Sjeremylt# reserved. See files LICENSE and NOTICE for details.
439b2de37Sjeremylt#
539b2de37Sjeremylt# This file is part of CEED, a collection of benchmarks, miniapps, software
639b2de37Sjeremylt# libraries and APIs for efficient high-order finite element and spectral
739b2de37Sjeremylt# element discretizations for exascale applications. For more information and
839b2de37Sjeremylt# source code availability see http://github.com/ceed.
939b2de37Sjeremylt#
1039b2de37Sjeremylt# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
1139b2de37Sjeremylt# a collaborative effort of two U.S. Department of Energy organizations (Office
1239b2de37Sjeremylt# of Science and the National Nuclear Security Administration) responsible for
1339b2de37Sjeremylt# the planning and preparation of a capable exascale ecosystem, including
1439b2de37Sjeremylt# software, applications, hardware, advanced system engineering and early
1539b2de37Sjeremylt# testbed platforms, in support of the nation's exascale computing imperative.
1639b2de37Sjeremylt
1739b2de37Sjeremyltfrom _ceed_cffi import ffi, lib
1839b2de37Sjeremyltimport sys
19477729cfSJeremy L Thompsonimport os
2039b2de37Sjeremyltimport io
21*e15f9bd0SJeremy L Thompsonimport numpy as np
220a0da059Sjeremyltimport tempfile
2339b2de37Sjeremyltfrom abc import ABC
2439b2de37Sjeremyltfrom .ceed_vector import Vector
2539b2de37Sjeremyltfrom .ceed_basis import BasisTensorH1, BasisTensorH1Lagrange, BasisH1
2669a53589Sjeremyltfrom .ceed_elemrestriction import ElemRestriction, StridedElemRestriction, BlockedElemRestriction, BlockedStridedElemRestriction
2739b2de37Sjeremyltfrom .ceed_qfunction import QFunction, QFunctionByName, IdentityQFunction
28777ff853SJeremy L Thompsonfrom .ceed_qfunctioncontext import QFunctionContext
2939b2de37Sjeremyltfrom .ceed_operator import Operator, CompositeOperator
3039b2de37Sjeremyltfrom .ceed_constants import *
3139b2de37Sjeremylt
3239b2de37Sjeremylt# ------------------------------------------------------------------------------
337a7b0fa3SJed Brown
347a7b0fa3SJed Brown
3539b2de37Sjeremyltclass Ceed():
3639b2de37Sjeremylt    """Ceed: core components."""
3739b2de37Sjeremylt
3839b2de37Sjeremylt    # Constructor
3974b533adSJed Brown    def __init__(self, resource="/cpu/self", on_error="store"):
4039b2de37Sjeremylt        # libCEED object
4139b2de37Sjeremylt        self._pointer = ffi.new("Ceed *")
4239b2de37Sjeremylt
4339b2de37Sjeremylt        # libCEED call
4439b2de37Sjeremylt        resourceAscii = ffi.new("char[]", resource.encode("ascii"))
45477729cfSJeremy L Thompson        os.environ["CEED_ERROR_HANDLER"] = "return"
46477729cfSJeremy L Thompson        err_code = lib.CeedInit(resourceAscii, self._pointer)
47477729cfSJeremy L Thompson        if err_code:
48477729cfSJeremy L Thompson            raise Exception("Error initializing backend resource: " + resource)
4974b533adSJed Brown        error_handlers = dict(
5074b533adSJed Brown            store="CeedErrorStore",
5174b533adSJed Brown            abort="CeedErrorAbort",
5274b533adSJed Brown        )
53477729cfSJeremy L Thompson        lib.CeedSetErrorHandler(
54477729cfSJeremy L Thompson            self._pointer[0], ffi.addressof(
5574b533adSJed Brown                lib, error_handlers[on_error]))
5639b2de37Sjeremylt
5739b2de37Sjeremylt    # Representation
5839b2de37Sjeremylt    def __repr__(self):
5939b2de37Sjeremylt        return "<Ceed instance at " + hex(id(self)) + ">"
6039b2de37Sjeremylt
610a0da059Sjeremylt    # String conversion for print() to stdout
620a0da059Sjeremylt    def __str__(self):
630a0da059Sjeremylt        """View a Ceed via print()."""
640a0da059Sjeremylt
650a0da059Sjeremylt        # libCEED call
660a0da059Sjeremylt        with tempfile.NamedTemporaryFile() as key_file:
670a0da059Sjeremylt            with open(key_file.name, 'r+') as stream_file:
680a0da059Sjeremylt                stream = ffi.cast("FILE *", stream_file)
690a0da059Sjeremylt
70477729cfSJeremy L Thompson                err_code = lib.CeedView(self._pointer[0], stream)
71477729cfSJeremy L Thompson                self._check_error(err_code)
720a0da059Sjeremylt
730a0da059Sjeremylt                stream_file.seek(0)
740a0da059Sjeremylt                out_string = stream_file.read()
750a0da059Sjeremylt
760a0da059Sjeremylt        return out_string
770a0da059Sjeremylt
78477729cfSJeremy L Thompson    # Error handler
79477729cfSJeremy L Thompson    def _check_error(self, err_code):
80477729cfSJeremy L Thompson        """Check return code and retrieve error message for non-zero code"""
81*e15f9bd0SJeremy L Thompson        if (err_code != lib.CEED_ERROR_SUCCESS):
82477729cfSJeremy L Thompson            message = ffi.new("char **")
83477729cfSJeremy L Thompson            lib.CeedGetErrorMessage(self._pointer[0], message)
84477729cfSJeremy L Thompson            raise Exception(ffi.string(message[0]).decode("UTF-8"))
85477729cfSJeremy L Thompson
8639b2de37Sjeremylt    # Get Resource
8739b2de37Sjeremylt    def get_resource(self):
8839b2de37Sjeremylt        """Get the full resource name for a Ceed context.
8939b2de37Sjeremylt
9039b2de37Sjeremylt           Returns:
9139b2de37Sjeremylt             resource: resource name"""
9239b2de37Sjeremylt
9339b2de37Sjeremylt        # libCEED call
9439b2de37Sjeremylt        resource = ffi.new("char **")
95477729cfSJeremy L Thompson        err_code = lib.CeedGetResource(self._pointer[0], resource)
96477729cfSJeremy L Thompson        self._check_error(err_code)
9739b2de37Sjeremylt
9839b2de37Sjeremylt        return ffi.string(resource[0]).decode("UTF-8")
9939b2de37Sjeremylt
10039b2de37Sjeremylt    # Preferred MemType
10139b2de37Sjeremylt    def get_preferred_memtype(self):
10239b2de37Sjeremylt        """Return Ceed preferred memory type.
10339b2de37Sjeremylt
10439b2de37Sjeremylt           Returns:
10539b2de37Sjeremylt             memtype: Ceed preferred memory type"""
10639b2de37Sjeremylt
10739b2de37Sjeremylt        # libCEED call
10839b2de37Sjeremylt        memtype = ffi.new("CeedMemType *", MEM_HOST)
109477729cfSJeremy L Thompson        err_code = lib.CeedGetPreferredMemType(self._pointer[0], memtype)
110477729cfSJeremy L Thompson        self._check_error(err_code)
11139b2de37Sjeremylt
11239b2de37Sjeremylt        return memtype[0]
11339b2de37Sjeremylt
114*e15f9bd0SJeremy L Thompson    # --- Basis utility functions ---
115*e15f9bd0SJeremy L Thompson
116*e15f9bd0SJeremy L Thompson    # Gauss quadrature
117*e15f9bd0SJeremy L Thompson    def gauss_quadrature(self, q):
118*e15f9bd0SJeremy L Thompson        """Construct a Gauss-Legendre quadrature.
119*e15f9bd0SJeremy L Thompson
120*e15f9bd0SJeremy L Thompson           Args:
121*e15f9bd0SJeremy L Thompson             Q: number of quadrature points (integrates polynomials of
122*e15f9bd0SJeremy L Thompson                  degree 2*Q-1 exactly)
123*e15f9bd0SJeremy L Thompson
124*e15f9bd0SJeremy L Thompson           Returns:
125*e15f9bd0SJeremy L Thompson             (qref1d, qweight1d): array of length Q to hold the abscissa on [-1, 1]
126*e15f9bd0SJeremy L Thompson                                    and array of length Q to hold the weights"""
127*e15f9bd0SJeremy L Thompson
128*e15f9bd0SJeremy L Thompson        # Setup arguments
129*e15f9bd0SJeremy L Thompson        qref1d = np.empty(q, dtype="float64")
130*e15f9bd0SJeremy L Thompson        qweight1d = np.empty(q, dtype="float64")
131*e15f9bd0SJeremy L Thompson
132*e15f9bd0SJeremy L Thompson        qref1d_pointer = ffi.new("CeedScalar *")
133*e15f9bd0SJeremy L Thompson        qref1d_pointer = ffi.cast(
134*e15f9bd0SJeremy L Thompson            "CeedScalar *",
135*e15f9bd0SJeremy L Thompson            qref1d.__array_interface__['data'][0])
136*e15f9bd0SJeremy L Thompson
137*e15f9bd0SJeremy L Thompson        qweight1d_pointer = ffi.new("CeedScalar *")
138*e15f9bd0SJeremy L Thompson        qweight1d_pointer = ffi.cast(
139*e15f9bd0SJeremy L Thompson            "CeedScalar *",
140*e15f9bd0SJeremy L Thompson            qweight1d.__array_interface__['data'][0])
141*e15f9bd0SJeremy L Thompson
142*e15f9bd0SJeremy L Thompson        # libCEED call
143*e15f9bd0SJeremy L Thompson        err_code = lib.CeedGaussQuadrature(q, qref1d_pointer, qweight1d_pointer)
144*e15f9bd0SJeremy L Thompson        self._check_error(err_code)
145*e15f9bd0SJeremy L Thompson
146*e15f9bd0SJeremy L Thompson        return qref1d, qweight1d
147*e15f9bd0SJeremy L Thompson
148*e15f9bd0SJeremy L Thompson    # Lobatto quadrature
149*e15f9bd0SJeremy L Thompson    def lobatto_quadrature(self, q):
150*e15f9bd0SJeremy L Thompson        """Construct a Gauss-Legendre-Lobatto quadrature.
151*e15f9bd0SJeremy L Thompson
152*e15f9bd0SJeremy L Thompson           Args:
153*e15f9bd0SJeremy L Thompson             q: number of quadrature points (integrates polynomials of
154*e15f9bd0SJeremy L Thompson                  degree 2*Q-3 exactly)
155*e15f9bd0SJeremy L Thompson
156*e15f9bd0SJeremy L Thompson           Returns:
157*e15f9bd0SJeremy L Thompson             (qref1d, qweight1d): array of length Q to hold the abscissa on [-1, 1]
158*e15f9bd0SJeremy L Thompson                                    and array of length Q to hold the weights"""
159*e15f9bd0SJeremy L Thompson
160*e15f9bd0SJeremy L Thompson        # Setup arguments
161*e15f9bd0SJeremy L Thompson        qref1d = np.empty(q, dtype="float64")
162*e15f9bd0SJeremy L Thompson        qref1d_pointer = ffi.new("CeedScalar *")
163*e15f9bd0SJeremy L Thompson        qref1d_pointer = ffi.cast(
164*e15f9bd0SJeremy L Thompson            "CeedScalar *",
165*e15f9bd0SJeremy L Thompson            qref1d.__array_interface__['data'][0])
166*e15f9bd0SJeremy L Thompson
167*e15f9bd0SJeremy L Thompson        qweight1d = np.empty(q, dtype="float64")
168*e15f9bd0SJeremy L Thompson        qweight1d_pointer = ffi.new("CeedScalar *")
169*e15f9bd0SJeremy L Thompson        qweight1d_pointer = ffi.cast(
170*e15f9bd0SJeremy L Thompson            "CeedScalar *",
171*e15f9bd0SJeremy L Thompson            qweight1d.__array_interface__['data'][0])
172*e15f9bd0SJeremy L Thompson
173*e15f9bd0SJeremy L Thompson        # libCEED call
174*e15f9bd0SJeremy L Thompson        err_code = lib.CeedLobattoQuadrature(
175*e15f9bd0SJeremy L Thompson            q, qref1d_pointer, qweight1d_pointer)
176*e15f9bd0SJeremy L Thompson        self._check_error(err_code)
177*e15f9bd0SJeremy L Thompson
178*e15f9bd0SJeremy L Thompson        return qref1d, qweight1d
179*e15f9bd0SJeremy L Thompson
180*e15f9bd0SJeremy L Thompson    # QR factorization
181*e15f9bd0SJeremy L Thompson    def qr_factorization(self, mat, tau, m, n):
182*e15f9bd0SJeremy L Thompson        """Return QR Factorization of a matrix.
183*e15f9bd0SJeremy L Thompson
184*e15f9bd0SJeremy L Thompson           Args:
185*e15f9bd0SJeremy L Thompson             ceed: Ceed context currently in use
186*e15f9bd0SJeremy L Thompson             *mat: Numpy array holding the row-major matrix to be factorized in place
187*e15f9bd0SJeremy L Thompson             *tau: Numpy array to hold the vector of lengt m of scaling factors
188*e15f9bd0SJeremy L Thompson             m: number of rows
189*e15f9bd0SJeremy L Thompson             n: numbef of columns"""
190*e15f9bd0SJeremy L Thompson
191*e15f9bd0SJeremy L Thompson        # Setup arguments
192*e15f9bd0SJeremy L Thompson        mat_pointer = ffi.new("CeedScalar *")
193*e15f9bd0SJeremy L Thompson        mat_pointer = ffi.cast(
194*e15f9bd0SJeremy L Thompson            "CeedScalar *",
195*e15f9bd0SJeremy L Thompson            mat.__array_interface__['data'][0])
196*e15f9bd0SJeremy L Thompson
197*e15f9bd0SJeremy L Thompson        tau_pointer = ffi.new("CeedScalar *")
198*e15f9bd0SJeremy L Thompson        tau_pointer = ffi.cast(
199*e15f9bd0SJeremy L Thompson            "CeedScalar *",
200*e15f9bd0SJeremy L Thompson            tau.__array_interface__['data'][0])
201*e15f9bd0SJeremy L Thompson
202*e15f9bd0SJeremy L Thompson        # libCEED call
203*e15f9bd0SJeremy L Thompson        err_code = lib.CeedQRFactorization(
204*e15f9bd0SJeremy L Thompson            self._pointer[0], mat_pointer, tau_pointer, m, n)
205*e15f9bd0SJeremy L Thompson        self._check_error(err_code)
206*e15f9bd0SJeremy L Thompson
207*e15f9bd0SJeremy L Thompson        return mat, tau
208*e15f9bd0SJeremy L Thompson
209*e15f9bd0SJeremy L Thompson    # Symmetric Schur decomposition
210*e15f9bd0SJeremy L Thompson    def symmetric_schur_decomposition(self, mat, n):
211*e15f9bd0SJeremy L Thompson        """Return symmetric Schur decomposition of a symmetric matrix
212*e15f9bd0SJeremy L Thompson             via symmetric QR factorization.
213*e15f9bd0SJeremy L Thompson
214*e15f9bd0SJeremy L Thompson           Args:
215*e15f9bd0SJeremy L Thompson             ceed: Ceed context currently in use
216*e15f9bd0SJeremy L Thompson             *mat: Numpy array holding the row-major matrix to be factorized in place
217*e15f9bd0SJeremy L Thompson             n: number of rows/columns
218*e15f9bd0SJeremy L Thompson
219*e15f9bd0SJeremy L Thompson           Returns:
220*e15f9bd0SJeremy L Thompson             lbda: Numpy array of length n holding eigenvalues"""
221*e15f9bd0SJeremy L Thompson
222*e15f9bd0SJeremy L Thompson        # Setup arguments
223*e15f9bd0SJeremy L Thompson        mat_pointer = ffi.new("CeedScalar *")
224*e15f9bd0SJeremy L Thompson        mat_pointer = ffi.cast(
225*e15f9bd0SJeremy L Thompson            "CeedScalar *",
226*e15f9bd0SJeremy L Thompson            mat.__array_interface__['data'][0])
227*e15f9bd0SJeremy L Thompson
228*e15f9bd0SJeremy L Thompson        lbda = np.empty(n, dtype="float64")
229*e15f9bd0SJeremy L Thompson        l_pointer = ffi.new("CeedScalar *")
230*e15f9bd0SJeremy L Thompson        l_pointer = ffi.cast(
231*e15f9bd0SJeremy L Thompson            "CeedScalar *",
232*e15f9bd0SJeremy L Thompson            lbda.__array_interface__['data'][0])
233*e15f9bd0SJeremy L Thompson
234*e15f9bd0SJeremy L Thompson        # libCEED call
235*e15f9bd0SJeremy L Thompson        err_code = lib.CeedSymmetricSchurDecomposition(
236*e15f9bd0SJeremy L Thompson            self._pointer[0], mat_pointer, l_pointer, n)
237*e15f9bd0SJeremy L Thompson        self._check_error(err_code)
238*e15f9bd0SJeremy L Thompson
239*e15f9bd0SJeremy L Thompson        return lbda
240*e15f9bd0SJeremy L Thompson
241*e15f9bd0SJeremy L Thompson    # Simultaneous Diagonalization
242*e15f9bd0SJeremy L Thompson    def simultaneous_diagonalization(self, matA, matB, n):
243*e15f9bd0SJeremy L Thompson        """Return Simultaneous Diagonalization of two matrices.
244*e15f9bd0SJeremy L Thompson
245*e15f9bd0SJeremy L Thompson           Args:
246*e15f9bd0SJeremy L Thompson             ceed: Ceed context currently in use
247*e15f9bd0SJeremy L Thompson             *matA: Numpy array holding the row-major matrix to be factorized with
248*e15f9bd0SJeremy L Thompson                      eigenvalues
249*e15f9bd0SJeremy L Thompson             *matB: Numpy array holding the row-major matrix to be factorized to identity
250*e15f9bd0SJeremy L Thompson             n: number of rows/columns
251*e15f9bd0SJeremy L Thompson
252*e15f9bd0SJeremy L Thompson           Returns:
253*e15f9bd0SJeremy L Thompson             (x, lbda): Numpy array holding the row-major orthogonal matrix and
254*e15f9bd0SJeremy L Thompson                          Numpy array holding the vector of length n of generalized
255*e15f9bd0SJeremy L Thompson                          eigenvalues"""
256*e15f9bd0SJeremy L Thompson
257*e15f9bd0SJeremy L Thompson        # Setup arguments
258*e15f9bd0SJeremy L Thompson        matA_pointer = ffi.new("CeedScalar *")
259*e15f9bd0SJeremy L Thompson        matA_pointer = ffi.cast(
260*e15f9bd0SJeremy L Thompson            "CeedScalar *",
261*e15f9bd0SJeremy L Thompson            matA.__array_interface__['data'][0])
262*e15f9bd0SJeremy L Thompson
263*e15f9bd0SJeremy L Thompson        matB_pointer = ffi.new("CeedScalar *")
264*e15f9bd0SJeremy L Thompson        matB_pointer = ffi.cast(
265*e15f9bd0SJeremy L Thompson            "CeedScalar *",
266*e15f9bd0SJeremy L Thompson            matB.__array_interface__['data'][0])
267*e15f9bd0SJeremy L Thompson
268*e15f9bd0SJeremy L Thompson        lbda = np.empty(n, dtype="float64")
269*e15f9bd0SJeremy L Thompson        l_pointer = ffi.new("CeedScalar *")
270*e15f9bd0SJeremy L Thompson        l_pointer = ffi.cast(
271*e15f9bd0SJeremy L Thompson            "CeedScalar *",
272*e15f9bd0SJeremy L Thompson            lbda.__array_interface__['data'][0])
273*e15f9bd0SJeremy L Thompson
274*e15f9bd0SJeremy L Thompson        x = np.empty(n * n, dtype="float64")
275*e15f9bd0SJeremy L Thompson        x_pointer = ffi.new("CeedScalar *")
276*e15f9bd0SJeremy L Thompson        x_pointer = ffi.cast("CeedScalar *", x.__array_interface__['data'][0])
277*e15f9bd0SJeremy L Thompson
278*e15f9bd0SJeremy L Thompson        # libCEED call
279*e15f9bd0SJeremy L Thompson        err_code = lib.CeedSimultaneousDiagonalization(self._pointer[0], matA_pointer, matB_pointer,
280*e15f9bd0SJeremy L Thompson                                                       x_pointer, l_pointer, n)
281*e15f9bd0SJeremy L Thompson        self._check_error(err_code)
282*e15f9bd0SJeremy L Thompson
283*e15f9bd0SJeremy L Thompson        return x, lbda
284*e15f9bd0SJeremy L Thompson
285*e15f9bd0SJeremy L Thompson    # --- libCEED objects ---
286*e15f9bd0SJeremy L Thompson
28739b2de37Sjeremylt    # CeedVector
28839b2de37Sjeremylt    def Vector(self, size):
28939b2de37Sjeremylt        """Ceed Vector: storing and manipulating vectors.
29039b2de37Sjeremylt
29139b2de37Sjeremylt           Args:
29239b2de37Sjeremylt             size: length of vector
29339b2de37Sjeremylt
29439b2de37Sjeremylt           Returns:
29539b2de37Sjeremylt             vector: Ceed Vector"""
29639b2de37Sjeremylt
29739b2de37Sjeremylt        return Vector(self, size)
29839b2de37Sjeremylt
29939b2de37Sjeremylt    # CeedElemRestriction
300d979a051Sjeremylt    def ElemRestriction(self, nelem, elemsize, ncomp, compstride, lsize, offsets,
301d979a051Sjeremylt                        memtype=lib.CEED_MEM_HOST, cmode=lib.CEED_COPY_VALUES):
30239b2de37Sjeremylt        """Ceed ElemRestriction: restriction from local vectors to elements.
30339b2de37Sjeremylt
30439b2de37Sjeremylt           Args:
305d979a051Sjeremylt             nelem: number of elements described by the restriction
30639b2de37Sjeremylt             elemsize: size (number of nodes) per element
307d979a051Sjeremylt             ncomp: number of field components per interpolation node
308d979a051Sjeremylt                      (1 for scalar fields)
309d979a051Sjeremylt             compstride: Stride between components for the same L-vector "node".
310d979a051Sjeremylt                           Data for node i, component k can be found in the
311d979a051Sjeremylt                           L-vector at index [offsets[i] + k*compstride].
312d979a051Sjeremylt             lsize: The size of the L-vector. This vector may be larger than
313d979a051Sjeremylt                       the elements and fields given by this restriction.
314d979a051Sjeremylt             *offsets: Numpy array of shape [nelem, elemsize]. Row i holds the
315d979a051Sjeremylt                         ordered list of the offsets (into the input Ceed Vector)
31639b2de37Sjeremylt                         for the unknowns corresponding to element i, where
317d979a051Sjeremylt                         0 <= i < nelem. All offsets must be in the range
318d979a051Sjeremylt                         [0, lsize - 1].
319d979a051Sjeremylt             **memtype: memory type of the offsets array, default CEED_MEM_HOST
320d979a051Sjeremylt             **cmode: copy mode for the offsets array, default CEED_COPY_VALUES
32139b2de37Sjeremylt
32239b2de37Sjeremylt           Returns:
32339b2de37Sjeremylt             elemrestriction: Ceed ElemRestiction"""
32439b2de37Sjeremylt
325d979a051Sjeremylt        return ElemRestriction(self, nelem, elemsize, ncomp, compstride, lsize,
326d979a051Sjeremylt                               offsets, memtype=memtype, cmode=cmode)
32739b2de37Sjeremylt
328d979a051Sjeremylt    def StridedElemRestriction(self, nelem, elemsize, ncomp, lsize, strides):
329d979a051Sjeremylt        """Ceed Identity ElemRestriction: strided restriction from local vectors
330d979a051Sjeremylt             to elements.
33139b2de37Sjeremylt
33239b2de37Sjeremylt           Args:
333d979a051Sjeremylt             nelem: number of elements described by the restriction
33439b2de37Sjeremylt             elemsize: size (number of nodes) per element
335a8d32208Sjeremylt             ncomp: number of field components per interpolation node
336a8d32208Sjeremylt                      (1 for scalar fields)
337d979a051Sjeremylt             lsize: The size of the L-vector. This vector may be larger than
338d979a051Sjeremylt                      the elements and fields given by this restriction.
33969a53589Sjeremylt             *strides: Array for strides between [nodes, components, elements].
34069a53589Sjeremylt                         The data for node i, component j, element k in the
34169a53589Sjeremylt                         L-vector is given by
34269a53589Sjeremylt                           i*strides[0] + j*strides[1] + k*strides[2]
34339b2de37Sjeremylt
34439b2de37Sjeremylt           Returns:
34569a53589Sjeremylt             elemrestriction: Ceed Strided ElemRestiction"""
34639b2de37Sjeremylt
3477a7b0fa3SJed Brown        return StridedElemRestriction(
348d979a051Sjeremylt            self, nelem, elemsize, ncomp, lsize, strides)
34939b2de37Sjeremylt
350d979a051Sjeremylt    def BlockedElemRestriction(self, nelem, elemsize, blksize, ncomp, compstride,
351d979a051Sjeremylt                               lsize, offsets, memtype=lib.CEED_MEM_HOST,
352d979a051Sjeremylt                               cmode=lib.CEED_COPY_VALUES):
353d979a051Sjeremylt        """Ceed Blocked ElemRestriction: blocked restriction from local vectors
354d979a051Sjeremylt             to elements.
35539b2de37Sjeremylt
35639b2de37Sjeremylt           Args:
357d979a051Sjeremylt             nelem: number of elements described by the restriction
35839b2de37Sjeremylt             elemsize: size (number of nodes) per element
35939b2de37Sjeremylt             blksize: number of elements in a block
360d979a051Sjeremylt             ncomp: number of field components per interpolation node
361d979a051Sjeremylt                       (1 for scalar fields)
362d979a051Sjeremylt             lsize: The size of the L-vector. This vector may be larger than
363d979a051Sjeremylt                      the elements and fields given by this restriction.
364d979a051Sjeremylt             *offsets: Numpy array of shape [nelem, elemsize]. Row i holds the
365d979a051Sjeremylt                         ordered list of the offsets (into the input Ceed Vector)
36639b2de37Sjeremylt                         for the unknowns corresponding to element i, where
367d979a051Sjeremylt                         0 <= i < nelem. All offsets must be in the range
368d979a051Sjeremylt                         [0, lsize - 1]. The backend will permute and pad this
36939b2de37Sjeremylt                         array to the desired ordering for the blocksize, which is
37039b2de37Sjeremylt                         typically given by the backend. The default reordering is
37139b2de37Sjeremylt                         to interlace elements.
372d979a051Sjeremylt             **memtype: memory type of the offsets array, default CEED_MEM_HOST
373d979a051Sjeremylt             **cmode: copy mode for the offsets array, default CEED_COPY_VALUES
37439b2de37Sjeremylt
37539b2de37Sjeremylt           Returns:
37639b2de37Sjeremylt             elemrestriction: Ceed Blocked ElemRestiction"""
37739b2de37Sjeremylt
378d979a051Sjeremylt        return BlockedElemRestriction(self, nelem, elemsize, blksize, ncomp,
379d979a051Sjeremylt                                      compstride, lsize, offsets,
380d979a051Sjeremylt                                      memtype=memtype, cmode=cmode)
38139b2de37Sjeremylt
382d979a051Sjeremylt    def BlockedStridedElemRestriction(self, nelem, elemsize, blksize, ncomp,
383d979a051Sjeremylt                                      lsize, strides):
384d979a051Sjeremylt        """Ceed Blocked Strided ElemRestriction: blocked and strided restriction
385d979a051Sjeremylt             from local vectors to elements.
38669a53589Sjeremylt
38769a53589Sjeremylt           Args:
388d979a051Sjeremylt             nelem: number of elements described in the restriction
38969a53589Sjeremylt             elemsize: size (number of nodes) per element
39069a53589Sjeremylt             blksize: number of elements in a block
39169a53589Sjeremylt             ncomp: number of field components per interpolation node
39269a53589Sjeremylt                      (1 for scalar fields)
393d979a051Sjeremylt             lsize: The size of the L-vector. This vector may be larger than
394d979a051Sjeremylt                      the elements and fields given by this restriction.
39569a53589Sjeremylt             *strides: Array for strides between [nodes, components, elements].
39669a53589Sjeremylt                         The data for node i, component j, element k in the
39769a53589Sjeremylt                         L-vector is given by
39869a53589Sjeremylt                           i*strides[0] + j*strides[1] + k*strides[2]
39969a53589Sjeremylt
40069a53589Sjeremylt           Returns:
40169a53589Sjeremylt             elemrestriction: Ceed Strided ElemRestiction"""
40269a53589Sjeremylt
40369a53589Sjeremylt        return BlockedStridedElemRestriction(self, nelem, elemsize, blksize,
404d979a051Sjeremylt                                             ncomp, lsize, strides)
40569a53589Sjeremylt
40639b2de37Sjeremylt    # CeedBasis
40739b2de37Sjeremylt    def BasisTensorH1(self, dim, ncomp, P1d, Q1d, interp1d, grad1d,
40839b2de37Sjeremylt                      qref1d, qweight1d):
40939b2de37Sjeremylt        """Ceed Tensor H1 Basis: finite element tensor-product basis objects for
41039b2de37Sjeremylt             H^1 discretizations.
41139b2de37Sjeremylt
41239b2de37Sjeremylt           Args:
41339b2de37Sjeremylt             dim: topological dimension
41439b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
41539b2de37Sjeremylt             P1d: number of nodes in one dimension
41639b2de37Sjeremylt             Q1d: number of quadrature points in one dimension
417d979a051Sjeremylt             *interp1d: Numpy array holding the row-major (Q1d * P1d) matrix
418d979a051Sjeremylt                          expressing the values of nodal basis functions at
419d979a051Sjeremylt                          quadrature points
420d979a051Sjeremylt             *grad1d: Numpy array holding the row-major (Q1d * P1d) matrix
421d979a051Sjeremylt                        expressing the derivatives of nodal basis functions at
422d979a051Sjeremylt                        quadrature points
423d979a051Sjeremylt             *qref1d: Numpy array of length Q1d holding the locations of
424d979a051Sjeremylt                        quadrature points on the 1D reference element [-1, 1]
425d979a051Sjeremylt             *qweight1d: Numpy array of length Q1d holding the quadrature
426d979a051Sjeremylt                           weights on the reference element
42739b2de37Sjeremylt
42839b2de37Sjeremylt           Returns:
42939b2de37Sjeremylt             basis: Ceed Basis"""
43039b2de37Sjeremylt
43139b2de37Sjeremylt        return BasisTensorH1(self, dim, ncomp, P1d, Q1d, interp1d, grad1d,
43239b2de37Sjeremylt                             qref1d, qweight1d)
43339b2de37Sjeremylt
43439b2de37Sjeremylt    def BasisTensorH1Lagrange(self, dim, ncomp, P, Q, qmode):
435d979a051Sjeremylt        """Ceed Tensor H1 Lagrange Basis: finite element tensor-product Lagrange
436d979a051Sjeremylt             basis objects for H^1 discretizations.
43739b2de37Sjeremylt
43839b2de37Sjeremylt           Args:
43939b2de37Sjeremylt             dim: topological dimension
44039b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
44139b2de37Sjeremylt             P: number of Gauss-Lobatto nodes in one dimension.  The
44239b2de37Sjeremylt                  polynomial degree of the resulting Q_k element is k=P-1.
44339b2de37Sjeremylt             Q: number of quadrature points in one dimension
44439b2de37Sjeremylt             qmode: distribution of the Q quadrature points (affects order of
44539b2de37Sjeremylt                      accuracy for the quadrature)
44639b2de37Sjeremylt
44739b2de37Sjeremylt           Returns:
44839b2de37Sjeremylt             basis: Ceed Basis"""
44939b2de37Sjeremylt
45039b2de37Sjeremylt        return BasisTensorH1Lagrange(self, dim, ncomp, P, Q, qmode)
45139b2de37Sjeremylt
45239b2de37Sjeremylt    def BasisH1(self, topo, ncomp, nnodes, nqpts, interp, grad, qref, qweight):
453d979a051Sjeremylt        """Ceed H1 Basis: finite element non tensor-product basis for H^1
454d979a051Sjeremylt             discretizations.
45539b2de37Sjeremylt
45639b2de37Sjeremylt           Args:
45739b2de37Sjeremylt             topo: topology of the element, e.g. hypercube, simplex, etc
45839b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
45939b2de37Sjeremylt             nnodes: total number of nodes
46039b2de37Sjeremylt             nqpts: total number of quadrature points
461d979a051Sjeremylt             *interp: Numpy array holding the row-major (nqpts * nnodes) matrix
462d979a051Sjeremylt                       expressing the values of nodal basis functions at
46339b2de37Sjeremylt                       quadrature points
464d979a051Sjeremylt             *grad: Numpy array holding the row-major (nqpts * dim * nnodes)
465d979a051Sjeremylt                     matrix expressing the derivatives of nodal basis functions
466d979a051Sjeremylt                     at quadrature points
467d979a051Sjeremylt             *qref: Numpy array of length (nqpts * dim) holding the locations of
468d979a051Sjeremylt                     quadrature points on the reference element [-1, 1]
469d979a051Sjeremylt             *qweight: Numpy array of length nnodes holding the quadrature
470d979a051Sjeremylt                        weights on the reference element
47139b2de37Sjeremylt
47239b2de37Sjeremylt           Returns:
47339b2de37Sjeremylt             basis: Ceed Basis"""
47439b2de37Sjeremylt
4757a7b0fa3SJed Brown        return BasisH1(self, topo, ncomp, nnodes, nqpts,
4767a7b0fa3SJed Brown                       interp, grad, qref, qweight)
47739b2de37Sjeremylt
47839b2de37Sjeremylt    # CeedQFunction
47939b2de37Sjeremylt    def QFunction(self, vlength, f, source):
480d979a051Sjeremylt        """Ceed QFunction: point-wise operation at quadrature points for
481d979a051Sjeremylt             evaluating volumetric terms.
48239b2de37Sjeremylt
48339b2de37Sjeremylt           Args:
48439b2de37Sjeremylt             vlength: vector length. Caller must ensure that number of quadrature
48539b2de37Sjeremylt                        points is a multiple of vlength
48639b2de37Sjeremylt             f: ctypes function pointer to evaluate action at quadrature points
48739b2de37Sjeremylt             source: absolute path to source of QFunction,
48839b2de37Sjeremylt               "\\abs_path\\file.h:function_name
48939b2de37Sjeremylt
49039b2de37Sjeremylt           Returns:
49139b2de37Sjeremylt             qfunction: Ceed QFunction"""
49239b2de37Sjeremylt
49339b2de37Sjeremylt        return QFunction(self, vlength, f, source)
49439b2de37Sjeremylt
49539b2de37Sjeremylt    def QFunctionByName(self, name):
49639b2de37Sjeremylt        """Ceed QFunction By Name: point-wise operation at quadrature points
49739b2de37Sjeremylt             from a given gallery, for evaluating volumetric terms.
49839b2de37Sjeremylt
49939b2de37Sjeremylt           Args:
50039b2de37Sjeremylt             name: name of QFunction to use from gallery
50139b2de37Sjeremylt
50239b2de37Sjeremylt           Returns:
50339b2de37Sjeremylt             qfunction: Ceed QFunction By Name"""
50439b2de37Sjeremylt
50539b2de37Sjeremylt        return QFunctionByName(self, name)
50639b2de37Sjeremylt
50739b2de37Sjeremylt    def IdentityQFunction(self, size, inmode, outmode):
50839b2de37Sjeremylt        """Ceed Idenity QFunction: identity qfunction operation.
50939b2de37Sjeremylt
51039b2de37Sjeremylt           Args:
51139b2de37Sjeremylt             size: size of the qfunction fields
51239b2de37Sjeremylt             **inmode: CeedEvalMode for input to Ceed QFunction
51339b2de37Sjeremylt             **outmode: CeedEvalMode for output to Ceed QFunction
51439b2de37Sjeremylt
51539b2de37Sjeremylt           Returns:
51639b2de37Sjeremylt             qfunction: Ceed Identity QFunction"""
51739b2de37Sjeremylt
51839b2de37Sjeremylt        return IdentityQFunction(self, size, inmode, outmode)
51939b2de37Sjeremylt
520777ff853SJeremy L Thompson    def QFunctionContext(self):
521777ff853SJeremy L Thompson        """Ceed QFunction Context: stores Ceed QFunction user context data.
522777ff853SJeremy L Thompson
523777ff853SJeremy L Thompson           Returns:
524777ff853SJeremy L Thompson             userContext: Ceed QFunction Context"""
525777ff853SJeremy L Thompson
526777ff853SJeremy L Thompson        return QFunctionContext(self)
527777ff853SJeremy L Thompson
52839b2de37Sjeremylt    # CeedOperator
52939b2de37Sjeremylt    def Operator(self, qf, dqf=None, qdfT=None):
53039b2de37Sjeremylt        """Ceed Operator: composed FE-type operations on vectors.
53139b2de37Sjeremylt
53239b2de37Sjeremylt           Args:
533d979a051Sjeremylt             qf: QFunction defining the action of the operator at quadrature
534d979a051Sjeremylt                   points
53539b2de37Sjeremylt             **dqf: QFunction defining the action of the Jacobian, default None
536d979a051Sjeremylt             **dqfT: QFunction defining the action of the transpose of the
537d979a051Sjeremylt                       Jacobian, default None
53839b2de37Sjeremylt
53939b2de37Sjeremylt           Returns:
54039b2de37Sjeremylt             operator: Ceed Operator"""
54139b2de37Sjeremylt
54239b2de37Sjeremylt        return Operator(self, qf, dqf, qdfT)
54339b2de37Sjeremylt
54439b2de37Sjeremylt    def CompositeOperator(self):
54539b2de37Sjeremylt        """Composite Ceed Operator: composition of multiple CeedOperators.
54639b2de37Sjeremylt
54739b2de37Sjeremylt           Returns:
54839b2de37Sjeremylt             operator: Ceed Composite Operator"""
54939b2de37Sjeremylt
55039b2de37Sjeremylt        return CompositeOperator(self)
55139b2de37Sjeremylt
55239b2de37Sjeremylt    # Destructor
55339b2de37Sjeremylt    def __del__(self):
55439b2de37Sjeremylt        # libCEED call
55539b2de37Sjeremylt        lib.CeedDestroy(self._pointer)
55639b2de37Sjeremylt
55739b2de37Sjeremylt# ------------------------------------------------------------------------------
558