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
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)]
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
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