def over_adds(b_centers, b_faces , b_values , b_indices): f_bound = self._f_bound neigh_centers = self.neighbour_centers(b_centers, b_faces) for i, neigh_center in enumerate(neigh_centers): # Check on the current extra border octant of the background grid if # is overlapped by foreground grids. check = utilities.check_into_squares(neigh_center, f_bound , self.logger , log_file) if check and b_faces[i] == 1: key = (grid, b_indices[i], "ghost_boundary") self._edl.update({key : neigh_center}) b_values[i] = self._e_array_gb.getValue(b_indices[i])
def init_mat(self, # Overlap octants' number. o_n_oct = 0): log_file = self.logger.handlers[0].baseFilename penalization = self._pen f_bound = self._f_bound grid = self._proc_g # Local and global matrix's sizes. n_oct = self._n_oct N_oct = self._N_oct sizes = (n_oct, N_oct) # The AIJ format is also called the Yale sparse matrix format or # compressed row storage (CSR). # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatMPIAIJSetPreallocation.html # http://lists.mcs.anl.gov/pipermail/petsc-users/2013-August/018502.html self._mat = PETSc.Mat().createAIJ(size = (sizes, sizes), #nnz = (5, 5) , # The line above is commented because # I think that the case below is # better, reflecting the "worst" cases # for the diagonal part and the other # one. If there is only one process, # we will have 5 elements of the # stencil on the same process, so into # the diagonal part. If otherwise, we # should use a single process for each # octant, we would have one element in # the diagonal part (row-column # intersection) and 4 elements into # the off-diagonal part, not 5. nnz = (5, 4) , #csr = (range(0, n_oct + 1), # range(0, n_oct)), comm = self._comm) # Getting ranges of the matrix owned by the current process. o_ranges = self._mat.getOwnershipRange() # Creating a block matrix tot_oct = self._tot_oct tot_sizes = (n_oct, tot_oct) b_size = self.find_block_dim() d_nz, o_nz = self.find_block_nnz(tot_oct, b_size) self._b_mat = PETSc.Mat().createBAIJ(size = (tot_sizes, tot_sizes), bsize = b_size , nnz = (d_nz, o_nz) , comm = self._comm_w) #print(self._b_mat.getSizes()) h = self._h h2 = h * h nfaces = glob.nfaces is_background = False overlap = o_n_oct * h p_bound = [] if not grid: is_background = True p_bound = self.apply_overlap(overlap) for octant in xrange(0, n_oct): indices, values = ([] for i in range(0, 2)) # Indices/values neighs, ghosts = ([] for i in range(0, 2)) g_octant = o_ranges[0] + octant py_oct = self._octree.get_octant(octant) center = self._octree.get_center(octant)[:2] # Check to know if a quad(oc)tree on the background is penalized. is_penalized = False # Background grid. if is_background: is_penalized = utilities.check_into_squares(center , p_bound , self.logger, log_file) if is_penalized: key = (grid, g_octant) self._edl.update({key : center}) # Residual evaluation... eval_res = (check_into_squares(center , f_bound , self.logger, log_file) and not is_penalized) if overlap else \ utilities.check_into_squares(center , f_bound , self.logger, log_file) if eval_res: sol_value = self._sol.getValue(g_octant) self._res_l.update({tuple(center) : sol_value}) # Here we are, upper grids. #else: # circle_center = (0.5, 0.5) # circle_radius = 0.125 # is_penalized = check_into_circle(center , # circle_center, # circle_radius) indices.append(g_octant) values.append(((-4.0 / h2) - penalization) if is_penalized else (-4.0 / h2)) for face in xrange(0, nfaces): if not self._octree.get_bound(py_oct, face): (neighs, ghosts) = self._octree.find_neighbours(octant, face , 1 , neighs, ghosts) if not ghosts[0]: index = neighs[0] + o_ranges[0] else: index = self._octree.get_ghost_global_idx(neighs[0]) indices.append(index) values.append(1.0 / h2) self._mat.setValues(g_octant, # Rows indices , # Columns values) # Values to be inserted # ATTENTION!! Non using these functions will give you an unassembled # matrix PETSc. self._mat.assemblyBegin() self._mat.assemblyEnd() self._b_mat.assemblyBegin() self._b_mat.assemblyEnd() msg = "Initialized matrix" extra_msg = "with sizes \"" + str(self._mat.getSizes()) + \ "\" and type \"" + str(self._mat.getType()) + "\"" self.log_msg(msg , "info", extra_msg)