Example #1
0
    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
Example #2
0
    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
Example #3
0
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