xref: /libCEED/python/ceed_vector.py (revision 9c774eddf8c0b4f5416196d32c5355c9591a7190)
17def3d77Svaleriabarra# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
27def3d77Svaleriabarra# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
37def3d77Svaleriabarra# reserved. See files LICENSE and NOTICE for details.
47def3d77Svaleriabarra#
57def3d77Svaleriabarra# This file is part of CEED, a collection of benchmarks, miniapps, software
67def3d77Svaleriabarra# libraries and APIs for efficient high-order finite element and spectral
77def3d77Svaleriabarra# element discretizations for exascale applications. For more information and
87def3d77Svaleriabarra# source code availability see http://github.com/ceed.
97def3d77Svaleriabarra#
107def3d77Svaleriabarra# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
117def3d77Svaleriabarra# a collaborative effort of two U.S. Department of Energy organizations (Office
127def3d77Svaleriabarra# of Science and the National Nuclear Security Administration) responsible for
137def3d77Svaleriabarra# the planning and preparation of a capable exascale ecosystem, including
147def3d77Svaleriabarra# software, applications, hardware, advanced system engineering and early
157def3d77Svaleriabarra# testbed platforms, in support of the nation's exascale computing imperative.
167def3d77Svaleriabarra
177def3d77Svaleriabarrafrom _ceed_cffi import ffi, lib
187def3d77Svaleriabarraimport tempfile
197def3d77Svaleriabarraimport numpy as np
20e259ae81SJed Brownimport contextlib
2180a9ef05SNatalie Beamsfrom .ceed_constants import MEM_HOST, USE_POINTER, COPY_VALUES, NORM_2, scalar_types
227def3d77Svaleriabarra
237def3d77Svaleriabarra# ------------------------------------------------------------------------------
247a7b0fa3SJed Brown
257a7b0fa3SJed Brown
267def3d77Svaleriabarraclass Vector():
277def3d77Svaleriabarra    """Ceed Vector: storing and manipulating vectors."""
287def3d77Svaleriabarra
297def3d77Svaleriabarra    # Constructor
307def3d77Svaleriabarra    def __init__(self, ceed, size):
317def3d77Svaleriabarra        # CeedVector object
327def3d77Svaleriabarra        self._pointer = ffi.new("CeedVector *")
337def3d77Svaleriabarra
347def3d77Svaleriabarra        # Reference to Ceed
357def3d77Svaleriabarra        self._ceed = ceed
367def3d77Svaleriabarra
377def3d77Svaleriabarra        # libCEED call
38477729cfSJeremy L Thompson        err_code = lib.CeedVectorCreate(
39477729cfSJeremy L Thompson            self._ceed._pointer[0], size, self._pointer)
40477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
417def3d77Svaleriabarra
427def3d77Svaleriabarra    # Destructor
437def3d77Svaleriabarra    def __del__(self):
447def3d77Svaleriabarra        # libCEED call
45477729cfSJeremy L Thompson        err_code = lib.CeedVectorDestroy(self._pointer)
46477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
477def3d77Svaleriabarra
487def3d77Svaleriabarra    # Representation
497def3d77Svaleriabarra    def __repr__(self):
507def3d77Svaleriabarra        return "<CeedVector instance at " + hex(id(self)) + ">"
517def3d77Svaleriabarra
527def3d77Svaleriabarra    # String conversion for print() to stdout
537def3d77Svaleriabarra    def __str__(self):
547def3d77Svaleriabarra        """View a Vector via print()."""
557def3d77Svaleriabarra
567def3d77Svaleriabarra        # libCEED call
577def3d77Svaleriabarra        fmt = ffi.new("char[]", "%f".encode('ascii'))
587def3d77Svaleriabarra        with tempfile.NamedTemporaryFile() as key_file:
597def3d77Svaleriabarra            with open(key_file.name, 'r+') as stream_file:
607def3d77Svaleriabarra                stream = ffi.cast("FILE *", stream_file)
617def3d77Svaleriabarra
62477729cfSJeremy L Thompson                err_code = lib.CeedVectorView(self._pointer[0], fmt, stream)
63477729cfSJeremy L Thompson                self._ceed._check_error(err_code)
647def3d77Svaleriabarra
657def3d77Svaleriabarra                stream_file.seek(0)
667def3d77Svaleriabarra                out_string = stream_file.read()
677def3d77Svaleriabarra
687def3d77Svaleriabarra        return out_string
697def3d77Svaleriabarra
707def3d77Svaleriabarra    # Set Vector's data array
717def3d77Svaleriabarra    def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES):
727def3d77Svaleriabarra        """Set the array used by a Vector, freeing any previously allocated
737def3d77Svaleriabarra           array if applicable.
747def3d77Svaleriabarra
757def3d77Svaleriabarra           Args:
767f1dc7b9SJeremy L Thompson             *array: Numpy or Numba array to be used
777def3d77Svaleriabarra             **memtype: memory type of the array being passed, default CEED_MEM_HOST
787def3d77Svaleriabarra             **cmode: copy mode for the array, default CEED_COPY_VALUES"""
797def3d77Svaleriabarra
80187168c7SJeremy L Thompson        # Store array reference if needed
81187168c7SJeremy L Thompson        if cmode == USE_POINTER:
82187168c7SJeremy L Thompson            self._array_reference = array
83187168c7SJeremy L Thompson        else:
84187168c7SJeremy L Thompson            self._array_reference = None
85187168c7SJeremy L Thompson
867def3d77Svaleriabarra        # Setup the numpy array for the libCEED call
877def3d77Svaleriabarra        array_pointer = ffi.new("CeedScalar *")
887f1dc7b9SJeremy L Thompson        if memtype == MEM_HOST:
897a7b0fa3SJed Brown            array_pointer = ffi.cast(
907a7b0fa3SJed Brown                "CeedScalar *",
917a7b0fa3SJed Brown                array.__array_interface__['data'][0])
927f1dc7b9SJeremy L Thompson        else:
937f1dc7b9SJeremy L Thompson            array_pointer = ffi.cast(
947f1dc7b9SJeremy L Thompson                "CeedScalar *",
957f1dc7b9SJeremy L Thompson                array.__cuda_array_interface__['data'][0])
967def3d77Svaleriabarra
977def3d77Svaleriabarra        # libCEED call
98477729cfSJeremy L Thompson        err_code = lib.CeedVectorSetArray(
99477729cfSJeremy L Thompson            self._pointer[0], memtype, cmode, array_pointer)
100477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
1017def3d77Svaleriabarra
1027def3d77Svaleriabarra    # Get Vector's data array
1037def3d77Svaleriabarra    def get_array(self, memtype=MEM_HOST):
1047def3d77Svaleriabarra        """Get read/write access to a Vector via the specified memory type.
1057def3d77Svaleriabarra
1067def3d77Svaleriabarra           Args:
1077def3d77Svaleriabarra             **memtype: memory type of the array being passed, default CEED_MEM_HOST
1087def3d77Svaleriabarra
1097def3d77Svaleriabarra           Returns:
1107f1dc7b9SJeremy L Thompson             *array: Numpy or Numba array"""
1117def3d77Svaleriabarra
1127def3d77Svaleriabarra        # Retrieve the length of the array
1137def3d77Svaleriabarra        length_pointer = ffi.new("CeedInt *")
114477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer)
115477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
1167def3d77Svaleriabarra
1177def3d77Svaleriabarra        # Setup the pointer's pointer
1187def3d77Svaleriabarra        array_pointer = ffi.new("CeedScalar **")
1197def3d77Svaleriabarra
1207def3d77Svaleriabarra        # libCEED call
121477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetArray(
122477729cfSJeremy L Thompson            self._pointer[0], memtype, array_pointer)
123477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
1247def3d77Svaleriabarra
1257f1dc7b9SJeremy L Thompson        # Return array created from buffer
1267f1dc7b9SJeremy L Thompson        if memtype == MEM_HOST:
1277def3d77Svaleriabarra            # Create buffer object from returned pointer
1287a7b0fa3SJed Brown            buff = ffi.buffer(
1297a7b0fa3SJed Brown                array_pointer[0],
1307a7b0fa3SJed Brown                ffi.sizeof("CeedScalar") *
1317a7b0fa3SJed Brown                length_pointer[0])
1327f1dc7b9SJeremy L Thompson            # return Numpy array
13380a9ef05SNatalie Beams            return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE])
1347f1dc7b9SJeremy L Thompson        else:
1357f1dc7b9SJeremy L Thompson            # CUDA array interface
1367f1dc7b9SJeremy L Thompson            # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html
137962dc42dSJeremy L Thompson            import numba.cuda as nbcuda
1387f1dc7b9SJeremy L Thompson            desc = {
1397f1dc7b9SJeremy L Thompson                'shape': (length_pointer[0]),
1407f1dc7b9SJeremy L Thompson                'typestr': '>f8',
1417f1dc7b9SJeremy L Thompson                'data': (int(ffi.cast("intptr_t", array_pointer[0])), False),
1427f1dc7b9SJeremy L Thompson                'version': 2
1437f1dc7b9SJeremy L Thompson            }
1447f1dc7b9SJeremy L Thompson            # return Numba array
1457f1dc7b9SJeremy L Thompson            return nbcuda.from_cuda_array_interface(desc)
1467def3d77Svaleriabarra
1477def3d77Svaleriabarra    # Get Vector's data array in read-only mode
1487def3d77Svaleriabarra    def get_array_read(self, memtype=MEM_HOST):
1497def3d77Svaleriabarra        """Get read-only access to a Vector via the specified memory type.
1507def3d77Svaleriabarra
1517def3d77Svaleriabarra           Args:
1527def3d77Svaleriabarra             **memtype: memory type of the array being passed, default CEED_MEM_HOST
1537def3d77Svaleriabarra
1547def3d77Svaleriabarra           Returns:
1557f1dc7b9SJeremy L Thompson             *array: Numpy or Numba array"""
1567def3d77Svaleriabarra
1577def3d77Svaleriabarra        # Retrieve the length of the array
1587def3d77Svaleriabarra        length_pointer = ffi.new("CeedInt *")
159477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer)
160477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
1617def3d77Svaleriabarra
1627def3d77Svaleriabarra        # Setup the pointer's pointer
1637def3d77Svaleriabarra        array_pointer = ffi.new("CeedScalar **")
1647def3d77Svaleriabarra
1657def3d77Svaleriabarra        # libCEED call
166477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetArrayRead(
167477729cfSJeremy L Thompson            self._pointer[0], memtype, array_pointer)
168477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
1697def3d77Svaleriabarra
1707f1dc7b9SJeremy L Thompson        # Return array created from buffer
1717f1dc7b9SJeremy L Thompson        if memtype == MEM_HOST:
1727def3d77Svaleriabarra            # Create buffer object from returned pointer
1737a7b0fa3SJed Brown            buff = ffi.buffer(
1747a7b0fa3SJed Brown                array_pointer[0],
1757a7b0fa3SJed Brown                ffi.sizeof("CeedScalar") *
1767a7b0fa3SJed Brown                length_pointer[0])
1777f1dc7b9SJeremy L Thompson            # return read only Numpy array
17880a9ef05SNatalie Beams            ret = np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE])
1797def3d77Svaleriabarra            ret.flags['WRITEABLE'] = False
1807def3d77Svaleriabarra            return ret
1817f1dc7b9SJeremy L Thompson        else:
1827f1dc7b9SJeremy L Thompson            # CUDA array interface
1837f1dc7b9SJeremy L Thompson            # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html
184962dc42dSJeremy L Thompson            import numba.cuda as nbcuda
1857f1dc7b9SJeremy L Thompson            desc = {
1867f1dc7b9SJeremy L Thompson                'shape': (length_pointer[0]),
1877f1dc7b9SJeremy L Thompson                'typestr': '>f8',
1887f1dc7b9SJeremy L Thompson                'data': (int(ffi.cast("intptr_t", array_pointer[0])), False),
1897f1dc7b9SJeremy L Thompson                'version': 2
1907f1dc7b9SJeremy L Thompson            }
1917f1dc7b9SJeremy L Thompson            # return read only Numba array
1927f1dc7b9SJeremy L Thompson            return nbcuda.from_cuda_array_interface(desc)
1937def3d77Svaleriabarra
194*9c774eddSJeremy L Thompson    # Get Vector's data array in write-only mode
195*9c774eddSJeremy L Thompson    def get_array_write(self, memtype=MEM_HOST):
196*9c774eddSJeremy L Thompson        """Get write-only access to a Vector via the specified memory type.
197*9c774eddSJeremy L Thompson           All old values should be considered invalid.
198*9c774eddSJeremy L Thompson
199*9c774eddSJeremy L Thompson           Args:
200*9c774eddSJeremy L Thompson             **memtype: memory type of the array being passed, default CEED_MEM_HOST
201*9c774eddSJeremy L Thompson
202*9c774eddSJeremy L Thompson           Returns:
203*9c774eddSJeremy L Thompson             *array: Numpy or Numba array"""
204*9c774eddSJeremy L Thompson
205*9c774eddSJeremy L Thompson        # Retrieve the length of the array
206*9c774eddSJeremy L Thompson        length_pointer = ffi.new("CeedInt *")
207*9c774eddSJeremy L Thompson        err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer)
208*9c774eddSJeremy L Thompson        self._ceed._check_error(err_code)
209*9c774eddSJeremy L Thompson
210*9c774eddSJeremy L Thompson        # Setup the pointer's pointer
211*9c774eddSJeremy L Thompson        array_pointer = ffi.new("CeedScalar **")
212*9c774eddSJeremy L Thompson
213*9c774eddSJeremy L Thompson        # libCEED call
214*9c774eddSJeremy L Thompson        err_code = lib.CeedVectorGetArrayWrite(
215*9c774eddSJeremy L Thompson            self._pointer[0], memtype, array_pointer)
216*9c774eddSJeremy L Thompson        self._ceed._check_error(err_code)
217*9c774eddSJeremy L Thompson
218*9c774eddSJeremy L Thompson        # Return array created from buffer
219*9c774eddSJeremy L Thompson        if memtype == MEM_HOST:
220*9c774eddSJeremy L Thompson            # Create buffer object from returned pointer
221*9c774eddSJeremy L Thompson            buff = ffi.buffer(
222*9c774eddSJeremy L Thompson                array_pointer[0],
223*9c774eddSJeremy L Thompson                ffi.sizeof("CeedScalar") *
224*9c774eddSJeremy L Thompson                length_pointer[0])
225*9c774eddSJeremy L Thompson            # return Numpy array
226*9c774eddSJeremy L Thompson            return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE])
227*9c774eddSJeremy L Thompson        else:
228*9c774eddSJeremy L Thompson            # CUDA array interface
229*9c774eddSJeremy L Thompson            # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html
230*9c774eddSJeremy L Thompson            import numba.cuda as nbcuda
231*9c774eddSJeremy L Thompson            desc = {
232*9c774eddSJeremy L Thompson                'shape': (length_pointer[0]),
233*9c774eddSJeremy L Thompson                'typestr': '>f8',
234*9c774eddSJeremy L Thompson                'data': (int(ffi.cast("intptr_t", array_pointer[0])), False),
235*9c774eddSJeremy L Thompson                'version': 2
236*9c774eddSJeremy L Thompson            }
237*9c774eddSJeremy L Thompson            # return Numba array
238*9c774eddSJeremy L Thompson            return nbcuda.from_cuda_array_interface(desc)
239*9c774eddSJeremy L Thompson
2407def3d77Svaleriabarra    # Restore the Vector's data array
2417def3d77Svaleriabarra    def restore_array(self):
2427def3d77Svaleriabarra        """Restore an array obtained using get_array()."""
2437def3d77Svaleriabarra
2447def3d77Svaleriabarra        # Setup the pointer's pointer
2457def3d77Svaleriabarra        array_pointer = ffi.new("CeedScalar **")
2467def3d77Svaleriabarra
2477def3d77Svaleriabarra        # libCEED call
248477729cfSJeremy L Thompson        err_code = lib.CeedVectorRestoreArray(self._pointer[0], array_pointer)
249477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
2507def3d77Svaleriabarra
2517def3d77Svaleriabarra    # Restore an array obtained using getArrayRead
2527def3d77Svaleriabarra    def restore_array_read(self):
2537def3d77Svaleriabarra        """Restore an array obtained using get_array_read()."""
2547def3d77Svaleriabarra
2557def3d77Svaleriabarra        # Setup the pointer's pointer
2567def3d77Svaleriabarra        array_pointer = ffi.new("CeedScalar **")
2577def3d77Svaleriabarra
2587def3d77Svaleriabarra        # libCEED call
259477729cfSJeremy L Thompson        err_code = lib.CeedVectorRestoreArrayRead(
260477729cfSJeremy L Thompson            self._pointer[0], array_pointer)
261477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
2627def3d77Svaleriabarra
263e259ae81SJed Brown    @contextlib.contextmanager
2647f1dc7b9SJeremy L Thompson    def array(self, *shape, memtype=MEM_HOST):
265e259ae81SJed Brown        """Context manager for array access.
266e259ae81SJed Brown
267e259ae81SJed Brown        Args:
268e259ae81SJed Brown          shape (tuple): shape of returned numpy.array
2697f1dc7b9SJeremy L Thompson          **memtype: memory type of the array being passed, default CEED_MEM_HOST
2707f1dc7b9SJeremy L Thompson
271e259ae81SJed Brown
272e259ae81SJed Brown        Returns:
273e259ae81SJed Brown          np.array: writable view of vector
274e259ae81SJed Brown
275e259ae81SJed Brown        Examples:
276e259ae81SJed Brown          Constructing the identity inside a libceed.Vector:
277e259ae81SJed Brown
278e259ae81SJed Brown          >>> vec = ceed.Vector(16)
279e259ae81SJed Brown          >>> with vec.array(4, 4) as x:
280e259ae81SJed Brown          >>>     x[...] = np.eye(4)
281e259ae81SJed Brown        """
2827f1dc7b9SJeremy L Thompson        x = self.get_array(memtype=memtype)
283e259ae81SJed Brown        if shape:
284e259ae81SJed Brown            x = x.reshape(shape)
285e259ae81SJed Brown        yield x
286e259ae81SJed Brown        self.restore_array()
287e259ae81SJed Brown
288e259ae81SJed Brown    @contextlib.contextmanager
2897f1dc7b9SJeremy L Thompson    def array_read(self, *shape, memtype=MEM_HOST):
290e259ae81SJed Brown        """Context manager for read-only array access.
291e259ae81SJed Brown
292e259ae81SJed Brown        Args:
293e259ae81SJed Brown          shape (tuple): shape of returned numpy.array
2947f1dc7b9SJeremy L Thompson          **memtype: memory type of the array being passed, default CEED_MEM_HOST
295e259ae81SJed Brown
296e259ae81SJed Brown        Returns:
297e259ae81SJed Brown          np.array: read-only view of vector
298e259ae81SJed Brown
299e259ae81SJed Brown        Examples:
300187168c7SJeremy L Thompson          Viewing contents of a reshaped libceed.Vector view:
301e259ae81SJed Brown
302e259ae81SJed Brown          >>> vec = ceed.Vector(6)
303e259ae81SJed Brown          >>> vec.set_value(1.3)
304e259ae81SJed Brown          >>> with vec.array_read(2, 3) as x:
305e259ae81SJed Brown          >>>     print(x)
306e259ae81SJed Brown        """
3077f1dc7b9SJeremy L Thompson        x = self.get_array_read(memtype=memtype)
308e259ae81SJed Brown        if shape:
309e259ae81SJed Brown            x = x.reshape(shape)
310e259ae81SJed Brown        yield x
311e259ae81SJed Brown        self.restore_array_read()
312e259ae81SJed Brown
313*9c774eddSJeremy L Thompson    @contextlib.contextmanager
314*9c774eddSJeremy L Thompson    def array_write(self, *shape, memtype=MEM_HOST):
315*9c774eddSJeremy L Thompson        """Context manager for write-only array access.
316*9c774eddSJeremy L Thompson           All old values should be considered invalid.
317*9c774eddSJeremy L Thompson
318*9c774eddSJeremy L Thompson        Args:
319*9c774eddSJeremy L Thompson          shape (tuple): shape of returned numpy.array
320*9c774eddSJeremy L Thompson          **memtype: memory type of the array being passed, default CEED_MEM_HOST
321*9c774eddSJeremy L Thompson
322*9c774eddSJeremy L Thompson        Returns:
323*9c774eddSJeremy L Thompson          np.array: write-only view of vector
324*9c774eddSJeremy L Thompson
325*9c774eddSJeremy L Thompson        Examples:
326*9c774eddSJeremy L Thompson          Viewing contents of a reshaped libceed.Vector view:
327*9c774eddSJeremy L Thompson
328*9c774eddSJeremy L Thompson          >>> vec = ceed.Vector(6)
329*9c774eddSJeremy L Thompson          >>> vec.set_value(1.3)
330*9c774eddSJeremy L Thompson          >>> with vec.array_read(2, 3) as x:
331*9c774eddSJeremy L Thompson          >>>     print(x)
332*9c774eddSJeremy L Thompson        """
333*9c774eddSJeremy L Thompson        x = self.get_array_write(memtype=memtype)
334*9c774eddSJeremy L Thompson        if shape:
335*9c774eddSJeremy L Thompson            x = x.reshape(shape)
336*9c774eddSJeremy L Thompson        yield x
337*9c774eddSJeremy L Thompson        self.restore_array()
338*9c774eddSJeremy L Thompson
3397def3d77Svaleriabarra    # Get the length of a Vector
3407def3d77Svaleriabarra    def get_length(self):
3417def3d77Svaleriabarra        """Get the length of a Vector.
3427def3d77Svaleriabarra
3437def3d77Svaleriabarra           Returns:
3447def3d77Svaleriabarra             length: length of the Vector"""
3457def3d77Svaleriabarra
3467def3d77Svaleriabarra        length_pointer = ffi.new("CeedInt *")
3477def3d77Svaleriabarra
3487def3d77Svaleriabarra        # libCEED call
349477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer)
350477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
3517def3d77Svaleriabarra
3527def3d77Svaleriabarra        return length_pointer[0]
3537def3d77Svaleriabarra
3547def3d77Svaleriabarra    # Get the length of a Vector
3557def3d77Svaleriabarra    def __len__(self):
3567def3d77Svaleriabarra        """Get the length of a Vector.
3577def3d77Svaleriabarra
3587def3d77Svaleriabarra           Returns:
3597def3d77Svaleriabarra             length: length of the Vector"""
3607def3d77Svaleriabarra
3617def3d77Svaleriabarra        length_pointer = ffi.new("CeedInt *")
3627def3d77Svaleriabarra
3637def3d77Svaleriabarra        # libCEED call
364477729cfSJeremy L Thompson        err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer)
365477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
3667def3d77Svaleriabarra
3677def3d77Svaleriabarra        return length_pointer[0]
3687def3d77Svaleriabarra
3697def3d77Svaleriabarra    # Set the Vector to a given constant value
3707def3d77Svaleriabarra    def set_value(self, value):
3717def3d77Svaleriabarra        """Set the Vector to a constant value.
3727def3d77Svaleriabarra
3737def3d77Svaleriabarra           Args:
3747def3d77Svaleriabarra             value: value to be used"""
3757def3d77Svaleriabarra
3767def3d77Svaleriabarra        # libCEED call
377477729cfSJeremy L Thompson        err_code = lib.CeedVectorSetValue(self._pointer[0], value)
378477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
3797def3d77Svaleriabarra
3807def3d77Svaleriabarra    # Sync the Vector to a specified memtype
381547d9b97Sjeremylt    def sync_array(self, memtype=MEM_HOST):
3827def3d77Svaleriabarra        """Sync the Vector to a specified memtype.
3837def3d77Svaleriabarra
3847def3d77Svaleriabarra           Args:
3857def3d77Svaleriabarra             **memtype: memtype to be synced"""
3867def3d77Svaleriabarra
3877def3d77Svaleriabarra        # libCEED call
388477729cfSJeremy L Thompson        err_code = lib.CeedVectorSyncArray(self._pointer[0], memtype)
389477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
3907def3d77Svaleriabarra
391547d9b97Sjeremylt    # Compute the norm of a vector
392547d9b97Sjeremylt    def norm(self, normtype=NORM_2):
393547d9b97Sjeremylt        """Get the norm of a Vector.
394547d9b97Sjeremylt
395547d9b97Sjeremylt           Args:
396547d9b97Sjeremylt             **normtype: type of norm to be computed"""
397547d9b97Sjeremylt
398547d9b97Sjeremylt        norm_pointer = ffi.new("CeedScalar *")
399547d9b97Sjeremylt
400547d9b97Sjeremylt        # libCEED call
401477729cfSJeremy L Thompson        err_code = lib.CeedVectorNorm(self._pointer[0], normtype, norm_pointer)
402477729cfSJeremy L Thompson        self._ceed._check_error(err_code)
403547d9b97Sjeremylt
404547d9b97Sjeremylt        return norm_pointer[0]
405547d9b97Sjeremylt
406d99fa3c5SJeremy L Thompson    # Take the reciprocal of a vector
407d99fa3c5SJeremy L Thompson    def reciprocal(self):
408d99fa3c5SJeremy L Thompson        """Take the reciprocal of a Vector."""
409d99fa3c5SJeremy L Thompson
410d99fa3c5SJeremy L Thompson        # libCEED call
411d99fa3c5SJeremy L Thompson        err_code = lib.CeedVectorReciprocal(self._pointer[0])
412d99fa3c5SJeremy L Thompson        self._ceed._check_error(err_code)
413d99fa3c5SJeremy L Thompson
414d99fa3c5SJeremy L Thompson        return self
415d99fa3c5SJeremy L Thompson
416e0dd3b27Sjeremylt    # Compute self = alpha self
417e0dd3b27Sjeremylt    def scale(self, alpha):
418e0dd3b27Sjeremylt        """Compute self = alpha self."""
419e0dd3b27Sjeremylt
420e0dd3b27Sjeremylt        # libCEED call
421e0dd3b27Sjeremylt        err_code = lib.CeedVectorScale(self._pointer[0], alpha)
422e0dd3b27Sjeremylt        self._ceed._check_error(err_code)
423e0dd3b27Sjeremylt
424e0dd3b27Sjeremylt        return self
425e0dd3b27Sjeremylt
4260c1bc3c2Sjeremylt    # Compute self = alpha x + self
4270c1bc3c2Sjeremylt    def axpy(self, alpha, x):
4280c1bc3c2Sjeremylt        """Compute self = alpha x + self."""
4290c1bc3c2Sjeremylt
4300c1bc3c2Sjeremylt        # libCEED call
4310c1bc3c2Sjeremylt        err_code = lib.CeedVectorAXPY(self._pointer[0], alpha, x._pointer[0])
4320c1bc3c2Sjeremylt        self._ceed._check_error(err_code)
4330c1bc3c2Sjeremylt
4340c1bc3c2Sjeremylt        return self
4350c1bc3c2Sjeremylt
4360c1bc3c2Sjeremylt    # Compute the pointwise multiplication self = x .* y
4370c1bc3c2Sjeremylt    def pointwise_mult(self, x, y):
4380c1bc3c2Sjeremylt        """Compute the pointwise multiplication self = x .* y."""
4390c1bc3c2Sjeremylt
4400c1bc3c2Sjeremylt        # libCEED call
4410c1bc3c2Sjeremylt        err_code = lib.CeedVectorPointwiseMult(
4420c1bc3c2Sjeremylt            self._pointer[0], x._pointer[0], y._pointer[0]
4430c1bc3c2Sjeremylt        )
4440c1bc3c2Sjeremylt        self._ceed._check_error(err_code)
4450c1bc3c2Sjeremylt
4460c1bc3c2Sjeremylt        return self
4470c1bc3c2Sjeremylt
44819798369SJed Brown    def _state(self):
44919798369SJed Brown        """Return the modification state of the Vector.
45019798369SJed Brown
45119798369SJed Brown        State is incremented each time the Vector is mutated, and is odd whenever a
45219798369SJed Brown        mutable reference has not been returned.
45319798369SJed Brown        """
45419798369SJed Brown
45519798369SJed Brown        state_pointer = ffi.new("uint64_t *")
45619798369SJed Brown        err_code = lib.CeedVectorGetState(self._pointer[0], state_pointer)
45719798369SJed Brown        self._ceed._check_error(err_code)
45819798369SJed Brown        return state_pointer[0]
45919798369SJed Brown
4607def3d77Svaleriabarra# ------------------------------------------------------------------------------
4617a7b0fa3SJed Brown
4627a7b0fa3SJed Brown
4637def3d77Svaleriabarraclass _VectorWrap(Vector):
4647def3d77Svaleriabarra    """Wrap a CeedVector pointer in a Vector object."""
4657def3d77Svaleriabarra
4667def3d77Svaleriabarra    # Constructor
4677def3d77Svaleriabarra    def __init__(self, ceed, pointer):
4687def3d77Svaleriabarra        # CeedVector object
4697def3d77Svaleriabarra        self._pointer = pointer
4707def3d77Svaleriabarra
4717def3d77Svaleriabarra        # Reference to Ceed
4727def3d77Svaleriabarra        self._ceed = ceed
4737def3d77Svaleriabarra
4747def3d77Svaleriabarra# ------------------------------------------------------------------------------
475