def _init_block(self): self._blocks = [[self]] rset, cset = self.sparsity.dsets if (isinstance(rset, GlobalDataSet) or isinstance(cset, GlobalDataSet)): self._init_global_block() return mat = PETSc.Mat() row_lg = rset.lgmap col_lg = cset.lgmap rdim, cdim = self.dims[0][0] if rdim == cdim and rdim > 1 and self.sparsity._block_sparse: # Size is total number of rows and columns, but the # /sparsity/ is the block sparsity. block_sparse = True create = mat.createBAIJ else: # Size is total number of rows and columns, sparsity is # the /dof/ sparsity. block_sparse = False create = mat.createAIJ create(size=((self.nrows, None), (self.ncols, None)), nnz=(self.sparsity.nnz, self.sparsity.onnz), bsize=(rdim, cdim), comm=self.comm) mat.setLGMap(rmap=row_lg, cmap=col_lg) # Stash entries destined for other processors mat.setOption(mat.Option.IGNORE_OFF_PROC_ENTRIES, False) # Any add or insertion that would generate a new entry that has not # been preallocated will raise an error mat.setOption(mat.Option.NEW_NONZERO_ALLOCATION_ERR, True) # Do not ignore zeros while we fill the initial matrix so that # petsc doesn't compress things out. if not block_sparse: mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, False) # When zeroing rows (e.g. for enforcing Dirichlet bcs), keep those in # the nonzero structure of the matrix. Otherwise PETSc would compact # the sparsity and render our sparsity caching useless. mat.setOption(mat.Option.KEEP_NONZERO_PATTERN, True) # We completely fill the allocated matrix when zeroing the # entries, so raise an error if we "missed" one. mat.setOption(mat.Option.UNUSED_NONZERO_LOCATION_ERR, True) # Put zeros in all the places we might eventually put a value. with timed_region("MatZeroInitial"): sparsity.fill_with_zeros(mat, self.sparsity.dims[0][0], self.sparsity.maps, self.sparsity.iteration_regions, set_diag=self.sparsity._has_diagonal) mat.assemble() mat.setOption(mat.Option.NEW_NONZERO_LOCATION_ERR, True) # Now we've filled up our matrix, so the sparsity is # "complete", we can ignore subsequent zero entries. if not block_sparse: mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, True) self.handle = mat
def _init_monolithic(self): mat = PETSc.Mat() rset, cset = self.sparsity.dsets if rset.cdim != 1: rlgmap = rset.unblocked_lgmap else: rlgmap = rset.lgmap if cset.cdim != 1: clgmap = cset.unblocked_lgmap else: clgmap = cset.lgmap mat.createAIJ(size=((self.nrows, None), (self.ncols, None)), nnz=(self.sparsity.nnz, self.sparsity.onnz), bsize=1, comm=self.comm) mat.setLGMap(rmap=rlgmap, cmap=clgmap) self.handle = mat self._blocks = [] rows, cols = self.sparsity.shape for i in range(rows): row = [] for j in range(cols): row.append(MatBlock(self, i, j)) self._blocks.append(row) mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, False) mat.setOption(mat.Option.KEEP_NONZERO_PATTERN, True) # We completely fill the allocated matrix when zeroing the # entries, so raise an error if we "missed" one. mat.setOption(mat.Option.UNUSED_NONZERO_LOCATION_ERR, True) mat.setOption(mat.Option.IGNORE_OFF_PROC_ENTRIES, False) mat.setOption(mat.Option.NEW_NONZERO_ALLOCATION_ERR, True) # The first assembly (filling with zeros) sets all possible entries. mat.setOption(mat.Option.SUBSET_OFF_PROC_ENTRIES, True) # Put zeros in all the places we might eventually put a value. with timed_region("MatZeroInitial"): for i in range(rows): for j in range(cols): sparsity.fill_with_zeros( self[i, j].handle, self[i, j].sparsity.dims[0][0], self[i, j].sparsity.maps, set_diag=self[i, j].sparsity._has_diagonal) self[i, j].handle.assemble() mat.assemble() mat.setOption(mat.Option.NEW_NONZERO_LOCATION_ERR, True) mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, True)
def _init_monolithic(self): mat = PETSc.Mat() rset, cset = self.sparsity.dsets if rset.cdim != 1: rlgmap = rset.unblocked_lgmap else: rlgmap = rset.lgmap if cset.cdim != 1: clgmap = cset.unblocked_lgmap else: clgmap = cset.lgmap mat.createAIJ(size=((self.nrows, None), (self.ncols, None)), nnz=(self.sparsity.nnz, self.sparsity.onnz), bsize=1, comm=self.comm) mat.setLGMap(rmap=rlgmap, cmap=clgmap) self.handle = mat self._blocks = [] rows, cols = self.sparsity.shape for i in range(rows): row = [] for j in range(cols): row.append(MatBlock(self, i, j)) self._blocks.append(row) mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, False) mat.setOption(mat.Option.KEEP_NONZERO_PATTERN, True) # We completely fill the allocated matrix when zeroing the # entries, so raise an error if we "missed" one. mat.setOption(mat.Option.UNUSED_NONZERO_LOCATION_ERR, True) mat.setOption(mat.Option.IGNORE_OFF_PROC_ENTRIES, True) mat.setOption(mat.Option.NEW_NONZERO_ALLOCATION_ERR, True) # Put zeros in all the places we might eventually put a value. with timed_region("MatZeroInitial"): for i in range(rows): for j in range(cols): sparsity.fill_with_zeros(self[i, j].handle, self[i, j].sparsity.dims[0][0], self[i, j].sparsity.maps, set_diag=self[i, j].sparsity._has_diagonal) mat.assemble() mat.setOption(mat.Option.IGNORE_ZERO_ENTRIES, True)