xref: /libCEED/python/ceed_elemrestriction.py (revision 709403c1d8a3197f71934fa05519eedc9835a633)
13d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors
23d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3c8e769f6Sjeremylt#
43d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause
5c8e769f6Sjeremylt#
63d8e8822SJeremy L Thompson# This file is part of CEED:  http://github.com/ceed
7c8e769f6Sjeremylt
8c8e769f6Sjeremyltfrom _ceed_cffi import ffi, lib
9c8e769f6Sjeremyltimport tempfile
10c8e769f6Sjeremyltimport numpy as np
11c8e769f6Sjeremyltfrom abc import ABC
12187168c7SJeremy L Thompsonfrom .ceed_constants import REQUEST_IMMEDIATE, REQUEST_ORDERED, MEM_HOST, USE_POINTER, COPY_VALUES, TRANSPOSE, NOTRANSPOSE
13c8e769f6Sjeremyltfrom .ceed_vector import _VectorWrap
14c8e769f6Sjeremylt
15c8e769f6Sjeremylt# ------------------------------------------------------------------------------
167a7b0fa3SJed Brown
177a7b0fa3SJed Brown
18c8e769f6Sjeremyltclass _ElemRestrictionBase(ABC):
19c8e769f6Sjeremylt    """Ceed ElemRestriction: restriction from local vectors to elements."""
20c8e769f6Sjeremylt
21c8e769f6Sjeremylt    # Destructor
22c8e769f6Sjeremylt    def __del__(self):
23c8e769f6Sjeremylt        # libCEED call
24477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionDestroy(self._pointer)
25477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
26c8e769f6Sjeremylt
27c8e769f6Sjeremylt    # Representation
28c8e769f6Sjeremylt    def __repr__(self):
29c8e769f6Sjeremylt        return "<CeedElemRestriction instance at " + hex(id(self)) + ">"
30c8e769f6Sjeremylt
31c8e769f6Sjeremylt    # String conversion for print() to stdout
32c8e769f6Sjeremylt    def __str__(self):
33c8e769f6Sjeremylt        """View an ElemRestriction via print()."""
34c8e769f6Sjeremylt
35c8e769f6Sjeremylt        # libCEED call
36c8e769f6Sjeremylt        with tempfile.NamedTemporaryFile() as key_file:
37c8e769f6Sjeremylt            with open(key_file.name, 'r+') as stream_file:
38c8e769f6Sjeremylt                stream = ffi.cast("FILE *", stream_file)
39c8e769f6Sjeremylt
40477729cfSJeremy L Thompson                err_code = lib.CeedElemRestrictionView(self._pointer[0], stream)
41477729cfSJeremy L Thompson                self._ceed._check_error(err_code)
42c8e769f6Sjeremylt
43c8e769f6Sjeremylt                stream_file.seek(0)
44c8e769f6Sjeremylt                out_string = stream_file.read()
45c8e769f6Sjeremylt
46c8e769f6Sjeremylt        return out_string
47c8e769f6Sjeremylt
48c8e769f6Sjeremylt    # Apply CeedElemRestriction
49a8d32208Sjeremylt    def apply(self, u, v, tmode=NOTRANSPOSE, request=REQUEST_IMMEDIATE):
50c8e769f6Sjeremylt        """Restrict a local vector to an element vector or apply its transpose.
51c8e769f6Sjeremylt
52c8e769f6Sjeremylt           Args:
53c8e769f6Sjeremylt             u: input vector
54c8e769f6Sjeremylt             v: output vector
55c8e769f6Sjeremylt             **tmode: apply restriction or transpose, default CEED_NOTRANSPOSE
56c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
57c8e769f6Sjeremylt
58c8e769f6Sjeremylt        # libCEED call
59477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionApply(self._pointer[0], tmode, u._pointer[0],
60a8d32208Sjeremylt                                                v._pointer[0], request)
61477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
62c8e769f6Sjeremylt
63c8e769f6Sjeremylt    # Transpose an ElemRestriction
64c8e769f6Sjeremylt    @property
65c8e769f6Sjeremylt    def T(self):
66c8e769f6Sjeremylt        """Transpose an ElemRestriction."""
67c8e769f6Sjeremylt
68c8e769f6Sjeremylt        return TransposeElemRestriction(self)
69c8e769f6Sjeremylt
70c8e769f6Sjeremylt    # Transpose an ElemRestriction
71c8e769f6Sjeremylt    @property
72c8e769f6Sjeremylt    def transpose(self):
73c8e769f6Sjeremylt        """Transpose an ElemRestriction."""
74c8e769f6Sjeremylt
75c8e769f6Sjeremylt        return TransposeElemRestriction(self)
76c8e769f6Sjeremylt
77c8e769f6Sjeremylt    # Create restriction vectors
78c8e769f6Sjeremylt    def create_vector(self, createLvec=True, createEvec=True):
79c8e769f6Sjeremylt        """Create Vectors associated with an ElemRestriction.
80c8e769f6Sjeremylt
81c8e769f6Sjeremylt           Args:
82c8e769f6Sjeremylt             **createLvec: flag to create local vector, default True
83c8e769f6Sjeremylt             **createEvec: flag to create element vector, default True
84c8e769f6Sjeremylt
85c8e769f6Sjeremylt           Returns:
86c8e769f6Sjeremylt             [lvec, evec]: local vector and element vector, or None if flag set to false"""
87c8e769f6Sjeremylt
88c8e769f6Sjeremylt        # Vector pointers
89c8e769f6Sjeremylt        lvecPointer = ffi.new("CeedVector *") if createLvec else ffi.NULL
90c8e769f6Sjeremylt        evecPointer = ffi.new("CeedVector *") if createEvec else ffi.NULL
91c8e769f6Sjeremylt
92c8e769f6Sjeremylt        # libCEED call
93477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateVector(self._pointer[0], lvecPointer,
94c8e769f6Sjeremylt                                                       evecPointer)
95477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
96c8e769f6Sjeremylt
97c8e769f6Sjeremylt        # Return vectors
987a7b0fa3SJed Brown        lvec = _VectorWrap(
99477729cfSJeremy L Thompson            self._ceed, lvecPointer) if createLvec else None
1007a7b0fa3SJed Brown        evec = _VectorWrap(
101477729cfSJeremy L Thompson            self._ceed, evecPointer) if createEvec else None
102c8e769f6Sjeremylt
103c8e769f6Sjeremylt        # Return
104c8e769f6Sjeremylt        return [lvec, evec]
105c8e769f6Sjeremylt
106c8e769f6Sjeremylt    # Get ElemRestriction multiplicity
107a8d32208Sjeremylt    def get_multiplicity(self):
108c8e769f6Sjeremylt        """Get the multiplicity of nodes in an ElemRestriction.
109c8e769f6Sjeremylt
110c8e769f6Sjeremylt           Returns:
111c8e769f6Sjeremylt             mult: local vector containing multiplicity of nodes in ElemRestriction"""
112c8e769f6Sjeremylt
113c8e769f6Sjeremylt        # Create mult vector
114c8e769f6Sjeremylt        [mult, evec] = self.create_vector(createEvec=False)
115c8e769f6Sjeremylt        mult.set_value(0)
116c8e769f6Sjeremylt
117c8e769f6Sjeremylt        # libCEED call
118477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionGetMultiplicity(
1197a7b0fa3SJed Brown            self._pointer[0], mult._pointer[0])
120477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
121c8e769f6Sjeremylt
122c8e769f6Sjeremylt        # Return
123c8e769f6Sjeremylt        return mult
124c8e769f6Sjeremylt
125c3a5a609SJeremy L Thompson    # Get ElemRestrition Layout
126c3a5a609SJeremy L Thompson    def get_layout(self):
127c3a5a609SJeremy L Thompson        """Get the element vector layout of an ElemRestriction.
128c3a5a609SJeremy L Thompson
129c3a5a609SJeremy L Thompson           Returns:
130c3a5a609SJeremy L Thompson             layout: Vector containing layout array, stored as [nodes, components, elements].
131c3a5a609SJeremy L Thompson                     The data for node i, component j, element k in the element
132c3a5a609SJeremy L Thompson                     vector is given by i*layout[0] + j*layout[1] + k*layout[2]."""
133c3a5a609SJeremy L Thompson
134c3a5a609SJeremy L Thompson        # Create output array
135c3a5a609SJeremy L Thompson        layout = np.zeros(3, dtype="int32")
136c3a5a609SJeremy L Thompson        array_pointer = ffi.cast(
137dd8ab4d9SJed Brown            "CeedInt (*)[3]",
138c3a5a609SJeremy L Thompson            layout.__array_interface__['data'][0])
139c3a5a609SJeremy L Thompson
140c3a5a609SJeremy L Thompson        # libCEED call
141c3a5a609SJeremy L Thompson        err_code = lib.CeedElemRestrictionGetELayout(
142c3a5a609SJeremy L Thompson            self._pointer[0], array_pointer)
143c3a5a609SJeremy L Thompson        self._ceed._check_error(err_code)
144c3a5a609SJeremy L Thompson
145c3a5a609SJeremy L Thompson        # Return
146c3a5a609SJeremy L Thompson        return layout
147c3a5a609SJeremy L Thompson
148c8e769f6Sjeremylt# ------------------------------------------------------------------------------
1497a7b0fa3SJed Brown
1507a7b0fa3SJed Brown
151c8e769f6Sjeremyltclass ElemRestriction(_ElemRestrictionBase):
152c8e769f6Sjeremylt    """Ceed ElemRestriction: restriction from local vectors to elements."""
153c8e769f6Sjeremylt
154c8e769f6Sjeremylt    # Constructor
155d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
156d979a051Sjeremylt                 memtype=MEM_HOST, cmode=COPY_VALUES):
157c8e769f6Sjeremylt        # CeedVector object
158c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
159c8e769f6Sjeremylt
160c8e769f6Sjeremylt        # Reference to Ceed
161c8e769f6Sjeremylt        self._ceed = ceed
162c8e769f6Sjeremylt
163187168c7SJeremy L Thompson        # Store array reference if needed
164187168c7SJeremy L Thompson        if cmode == USE_POINTER:
165187168c7SJeremy L Thompson            self._array_reference = offsets
166187168c7SJeremy L Thompson        else:
167187168c7SJeremy L Thompson            self._array_reference = None
168187168c7SJeremy L Thompson
169c8e769f6Sjeremylt        # Setup the numpy array for the libCEED call
170d979a051Sjeremylt        offsets_pointer = ffi.new("const CeedInt *")
171d979a051Sjeremylt        offsets_pointer = ffi.cast("const CeedInt *",
172d979a051Sjeremylt                                   offsets.__array_interface__['data'][0])
173c8e769f6Sjeremylt
174c8e769f6Sjeremylt        # libCEED call
175477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreate(self._ceed._pointer[0], nelem,
176477729cfSJeremy L Thompson                                                 elemsize, ncomp, compstride,
177477729cfSJeremy L Thompson                                                 lsize, memtype, cmode,
178d979a051Sjeremylt                                                 offsets_pointer, self._pointer)
179477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
180c8e769f6Sjeremylt
181c8e769f6Sjeremylt# ------------------------------------------------------------------------------
1827a7b0fa3SJed Brown
1837a7b0fa3SJed Brown
184*709403c1SSebastian Grimbergclass OrientedElemRestriction(_ElemRestrictionBase):
185*709403c1SSebastian Grimberg    """Ceed Oriented ElemRestriction: oriented restriction from local vectors to elements."""
186*709403c1SSebastian Grimberg
187*709403c1SSebastian Grimberg    # Constructor
188*709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
189*709403c1SSebastian Grimberg                 orients, memtype=MEM_HOST, cmode=COPY_VALUES):
190*709403c1SSebastian Grimberg        # CeedVector object
191*709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
192*709403c1SSebastian Grimberg
193*709403c1SSebastian Grimberg        # Reference to Ceed
194*709403c1SSebastian Grimberg        self._ceed = ceed
195*709403c1SSebastian Grimberg
196*709403c1SSebastian Grimberg        # Store array reference if needed
197*709403c1SSebastian Grimberg        if cmode == USE_POINTER:
198*709403c1SSebastian Grimberg            self._array_reference = offsets
199*709403c1SSebastian Grimberg            self._array_reference_aux = orients
200*709403c1SSebastian Grimberg        else:
201*709403c1SSebastian Grimberg            self._array_reference = None
202*709403c1SSebastian Grimberg            self._array_reference_aux = None
203*709403c1SSebastian Grimberg
204*709403c1SSebastian Grimberg        # Setup the numpy arrays for the libCEED call
205*709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
206*709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
207*709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
208*709403c1SSebastian Grimberg        orients_pointer = ffi.new("const bool *")
209*709403c1SSebastian Grimberg        orients_pointer = ffi.cast("const bool *",
210*709403c1SSebastian Grimberg                                   orients.__array_interface__['data'][0])
211*709403c1SSebastian Grimberg
212*709403c1SSebastian Grimberg        # libCEED call
213*709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateOriented(self._ceed._pointer[0], nelem,
214*709403c1SSebastian Grimberg                                                         elemsize, ncomp, compstride,
215*709403c1SSebastian Grimberg                                                         lsize, memtype, cmode,
216*709403c1SSebastian Grimberg                                                         offsets_pointer, orients_pointer,
217*709403c1SSebastian Grimberg                                                         self._pointer)
218*709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
219*709403c1SSebastian Grimberg
220*709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
221*709403c1SSebastian Grimberg
222*709403c1SSebastian Grimberg
223*709403c1SSebastian Grimbergclass CurlOrientedElemRestriction(_ElemRestrictionBase):
224*709403c1SSebastian Grimberg    """Ceed Curl Oriented ElemRestriction: curl-oriented restriction from local vectors to elements."""
225*709403c1SSebastian Grimberg
226*709403c1SSebastian Grimberg    # Constructor
227*709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
228*709403c1SSebastian Grimberg                 curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES):
229*709403c1SSebastian Grimberg        # CeedVector object
230*709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
231*709403c1SSebastian Grimberg
232*709403c1SSebastian Grimberg        # Reference to Ceed
233*709403c1SSebastian Grimberg        self._ceed = ceed
234*709403c1SSebastian Grimberg
235*709403c1SSebastian Grimberg        # Store array reference if needed
236*709403c1SSebastian Grimberg        if cmode == USE_POINTER:
237*709403c1SSebastian Grimberg            self._array_reference = offsets
238*709403c1SSebastian Grimberg            self._array_reference_aux = curl_orients
239*709403c1SSebastian Grimberg        else:
240*709403c1SSebastian Grimberg            self._array_reference = None
241*709403c1SSebastian Grimberg            self._array_reference_aux = None
242*709403c1SSebastian Grimberg
243*709403c1SSebastian Grimberg        # Setup the numpy arrays for the libCEED call
244*709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
245*709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
246*709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
247*709403c1SSebastian Grimberg        curl_orients_pointer = ffi.new("const CeedInt8 *")
248*709403c1SSebastian Grimberg        curl_orients_pointer = ffi.cast("const CeedInt8 *",
249*709403c1SSebastian Grimberg                                        curl_orients.__array_interface__['data'][0])
250*709403c1SSebastian Grimberg
251*709403c1SSebastian Grimberg        # libCEED call
252*709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateCurlOriented(self._ceed._pointer[0], nelem,
253*709403c1SSebastian Grimberg                                                             elemsize, ncomp, compstride,
254*709403c1SSebastian Grimberg                                                             lsize, memtype, cmode,
255*709403c1SSebastian Grimberg                                                             offsets_pointer,
256*709403c1SSebastian Grimberg                                                             curl_orients_pointer,
257*709403c1SSebastian Grimberg                                                             self._pointer)
258*709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
259*709403c1SSebastian Grimberg
260*709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
261*709403c1SSebastian Grimberg
262*709403c1SSebastian Grimberg
26369a53589Sjeremyltclass StridedElemRestriction(_ElemRestrictionBase):
26469a53589Sjeremylt    """Ceed Strided ElemRestriction: strided restriction from local vectors to elements."""
265c8e769f6Sjeremylt
266c8e769f6Sjeremylt    # Constructor
267d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, ncomp, lsize, strides):
268c8e769f6Sjeremylt        # CeedVector object
269c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
270c8e769f6Sjeremylt
271c8e769f6Sjeremylt        # Reference to Ceed
272c8e769f6Sjeremylt        self._ceed = ceed
273c8e769f6Sjeremylt
27469a53589Sjeremylt        # Setup the numpy array for the libCEED call
27569a53589Sjeremylt        strides_pointer = ffi.new("const CeedInt *")
27669a53589Sjeremylt        strides_pointer = ffi.cast("const CeedInt *",
27769a53589Sjeremylt                                   strides.__array_interface__['data'][0])
27869a53589Sjeremylt
279c8e769f6Sjeremylt        # libCEED call
280477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateStrided(self._ceed._pointer[0],
281477729cfSJeremy L Thompson                                                        nelem, elemsize, ncomp,
282477729cfSJeremy L Thompson                                                        lsize, strides_pointer,
283477729cfSJeremy L Thompson                                                        self._pointer)
284477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
285c8e769f6Sjeremylt
286c8e769f6Sjeremylt# ------------------------------------------------------------------------------
2877a7b0fa3SJed Brown
2887a7b0fa3SJed Brown
289c8e769f6Sjeremyltclass BlockedElemRestriction(_ElemRestrictionBase):
290c8e769f6Sjeremylt    """Ceed Blocked ElemRestriction: blocked restriction from local vectors to elements."""
291c8e769f6Sjeremylt
292c8e769f6Sjeremylt    # Constructor
293d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
294d979a051Sjeremylt                 offsets, memtype=MEM_HOST, cmode=COPY_VALUES):
295c8e769f6Sjeremylt        # CeedVector object
296c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
297c8e769f6Sjeremylt
298c8e769f6Sjeremylt        # Reference to Ceed
299c8e769f6Sjeremylt        self._ceed = ceed
300c8e769f6Sjeremylt
301c8e769f6Sjeremylt        # Setup the numpy array for the libCEED call
302d979a051Sjeremylt        offsets_pointer = ffi.new("const CeedInt *")
303d979a051Sjeremylt        offsets_pointer = ffi.cast("const CeedInt *",
304d979a051Sjeremylt                                   offsets.__array_interface__['data'][0])
305c8e769f6Sjeremylt
306c8e769f6Sjeremylt        # libCEED call
307477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateBlocked(self._ceed._pointer[0], nelem,
308d979a051Sjeremylt                                                        elemsize, blksize, ncomp,
309d979a051Sjeremylt                                                        compstride, lsize, memtype, cmode,
310d979a051Sjeremylt                                                        offsets_pointer, self._pointer)
311477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
312c8e769f6Sjeremylt
313c8e769f6Sjeremylt    # Transpose a Blocked ElemRestriction
314c8e769f6Sjeremylt    @property
315c8e769f6Sjeremylt    def T(self):
316c8e769f6Sjeremylt        """Transpose a BlockedElemRestriction."""
317c8e769f6Sjeremylt
318c8e769f6Sjeremylt        return TransposeBlockedElemRestriction(self)
319c8e769f6Sjeremylt
320c8e769f6Sjeremylt    # Transpose a Blocked ElemRestriction
321c8e769f6Sjeremylt    @property
322c8e769f6Sjeremylt    def transpose(self):
323c8e769f6Sjeremylt        """Transpose a BlockedElemRestriction."""
324c8e769f6Sjeremylt
325c8e769f6Sjeremylt        return TransposeBlockedElemRestriction(self)
326c8e769f6Sjeremylt
327c8e769f6Sjeremylt    # Apply CeedElemRestriction to single block
328a8d32208Sjeremylt    def apply_block(self, block, u, v, tmode=NOTRANSPOSE,
329c8e769f6Sjeremylt                    request=REQUEST_IMMEDIATE):
330c8e769f6Sjeremylt        """Restrict a local vector to a block of an element vector or apply its transpose.
331c8e769f6Sjeremylt
332c8e769f6Sjeremylt           Args:
333c8e769f6Sjeremylt             block: block number to restrict to/from, i.e. block=0 will handle
334c8e769f6Sjeremylt                      elements [0 : blksize] and block=3 will handle elements
335c8e769f6Sjeremylt                      [3*blksize : 4*blksize]
336c8e769f6Sjeremylt             u: input vector
337c8e769f6Sjeremylt             v: output vector
338c8e769f6Sjeremylt             **tmode: apply restriction or transpose, default CEED_NOTRANSPOSE
339c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
340c8e769f6Sjeremylt
341c8e769f6Sjeremylt        # libCEED call
342477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionApplyBlock(self._pointer[0], block, tmode,
343477729cfSJeremy L Thompson                                                     u._pointer[0], v._pointer[0],
344477729cfSJeremy L Thompson                                                     request)
345477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
346c8e769f6Sjeremylt
347c8e769f6Sjeremylt# ------------------------------------------------------------------------------
3487a7b0fa3SJed Brown
3497a7b0fa3SJed Brown
350*709403c1SSebastian Grimbergclass BlockedOrientedElemRestriction(BlockedElemRestriction):
351*709403c1SSebastian Grimberg    """Ceed Blocked Oriented ElemRestriction: blocked oriented restriction from local vectors to elements."""
352*709403c1SSebastian Grimberg
353*709403c1SSebastian Grimberg    # Constructor
354*709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
355*709403c1SSebastian Grimberg                 offsets, orients, memtype=MEM_HOST, cmode=COPY_VALUES):
356*709403c1SSebastian Grimberg        # CeedVector object
357*709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
358*709403c1SSebastian Grimberg
359*709403c1SSebastian Grimberg        # Reference to Ceed
360*709403c1SSebastian Grimberg        self._ceed = ceed
361*709403c1SSebastian Grimberg
362*709403c1SSebastian Grimberg        # Setup the numpy array for the libCEED call
363*709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
364*709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
365*709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
366*709403c1SSebastian Grimberg        orients_pointer = ffi.new("const bool *")
367*709403c1SSebastian Grimberg        orients_pointer = ffi.cast("const bool *",
368*709403c1SSebastian Grimberg                                   orients.__array_interface__['data'][0])
369*709403c1SSebastian Grimberg
370*709403c1SSebastian Grimberg        # libCEED call
371*709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateBlockedOriented(self._ceed._pointer[0], nelem,
372*709403c1SSebastian Grimberg                                                                elemsize, blksize, ncomp,
373*709403c1SSebastian Grimberg                                                                compstride, lsize, memtype, cmode,
374*709403c1SSebastian Grimberg                                                                offsets_pointer, orients_pointer,
375*709403c1SSebastian Grimberg                                                                self._pointer)
376*709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
377*709403c1SSebastian Grimberg
378*709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
379*709403c1SSebastian Grimberg
380*709403c1SSebastian Grimberg
381*709403c1SSebastian Grimbergclass BlockedCurlOrientedElemRestriction(BlockedElemRestriction):
382*709403c1SSebastian Grimberg    """Ceed Blocked Curl Oriented ElemRestriction: blocked curl-oriented restriction from local vectors to elements."""
383*709403c1SSebastian Grimberg
384*709403c1SSebastian Grimberg    # Constructor
385*709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
386*709403c1SSebastian Grimberg                 offsets, curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES):
387*709403c1SSebastian Grimberg        # CeedVector object
388*709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
389*709403c1SSebastian Grimberg
390*709403c1SSebastian Grimberg        # Reference to Ceed
391*709403c1SSebastian Grimberg        self._ceed = ceed
392*709403c1SSebastian Grimberg
393*709403c1SSebastian Grimberg        # Setup the numpy array for the libCEED call
394*709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
395*709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
396*709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
397*709403c1SSebastian Grimberg        curl_orients_pointer = ffi.new("const CeedInt8 *")
398*709403c1SSebastian Grimberg        curl_orients_pointer = ffi.cast("const CeedInt8 *",
399*709403c1SSebastian Grimberg                                        curl_orients.__array_interface__['data'][0])
400*709403c1SSebastian Grimberg
401*709403c1SSebastian Grimberg        # libCEED call
402*709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateBlockedCurlOriented(self._ceed._pointer[0], nelem,
403*709403c1SSebastian Grimberg                                                                    elemsize, blksize, ncomp,
404*709403c1SSebastian Grimberg                                                                    compstride, lsize, memtype, cmode,
405*709403c1SSebastian Grimberg                                                                    offsets_pointer, curl_orients_pointer,
406*709403c1SSebastian Grimberg                                                                    self._pointer)
407*709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
408*709403c1SSebastian Grimberg
409*709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
410*709403c1SSebastian Grimberg
411*709403c1SSebastian Grimberg
41269a53589Sjeremyltclass BlockedStridedElemRestriction(BlockedElemRestriction):
413*709403c1SSebastian Grimberg    """Ceed Blocked Strided ElemRestriction: blocked strided restriction from local vectors to elements."""
41469a53589Sjeremylt
41569a53589Sjeremylt    # Constructor
416d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, lsize, strides):
41769a53589Sjeremylt        # CeedVector object
41869a53589Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
41969a53589Sjeremylt
42069a53589Sjeremylt        # Reference to Ceed
42169a53589Sjeremylt        self._ceed = ceed
42269a53589Sjeremylt
42369a53589Sjeremylt        # Setup the numpy array for the libCEED call
42469a53589Sjeremylt        strides_pointer = ffi.new("const CeedInt *")
42569a53589Sjeremylt        strides_pointer = ffi.cast("const CeedInt *",
42669a53589Sjeremylt                                   strides.__array_interface__['data'][0])
42769a53589Sjeremylt
42869a53589Sjeremylt        # libCEED call
429477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateBlockedStrided(self._ceed._pointer[0], nelem,
430d979a051Sjeremylt                                                               elemsize, blksize, ncomp,
431d979a051Sjeremylt                                                               lsize, strides_pointer,
43269a53589Sjeremylt                                                               self._pointer)
433477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
43469a53589Sjeremylt
43569a53589Sjeremylt# ------------------------------------------------------------------------------
4367a7b0fa3SJed Brown
4377a7b0fa3SJed Brown
438c8e769f6Sjeremyltclass TransposeElemRestriction():
439c8e769f6Sjeremylt    """Ceed ElemRestriction: transpose restriction from elements to local vectors."""
440c8e769f6Sjeremylt
441c8e769f6Sjeremylt    # Attributes
442c8e769f6Sjeremylt    _elemrestriction = None
443c8e769f6Sjeremylt
444c8e769f6Sjeremylt    # Constructor
445c8e769f6Sjeremylt    def __init__(self, elemrestriction):
446c8e769f6Sjeremylt
447c8e769f6Sjeremylt        # Reference elemrestriction
448c8e769f6Sjeremylt        self._elemrestriction = elemrestriction
449c8e769f6Sjeremylt
450c8e769f6Sjeremylt    # Representation
451c8e769f6Sjeremylt    def __repr__(self):
4527a7b0fa3SJed Brown        return "<Transpose CeedElemRestriction instance at " + \
4537a7b0fa3SJed Brown            hex(id(self)) + ">"
454c8e769f6Sjeremylt
455c8e769f6Sjeremylt    # Apply Transpose CeedElemRestriction
4567a7b0fa3SJed Brown
457a8d32208Sjeremylt    def apply(self, u, v, request=REQUEST_IMMEDIATE):
458c8e769f6Sjeremylt        """Restrict an element vector to a local vector.
459c8e769f6Sjeremylt
460c8e769f6Sjeremylt           Args:
461c8e769f6Sjeremylt             u: input vector
462c8e769f6Sjeremylt             v: output vector
463c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
464c8e769f6Sjeremylt
465c8e769f6Sjeremylt        # libCEED call
466a8d32208Sjeremylt        self._elemrestriction.apply(u, v, request=request, tmode=TRANSPOSE)
467c8e769f6Sjeremylt
468c8e769f6Sjeremylt# ------------------------------------------------------------------------------
4697a7b0fa3SJed Brown
4707a7b0fa3SJed Brown
471c8e769f6Sjeremyltclass TransposeBlockedElemRestriction(TransposeElemRestriction):
472c8e769f6Sjeremylt    """Transpose Ceed Blocked ElemRestriction: blocked transpose restriction from elements
473c8e769f6Sjeremylt         to local vectors."""
474c8e769f6Sjeremylt
475c8e769f6Sjeremylt    # Apply Transpose CeedElemRestriction
476a8d32208Sjeremylt    def apply_block(self, block, u, v, request=REQUEST_IMMEDIATE):
477c8e769f6Sjeremylt        """Restrict a block of an element vector to a local vector.
478c8e769f6Sjeremylt
479c8e769f6Sjeremylt           Args:
480c8e769f6Sjeremylt             block: block number to restrict to/from, i.e. block=0 will handle
481c8e769f6Sjeremylt                      elements [0 : blksize] and block=3 will handle elements
482c8e769f6Sjeremylt                      [3*blksize : 4*blksize]
483c8e769f6Sjeremylt             u: input vector
484c8e769f6Sjeremylt             v: output vector
485c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
486c8e769f6Sjeremylt
487c8e769f6Sjeremylt        # libCEED call
488a8d32208Sjeremylt        self._elemrestriction.apply_block(block, u, v, request=request,
489c8e769f6Sjeremylt                                          tmode=TRANSPOSE)
490c8e769f6Sjeremylt
491c8e769f6Sjeremylt# ------------------------------------------------------------------------------
492