コード例 #1
0
ファイル: cg.py プロジェクト: sdrave/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        # evaluate function at all quadrature points -> shape = (g.size(0), number of quadrature points)
        F = self.function(g.quadrature_points(0, order=self.order), mu=mu)

        # evaluate the shape functions at the quadrature points on the reference
        # element -> shape = (number of shape functions, number of quadrature points)
        q, w = g.reference_element.quadrature(order=self.order)
        if g.dim == 2:
            SF = np.array(((1 - q[..., 0]) * (1 - q[..., 1]),
                           (1 - q[..., 1]) * (q[..., 0]),
                           (q[..., 0]) * (q[..., 1]),
                           (q[..., 1]) * (1 - q[..., 0])))
        else:
            raise NotImplementedError

        # integrate the products of the function with the shape functions on each element
        # -> shape = (g.size(0), number of shape functions)
        SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(0), w).ravel()

        # map local DOFs to global DOFs
        # FIXME This implementation is horrible, find a better way!
        SF_I = g.subentities(0, g.dim).ravel()
        I = np.array(coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim))).todense()).ravel()

        # neumann boundary treatment
        if bi is not None and bi.has_neumann and self.neumann_data is not None:
            NI = bi.neumann_boundaries(1)
            F = -self.neumann_data(g.quadrature_points(1, order=self.order)[NI], mu=mu)
            q, w = line.quadrature(order=self.order)
            SF = np.squeeze(np.array([1 - q, q]))
            SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(1)[NI], w).ravel()
            SF_I = g.subentities(1, 2)[NI].ravel()
            I += np.array(coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim)))
                                    .todense()).ravel()

        if bi is not None and bi.has_robin and self.robin_data is not None:
            RI = bi.robin_boundaries(1)
            xref = g.quadrature_points(1, order=self.order)[RI]
            F = self.robin_data[0](xref, mu=mu) * self.robin_data[1](xref, mu=mu)
            q, w = line.quadrature(order=self.order)
            SF = np.squeeze(np.array([1 - q, q]))
            SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(1)[RI], w).ravel()
            SF_I = g.subentities(1, 2)[RI].ravel()
            I += np.array(coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim)))
                                    .todense()).ravel()

        if bi is not None and bi.has_dirichlet:
            DI = bi.dirichlet_boundaries(g.dim)
            if self.dirichlet_data is not None:
                I[DI] = self.dirichlet_data(g.centers(g.dim)[DI], mu=mu)
            else:
                I[DI] = 0

        return I.reshape((1, -1))
コード例 #2
0
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        if g.dim > 2:
            raise NotImplementedError

        if bi is None or not bi.has_robin or self.robin_data is None:
            return coo_matrix((g.size(g.dim), g.size(g.dim))).tocsc()

        RI = bi.robin_boundaries(1)
        if g.dim == 1:
            robin_c = self.robin_data[0](g.centers(1)[RI], mu=mu)
            I = coo_matrix((robin_c, (RI, RI)), shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()
        else:
            xref = g.quadrature_points(1, order=self.order)[RI]
            # xref(robin-index, quadraturepoint-index)
            if self.robin_data[0].shape_range == ():
                robin_c = self.robin_data[0](xref, mu=mu)
            else:
                robin_elements = g.superentities(1, 0)[RI, 0]
                robin_indices = g.superentity_indices(1, 0)[RI, 0]
                normals = g.unit_outer_normals()[robin_elements, robin_indices]
                robin_values = self.robin_data[0](xref, mu=mu)
                robin_c = np.einsum('ei,eqi->eq', normals, robin_values)

            # robin_c(robin-index, quadraturepoint-index)
            q, w = line.quadrature(order=self.order)
            SF = np.squeeze(np.array([1 - q, q]))
            SF_INTS = np.einsum('ep,pi,pj,e,p->eij', robin_c, SF, SF, g.integration_elements(1)[RI], w).ravel()
            SF_I0 = np.repeat(g.subentities(1, g.dim)[RI], 2).ravel()
            SF_I1 = np.tile(g.subentities(1, g.dim)[RI], [1, 2]).ravel()
            I = coo_matrix((SF_INTS, (SF_I0, SF_I1)), shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()
コード例 #3
0
ファイル: cg.py プロジェクト: prklVIP/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        NI = bi.boundaries(self.boundary_type,
                           1) if self.boundary_type else g.boundaries(1)
        if g.dim == 1:
            I = np.zeros(self.range.dim)
            I[NI] = self.function(g.centers(1)[NI])
        else:
            F = self.function(g.quadrature_points(1, order=self.order)[NI],
                              mu=mu)
            q, w = line.quadrature(order=self.order)
            # remove last dimension of q, as line coordinates are one dimensional
            q = q[:, 0]
            SF = np.array([1 - q, q])
            SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF,
                                g.integration_elements(1)[NI], w).ravel()
            SF_I = g.subentities(1, 2)[NI].ravel()
            I = coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)),
                           shape=(1, g.size(g.dim))).toarray().ravel()

        if self.dirichlet_clear_dofs and bi.has_dirichlet:
            DI = bi.dirichlet_boundaries(g.dim)
            I[DI] = 0

        return I.reshape((-1, 1))
