示例#1
0
    def __init__(self, ref_el, degree):
        nodes = []
        dim = ref_el.get_spatial_dimension()

        Q = quadrature.make_quadrature(ref_el, 2 * (degree + 1))

        f_at_qpts = numpy.ones(len(Q.wts))
        nodes.append(functional.IntegralMoment(ref_el, Q, f_at_qpts))

        vertices = ref_el.get_vertices()
        midpoint = tuple(sum(numpy.array(vertices)) / len(vertices))
        for k in range(1, degree + 1):
            # Loop over all multi-indices of degree k.
            for alpha in mis(dim, k):
                nodes.append(
                    functional.PointDerivative(ref_el, midpoint, alpha))

        entity_ids = {
            d: {e: []
                for e in ref_el.sub_entities[d]}
            for d in range(dim + 1)
        }
        entity_ids[dim][0] = list(range(len(nodes)))

        super(DiscontinuousTaylorDualSet,
              self).__init__(nodes, ref_el, entity_ids)
示例#2
0
    def __init__(self, ref_el, degree, order=1):
        bc_nodes = []
        for x in ref_el.get_vertices():
            bc_nodes.append([functional.PointEvaluation(ref_el, x),
                             *[functional.PointDerivative(ref_el, x, [alpha]) for alpha in range(1, order)]])
        bc_nodes[1].reverse()
        k = len(bc_nodes[0])
        idof = slice(k, -k)
        bdof = list(range(-k, k))
        bdof = bdof[k:] + bdof[:k]

        # Define the generalized eigenproblem on a GLL element
        gll = GaussLobattoLegendre(ref_el, degree)
        xhat = numpy.array([list(x.get_point_dict().keys())[0][0] for x in gll.dual_basis()])

        # Tabulate the BC nodes
        constraints = gll.tabulate(order-1, ref_el.get_vertices())
        C = numpy.column_stack(list(constraints.values()))
        perm = list(range(len(bdof)))
        perm = perm[::2] + perm[-1::-2]
        C = C[:, perm].T

        # Tabulate the basis that splits the DOFs into interior and bcs
        E = numpy.eye(gll.space_dimension())
        E[bdof, idof] = -C[:, idof]
        E[bdof, :] = numpy.dot(numpy.linalg.inv(C[:, bdof]), E[bdof, :])

        # Assemble the constrained Galerkin matrices on the reference cell
        rule = quadrature.GaussLegendreQuadratureLineRule(ref_el, degree+1)
        phi = gll.tabulate(order, rule.get_points())
        E0 = numpy.dot(phi[(0, )].T, E)
        Ek = numpy.dot(phi[(order, )].T, E)
        B = numpy.dot(numpy.multiply(E0.T, rule.get_weights()), E0)
        A = numpy.dot(numpy.multiply(Ek.T, rule.get_weights()), Ek)

        # Eigenfunctions in the constrained basis
        S = numpy.eye(A.shape[0])
        if S.shape[0] > len(bdof):
            _, Sii = sym_eig(A[idof, idof], B[idof, idof])
            S[idof, idof] = Sii
            S[idof, bdof] = numpy.dot(Sii, numpy.dot(Sii.T, -B[idof, bdof]))

        # Eigenfunctions in the Lagrange basis
        S = numpy.dot(E, S)
        self.gll_points = xhat
        self.gll_tabulation = S.T

        # Interpolate eigenfunctions onto the quadrature points
        basis = numpy.dot(S.T, phi[(0, )])
        nodes = bc_nodes[0] + [functional.IntegralMoment(ref_el, rule, f) for f in basis[idof]] + bc_nodes[1]

        entity_ids = {0: {0: [0], 1: [degree]},
                      1: {0: list(range(1, degree))}}
        entity_permutations = {}
        entity_permutations[0] = {0: {0: [0]}, 1: {0: [0]}}
        entity_permutations[1] = {0: make_entity_permutations(1, degree - 1)}
        super(FDMDual, self).__init__(nodes, ref_el, entity_ids, entity_permutations)