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)
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)