コード例 #4
0
ファイル: cg.py プロジェクト: sdrave/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        if g.dim > 2:
            raise NotImplementedError

        if bi is None or not bi.has_robin or self.robin_data is None:
            return coo_matrix((g.size(g.dim), g.size(g.dim))).tocsc()

        RI = bi.robin_boundaries(1)
        if g.dim == 1:
            robin_c = self.robin_data[0](g.centers(1)[RI], mu=mu)
            I = coo_matrix((robin_c, (RI, RI)), shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()
        else:
            xref = g.quadrature_points(1, order=self.order)[RI]
            robin_c = self.robin_data[0](xref, mu=mu)
            q, w = line.quadrature(order=self.order)
            SF = np.squeeze(np.array([1 - q, q]))
            SF_INTS = np.einsum('ep,pi,pj,e,p->eij', robin_c, SF, SF, g.integration_elements(1)[RI], w).ravel()
            SF_I0 = np.repeat(g.subentities(1, g.dim)[RI], 2).ravel()
            SF_I1 = np.tile(g.subentities(1, g.dim)[RI], [1, 2]).ravel()
            I = coo_matrix((SF_INTS, (SF_I0, SF_I1)), shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()
コード例 #5
0
ファイル: cg.py プロジェクト: emamy/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        # our shape functions
        if g.dim == 2:
            SF = [
                lambda X: 1 - X[..., 0] - X[..., 1], lambda X: X[..., 0],
                lambda X: X[..., 1]
            ]
            q, w = triangle.quadrature(order=2)
        elif g.dim == 1:
            SF = [lambda X: 1 - X[..., 0], lambda X: X[..., 0]]
            q, w = line.quadrature(order=2)
        else:
            raise NotImplementedError

        # evaluate the shape functions on the quadrature points
        SFQ = np.array(tuple(f(q) for f in SF))

        self.logger.info(
            'Integrate the products of the shape functions on each element')
        # -> shape = (g.size(0), number of shape functions ** 2)
        if self.coefficient_function is not None:
            C = self.coefficient_function(self.grid.centers(0), mu=mu)
            SF_INTS = np.einsum('iq,jq,q,e,e->eij', SFQ, SFQ, w,
                                g.integration_elements(0), C).ravel()
            del C
        else:
            SF_INTS = np.einsum('iq,jq,q,e->eij', SFQ, SFQ, w,
                                g.integration_elements(0)).ravel()

        del SFQ

        self.logger.info('Determine global dofs ...')
        SF_I0 = np.repeat(g.subentities(0, g.dim), g.dim + 1, axis=1).ravel()
        SF_I1 = np.tile(g.subentities(0, g.dim), [1, g.dim + 1]).ravel()

        self.logger.info('Boundary treatment ...')
        if bi.has_dirichlet:
            if self.dirichlet_clear_rows:
                SF_INTS = np.where(bi.dirichlet_mask(g.dim)[SF_I0], 0, SF_INTS)
            if self.dirichlet_clear_columns:
                SF_INTS = np.where(bi.dirichlet_mask(g.dim)[SF_I1], 0, SF_INTS)
            if not self.dirichlet_clear_diag and (
                    self.dirichlet_clear_rows or self.dirichlet_clear_columns):
                SF_INTS = np.hstack(
                    (SF_INTS, np.ones(bi.dirichlet_boundaries(g.dim).size)))
                SF_I0 = np.hstack((SF_I0, bi.dirichlet_boundaries(g.dim)))
                SF_I1 = np.hstack((SF_I1, bi.dirichlet_boundaries(g.dim)))

        self.logger.info('Assemble system matrix ...')
        A = coo_matrix((SF_INTS, (SF_I0, SF_I1)),
                       shape=(g.size(g.dim), g.size(g.dim)))
        del SF_INTS, SF_I0, SF_I1
        A = csc_matrix(
            A).copy()  # See DiffusionOperatorP1 for why copy() is necessary

        return A
コード例 #6
0
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        # our shape functions
        if g.dim == 2:
            SF = [lambda X: 1 - X[..., 0] - X[..., 1],
                  lambda X: X[..., 0],
                  lambda X: X[..., 1]]
            q, w = triangle.quadrature(order=2)
        elif g.dim == 1:
            SF = [lambda X: 1 - X[..., 0],
                  lambda X: X[..., 0]]
            q, w = line.quadrature(order=2)
        else:
            raise NotImplementedError

        # evaluate the shape functions on the quadrature points
        SFQ = np.array(tuple(f(q) for f in SF))

        self.logger.info('Integrate the products of the shape functions on each element')
        # -> shape = (g.size(0), number of shape functions ** 2)
        if self.coefficient_function is not None:
            C = self.coefficient_function(self.grid.centers(0), mu=mu)
            SF_INTS = np.einsum('iq,jq,q,e,e->eij', SFQ, SFQ, w, g.integration_elements(0), C).ravel()
            del C
        else:
            SF_INTS = np.einsum('iq,jq,q,e->eij', SFQ, SFQ, w, g.integration_elements(0)).ravel()

        del SFQ

        self.logger.info('Determine global dofs ...')
        SF_I0 = np.repeat(g.subentities(0, g.dim), g.dim + 1, axis=1).ravel()
        SF_I1 = np.tile(g.subentities(0, g.dim), [1, g.dim + 1]).ravel()

        self.logger.info('Boundary treatment ...')
        if bi.has_dirichlet:
            if self.dirichlet_clear_rows:
                SF_INTS = np.where(bi.dirichlet_mask(g.dim)[SF_I0], 0, SF_INTS)
            if self.dirichlet_clear_columns:
                SF_INTS = np.where(bi.dirichlet_mask(g.dim)[SF_I1], 0, SF_INTS)
            if not self.dirichlet_clear_diag and (self.dirichlet_clear_rows or self.dirichlet_clear_columns):
                SF_INTS = np.hstack((SF_INTS, np.ones(bi.dirichlet_boundaries(g.dim).size)))
                SF_I0 = np.hstack((SF_I0, bi.dirichlet_boundaries(g.dim)))
                SF_I1 = np.hstack((SF_I1, bi.dirichlet_boundaries(g.dim)))

        self.logger.info('Assemble system matrix ...')
        A = coo_matrix((SF_INTS, (SF_I0, SF_I1)), shape=(g.size(g.dim), g.size(g.dim)))
        del SF_INTS, SF_I0, SF_I1
        A = csc_matrix(A).copy()  # See DiffusionOperatorP1 for why copy() is necessary

        return A
コード例 #7
0
ファイル: cg.py プロジェクト: michaellaier/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        # evaluate function at all quadrature points -> shape = (g.size(0), number of quadrature points)
        F = self.function(g.quadrature_points(0, order=self.order), mu=mu)

        # evaluate the shape functions at the quadrature points on the reference
        # element -> shape = (number of shape functions, number of quadrature points)
        q, w = g.reference_element.quadrature(order=self.order)
        if g.dim == 1:
            SF = np.array((1 - q[..., 0], q[..., 0]))
        elif g.dim == 2:
            SF = np.array(((1 - np.sum(q, axis=-1)),
                           q[..., 0],
                           q[..., 1]))
        else:
            raise NotImplementedError

        # integrate the products of the function with the shape functions on each element
        # -> shape = (g.size(0), number of shape functions)
        SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(0), w).ravel()

        # map local DOFs to global DOFs
        # FIXME This implementation is horrible, find a better way!
        SF_I = g.subentities(0, g.dim).ravel()
        I = np.array(coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim))).todense()).ravel()

        # boundary treatment
        if bi is not None and bi.has_neumann and self.neumann_data is not None:
            NI = bi.neumann_boundaries(1)
            if g.dim == 1:
                I[NI] -= self.neumann_data(g.centers(1)[NI])
            else:
                F = -self.neumann_data(g.quadrature_points(1, order=self.order)[NI], mu=mu)
                q, w = line.quadrature(order=self.order)
                SF = np.squeeze(np.array([1 - q, q]))
                SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(1)[NI], w).ravel()
                SF_I = g.subentities(1, 2)[NI].ravel()
                I += np.array(coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim)))
                                        .todense()).ravel()

        if bi is not None and bi.has_dirichlet:
            DI = bi.dirichlet_boundaries(g.dim)
            if self.dirichlet_data is not None:
                I[DI] = self.dirichlet_data(g.centers(g.dim)[DI], mu=mu)
            else:
                I[DI] = 0

        return I.reshape((1, -1))
