xref: /libCEED/python/ceed.py (revision 7a7b0fa3029ed576dc3d3fb37afaf50f3689b395)
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
1939b2de37Sjeremyltimport io
200a0da059Sjeremyltimport tempfile
2139b2de37Sjeremyltfrom abc import ABC
2239b2de37Sjeremyltfrom .ceed_vector import Vector
2339b2de37Sjeremyltfrom .ceed_basis import BasisTensorH1, BasisTensorH1Lagrange, BasisH1
2469a53589Sjeremyltfrom .ceed_elemrestriction import ElemRestriction, StridedElemRestriction, BlockedElemRestriction, BlockedStridedElemRestriction
2539b2de37Sjeremyltfrom .ceed_qfunction import QFunction, QFunctionByName, IdentityQFunction
2639b2de37Sjeremyltfrom .ceed_operator import Operator, CompositeOperator
2739b2de37Sjeremyltfrom .ceed_constants import *
2839b2de37Sjeremylt
2939b2de37Sjeremylt# ------------------------------------------------------------------------------
30*7a7b0fa3SJed Brown
31*7a7b0fa3SJed Brown
3239b2de37Sjeremyltclass Ceed():
3339b2de37Sjeremylt    """Ceed: core components."""
3439b2de37Sjeremylt    # Attributes
3539b2de37Sjeremylt    _pointer = ffi.NULL
3639b2de37Sjeremylt
3739b2de37Sjeremylt    # Constructor
3839b2de37Sjeremylt    def __init__(self, resource="/cpu/self"):
3939b2de37Sjeremylt        # libCEED object
4039b2de37Sjeremylt        self._pointer = ffi.new("Ceed *")
4139b2de37Sjeremylt
4239b2de37Sjeremylt        # libCEED call
4339b2de37Sjeremylt        resourceAscii = ffi.new("char[]", resource.encode("ascii"))
4439b2de37Sjeremylt        lib.CeedInit(resourceAscii, self._pointer)
4539b2de37Sjeremylt
4639b2de37Sjeremylt    # Representation
4739b2de37Sjeremylt    def __repr__(self):
4839b2de37Sjeremylt        return "<Ceed instance at " + hex(id(self)) + ">"
4939b2de37Sjeremylt
500a0da059Sjeremylt    # String conversion for print() to stdout
510a0da059Sjeremylt    def __str__(self):
520a0da059Sjeremylt        """View a Ceed via print()."""
530a0da059Sjeremylt
540a0da059Sjeremylt        # libCEED call
550a0da059Sjeremylt        with tempfile.NamedTemporaryFile() as key_file:
560a0da059Sjeremylt            with open(key_file.name, 'r+') as stream_file:
570a0da059Sjeremylt                stream = ffi.cast("FILE *", stream_file)
580a0da059Sjeremylt
590a0da059Sjeremylt                lib.CeedView(self._pointer[0], stream)
600a0da059Sjeremylt
610a0da059Sjeremylt                stream_file.seek(0)
620a0da059Sjeremylt                out_string = stream_file.read()
630a0da059Sjeremylt
640a0da059Sjeremylt        return out_string
650a0da059Sjeremylt
6639b2de37Sjeremylt    # Get Resource
6739b2de37Sjeremylt    def get_resource(self):
6839b2de37Sjeremylt        """Get the full resource name for a Ceed context.
6939b2de37Sjeremylt
7039b2de37Sjeremylt           Returns:
7139b2de37Sjeremylt             resource: resource name"""
7239b2de37Sjeremylt
7339b2de37Sjeremylt        # libCEED call
7439b2de37Sjeremylt        resource = ffi.new("char **")
7539b2de37Sjeremylt        lib.CeedGetResource(self._pointer[0], resource)
7639b2de37Sjeremylt
7739b2de37Sjeremylt        return ffi.string(resource[0]).decode("UTF-8")
7839b2de37Sjeremylt
7939b2de37Sjeremylt    # Preferred MemType
8039b2de37Sjeremylt    def get_preferred_memtype(self):
8139b2de37Sjeremylt        """Return Ceed preferred memory type.
8239b2de37Sjeremylt
8339b2de37Sjeremylt           Returns:
8439b2de37Sjeremylt             memtype: Ceed preferred memory type"""
8539b2de37Sjeremylt
8639b2de37Sjeremylt        # libCEED call
8739b2de37Sjeremylt        memtype = ffi.new("CeedMemType *", MEM_HOST)
8839b2de37Sjeremylt        lib.CeedGetPreferredMemType(self._pointer[0], memtype)
8939b2de37Sjeremylt
9039b2de37Sjeremylt        return memtype[0]
9139b2de37Sjeremylt
9239b2de37Sjeremylt    # CeedVector
9339b2de37Sjeremylt    def Vector(self, size):
9439b2de37Sjeremylt        """Ceed Vector: storing and manipulating vectors.
9539b2de37Sjeremylt
9639b2de37Sjeremylt           Args:
9739b2de37Sjeremylt             size: length of vector
9839b2de37Sjeremylt
9939b2de37Sjeremylt           Returns:
10039b2de37Sjeremylt             vector: Ceed Vector"""
10139b2de37Sjeremylt
10239b2de37Sjeremylt        return Vector(self, size)
10339b2de37Sjeremylt
10439b2de37Sjeremylt    # CeedElemRestriction
10539b2de37Sjeremylt    def ElemRestriction(self, nelem, elemsize, nnodes, ncomp, indices,
106a8d32208Sjeremylt                        memtype=lib.CEED_MEM_HOST, cmode=lib.CEED_COPY_VALUES,
10761dbc9d2Sjeremylt                        imode=lib.CEED_NONINTERLACED):
10839b2de37Sjeremylt        """Ceed ElemRestriction: restriction from local vectors to elements.
10939b2de37Sjeremylt
11039b2de37Sjeremylt           Args:
11139b2de37Sjeremylt             nelem: number of elements described in the indices array
11239b2de37Sjeremylt             elemsize: size (number of nodes) per element
11339b2de37Sjeremylt             nnodes: the number of nodes in the local vector. The input Ceed Vector
11439b2de37Sjeremylt                       to which the restriction will be applied is of size
11539b2de37Sjeremylt                       (nnodes * ncomp). This size may include data
11639b2de37Sjeremylt                       used by other Ceed ElemRestriction objects describing
11739b2de37Sjeremylt                       different types of elements.
11839b2de37Sjeremylt             ncomp: number of field components per interpolation node (1 for scalar fields)
11939b2de37Sjeremylt             *indices: Numpy array of shape [nelem, elemsize]. Row i holds the
12039b2de37Sjeremylt                          ordered list of the indices (into the input Ceed Vector)
12139b2de37Sjeremylt                          for the unknowns corresponding to element i, where
12239b2de37Sjeremylt                          0 <= i < nelem. All indices must be in the range
12339b2de37Sjeremylt                          [0, nnodes - 1].
12439b2de37Sjeremylt             **memtype: memory type of the indices array, default CEED_MEM_HOST
12539b2de37Sjeremylt             **cmode: copy mode for the indices array, default CEED_COPY_VALUES
12661dbc9d2Sjeremylt             **imode: ordering of the ncomp components, i.e. it specifies
127a8d32208Sjeremylt                        the ordering of the components of the local vector used
12861dbc9d2Sjeremylt                        by this CeedElemRestriction. CEED_NONINTERLACED indicates
12961dbc9d2Sjeremylt                        the component is the outermost index and CEED_INTERLACED
130a8d32208Sjeremylt                        indicates the component is the innermost index in
13161dbc9d2Sjeremylt                        ordering of the local vector, default CEED_NONINTERLACED
13239b2de37Sjeremylt
13339b2de37Sjeremylt           Returns:
13439b2de37Sjeremylt             elemrestriction: Ceed ElemRestiction"""
13539b2de37Sjeremylt
13639b2de37Sjeremylt        return ElemRestriction(self, nelem, elemsize, nnodes, ncomp, indices,
13761dbc9d2Sjeremylt                               memtype=memtype, cmode=cmode, imode=imode)
13839b2de37Sjeremylt
13969a53589Sjeremylt    def StridedElemRestriction(self, nelem, elemsize, nnodes, ncomp, strides):
14069a53589Sjeremylt        """Ceed Identity ElemRestriction: strided restriction from local vectors to elements.
14139b2de37Sjeremylt
14239b2de37Sjeremylt           Args:
14339b2de37Sjeremylt             nelem: number of elements described in the indices array
14439b2de37Sjeremylt             elemsize: size (number of nodes) per element
14539b2de37Sjeremylt             nnodes: the number of nodes in the local vector. The input Ceed Vector
14639b2de37Sjeremylt                       to which the restriction will be applied is of size
14739b2de37Sjeremylt                       (nnodes * ncomp). This size may include data
14839b2de37Sjeremylt                       used by other Ceed ElemRestriction objects describing
14939b2de37Sjeremylt                       different types of elements.
150a8d32208Sjeremylt             ncomp: number of field components per interpolation node
151a8d32208Sjeremylt                      (1 for scalar fields)
15269a53589Sjeremylt             *strides: Array for strides between [nodes, components, elements].
15369a53589Sjeremylt                         The data for node i, component j, element k in the
15469a53589Sjeremylt                         L-vector is given by
15569a53589Sjeremylt                           i*strides[0] + j*strides[1] + k*strides[2]
15639b2de37Sjeremylt
15739b2de37Sjeremylt           Returns:
15869a53589Sjeremylt             elemrestriction: Ceed Strided ElemRestiction"""
15939b2de37Sjeremylt
160*7a7b0fa3SJed Brown        return StridedElemRestriction(
161*7a7b0fa3SJed Brown            self, nelem, elemsize, nnodes, ncomp, strides)
16239b2de37Sjeremylt
16339b2de37Sjeremylt    def BlockedElemRestriction(self, nelem, elemsize, blksize, nnodes, ncomp,
16439b2de37Sjeremylt                               indices, memtype=lib.CEED_MEM_HOST,
165a8d32208Sjeremylt                               cmode=lib.CEED_COPY_VALUES,
16661dbc9d2Sjeremylt                               imode=lib.CEED_NONINTERLACED):
16739b2de37Sjeremylt        """Ceed Blocked ElemRestriction: blocked restriction from local vectors to elements.
16839b2de37Sjeremylt
16939b2de37Sjeremylt           Args:
17039b2de37Sjeremylt             nelem: number of elements described in the indices array
17139b2de37Sjeremylt             elemsize: size (number of nodes) per element
17239b2de37Sjeremylt             blksize: number of elements in a block
17339b2de37Sjeremylt             nnodes: the number of nodes in the local vector. The input Ceed Vector
17439b2de37Sjeremylt                       to which the restriction will be applied is of size
17539b2de37Sjeremylt                       (nnodes * ncomp). This size may include data
17639b2de37Sjeremylt                       used by other Ceed ElemRestriction objects describing
17739b2de37Sjeremylt                       different types of elements.
17839b2de37Sjeremylt             ncomp: number of field components per interpolation node (1 for scalar fields)
17939b2de37Sjeremylt             *indices: Numpy array of shape [nelem, elemsize]. Row i holds the
18039b2de37Sjeremylt                          ordered list of the indices (into the input Ceed Vector)
18139b2de37Sjeremylt                          for the unknowns corresponding to element i, where
18239b2de37Sjeremylt                          0 <= i < nelem. All indices must be in the range
18339b2de37Sjeremylt                          [0, nnodes - 1]. The backend will permute and pad this
18439b2de37Sjeremylt                          array to the desired ordering for the blocksize, which is
18539b2de37Sjeremylt                          typically given by the backend. The default reordering is
18639b2de37Sjeremylt                          to interlace elements.
18739b2de37Sjeremylt             **memtype: memory type of the indices array, default CEED_MEM_HOST
18839b2de37Sjeremylt             **cmode: copy mode for the indices array, default CEED_COPY_VALUES
18961dbc9d2Sjeremylt             **imode: ordering of the ncomp components, i.e. it specifies
190a8d32208Sjeremylt                        the ordering of the components of the local vector used
19161dbc9d2Sjeremylt                        by this CeedElemRestriction. CEED_NONINTERLACED indicates
19261dbc9d2Sjeremylt                        the component is the outermost index and CEED_INTERLACED
193a8d32208Sjeremylt                        indicates the component is the innermost index in
19461dbc9d2Sjeremylt                        ordering of the local vector, default CEED_NONINTERLACED
19539b2de37Sjeremylt
19639b2de37Sjeremylt           Returns:
19739b2de37Sjeremylt             elemrestriction: Ceed Blocked ElemRestiction"""
19839b2de37Sjeremylt
19939b2de37Sjeremylt        return BlockedElemRestriction(self, nelem, elemsize, blksize, nnodes,
20039b2de37Sjeremylt                                      ncomp, indices, memtype=memtype,
20161dbc9d2Sjeremylt                                      cmode=cmode, imode=imode)
20239b2de37Sjeremylt
20369a53589Sjeremylt    def BlockedStridedElemRestriction(self, nelem, elemsize, blksize, nnodes,
20469a53589Sjeremylt                                      ncomp, strides):
20569a53589Sjeremylt        """Ceed Blocked Strided ElemRestriction: blocked and strided restriction from local vectors to elements.
20669a53589Sjeremylt
20769a53589Sjeremylt           Args:
20869a53589Sjeremylt             nelem: number of elements described in the indices array
20969a53589Sjeremylt             elemsize: size (number of nodes) per element
21069a53589Sjeremylt             blksize: number of elements in a block
21169a53589Sjeremylt             nnodes: the number of nodes in the local vector. The input Ceed Vector
21269a53589Sjeremylt                       to which the restriction will be applied is of size
21369a53589Sjeremylt                       (nnodes * ncomp). This size may include data
21469a53589Sjeremylt                       used by other Ceed ElemRestriction objects describing
21569a53589Sjeremylt                       different types of elements.
21669a53589Sjeremylt             ncomp: number of field components per interpolation node
21769a53589Sjeremylt                      (1 for scalar fields)
21869a53589Sjeremylt             *strides: Array for strides between [nodes, components, elements].
21969a53589Sjeremylt                         The data for node i, component j, element k in the
22069a53589Sjeremylt                         L-vector is given by
22169a53589Sjeremylt                           i*strides[0] + j*strides[1] + k*strides[2]
22269a53589Sjeremylt
22369a53589Sjeremylt           Returns:
22469a53589Sjeremylt             elemrestriction: Ceed Strided ElemRestiction"""
22569a53589Sjeremylt
22669a53589Sjeremylt        return BlockedStridedElemRestriction(self, nelem, elemsize, blksize,
22769a53589Sjeremylt                                             nnodes, ncomp, strides)
22869a53589Sjeremylt
22939b2de37Sjeremylt    # CeedBasis
23039b2de37Sjeremylt    def BasisTensorH1(self, dim, ncomp, P1d, Q1d, interp1d, grad1d,
23139b2de37Sjeremylt                      qref1d, qweight1d):
23239b2de37Sjeremylt        """Ceed Tensor H1 Basis: finite element tensor-product basis objects for
23339b2de37Sjeremylt             H^1 discretizations.
23439b2de37Sjeremylt
23539b2de37Sjeremylt           Args:
23639b2de37Sjeremylt             dim: topological dimension
23739b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
23839b2de37Sjeremylt             P1d: number of nodes in one dimension
23939b2de37Sjeremylt             Q1d: number of quadrature points in one dimension
24039b2de37Sjeremylt             *interp1d: Numpy array holding the row-major (Q1d * P1d) matrix expressing the
24139b2de37Sjeremylt                         values of nodal basis functions at quadrature points
24239b2de37Sjeremylt             *grad1d: Numpy array holding the row-major (Q1d * P1d) matrix expressing the
24339b2de37Sjeremylt                       derivatives of nodal basis functions at quadrature points
24439b2de37Sjeremylt             *qref1d: Numpy array of length Q1d holding the locations of quadrature points
24539b2de37Sjeremylt                       on the 1D reference element [-1, 1]
24639b2de37Sjeremylt             *qweight1d: Numpy array of length Q1d holding the quadrature weights on the
24739b2de37Sjeremylt                          reference element
24839b2de37Sjeremylt
24939b2de37Sjeremylt           Returns:
25039b2de37Sjeremylt             basis: Ceed Basis"""
25139b2de37Sjeremylt
25239b2de37Sjeremylt        return BasisTensorH1(self, dim, ncomp, P1d, Q1d, interp1d, grad1d,
25339b2de37Sjeremylt                             qref1d, qweight1d)
25439b2de37Sjeremylt
25539b2de37Sjeremylt    def BasisTensorH1Lagrange(self, dim, ncomp, P, Q, qmode):
25639b2de37Sjeremylt        """Ceed Tensor H1 Lagrange Basis: finite element tensor-product Lagrange basis
25739b2de37Sjeremylt             objects for H^1 discretizations.
25839b2de37Sjeremylt
25939b2de37Sjeremylt           Args:
26039b2de37Sjeremylt             dim: topological dimension
26139b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
26239b2de37Sjeremylt             P: number of Gauss-Lobatto nodes in one dimension.  The
26339b2de37Sjeremylt                  polynomial degree of the resulting Q_k element is k=P-1.
26439b2de37Sjeremylt             Q: number of quadrature points in one dimension
26539b2de37Sjeremylt             qmode: distribution of the Q quadrature points (affects order of
26639b2de37Sjeremylt                      accuracy for the quadrature)
26739b2de37Sjeremylt
26839b2de37Sjeremylt           Returns:
26939b2de37Sjeremylt             basis: Ceed Basis"""
27039b2de37Sjeremylt
27139b2de37Sjeremylt        return BasisTensorH1Lagrange(self, dim, ncomp, P, Q, qmode)
27239b2de37Sjeremylt
27339b2de37Sjeremylt    def BasisH1(self, topo, ncomp, nnodes, nqpts, interp, grad, qref, qweight):
27439b2de37Sjeremylt        """Ceed H1 Basis: finite element non tensor-product basis for H^1 discretizations.
27539b2de37Sjeremylt
27639b2de37Sjeremylt           Args:
27739b2de37Sjeremylt             topo: topology of the element, e.g. hypercube, simplex, etc
27839b2de37Sjeremylt             ncomp: number of field components (1 for scalar fields)
27939b2de37Sjeremylt             nnodes: total number of nodes
28039b2de37Sjeremylt             nqpts: total number of quadrature points
28139b2de37Sjeremylt             *interp: Numpy array holding the row-major (nqpts * nnodes) matrix expressing
28239b2de37Sjeremylt                       the values of nodal basis functions at quadrature points
28339b2de37Sjeremylt             *grad: Numpy array holding the row-major (nqpts * dim * nnodes) matrix
28439b2de37Sjeremylt                     expressing the derivatives of nodal basis functions at
28539b2de37Sjeremylt                     quadrature points
28639b2de37Sjeremylt             *qref: Numpy array of length (nqpts * dim) holding the locations of quadrature
28739b2de37Sjeremylt                     points on the reference element [-1, 1]
28839b2de37Sjeremylt             *qweight: Numpy array of length nnodes holding the quadrature weights on the
28939b2de37Sjeremylt                        reference element
29039b2de37Sjeremylt
29139b2de37Sjeremylt           Returns:
29239b2de37Sjeremylt             basis: Ceed Basis"""
29339b2de37Sjeremylt
294*7a7b0fa3SJed Brown        return BasisH1(self, topo, ncomp, nnodes, nqpts,
295*7a7b0fa3SJed Brown                       interp, grad, qref, qweight)
29639b2de37Sjeremylt
29739b2de37Sjeremylt    # CeedQFunction
29839b2de37Sjeremylt    def QFunction(self, vlength, f, source):
29939b2de37Sjeremylt        """Ceed QFunction: point-wise operation at quadrature points for evaluating
30039b2de37Sjeremylt             volumetric terms.
30139b2de37Sjeremylt
30239b2de37Sjeremylt           Args:
30339b2de37Sjeremylt             vlength: vector length. Caller must ensure that number of quadrature
30439b2de37Sjeremylt                        points is a multiple of vlength
30539b2de37Sjeremylt             f: ctypes function pointer to evaluate action at quadrature points
30639b2de37Sjeremylt             source: absolute path to source of QFunction,
30739b2de37Sjeremylt               "\\abs_path\\file.h:function_name
30839b2de37Sjeremylt
30939b2de37Sjeremylt           Returns:
31039b2de37Sjeremylt             qfunction: Ceed QFunction"""
31139b2de37Sjeremylt
31239b2de37Sjeremylt        return QFunction(self, vlength, f, source)
31339b2de37Sjeremylt
31439b2de37Sjeremylt    def QFunctionByName(self, name):
31539b2de37Sjeremylt        """Ceed QFunction By Name: point-wise operation at quadrature points
31639b2de37Sjeremylt             from a given gallery, for evaluating volumetric terms.
31739b2de37Sjeremylt
31839b2de37Sjeremylt           Args:
31939b2de37Sjeremylt             name: name of QFunction to use from gallery
32039b2de37Sjeremylt
32139b2de37Sjeremylt           Returns:
32239b2de37Sjeremylt             qfunction: Ceed QFunction By Name"""
32339b2de37Sjeremylt
32439b2de37Sjeremylt        return QFunctionByName(self, name)
32539b2de37Sjeremylt
32639b2de37Sjeremylt    def IdentityQFunction(self, size, inmode, outmode):
32739b2de37Sjeremylt        """Ceed Idenity QFunction: identity qfunction operation.
32839b2de37Sjeremylt
32939b2de37Sjeremylt           Args:
33039b2de37Sjeremylt             size: size of the qfunction fields
33139b2de37Sjeremylt             **inmode: CeedEvalMode for input to Ceed QFunction
33239b2de37Sjeremylt             **outmode: CeedEvalMode for output to Ceed QFunction
33339b2de37Sjeremylt
33439b2de37Sjeremylt           Returns:
33539b2de37Sjeremylt             qfunction: Ceed Identity QFunction"""
33639b2de37Sjeremylt
33739b2de37Sjeremylt        return IdentityQFunction(self, size, inmode, outmode)
33839b2de37Sjeremylt
33939b2de37Sjeremylt    # CeedOperator
34039b2de37Sjeremylt    def Operator(self, qf, dqf=None, qdfT=None):
34139b2de37Sjeremylt        """Ceed Operator: composed FE-type operations on vectors.
34239b2de37Sjeremylt
34339b2de37Sjeremylt           Args:
34439b2de37Sjeremylt             qf: QFunction defining the action of the operator at quadrature points
34539b2de37Sjeremylt             **dqf: QFunction defining the action of the Jacobian, default None
34639b2de37Sjeremylt             **dqfT: QFunction defining the action of the transpose of the Jacobian,
34739b2de37Sjeremylt                       default None
34839b2de37Sjeremylt
34939b2de37Sjeremylt           Returns:
35039b2de37Sjeremylt             operator: Ceed Operator"""
35139b2de37Sjeremylt
35239b2de37Sjeremylt        return Operator(self, qf, dqf, qdfT)
35339b2de37Sjeremylt
35439b2de37Sjeremylt    def CompositeOperator(self):
35539b2de37Sjeremylt        """Composite Ceed Operator: composition of multiple CeedOperators.
35639b2de37Sjeremylt
35739b2de37Sjeremylt           Returns:
35839b2de37Sjeremylt             operator: Ceed Composite Operator"""
35939b2de37Sjeremylt
36039b2de37Sjeremylt        return CompositeOperator(self)
36139b2de37Sjeremylt
36239b2de37Sjeremylt    # Destructor
36339b2de37Sjeremylt    def __del__(self):
36439b2de37Sjeremylt        # libCEED call
36539b2de37Sjeremylt        lib.CeedDestroy(self._pointer)
36639b2de37Sjeremylt
36739b2de37Sjeremylt# ------------------------------------------------------------------------------
368