xref: /libCEED/python/ceed_elemrestriction.py (revision 56c48462b0d39517237dc0770653f43cb7356d08)
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
125*56c48462SJeremy L Thompson    # Get ElemRestrition L-vector Layout
126*56c48462SJeremy L Thompson    def get_l_layout(self):
127*56c48462SJeremy L Thompson        """Get the local vector layout of an ElemRestriction.
128*56c48462SJeremy L Thompson
129*56c48462SJeremy L Thompson           Returns:
130*56c48462SJeremy L Thompson             layout: Vector containing layout array, stored as [nodes, components, elements].
131*56c48462SJeremy L Thompson                     The data for node i, component j, element k in the element
132*56c48462SJeremy L Thompson                     vector is given by i*layout[0] + j*layout[1] + k*layout[2]."""
133*56c48462SJeremy L Thompson
134*56c48462SJeremy L Thompson        # Create output array
135*56c48462SJeremy L Thompson        layout = np.zeros(3, dtype="int32")
136*56c48462SJeremy L Thompson        layout_pointer = ffi.cast("const CeedInt *",
137*56c48462SJeremy L Thompson                                  layout.__array_interface__['data'][0])
138*56c48462SJeremy L Thompson
139*56c48462SJeremy L Thompson        # libCEED call
140*56c48462SJeremy L Thompson        err_code = lib.CeedElemRestrictionGetLLayout(
141*56c48462SJeremy L Thompson            self._pointer[0], layout_pointer)
142*56c48462SJeremy L Thompson        self._ceed._check_error(err_code)
143*56c48462SJeremy L Thompson
144*56c48462SJeremy L Thompson        # Return
145*56c48462SJeremy L Thompson        return layout
146*56c48462SJeremy L Thompson
147*56c48462SJeremy L Thompson    # Get ElemRestrition E-vector Layout
148*56c48462SJeremy L Thompson    def get_e_layout(self):
149c3a5a609SJeremy L Thompson        """Get the element vector layout of an ElemRestriction.
150c3a5a609SJeremy L Thompson
151c3a5a609SJeremy L Thompson           Returns:
152c3a5a609SJeremy L Thompson             layout: Vector containing layout array, stored as [nodes, components, elements].
153c3a5a609SJeremy L Thompson                     The data for node i, component j, element k in the element
154c3a5a609SJeremy L Thompson                     vector is given by i*layout[0] + j*layout[1] + k*layout[2]."""
155c3a5a609SJeremy L Thompson
156c3a5a609SJeremy L Thompson        # Create output array
157c3a5a609SJeremy L Thompson        layout = np.zeros(3, dtype="int32")
158*56c48462SJeremy L Thompson        layout_pointer = ffi.cast("const CeedInt *",
159c3a5a609SJeremy L Thompson                                  layout.__array_interface__['data'][0])
160c3a5a609SJeremy L Thompson
161c3a5a609SJeremy L Thompson        # libCEED call
162c3a5a609SJeremy L Thompson        err_code = lib.CeedElemRestrictionGetELayout(
163*56c48462SJeremy L Thompson            self._pointer[0], layout_pointer)
164c3a5a609SJeremy L Thompson        self._ceed._check_error(err_code)
165c3a5a609SJeremy L Thompson
166c3a5a609SJeremy L Thompson        # Return
167c3a5a609SJeremy L Thompson        return layout
168c3a5a609SJeremy L Thompson
169c8e769f6Sjeremylt# ------------------------------------------------------------------------------
1707a7b0fa3SJed Brown
1717a7b0fa3SJed Brown
172c8e769f6Sjeremyltclass ElemRestriction(_ElemRestrictionBase):
173c8e769f6Sjeremylt    """Ceed ElemRestriction: restriction from local vectors to elements."""
174c8e769f6Sjeremylt
175c8e769f6Sjeremylt    # Constructor
176d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
177d979a051Sjeremylt                 memtype=MEM_HOST, cmode=COPY_VALUES):
178c8e769f6Sjeremylt        # CeedVector object
179c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
180c8e769f6Sjeremylt
181c8e769f6Sjeremylt        # Reference to Ceed
182c8e769f6Sjeremylt        self._ceed = ceed
183c8e769f6Sjeremylt
184187168c7SJeremy L Thompson        # Store array reference if needed
185187168c7SJeremy L Thompson        if cmode == USE_POINTER:
186187168c7SJeremy L Thompson            self._array_reference = offsets
187187168c7SJeremy L Thompson        else:
188187168c7SJeremy L Thompson            self._array_reference = None
189187168c7SJeremy L Thompson
190c8e769f6Sjeremylt        # Setup the numpy array for the libCEED call
191d979a051Sjeremylt        offsets_pointer = ffi.new("const CeedInt *")
192d979a051Sjeremylt        offsets_pointer = ffi.cast("const CeedInt *",
193d979a051Sjeremylt                                   offsets.__array_interface__['data'][0])
194c8e769f6Sjeremylt
195c8e769f6Sjeremylt        # libCEED call
196477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreate(self._ceed._pointer[0], nelem,
197477729cfSJeremy L Thompson                                                 elemsize, ncomp, compstride,
198477729cfSJeremy L Thompson                                                 lsize, memtype, cmode,
199d979a051Sjeremylt                                                 offsets_pointer, self._pointer)
200477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
201c8e769f6Sjeremylt
202c8e769f6Sjeremylt# ------------------------------------------------------------------------------
2037a7b0fa3SJed Brown
2047a7b0fa3SJed Brown
205709403c1SSebastian Grimbergclass OrientedElemRestriction(_ElemRestrictionBase):
206709403c1SSebastian Grimberg    """Ceed Oriented ElemRestriction: oriented restriction from local vectors to elements."""
207709403c1SSebastian Grimberg
208709403c1SSebastian Grimberg    # Constructor
209709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
210709403c1SSebastian Grimberg                 orients, memtype=MEM_HOST, cmode=COPY_VALUES):
211709403c1SSebastian Grimberg        # CeedVector object
212709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
213709403c1SSebastian Grimberg
214709403c1SSebastian Grimberg        # Reference to Ceed
215709403c1SSebastian Grimberg        self._ceed = ceed
216709403c1SSebastian Grimberg
217709403c1SSebastian Grimberg        # Store array reference if needed
218709403c1SSebastian Grimberg        if cmode == USE_POINTER:
219709403c1SSebastian Grimberg            self._array_reference = offsets
220709403c1SSebastian Grimberg            self._array_reference_aux = orients
221709403c1SSebastian Grimberg        else:
222709403c1SSebastian Grimberg            self._array_reference = None
223709403c1SSebastian Grimberg            self._array_reference_aux = None
224709403c1SSebastian Grimberg
225709403c1SSebastian Grimberg        # Setup the numpy arrays for the libCEED call
226709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
227709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
228709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
229709403c1SSebastian Grimberg        orients_pointer = ffi.new("const bool *")
230709403c1SSebastian Grimberg        orients_pointer = ffi.cast("const bool *",
231709403c1SSebastian Grimberg                                   orients.__array_interface__['data'][0])
232709403c1SSebastian Grimberg
233709403c1SSebastian Grimberg        # libCEED call
234709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateOriented(self._ceed._pointer[0], nelem,
235709403c1SSebastian Grimberg                                                         elemsize, ncomp, compstride,
236709403c1SSebastian Grimberg                                                         lsize, memtype, cmode,
237709403c1SSebastian Grimberg                                                         offsets_pointer, orients_pointer,
238709403c1SSebastian Grimberg                                                         self._pointer)
239709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
240709403c1SSebastian Grimberg
241709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
242709403c1SSebastian Grimberg
243709403c1SSebastian Grimberg
244709403c1SSebastian Grimbergclass CurlOrientedElemRestriction(_ElemRestrictionBase):
245709403c1SSebastian Grimberg    """Ceed Curl Oriented ElemRestriction: curl-oriented restriction from local vectors to elements."""
246709403c1SSebastian Grimberg
247709403c1SSebastian Grimberg    # Constructor
248709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets,
249709403c1SSebastian Grimberg                 curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES):
250709403c1SSebastian Grimberg        # CeedVector object
251709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
252709403c1SSebastian Grimberg
253709403c1SSebastian Grimberg        # Reference to Ceed
254709403c1SSebastian Grimberg        self._ceed = ceed
255709403c1SSebastian Grimberg
256709403c1SSebastian Grimberg        # Store array reference if needed
257709403c1SSebastian Grimberg        if cmode == USE_POINTER:
258709403c1SSebastian Grimberg            self._array_reference = offsets
259709403c1SSebastian Grimberg            self._array_reference_aux = curl_orients
260709403c1SSebastian Grimberg        else:
261709403c1SSebastian Grimberg            self._array_reference = None
262709403c1SSebastian Grimberg            self._array_reference_aux = None
263709403c1SSebastian Grimberg
264709403c1SSebastian Grimberg        # Setup the numpy arrays for the libCEED call
265709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
266709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
267709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
268709403c1SSebastian Grimberg        curl_orients_pointer = ffi.new("const CeedInt8 *")
269709403c1SSebastian Grimberg        curl_orients_pointer = ffi.cast("const CeedInt8 *",
270709403c1SSebastian Grimberg                                        curl_orients.__array_interface__['data'][0])
271709403c1SSebastian Grimberg
272709403c1SSebastian Grimberg        # libCEED call
273709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateCurlOriented(self._ceed._pointer[0], nelem,
274709403c1SSebastian Grimberg                                                             elemsize, ncomp, compstride,
275709403c1SSebastian Grimberg                                                             lsize, memtype, cmode,
276709403c1SSebastian Grimberg                                                             offsets_pointer,
277709403c1SSebastian Grimberg                                                             curl_orients_pointer,
278709403c1SSebastian Grimberg                                                             self._pointer)
279709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
280709403c1SSebastian Grimberg
281709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
282709403c1SSebastian Grimberg
283709403c1SSebastian Grimberg
28469a53589Sjeremyltclass StridedElemRestriction(_ElemRestrictionBase):
28569a53589Sjeremylt    """Ceed Strided ElemRestriction: strided restriction from local vectors to elements."""
286c8e769f6Sjeremylt
287c8e769f6Sjeremylt    # Constructor
288d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, ncomp, lsize, strides):
289c8e769f6Sjeremylt        # CeedVector object
290c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
291c8e769f6Sjeremylt
292c8e769f6Sjeremylt        # Reference to Ceed
293c8e769f6Sjeremylt        self._ceed = ceed
294c8e769f6Sjeremylt
29569a53589Sjeremylt        # Setup the numpy array for the libCEED call
29669a53589Sjeremylt        strides_pointer = ffi.new("const CeedInt *")
29769a53589Sjeremylt        strides_pointer = ffi.cast("const CeedInt *",
29869a53589Sjeremylt                                   strides.__array_interface__['data'][0])
29969a53589Sjeremylt
300c8e769f6Sjeremylt        # libCEED call
301477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateStrided(self._ceed._pointer[0],
302477729cfSJeremy L Thompson                                                        nelem, elemsize, ncomp,
303477729cfSJeremy L Thompson                                                        lsize, strides_pointer,
304477729cfSJeremy L Thompson                                                        self._pointer)
305477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
306c8e769f6Sjeremylt
307c8e769f6Sjeremylt# ------------------------------------------------------------------------------
3087a7b0fa3SJed Brown
3097a7b0fa3SJed Brown
310c8e769f6Sjeremyltclass BlockedElemRestriction(_ElemRestrictionBase):
311c8e769f6Sjeremylt    """Ceed Blocked ElemRestriction: blocked restriction from local vectors to elements."""
312c8e769f6Sjeremylt
313c8e769f6Sjeremylt    # Constructor
314d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
315d979a051Sjeremylt                 offsets, memtype=MEM_HOST, cmode=COPY_VALUES):
316c8e769f6Sjeremylt        # CeedVector object
317c8e769f6Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
318c8e769f6Sjeremylt
319c8e769f6Sjeremylt        # Reference to Ceed
320c8e769f6Sjeremylt        self._ceed = ceed
321c8e769f6Sjeremylt
322c8e769f6Sjeremylt        # Setup the numpy array for the libCEED call
323d979a051Sjeremylt        offsets_pointer = ffi.new("const CeedInt *")
324d979a051Sjeremylt        offsets_pointer = ffi.cast("const CeedInt *",
325d979a051Sjeremylt                                   offsets.__array_interface__['data'][0])
326c8e769f6Sjeremylt
327c8e769f6Sjeremylt        # libCEED call
328477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateBlocked(self._ceed._pointer[0], nelem,
329d979a051Sjeremylt                                                        elemsize, blksize, ncomp,
330d979a051Sjeremylt                                                        compstride, lsize, memtype, cmode,
331d979a051Sjeremylt                                                        offsets_pointer, self._pointer)
332477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
333c8e769f6Sjeremylt
334c8e769f6Sjeremylt    # Transpose a Blocked ElemRestriction
335c8e769f6Sjeremylt    @property
336c8e769f6Sjeremylt    def T(self):
337c8e769f6Sjeremylt        """Transpose a Blocked ElemRestriction."""
338c8e769f6Sjeremylt
339c8e769f6Sjeremylt        return TransposeBlockedElemRestriction(self)
340c8e769f6Sjeremylt
341c8e769f6Sjeremylt    # Transpose a Blocked ElemRestriction
342c8e769f6Sjeremylt    @property
343c8e769f6Sjeremylt    def transpose(self):
344c8e769f6Sjeremylt        """Transpose a Blocked ElemRestriction."""
345c8e769f6Sjeremylt
346c8e769f6Sjeremylt        return TransposeBlockedElemRestriction(self)
347c8e769f6Sjeremylt
348c8e769f6Sjeremylt    # Apply CeedElemRestriction to single block
349a8d32208Sjeremylt    def apply_block(self, block, u, v, tmode=NOTRANSPOSE,
350c8e769f6Sjeremylt                    request=REQUEST_IMMEDIATE):
351c8e769f6Sjeremylt        """Restrict a local vector to a block of an element vector or apply its transpose.
352c8e769f6Sjeremylt
353c8e769f6Sjeremylt           Args:
354c8e769f6Sjeremylt             block: block number to restrict to/from, i.e. block=0 will handle
355c8e769f6Sjeremylt                      elements [0 : blksize] and block=3 will handle elements
356c8e769f6Sjeremylt                      [3*blksize : 4*blksize]
357c8e769f6Sjeremylt             u: input vector
358c8e769f6Sjeremylt             v: output vector
359c8e769f6Sjeremylt             **tmode: apply restriction or transpose, default CEED_NOTRANSPOSE
360c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
361c8e769f6Sjeremylt
362c8e769f6Sjeremylt        # libCEED call
363477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionApplyBlock(self._pointer[0], block, tmode,
364477729cfSJeremy L Thompson                                                     u._pointer[0], v._pointer[0],
365477729cfSJeremy L Thompson                                                     request)
366477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
367c8e769f6Sjeremylt
368c8e769f6Sjeremylt# ------------------------------------------------------------------------------
3697a7b0fa3SJed Brown
3707a7b0fa3SJed Brown
371709403c1SSebastian Grimbergclass BlockedOrientedElemRestriction(BlockedElemRestriction):
372709403c1SSebastian Grimberg    """Ceed Blocked Oriented ElemRestriction: blocked oriented restriction from local vectors to elements."""
373709403c1SSebastian Grimberg
374709403c1SSebastian Grimberg    # Constructor
375709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
376709403c1SSebastian Grimberg                 offsets, orients, memtype=MEM_HOST, cmode=COPY_VALUES):
377709403c1SSebastian Grimberg        # CeedVector object
378709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
379709403c1SSebastian Grimberg
380709403c1SSebastian Grimberg        # Reference to Ceed
381709403c1SSebastian Grimberg        self._ceed = ceed
382709403c1SSebastian Grimberg
383709403c1SSebastian Grimberg        # Setup the numpy array for the libCEED call
384709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
385709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
386709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
387709403c1SSebastian Grimberg        orients_pointer = ffi.new("const bool *")
388709403c1SSebastian Grimberg        orients_pointer = ffi.cast("const bool *",
389709403c1SSebastian Grimberg                                   orients.__array_interface__['data'][0])
390709403c1SSebastian Grimberg
391709403c1SSebastian Grimberg        # libCEED call
392709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateBlockedOriented(self._ceed._pointer[0], nelem,
393709403c1SSebastian Grimberg                                                                elemsize, blksize, ncomp,
394709403c1SSebastian Grimberg                                                                compstride, lsize, memtype, cmode,
395709403c1SSebastian Grimberg                                                                offsets_pointer, orients_pointer,
396709403c1SSebastian Grimberg                                                                self._pointer)
397709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
398709403c1SSebastian Grimberg
399709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
400709403c1SSebastian Grimberg
401709403c1SSebastian Grimberg
402709403c1SSebastian Grimbergclass BlockedCurlOrientedElemRestriction(BlockedElemRestriction):
403709403c1SSebastian Grimberg    """Ceed Blocked Curl Oriented ElemRestriction: blocked curl-oriented restriction from local vectors to elements."""
404709403c1SSebastian Grimberg
405709403c1SSebastian Grimberg    # Constructor
406709403c1SSebastian Grimberg    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize,
407709403c1SSebastian Grimberg                 offsets, curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES):
408709403c1SSebastian Grimberg        # CeedVector object
409709403c1SSebastian Grimberg        self._pointer = ffi.new("CeedElemRestriction *")
410709403c1SSebastian Grimberg
411709403c1SSebastian Grimberg        # Reference to Ceed
412709403c1SSebastian Grimberg        self._ceed = ceed
413709403c1SSebastian Grimberg
414709403c1SSebastian Grimberg        # Setup the numpy array for the libCEED call
415709403c1SSebastian Grimberg        offsets_pointer = ffi.new("const CeedInt *")
416709403c1SSebastian Grimberg        offsets_pointer = ffi.cast("const CeedInt *",
417709403c1SSebastian Grimberg                                   offsets.__array_interface__['data'][0])
418709403c1SSebastian Grimberg        curl_orients_pointer = ffi.new("const CeedInt8 *")
419709403c1SSebastian Grimberg        curl_orients_pointer = ffi.cast("const CeedInt8 *",
420709403c1SSebastian Grimberg                                        curl_orients.__array_interface__['data'][0])
421709403c1SSebastian Grimberg
422709403c1SSebastian Grimberg        # libCEED call
423709403c1SSebastian Grimberg        err_code = lib.CeedElemRestrictionCreateBlockedCurlOriented(self._ceed._pointer[0], nelem,
424709403c1SSebastian Grimberg                                                                    elemsize, blksize, ncomp,
425709403c1SSebastian Grimberg                                                                    compstride, lsize, memtype, cmode,
426709403c1SSebastian Grimberg                                                                    offsets_pointer, curl_orients_pointer,
427709403c1SSebastian Grimberg                                                                    self._pointer)
428709403c1SSebastian Grimberg        self._ceed._check_error(err_code)
429709403c1SSebastian Grimberg
430709403c1SSebastian Grimberg# ------------------------------------------------------------------------------
431709403c1SSebastian Grimberg
432709403c1SSebastian Grimberg
43369a53589Sjeremyltclass BlockedStridedElemRestriction(BlockedElemRestriction):
434709403c1SSebastian Grimberg    """Ceed Blocked Strided ElemRestriction: blocked strided restriction from local vectors to elements."""
43569a53589Sjeremylt
43669a53589Sjeremylt    # Constructor
437d979a051Sjeremylt    def __init__(self, ceed, nelem, elemsize, blksize, ncomp, lsize, strides):
43869a53589Sjeremylt        # CeedVector object
43969a53589Sjeremylt        self._pointer = ffi.new("CeedElemRestriction *")
44069a53589Sjeremylt
44169a53589Sjeremylt        # Reference to Ceed
44269a53589Sjeremylt        self._ceed = ceed
44369a53589Sjeremylt
44469a53589Sjeremylt        # Setup the numpy array for the libCEED call
44569a53589Sjeremylt        strides_pointer = ffi.new("const CeedInt *")
44669a53589Sjeremylt        strides_pointer = ffi.cast("const CeedInt *",
44769a53589Sjeremylt                                   strides.__array_interface__['data'][0])
44869a53589Sjeremylt
44969a53589Sjeremylt        # libCEED call
450477729cfSJeremy L Thompson        err_code = lib.CeedElemRestrictionCreateBlockedStrided(self._ceed._pointer[0], nelem,
451d979a051Sjeremylt                                                               elemsize, blksize, ncomp,
452d979a051Sjeremylt                                                               lsize, strides_pointer,
45369a53589Sjeremylt                                                               self._pointer)
454477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
45569a53589Sjeremylt
45669a53589Sjeremylt# ------------------------------------------------------------------------------
4577a7b0fa3SJed Brown
4587a7b0fa3SJed Brown
459c8e769f6Sjeremyltclass TransposeElemRestriction():
460c8e769f6Sjeremylt    """Ceed ElemRestriction: transpose restriction from elements to local vectors."""
461c8e769f6Sjeremylt
462c8e769f6Sjeremylt    # Attributes
463c8e769f6Sjeremylt    _elemrestriction = None
464c8e769f6Sjeremylt
465c8e769f6Sjeremylt    # Constructor
466c8e769f6Sjeremylt    def __init__(self, elemrestriction):
467c8e769f6Sjeremylt
468c8e769f6Sjeremylt        # Reference elemrestriction
469c8e769f6Sjeremylt        self._elemrestriction = elemrestriction
470c8e769f6Sjeremylt
471c8e769f6Sjeremylt    # Representation
472c8e769f6Sjeremylt    def __repr__(self):
4737a7b0fa3SJed Brown        return "<Transpose CeedElemRestriction instance at " + \
4747a7b0fa3SJed Brown            hex(id(self)) + ">"
475c8e769f6Sjeremylt
476c8e769f6Sjeremylt    # Apply Transpose CeedElemRestriction
4777a7b0fa3SJed Brown
478a8d32208Sjeremylt    def apply(self, u, v, request=REQUEST_IMMEDIATE):
479c8e769f6Sjeremylt        """Restrict an element vector to a local vector.
480c8e769f6Sjeremylt
481c8e769f6Sjeremylt           Args:
482c8e769f6Sjeremylt             u: input vector
483c8e769f6Sjeremylt             v: output vector
484c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
485c8e769f6Sjeremylt
486c8e769f6Sjeremylt        # libCEED call
487a8d32208Sjeremylt        self._elemrestriction.apply(u, v, request=request, tmode=TRANSPOSE)
488c8e769f6Sjeremylt
489c8e769f6Sjeremylt# ------------------------------------------------------------------------------
4907a7b0fa3SJed Brown
4917a7b0fa3SJed Brown
492c8e769f6Sjeremyltclass TransposeBlockedElemRestriction(TransposeElemRestriction):
493c8e769f6Sjeremylt    """Transpose Ceed Blocked ElemRestriction: blocked transpose restriction from elements
494c8e769f6Sjeremylt         to local vectors."""
495c8e769f6Sjeremylt
496c8e769f6Sjeremylt    # Apply Transpose CeedElemRestriction
497a8d32208Sjeremylt    def apply_block(self, block, u, v, request=REQUEST_IMMEDIATE):
498c8e769f6Sjeremylt        """Restrict a block of an element vector to a local vector.
499c8e769f6Sjeremylt
500c8e769f6Sjeremylt           Args:
501c8e769f6Sjeremylt             block: block number to restrict to/from, i.e. block=0 will handle
502c8e769f6Sjeremylt                      elements [0 : blksize] and block=3 will handle elements
503c8e769f6Sjeremylt                      [3*blksize : 4*blksize]
504c8e769f6Sjeremylt             u: input vector
505c8e769f6Sjeremylt             v: output vector
506c8e769f6Sjeremylt             **request: Ceed request, default CEED_REQUEST_IMMEDIATE"""
507c8e769f6Sjeremylt
508c8e769f6Sjeremylt        # libCEED call
509a8d32208Sjeremylt        self._elemrestriction.apply_block(block, u, v, request=request,
510c8e769f6Sjeremylt                                          tmode=TRANSPOSE)
511c8e769f6Sjeremylt
512c8e769f6Sjeremylt# ------------------------------------------------------------------------------
513