Пример #1
0
    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]
Пример #2
0
    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)
Пример #3
0
    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
Пример #4
0
    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))
Пример #5
0
    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
Пример #6
0
    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
Пример #7
0
    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)
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
    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
Пример #13
0
    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)
Пример #14
0
    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)
Пример #15
0
    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)
Пример #16
0
    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
Пример #17
0
    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)