예제 #1
0
 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])
예제 #2
0
    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)