コード例 #8
0
ファイル: cg.py プロジェクト: tobiasleibner/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        NI = bi.neumann_boundaries(1)
        F = self.function(g.quadrature_points(1, order=self.order)[NI], mu=mu)
        q, w = line.quadrature(order=self.order)
        # remove last dimension of q, as line coordinates are one dimensional
        q = q[:, 0]
        SF = np.array([1 - q, q])
        SF_INTS = np.einsum('ei,pi,e,i->ep', F, SF, g.integration_elements(1)[NI], w).ravel()
        SF_I = g.subentities(1, 2)[NI].ravel()
        I = coo_matrix((SF_INTS, (np.zeros_like(SF_I), SF_I)), shape=(1, g.size(g.dim))).toarray().ravel()

        if self.dirichlet_clear_dofs and bi.has_dirichlet:
            DI = bi.dirichlet_boundaries(g.dim)
            I[DI] = 0

        return I.reshape((-1, 1))
コード例 #9
0
ファイル: cg.py プロジェクト: prklVIP/pymor
    def _assemble(self, mu=None):
        g = self.grid
        bi = self.boundary_info

        if g.dim > 2:
            raise NotImplementedError

        if bi is None or not bi.has_robin or self.robin_data is None:
            return coo_matrix((g.size(g.dim), g.size(g.dim))).tocsc()

        RI = bi.robin_boundaries(1)
        if g.dim == 1:
            robin_c = self.robin_data[0](g.centers(1)[RI], mu=mu)
            I = coo_matrix((robin_c, (RI, RI)),
                           shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()
        else:
            xref = g.quadrature_points(1, order=self.order)[RI]
            # xref(robin-index, quadraturepoint-index)
            if self.robin_data[0].shape_range == ():
                robin_c = self.robin_data[0](xref, mu=mu)
            else:
                robin_elements = g.superentities(1, 0)[RI, 0]
                robin_indices = g.superentity_indices(1, 0)[RI, 0]
                normals = g.unit_outer_normals()[robin_elements, robin_indices]
                robin_values = self.robin_data[0](xref, mu=mu)
                robin_c = np.einsum('ei,eqi->eq', normals, robin_values)

            # robin_c(robin-index, quadraturepoint-index)
            q, w = line.quadrature(order=self.order)
            # remove last dimension of q, as line coordinates are one dimensional
            q = q[:, 0]
            SF = np.array([1 - q, q])
            SF_INTS = np.einsum('ep,pi,pj,e,p->eij', robin_c, SF, SF,
                                g.integration_elements(1)[RI], w).ravel()
            SF_I0 = np.repeat(g.subentities(1, g.dim)[RI], 2).ravel()
            SF_I1 = np.tile(g.subentities(1, g.dim)[RI], [1, 2]).ravel()
            I = coo_matrix((SF_INTS, (SF_I0, SF_I1)),
                           shape=(g.size(g.dim), g.size(g.dim)))
            return csc_matrix(I).copy()