Esempio n. 1
0
    def createLaplacianMat(self):
        '''create a PETSc.Mat() for discrete Laplacian.
        TODO: more than dim 3; more than second order; different dx,dy,dz'''
        dim = self.Dim

        dx = (self.hGrid,)*dim
        ll = np.array(self.ll) + self.hGrid/2
        pt = self.getCoordinates()
        # find the sub index of itself 
        subItself = findGridInterpBasePt(pt,dx,ll,0)

        if dim == 2:
            offsets = np.array([[0,0,1,0,-1],
                                [0,1,0,-1,0]])
            weight = np.array([-4.,1.,1.,1.,1.]) / self.hGrid**2
        elif dim == 3:
            offsets = np.array([[0,0,0,1,0,0,-1],
                                [0,0,1,0,0,-1,0],
                                [0,1,0,0,-1,0,0]]) 
            weight = np.array([-6.,1.,1.,1.,1.,1.,1.]) / self.hGrid**2

        sub = ( subItself[...,np.newaxis] + offsets[np.newaxis,...] ).transpose((1,0,2))
        # Convert sub indices to global PETSc indices
        ind = self.subToPetscInd(sub)

        weights = np.tile(weight,(ind.shape[0],1)) 

        L = self.createMat((self.gvec.sizes,self.gvec.sizes),ind,weights,(2*dim+1,dim))
        
        return L
Esempio n. 2
0
def build_interp_matrix(int_band, cp, dx, p, ll, shape):
    dim = len(shape)
    offsets = np.mgrid[tuple(slice(p + 1) for _ in xrange(dim))].reshape((dim, -1))
    Ei = np.tile(np.arange(cp.shape[0])[:, np.newaxis], (p + 1) ** dim)
    Ej = np.zeros_like(Ei)
    Es = np.zeros_like(Ei, dtype=np.float)

    base_points = findGridInterpBasePt(cp, dx, ll, p)
    weights = buildInterpWeights(base_points * dx + ll, cp, dx, p + 1)
    Ej = np.ravel_multi_index(
        (base_points[..., np.newaxis] + offsets[np.newaxis, ...]).transpose((0, 2, 1)).reshape((-1, dim)).T, shape
    )
    Es = weights
    E = coo_matrix((Es.ravel(), (Ei.ravel(), Ej.ravel())), (cp.shape[0], reduce(mul, shape))).tocsr()
    return E[:, np.ravel_multi_index(int_band.T, shape)]
Esempio n. 3
0
    def findIndForIntpl(self,cp):
        '''find the indices of interpolation points'''
        dim = self.Dim
        dx = (self.hGrid,)*dim
        p = self.interpDegree
        M = self.M
        m = self.m
        ll = np.array(self.ll) + self.hGrid/2;
        #find base point first
        subBasept = findGridInterpBasePt(cp, dx, ll, p)
        offsets = np.mgrid[(slice(p+1),)*dim].reshape((dim, -1))
#        x = np.arange((p+1)**dim)
#        offsets = np.column_stack(np.unravel_index(x,(p+1,)*dim,order='F')).T
        sub = ( subBasept[...,np.newaxis] + offsets[np.newaxis,...] ).transpose((1,0,2))
        ind = self.subToPetscInd(sub)

        basept = subBasept*dx + ll
        return basept,ind
Esempio n. 4
0
    def createExtensionMat(self, p = None, cp = None):
        '''create a PETSc.Mat() for the closest point extension'''

        if p is None: p = self.interpDegree

        if cp is None:
            wvecsizes = self.wvec.sizes
            cp = self.cp
        else:
            wvecsizes = (cp.shape[0],PETSc.DECIDE)
        gvec = self.gvec

        dim = self.Dim
        dx = (self.hGrid,)*dim
        M = self.M
        m = self.m
        # The lower left grid point 'll' is at the center of the lower left element 'self.ll'
        ll = np.array(self.ll) + self.hGrid/2;

        # find the sub-indices of the base points, 'subBasept' is a N*dim array (N:number of base-points).
        subBasept = findGridInterpBasePt(cp, dx, ll, p)
        # offsets is the sub-indices of the interpolation stencil, a dim*STENCIL array (STENCIL=(p+1)^dim).
        # If in 'C' order, should be the following line: 
        offsets = np.mgrid[(slice(p+1),)*dim].reshape((dim, -1))
        # or equivalently the following two lines:
#        x = np.arange((p+1)**dim)
#        offsets = np.column_stack(np.unravel_index(x,(p+1,)*dim,order='C')).T
        #If in the structure branch, it should be 'Fortran' order:
#        x = np.arange((p+1)**dim)
#        offsets = np.column_stack(np.unravel_index(x,(p+1,)*dim,order='F')).T
        # The sub indices of the whole interpolation stencil with Fortran order, a dim*N*STENCIL array.         
        sub = ( subBasept[...,np.newaxis] + offsets[np.newaxis,...] ).transpose((1,0,2))
        # Convert sub indices to global PETSc indices
        ind = self.subToPetscInd(sub)

        basept = subBasept*dx + ll
        weights = buildInterpWeights(basept,cp,dx,p+1)

        E = self.createMat((wvecsizes,gvec.sizes),ind,weights)
        
        return E