def multigrid_create_h1(self, p_mult_fine, rstr_coarse, basis_coarse, interp_C_to_F): """ Create a multigrid coarse operator and level transfer operators for a CeedOperator with a Lagrange tensor basis for the active basis Args: p_mult_fine: L-vector multiplicity in parallel gather/scatter rstr_coarse: Coarse grid restriction basis_coarse: Coarse grid active vector basis interp_C_to_F: Matrix for coarse to fine interpolation""" # Setup arguments interpCtoF_pointer = ffi.new("CeedScalar *") interpCtoF_pointer = ffi.cast( "CeedScalar *", interp_C_to_F.__array_interface__['data'][0]) # Operator pointers opCoarsePointer = ffi.new("CeedOperator *") opProlongPointer = ffi.new("CeedOperator *") opRestrictPointer = ffi.new("CeedOperator *") # libCEED call lib.CeedOperatorMultigridLevelCreateH1( self._pointer[0], p_mult_fine._pointer[0], rstr_coarse._pointer[0], basis_coarse._pointer[0], interpCtoF_pointer, opCoarsePointer, opProlongPointer, opRestrictPointer) # Wrap operators opCoarse = _OperatorWrap(self._ceed, opCoarsePointer) opProlong = _OperatorWrap(self._ceed, opProlongPointer) opRestrict = _OperatorWrap(self._ceed, opRestrictPointer) # Return return [opCoarse, opProlong, opRestrict]
def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets, memtype=MEM_HOST, cmode=COPY_VALUES): # CeedVector object self._pointer = ffi.new("CeedElemRestriction *") # Reference to Ceed self._ceed = ceed # Store array reference if needed if cmode == USE_POINTER: self._array_reference = offsets else: self._array_reference = None # Setup the numpy array for the libCEED call offsets_pointer = ffi.new("const CeedInt *") offsets_pointer = ffi.cast("const CeedInt *", offsets.__array_interface__['data'][0]) # libCEED call err_code = lib.CeedElemRestrictionCreate(self._ceed._pointer[0], nelem, elemsize, ncomp, compstride, lsize, memtype, cmode, offsets_pointer, self._pointer) self._ceed._check_error(err_code)
def simultaneous_diagonalization(self, matA, matB, n): """Return Simultaneous Diagonalization of two matrices. Args: ceed: Ceed context currently in use *matA: Numpy array holding the row-major matrix to be factorized with eigenvalues *matB: Numpy array holding the row-major matrix to be factorized to identity n: number of rows/columns Returns: (x, lbda): Numpy array holding the row-major orthogonal matrix and Numpy array holding the vector of length n of generalized eigenvalues""" # Setup arguments matA_pointer = ffi.new("CeedScalar *") matA_pointer = ffi.cast( "CeedScalar *", matA.__array_interface__['data'][0]) matB_pointer = ffi.new("CeedScalar *") matB_pointer = ffi.cast( "CeedScalar *", matB.__array_interface__['data'][0]) lbda = np.empty(n, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) l_pointer = ffi.new("CeedScalar *") l_pointer = ffi.cast( "CeedScalar *", lbda.__array_interface__['data'][0]) x = np.empty(n * n, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) x_pointer = ffi.new("CeedScalar *") x_pointer = ffi.cast("CeedScalar *", x.__array_interface__['data'][0]) # libCEED call err_code = lib.CeedSimultaneousDiagonalization(self._pointer[0], matA_pointer, matB_pointer, x_pointer, l_pointer, n) self._check_error(err_code) return x, lbda
def set_context(self, ctx): """Set global context for a QFunction. Args: *ctx: Numpy array holding context data to set""" # Setup the numpy array for the libCEED call ctx_pointer = ffi.new("CeedScalar *") ctx_pointer = ffi.cast("void *", ctx.__array_interface__['data'][0]) # libCEED call lib.CeedQFunctionSetContext(self._pointer[0], ctx_pointer, len(ctx))
def __str__(self): """View an ElemRestriction via print().""" # libCEED call with tempfile.NamedTemporaryFile() as key_file: with open(key_file.name, 'r+') as stream_file: stream = ffi.cast("FILE *", stream_file) lib.CeedElemRestrictionView(self._pointer[0], stream) stream_file.seek(0) out_string = stream_file.read() return out_string
def qr_factorization(ceed, mat, tau, m, n): """Return QR Factorization of a matrix. Args: ceed: Ceed context currently in use *mat: Numpy array holding the row-major matrix to be factorized in place *tau: Numpy array to hold the vector of lengt m of scaling factors m: number of rows n: numbef of columns""" # Setup arguments mat_pointer = ffi.new("CeedScalar *") mat_pointer = ffi.cast("CeedScalar *", mat.__array_interface__['data'][0]) tau_pointer = ffi.new("CeedScalar *") tau_pointer = ffi.cast("CeedScalar *", tau.__array_interface__['data'][0]) # libCEED call lib.CeedQRFactorization(ceed._pointer[0], mat_pointer, tau_pointer, m, n) return mat, tau
def __init__(self, ceed, vlength, f, source): # libCEED object self._pointer = ffi.new("CeedQFunction *") # Reference to Ceed self._ceed = ceed # Function pointer fpointer = ffi.cast("CeedQFunctionUser", ctypes.cast(f, ctypes.c_void_p).value) # libCEED call sourceAscii = ffi.new("char[]", source.encode('ascii')) lib.CeedQFunctionCreateInterior(self._ceed._pointer[0], vlength, fpointer, sourceAscii, self._pointer)
def __str__(self): """View a Basis via print().""" # libCEED call with tempfile.NamedTemporaryFile() as key_file: with open(key_file.name, 'r+') as stream_file: stream = ffi.cast("FILE *", stream_file) err_code = lib.CeedBasisView(self._pointer[0], stream) self._ceed._check_error(err_code) stream_file.seek(0) out_string = stream_file.read() return out_string
def __str__(self): """View a Vector via print().""" # libCEED call fmt = ffi.new("char[]", "%f".encode('ascii')) with tempfile.NamedTemporaryFile() as key_file: with open(key_file.name, 'r+') as stream_file: stream = ffi.cast("FILE *", stream_file) lib.CeedVectorView(self._pointer[0], fmt, stream) stream_file.seek(0) out_string = stream_file.read() return out_string
def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES): """Set the array used by a Vector, freeing any previously allocated array if applicable. Args: *array: Numpy array to be used **memtype: memory type of the array being passed, default CEED_MEM_HOST **cmode: copy mode for the array, default CEED_COPY_VALUES""" # Setup the numpy array for the libCEED call array_pointer = ffi.new("CeedScalar *") array_pointer = ffi.cast("CeedScalar *", array.__array_interface__['data'][0]) # libCEED call lib.CeedVectorSetArray(self._pointer[0], memtype, cmode, array_pointer)
def get_data(self, memtype=MEM_HOST): """Get read/write access to a QFunction Context via the specified memory type. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *data: Numpy or Numba array""" # Retrieve the length of the array size_pointer = ffi.new("size_t *") err_code = lib.CeedQFunctionContextGetContextSize( self._pointer[0], size_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer data_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedQFunctionContextGetData(self._pointer[0], memtype, data_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(data_pointer[0], size_pointer[0]) # return Numpy array return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda if lib.CEED_SCALAR_TYPE == lib.CEED_SCALAR_FP32: scalar_type_str = '>f4' else: scalar_type_str = '>f8' desc = { 'shape': (size_pointer[0] / ffi.sizeof("CeedScalar")), 'typestr': scalar_type_str, 'data': (int(ffi.cast("intptr_t", data_pointer[0])), False), 'version': 2 } # return Numba array return nbcuda.from_cuda_array_interface(desc)
def __str__(self): """View a QFunction Context via print().""" # libCEED call fmt = ffi.new("char[]", "%f".encode('ascii')) with tempfile.NamedTemporaryFile() as key_file: with open(key_file.name, 'r+') as stream_file: stream = ffi.cast("FILE *", stream_file) err_code = lib.CeedQFunctionContextView( self._pointer[0], stream) self._ceed._check_error(err_code) stream_file.seek(0) out_string = stream_file.read() return out_string
def __init__(self, ceed, nelem, elemsize, blksize, ncomp, lsize, strides): # CeedVector object self._pointer = ffi.new("CeedElemRestriction *") # Reference to Ceed self._ceed = ceed # Setup the numpy array for the libCEED call strides_pointer = ffi.new("const CeedInt *") strides_pointer = ffi.cast("const CeedInt *", strides.__array_interface__['data'][0]) # libCEED call err_code = lib.CeedElemRestrictionCreateBlockedStrided( self._ceed._pointer[0], nelem, elemsize, blksize, ncomp, lsize, strides_pointer, self._pointer) self._ceed._check_error(err_code)
def get_array_write(self, memtype=MEM_HOST): """Get write-only access to a Vector via the specified memory type. All old values should be considered invalid. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *array: Numpy or Numba array""" # Retrieve the length of the array length_pointer = ffi.new("CeedSize *") err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer array_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedVectorGetArrayWrite(self._pointer[0], memtype, array_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) # return Numpy array return np.frombuffer(buff, dtype=scalar_types[lib.CEED_SCALAR_TYPE]) else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda desc = { 'shape': (length_pointer[0]), 'typestr': '>f8', 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 'version': 2 } # return Numba array return nbcuda.from_cuda_array_interface(desc)
def get_array_read(self, memtype=MEM_HOST): """Get read-only access to a Vector via the specified memory type. Args: **memtype: memory type of the array being passed, default CEED_MEM_HOST Returns: *array: Numpy or Numba array""" # Retrieve the length of the array length_pointer = ffi.new("CeedInt *") err_code = lib.CeedVectorGetLength(self._pointer[0], length_pointer) self._ceed._check_error(err_code) # Setup the pointer's pointer array_pointer = ffi.new("CeedScalar **") # libCEED call err_code = lib.CeedVectorGetArrayRead(self._pointer[0], memtype, array_pointer) self._ceed._check_error(err_code) # Return array created from buffer if memtype == MEM_HOST: # Create buffer object from returned pointer buff = ffi.buffer(array_pointer[0], ffi.sizeof("CeedScalar") * length_pointer[0]) # return read only Numpy array ret = np.frombuffer(buff, dtype="float64") ret.flags['WRITEABLE'] = False return ret else: # CUDA array interface # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html import numba.cuda as nbcuda desc = { 'shape': (length_pointer[0]), 'typestr': '>f8', 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False), 'version': 2 } # return read only Numba array return nbcuda.from_cuda_array_interface(desc)
def get_layout(self): """Get the element vector layout of an ElemRestriction. Returns: layout: Vector containing layout array, stored as [nodes, components, elements]. The data for node i, component j, element k in the element vector is given by i*layout[0] + j*layout[1] + k*layout[2].""" # Create output array layout = np.zeros(3, dtype="int32") array_pointer = ffi.cast("CeedInt *", layout.__array_interface__['data'][0]) # libCEED call err_code = lib.CeedElemRestrictionGetELayout(self._pointer[0], array_pointer) self._ceed._check_error(err_code) # Return return layout
def __init__(self, ceed, nelem, elemsize, nnodes, ncomp, indices, memtype=MEM_HOST, cmode=COPY_VALUES): # CeedVector object self._pointer = ffi.new("CeedElemRestriction *") # Reference to Ceed self._ceed = ceed # Setup the numpy array for the libCEED call indices_pointer = ffi.new("const CeedInt *") indices_pointer = ffi.cast("const CeedInt *", indices.__array_interface__['data'][0]) # libCEED call lib.CeedElemRestrictionCreate(self._ceed._pointer[0], nelem, elemsize, nnodes, ncomp, memtype, cmode, indices_pointer, self._pointer)