1*3d8e8822SJeremy L Thompson# Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors 2*3d8e8822SJeremy L Thompson# All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 37def3d77Svaleriabarra# 4*3d8e8822SJeremy L Thompson# SPDX-License-Identifier: BSD-2-Clause 57def3d77Svaleriabarra# 6*3d8e8822SJeremy L Thompson# This file is part of CEED: http://github.com/ceed 77def3d77Svaleriabarra 87def3d77Svaleriabarrafrom _ceed_cffi import ffi, lib 97def3d77Svaleriabarraimport tempfile 107def3d77Svaleriabarraimport numpy as np 11e259ae81SJed Brownimport contextlib 1280a9ef05SNatalie Beamsfrom .ceed_constants import MEM_HOST, USE_POINTER, COPY_VALUES, NORM_2, scalar_types 137def3d77Svaleriabarra 147def3d77Svaleriabarra# ------------------------------------------------------------------------------ 157a7b0fa3SJed Brown 167a7b0fa3SJed Brown 177def3d77Svaleriabarraclass Vector(): 187def3d77Svaleriabarra """Ceed Vector: storing and manipulating vectors.""" 197def3d77Svaleriabarra 207def3d77Svaleriabarra # Constructor 217def3d77Svaleriabarra def __init__(self, ceed, size): 227def3d77Svaleriabarra # CeedVector object 237def3d77Svaleriabarra self._pointer = ffi.new("CeedVector *") 247def3d77Svaleriabarra 257def3d77Svaleriabarra # Reference to Ceed 267def3d77Svaleriabarra self._ceed = ceed 277def3d77Svaleriabarra 287def3d77Svaleriabarra # libCEED call 29477729cfSJeremy L Thompson err_code = lib.CeedVectorCreate( 30477729cfSJeremy L Thompson self._ceed._pointer[0], size, self._pointer) 31477729cfSJeremy L Thompson self._ceed._check_error(err_code) 327def3d77Svaleriabarra 337def3d77Svaleriabarra # Destructor 347def3d77Svaleriabarra def __del__(self): 357def3d77Svaleriabarra # libCEED call 36477729cfSJeremy L Thompson err_code = lib.CeedVectorDestroy(self._pointer) 37477729cfSJeremy L Thompson self._ceed._check_error(err_code) 387def3d77Svaleriabarra 397def3d77Svaleriabarra # Representation 407def3d77Svaleriabarra def __repr__(self): 417def3d77Svaleriabarra return "<CeedVector instance at " + hex(id(self)) + ">" 427def3d77Svaleriabarra 437def3d77Svaleriabarra # String conversion for print() to stdout 447def3d77Svaleriabarra def __str__(self): 457def3d77Svaleriabarra """View a Vector via print().""" 467def3d77Svaleriabarra 477def3d77Svaleriabarra # libCEED call 487def3d77Svaleriabarra fmt = ffi.new("char[]", "%f".encode('ascii')) 497def3d77Svaleriabarra with tempfile.NamedTemporaryFile() as key_file: 507def3d77Svaleriabarra with open(key_file.name, 'r+') as stream_file: 517def3d77Svaleriabarra stream = ffi.cast("FILE *", stream_file) 527def3d77Svaleriabarra 53477729cfSJeremy L Thompson err_code = lib.CeedVectorView(self._pointer[0], fmt, stream) 54477729cfSJeremy L Thompson self._ceed._check_error(err_code) 557def3d77Svaleriabarra 567def3d77Svaleriabarra stream_file.seek(0) 577def3d77Svaleriabarra out_string = stream_file.read() 587def3d77Svaleriabarra 597def3d77Svaleriabarra return out_string 607def3d77Svaleriabarra 617def3d77Svaleriabarra # Set Vector's data array 627def3d77Svaleriabarra def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES): 637def3d77Svaleriabarra """Set the array used by a Vector, freeing any previously allocated 647def3d77Svaleriabarra array if applicable. 657def3d77Svaleriabarra 667def3d77Svaleriabarra Args: 677f1dc7b9SJeremy L Thompson *array: Numpy or Numba array to be used 687def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 697def3d77Svaleriabarra **cmode: copy mode for the array, default CEED_COPY_VALUES""" 707def3d77Svaleriabarra 71187168c7SJeremy L Thompson # Store array reference if needed 72187168c7SJeremy L Thompson if cmode == USE_POINTER: 73187168c7SJeremy L Thompson self._array_reference = array 74187168c7SJeremy L Thompson else: 75187168c7SJeremy L Thompson self._array_reference = None 76187168c7SJeremy L Thompson 777def3d77Svaleriabarra # Setup the numpy array for the libCEED call 787def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar *") 797f1dc7b9SJeremy L Thompson if memtype == MEM_HOST: 807a7b0fa3SJed Brown array_pointer = ffi.cast( 817a7b0fa3SJed Brown "CeedScalar *", 827a7b0fa3SJed Brown array.__array_interface__['data'][0]) 837f1dc7b9SJeremy L Thompson else: 847f1dc7b9SJeremy L Thompson array_pointer = ffi.cast( 857f1dc7b9SJeremy L Thompson "CeedScalar *", 867f1dc7b9SJeremy L Thompson array.__cuda_array_interface__['data'][0]) 877def3d77Svaleriabarra 887def3d77Svaleriabarra # libCEED call 89477729cfSJeremy L Thompson err_code = lib.CeedVectorSetArray( 90477729cfSJeremy L Thompson self._pointer[0], memtype, cmode, array_pointer) 91477729cfSJeremy L Thompson self._ceed._check_error(err_code) 927def3d77Svaleriabarra 937def3d77Svaleriabarra # Get Vector's data array 947def3d77Svaleriabarra def get_array(self, memtype=MEM_HOST): 957def3d77Svaleriabarra """Get read/write access to a Vector via the specified memory type. 967def3d77Svaleriabarra 977def3d77Svaleriabarra Args: 987def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 997def3d77Svaleriabarra 1007def3d77Svaleriabarra Returns: 1017f1dc7b9SJeremy L Thompson *array: Numpy or Numba array""" 1027def3d77Svaleriabarra 1037def3d77Svaleriabarra # Retrieve the length of the array 1041f9221feSJeremy L Thompson length_pointer = ffi.new("CeedSize *") 105477729cfSJeremy L Thompson err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) 106477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1077def3d77Svaleriabarra 1087def3d77Svaleriabarra # Setup the pointer's pointer 1097def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 1107def3d77Svaleriabarra 1117def3d77Svaleriabarra # libCEED call 112477729cfSJeremy L Thompson err_code = lib.CeedVectorGetArray( 113477729cfSJeremy L Thompson self._pointer[0], memtype, array_pointer) 114477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1157def3d77Svaleriabarra 1167f1dc7b9SJeremy L Thompson # Return array created from buffer 1177f1dc7b9SJeremy L Thompson if memtype == MEM_HOST: 1187def3d77Svaleriabarra # Create buffer object from returned pointer 1197a7b0fa3SJed Brown buff = ffi.buffer( 1207a7b0fa3SJed Brown array_pointer[0], 1217a7b0fa3SJed Brown ffi.sizeof("CeedScalar") * 1227a7b0fa3SJed Brown length_pointer[0]) 1237f1dc7b9SJeremy L Thompson # return Numpy array 12480a9ef05SNatalie Beams return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) 1257f1dc7b9SJeremy L Thompson else: 1267f1dc7b9SJeremy L Thompson # CUDA array interface 1277f1dc7b9SJeremy L Thompson # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html 128962dc42dSJeremy L Thompson import numba.cuda as nbcuda 1297f1dc7b9SJeremy L Thompson desc = { 1307f1dc7b9SJeremy L Thompson 'shape': (length_pointer[0]), 1317f1dc7b9SJeremy L Thompson 'typestr': '>f8', 1327f1dc7b9SJeremy L Thompson 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 1337f1dc7b9SJeremy L Thompson 'version': 2 1347f1dc7b9SJeremy L Thompson } 1357f1dc7b9SJeremy L Thompson # return Numba array 1367f1dc7b9SJeremy L Thompson return nbcuda.from_cuda_array_interface(desc) 1377def3d77Svaleriabarra 1387def3d77Svaleriabarra # Get Vector's data array in read-only mode 1397def3d77Svaleriabarra def get_array_read(self, memtype=MEM_HOST): 1407def3d77Svaleriabarra """Get read-only access to a Vector via the specified memory type. 1417def3d77Svaleriabarra 1427def3d77Svaleriabarra Args: 1437def3d77Svaleriabarra **memtype: memory type of the array being passed, default CEED_MEM_HOST 1447def3d77Svaleriabarra 1457def3d77Svaleriabarra Returns: 1467f1dc7b9SJeremy L Thompson *array: Numpy or Numba array""" 1477def3d77Svaleriabarra 1487def3d77Svaleriabarra # Retrieve the length of the array 1491f9221feSJeremy L Thompson length_pointer = ffi.new("CeedSize *") 150477729cfSJeremy L Thompson err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) 151477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1527def3d77Svaleriabarra 1537def3d77Svaleriabarra # Setup the pointer's pointer 1547def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 1557def3d77Svaleriabarra 1567def3d77Svaleriabarra # libCEED call 157477729cfSJeremy L Thompson err_code = lib.CeedVectorGetArrayRead( 158477729cfSJeremy L Thompson self._pointer[0], memtype, array_pointer) 159477729cfSJeremy L Thompson self._ceed._check_error(err_code) 1607def3d77Svaleriabarra 1617f1dc7b9SJeremy L Thompson # Return array created from buffer 1627f1dc7b9SJeremy L Thompson if memtype == MEM_HOST: 1637def3d77Svaleriabarra # Create buffer object from returned pointer 1647a7b0fa3SJed Brown buff = ffi.buffer( 1657a7b0fa3SJed Brown array_pointer[0], 1667a7b0fa3SJed Brown ffi.sizeof("CeedScalar") * 1677a7b0fa3SJed Brown length_pointer[0]) 1687f1dc7b9SJeremy L Thompson # return read only Numpy array 16980a9ef05SNatalie Beams ret = np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) 1707def3d77Svaleriabarra ret.flags['WRITEABLE'] = False 1717def3d77Svaleriabarra return ret 1727f1dc7b9SJeremy L Thompson else: 1737f1dc7b9SJeremy L Thompson # CUDA array interface 1747f1dc7b9SJeremy L Thompson # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html 175962dc42dSJeremy L Thompson import numba.cuda as nbcuda 1767f1dc7b9SJeremy L Thompson desc = { 1777f1dc7b9SJeremy L Thompson 'shape': (length_pointer[0]), 1787f1dc7b9SJeremy L Thompson 'typestr': '>f8', 1797f1dc7b9SJeremy L Thompson 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 1807f1dc7b9SJeremy L Thompson 'version': 2 1817f1dc7b9SJeremy L Thompson } 1827f1dc7b9SJeremy L Thompson # return read only Numba array 1837f1dc7b9SJeremy L Thompson return nbcuda.from_cuda_array_interface(desc) 1847def3d77Svaleriabarra 1859c774eddSJeremy L Thompson # Get Vector's data array in write-only mode 1869c774eddSJeremy L Thompson def get_array_write(self, memtype=MEM_HOST): 1879c774eddSJeremy L Thompson """Get write-only access to a Vector via the specified memory type. 1889c774eddSJeremy L Thompson All old values should be considered invalid. 1899c774eddSJeremy L Thompson 1909c774eddSJeremy L Thompson Args: 1919c774eddSJeremy L Thompson **memtype: memory type of the array being passed, default CEED_MEM_HOST 1929c774eddSJeremy L Thompson 1939c774eddSJeremy L Thompson Returns: 1949c774eddSJeremy L Thompson *array: Numpy or Numba array""" 1959c774eddSJeremy L Thompson 1969c774eddSJeremy L Thompson # Retrieve the length of the array 1971f9221feSJeremy L Thompson length_pointer = ffi.new("CeedSize *") 1989c774eddSJeremy L Thompson err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) 1999c774eddSJeremy L Thompson self._ceed._check_error(err_code) 2009c774eddSJeremy L Thompson 2019c774eddSJeremy L Thompson # Setup the pointer's pointer 2029c774eddSJeremy L Thompson array_pointer = ffi.new("CeedScalar **") 2039c774eddSJeremy L Thompson 2049c774eddSJeremy L Thompson # libCEED call 2059c774eddSJeremy L Thompson err_code = lib.CeedVectorGetArrayWrite( 2069c774eddSJeremy L Thompson self._pointer[0], memtype, array_pointer) 2079c774eddSJeremy L Thompson self._ceed._check_error(err_code) 2089c774eddSJeremy L Thompson 2099c774eddSJeremy L Thompson # Return array created from buffer 2109c774eddSJeremy L Thompson if memtype == MEM_HOST: 2119c774eddSJeremy L Thompson # Create buffer object from returned pointer 2129c774eddSJeremy L Thompson buff = ffi.buffer( 2139c774eddSJeremy L Thompson array_pointer[0], 2149c774eddSJeremy L Thompson ffi.sizeof("CeedScalar") * 2159c774eddSJeremy L Thompson length_pointer[0]) 2169c774eddSJeremy L Thompson # return Numpy array 2179c774eddSJeremy L Thompson return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) 2189c774eddSJeremy L Thompson else: 2199c774eddSJeremy L Thompson # CUDA array interface 2209c774eddSJeremy L Thompson # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html 2219c774eddSJeremy L Thompson import numba.cuda as nbcuda 2229c774eddSJeremy L Thompson desc = { 2239c774eddSJeremy L Thompson 'shape': (length_pointer[0]), 2249c774eddSJeremy L Thompson 'typestr': '>f8', 2259c774eddSJeremy L Thompson 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 2269c774eddSJeremy L Thompson 'version': 2 2279c774eddSJeremy L Thompson } 2289c774eddSJeremy L Thompson # return Numba array 2299c774eddSJeremy L Thompson return nbcuda.from_cuda_array_interface(desc) 2309c774eddSJeremy L Thompson 2317def3d77Svaleriabarra # Restore the Vector's data array 2327def3d77Svaleriabarra def restore_array(self): 2337def3d77Svaleriabarra """Restore an array obtained using get_array().""" 2347def3d77Svaleriabarra 2357def3d77Svaleriabarra # Setup the pointer's pointer 2367def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 2377def3d77Svaleriabarra 2387def3d77Svaleriabarra # libCEED call 239477729cfSJeremy L Thompson err_code = lib.CeedVectorRestoreArray(self._pointer[0], array_pointer) 240477729cfSJeremy L Thompson self._ceed._check_error(err_code) 2417def3d77Svaleriabarra 2427def3d77Svaleriabarra # Restore an array obtained using getArrayRead 2437def3d77Svaleriabarra def restore_array_read(self): 2447def3d77Svaleriabarra """Restore an array obtained using get_array_read().""" 2457def3d77Svaleriabarra 2467def3d77Svaleriabarra # Setup the pointer's pointer 2477def3d77Svaleriabarra array_pointer = ffi.new("CeedScalar **") 2487def3d77Svaleriabarra 2497def3d77Svaleriabarra # libCEED call 250477729cfSJeremy L Thompson err_code = lib.CeedVectorRestoreArrayRead( 251477729cfSJeremy L Thompson self._pointer[0], array_pointer) 252477729cfSJeremy L Thompson self._ceed._check_error(err_code) 2537def3d77Svaleriabarra 254e259ae81SJed Brown @contextlib.contextmanager 2557f1dc7b9SJeremy L Thompson def array(self, *shape, memtype=MEM_HOST): 256e259ae81SJed Brown """Context manager for array access. 257e259ae81SJed Brown 258e259ae81SJed Brown Args: 259e259ae81SJed Brown shape (tuple): shape of returned numpy.array 2607f1dc7b9SJeremy L Thompson **memtype: memory type of the array being passed, default CEED_MEM_HOST 2617f1dc7b9SJeremy L Thompson 262e259ae81SJed Brown 263e259ae81SJed Brown Returns: 264e259ae81SJed Brown np.array: writable view of vector 265e259ae81SJed Brown 266e259ae81SJed Brown Examples: 267e259ae81SJed Brown Constructing the identity inside a libceed.Vector: 268e259ae81SJed Brown 269e259ae81SJed Brown >>> vec = ceed.Vector(16) 270e259ae81SJed Brown >>> with vec.array(4, 4) as x: 271e259ae81SJed Brown >>> x[...] = np.eye(4) 272e259ae81SJed Brown """ 2737f1dc7b9SJeremy L Thompson x = self.get_array(memtype=memtype) 274e259ae81SJed Brown if shape: 275e259ae81SJed Brown x = x.reshape(shape) 276e259ae81SJed Brown yield x 277e259ae81SJed Brown self.restore_array() 278e259ae81SJed Brown 279e259ae81SJed Brown @contextlib.contextmanager 2807f1dc7b9SJeremy L Thompson def array_read(self, *shape, memtype=MEM_HOST): 281e259ae81SJed Brown """Context manager for read-only array access. 282e259ae81SJed Brown 283e259ae81SJed Brown Args: 284e259ae81SJed Brown shape (tuple): shape of returned numpy.array 2857f1dc7b9SJeremy L Thompson **memtype: memory type of the array being passed, default CEED_MEM_HOST 286e259ae81SJed Brown 287e259ae81SJed Brown Returns: 288e259ae81SJed Brown np.array: read-only view of vector 289e259ae81SJed Brown 290e259ae81SJed Brown Examples: 291187168c7SJeremy L Thompson Viewing contents of a reshaped libceed.Vector view: 292e259ae81SJed Brown 293e259ae81SJed Brown >>> vec = ceed.Vector(6) 294e259ae81SJed Brown >>> vec.set_value(1.3) 295e259ae81SJed Brown >>> with vec.array_read(2, 3) as x: 296e259ae81SJed Brown >>> print(x) 297e259ae81SJed Brown """ 2987f1dc7b9SJeremy L Thompson x = self.get_array_read(memtype=memtype) 299e259ae81SJed Brown if shape: 300e259ae81SJed Brown x = x.reshape(shape) 301e259ae81SJed Brown yield x 302e259ae81SJed Brown self.restore_array_read() 303e259ae81SJed Brown 3049c774eddSJeremy L Thompson @contextlib.contextmanager 3059c774eddSJeremy L Thompson def array_write(self, *shape, memtype=MEM_HOST): 3069c774eddSJeremy L Thompson """Context manager for write-only array access. 3079c774eddSJeremy L Thompson All old values should be considered invalid. 3089c774eddSJeremy L Thompson 3099c774eddSJeremy L Thompson Args: 3109c774eddSJeremy L Thompson shape (tuple): shape of returned numpy.array 3119c774eddSJeremy L Thompson **memtype: memory type of the array being passed, default CEED_MEM_HOST 3129c774eddSJeremy L Thompson 3139c774eddSJeremy L Thompson Returns: 3149c774eddSJeremy L Thompson np.array: write-only view of vector 3159c774eddSJeremy L Thompson 3169c774eddSJeremy L Thompson Examples: 3179c774eddSJeremy L Thompson Viewing contents of a reshaped libceed.Vector view: 3189c774eddSJeremy L Thompson 3199c774eddSJeremy L Thompson >>> vec = ceed.Vector(6) 3209c774eddSJeremy L Thompson >>> vec.set_value(1.3) 3219c774eddSJeremy L Thompson >>> with vec.array_read(2, 3) as x: 3229c774eddSJeremy L Thompson >>> print(x) 3239c774eddSJeremy L Thompson """ 3249c774eddSJeremy L Thompson x = self.get_array_write(memtype=memtype) 3259c774eddSJeremy L Thompson if shape: 3269c774eddSJeremy L Thompson x = x.reshape(shape) 3279c774eddSJeremy L Thompson yield x 3289c774eddSJeremy L Thompson self.restore_array() 3299c774eddSJeremy L Thompson 3307def3d77Svaleriabarra # Get the length of a Vector 3317def3d77Svaleriabarra def get_length(self): 3327def3d77Svaleriabarra """Get the length of a Vector. 3337def3d77Svaleriabarra 3347def3d77Svaleriabarra Returns: 3357def3d77Svaleriabarra length: length of the Vector""" 3367def3d77Svaleriabarra 3371f9221feSJeremy L Thompson length_pointer = ffi.new("CeedSize *") 3387def3d77Svaleriabarra 3397def3d77Svaleriabarra # libCEED call 340477729cfSJeremy L Thompson err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) 341477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3427def3d77Svaleriabarra 3437def3d77Svaleriabarra return length_pointer[0] 3447def3d77Svaleriabarra 3457def3d77Svaleriabarra # Get the length of a Vector 3467def3d77Svaleriabarra def __len__(self): 3477def3d77Svaleriabarra """Get the length of a Vector. 3487def3d77Svaleriabarra 3497def3d77Svaleriabarra Returns: 3507def3d77Svaleriabarra length: length of the Vector""" 3517def3d77Svaleriabarra 3521f9221feSJeremy L Thompson length_pointer = ffi.new("CeedSize *") 3537def3d77Svaleriabarra 3547def3d77Svaleriabarra # libCEED call 355477729cfSJeremy L Thompson err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) 356477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3577def3d77Svaleriabarra 3587def3d77Svaleriabarra return length_pointer[0] 3597def3d77Svaleriabarra 3607def3d77Svaleriabarra # Set the Vector to a given constant value 3617def3d77Svaleriabarra def set_value(self, value): 3627def3d77Svaleriabarra """Set the Vector to a constant value. 3637def3d77Svaleriabarra 3647def3d77Svaleriabarra Args: 3657def3d77Svaleriabarra value: value to be used""" 3667def3d77Svaleriabarra 3677def3d77Svaleriabarra # libCEED call 368477729cfSJeremy L Thompson err_code = lib.CeedVectorSetValue(self._pointer[0], value) 369477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3707def3d77Svaleriabarra 3717def3d77Svaleriabarra # Sync the Vector to a specified memtype 372547d9b97Sjeremylt def sync_array(self, memtype=MEM_HOST): 3737def3d77Svaleriabarra """Sync the Vector to a specified memtype. 3747def3d77Svaleriabarra 3757def3d77Svaleriabarra Args: 3767def3d77Svaleriabarra **memtype: memtype to be synced""" 3777def3d77Svaleriabarra 3787def3d77Svaleriabarra # libCEED call 379477729cfSJeremy L Thompson err_code = lib.CeedVectorSyncArray(self._pointer[0], memtype) 380477729cfSJeremy L Thompson self._ceed._check_error(err_code) 3817def3d77Svaleriabarra 382547d9b97Sjeremylt # Compute the norm of a vector 383547d9b97Sjeremylt def norm(self, normtype=NORM_2): 384547d9b97Sjeremylt """Get the norm of a Vector. 385547d9b97Sjeremylt 386547d9b97Sjeremylt Args: 387547d9b97Sjeremylt **normtype: type of norm to be computed""" 388547d9b97Sjeremylt 389547d9b97Sjeremylt norm_pointer = ffi.new("CeedScalar *") 390547d9b97Sjeremylt 391547d9b97Sjeremylt # libCEED call 392477729cfSJeremy L Thompson err_code = lib.CeedVectorNorm(self._pointer[0], normtype, norm_pointer) 393477729cfSJeremy L Thompson self._ceed._check_error(err_code) 394547d9b97Sjeremylt 395547d9b97Sjeremylt return norm_pointer[0] 396547d9b97Sjeremylt 397d99fa3c5SJeremy L Thompson # Take the reciprocal of a vector 398d99fa3c5SJeremy L Thompson def reciprocal(self): 399d99fa3c5SJeremy L Thompson """Take the reciprocal of a Vector.""" 400d99fa3c5SJeremy L Thompson 401d99fa3c5SJeremy L Thompson # libCEED call 402d99fa3c5SJeremy L Thompson err_code = lib.CeedVectorReciprocal(self._pointer[0]) 403d99fa3c5SJeremy L Thompson self._ceed._check_error(err_code) 404d99fa3c5SJeremy L Thompson 405d99fa3c5SJeremy L Thompson return self 406d99fa3c5SJeremy L Thompson 407e0dd3b27Sjeremylt # Compute self = alpha self 408e0dd3b27Sjeremylt def scale(self, alpha): 409e0dd3b27Sjeremylt """Compute self = alpha self.""" 410e0dd3b27Sjeremylt 411e0dd3b27Sjeremylt # libCEED call 412e0dd3b27Sjeremylt err_code = lib.CeedVectorScale(self._pointer[0], alpha) 413e0dd3b27Sjeremylt self._ceed._check_error(err_code) 414e0dd3b27Sjeremylt 415e0dd3b27Sjeremylt return self 416e0dd3b27Sjeremylt 4170c1bc3c2Sjeremylt # Compute self = alpha x + self 4180c1bc3c2Sjeremylt def axpy(self, alpha, x): 4190c1bc3c2Sjeremylt """Compute self = alpha x + self.""" 4200c1bc3c2Sjeremylt 4210c1bc3c2Sjeremylt # libCEED call 4220c1bc3c2Sjeremylt err_code = lib.CeedVectorAXPY(self._pointer[0], alpha, x._pointer[0]) 4230c1bc3c2Sjeremylt self._ceed._check_error(err_code) 4240c1bc3c2Sjeremylt 4250c1bc3c2Sjeremylt return self 4260c1bc3c2Sjeremylt 4270c1bc3c2Sjeremylt # Compute the pointwise multiplication self = x .* y 4280c1bc3c2Sjeremylt def pointwise_mult(self, x, y): 4290c1bc3c2Sjeremylt """Compute the pointwise multiplication self = x .* y.""" 4300c1bc3c2Sjeremylt 4310c1bc3c2Sjeremylt # libCEED call 4320c1bc3c2Sjeremylt err_code = lib.CeedVectorPointwiseMult( 4330c1bc3c2Sjeremylt self._pointer[0], x._pointer[0], y._pointer[0] 4340c1bc3c2Sjeremylt ) 4350c1bc3c2Sjeremylt self._ceed._check_error(err_code) 4360c1bc3c2Sjeremylt 4370c1bc3c2Sjeremylt return self 4380c1bc3c2Sjeremylt 43919798369SJed Brown def _state(self): 44019798369SJed Brown """Return the modification state of the Vector. 44119798369SJed Brown 44219798369SJed Brown State is incremented each time the Vector is mutated, and is odd whenever a 44319798369SJed Brown mutable reference has not been returned. 44419798369SJed Brown """ 44519798369SJed Brown 44619798369SJed Brown state_pointer = ffi.new("uint64_t *") 44719798369SJed Brown err_code = lib.CeedVectorGetState(self._pointer[0], state_pointer) 44819798369SJed Brown self._ceed._check_error(err_code) 44919798369SJed Brown return state_pointer[0] 45019798369SJed Brown 4517def3d77Svaleriabarra# ------------------------------------------------------------------------------ 4527a7b0fa3SJed Brown 4537a7b0fa3SJed Brown 4547def3d77Svaleriabarraclass _VectorWrap(Vector): 4557def3d77Svaleriabarra """Wrap a CeedVector pointer in a Vector object.""" 4567def3d77Svaleriabarra 4577def3d77Svaleriabarra # Constructor 4587def3d77Svaleriabarra def __init__(self, ceed, pointer): 4597def3d77Svaleriabarra # CeedVector object 4607def3d77Svaleriabarra self._pointer = pointer 4617def3d77Svaleriabarra 4627def3d77Svaleriabarra # Reference to Ceed 4637def3d77Svaleriabarra self._ceed = ceed 4647def3d77Svaleriabarra 4657def3d77Svaleriabarra# ------------------------------------------------------------------------------ 466