def assemble_A_tilde_diagonal(self): """ Assemble diagonal à and Ã_inv matrices """ uvw = self.simulation.data['uvw_star'] Vuvw = uvw.function_space() Aglobal = self.M if self.a_tilde_is_mass else self.A if self.A_tilde is None: At = create_block_matrix(Vuvw, 'diag') Ati = create_block_matrix(Vuvw, 'diag') self.u_diag = dolfin.Vector(uvw.vector()) else: At = self.A_tilde Ati = self.A_tilde_inv At.zero() Ati.zero() if self.lump_diagonal: self.u_diag[:] = 1.0 self.u_diag.apply('insert') self.u_diag = Aglobal * self.u_diag else: Aglobal.get_diagonal(self.u_diag) # Setup the diagonal A matrix At.set_diagonal(self.u_diag) # Setup the inverse of the diagonal A matrix inv_diag = 1.0 / self.u_diag.get_local() self.u_diag.set_local(inv_diag) self.u_diag.apply('insert') Ati.set_diagonal(self.u_diag) return At, Ati
def assemble_A_tilde_multi_element(self, Nelem): """ Assemble block diagonal à and Ã_inv matrices where the blocks are the dofs of N elememts a single element """ if self.block_partitions is None: self.block_partitions = create_block_partitions( self.simulation, self.Vuvw, Nelem) self.simulation.log.info( 'SIMPLE solver with %d cell blocks found %d blocks in total' % (Nelem, len(self.block_partitions))) Aglobal = self.M if self.a_tilde_is_mass else self.A if self.A_tilde is None: block_dofs = [dofs for _, dofs, _ in self.block_partitions] At = create_block_matrix(self.Vuvw, block_dofs) Ati = At.copy() else: At = self.A_tilde Ati = self.A_tilde_inv At.zero() Ati.zero() # Loop over super-cells and get the block diagonal parts (should be moved to C++) istart = Aglobal.local_range(0)[0] for _cells, dofs, _dof_idx in self.block_partitions: global_dofs = dofs + istart N = len(dofs) Ablock = numpy.zeros((N, N), float) Aglobal.get(Ablock, global_dofs, global_dofs) Ablock_inv = numpy.linalg.inv(Ablock) At.set(Ablock, dofs, global_dofs) Ati.set(Ablock_inv, dofs, global_dofs) return At, Ati
def mk_mat(mesh_size=1, order=2, block=False): mesh = dolfin.UnitSquareMesh(mesh_size, mesh_size) V = dolfin.FunctionSpace(mesh, 'DG', order) if block: blocks = [ list(range(order * 3)), list(range(order * 3 * 1, order * 3 * 2)) ] A = create_block_matrix(V, blocks) else: u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) A = dolfin.assemble(u * v * dolfin.dx) A.zero() return A