def __init__(self, cell, order): assert cell == UFCInterval() and order == 3 entity_ids = {0: {0: [0], 1: [1]}, 1: {0: [2, 3]}} vertnodes = [PointEvaluation(cell, xx) for xx in cell.vertices] Q = make_quadrature(cell, 3) # 1st integral moment node is integral(1*f(x)*dx) ones = np.asarray([1.0 for x in Q.pts]) # 2nd integral moment node is integral(x*f(x)*dx) xs = np.asarray([x for (x, ) in Q.pts]) intnodes = [IntegralMoment(cell, Q, ones), IntegralMoment(cell, Q, xs)] nodes = vertnodes + intnodes super().__init__(nodes, cell, entity_ids)
def __init__(self, ref_el, points): # Create entity dofs. entity_dofs = {dim: {entity: [] for entity in entities} for dim, entities in ref_el.get_topology().items()} entity_dofs[ref_el.get_dimension()] = {0: list(range(len(points)))} # The dual nodes are PointEvaluations at the quadrature points. # FIXME: KBO: Check if this gives expected results for code like evaluate_dof. nodes = [PointEvaluation(ref_el, tuple(point)) for point in points] # Construct the dual set dual = DualSet(nodes, ref_el, entity_dofs) super(QuadratureElement, self).__init__(ref_el, dual, order=None) self._points = points # save the quadrature points
def __init__(self, ref_el, degree): sd = ref_el.get_spatial_dimension() if sd in (0, 1): raise ValueError( "Cannot use this trace class on a %d-dimensional cell." % sd) # Constructing facet element as a discontinuous Lagrange element dglagrange = DiscontinuousLagrange(ufc_simplex(sd - 1), degree) # Construct entity ids (assigning top. dim. and initializing as empty) entity_dofs = {} # Looping over dictionary of cell topology to construct the empty # dictionary for entity ids of the trace element topology = ref_el.get_topology() for top_dim, entities in topology.items(): entity_dofs[top_dim] = {} for entity in entities: entity_dofs[top_dim][entity] = [] # Filling in entity ids and generating points for dual basis nf = dglagrange.space_dimension() points = [] num_facets = sd + 1 for f in range(num_facets): entity_dofs[sd - 1][f] = range(f * nf, (f + 1) * nf) for dof in dglagrange.dual_basis(): facet_point = list(dof.get_point_dict().keys())[0] transform = ref_el.get_entity_transform(sd - 1, f) points.append(tuple(transform(facet_point))) # Setting up dual basis - only point evaluations nodes = [PointEvaluation(ref_el, pt) for pt in points] dual = dual_set.DualSet(nodes, ref_el, entity_dofs) super(HDivTrace, self).__init__(ref_el, dual, dglagrange.get_order(), dglagrange.get_formdegree(), dglagrange.mapping()[0]) # Set up facet element self.facet_element = dglagrange # degree for quadrature rule self.polydegree = degree
def __init__(self, ufl_element): "Create QuadratureElement" # Compute number of points per axis from the degree of the element degree = ufl_element.degree() if degree is None: degree = default_quadrature_degree scheme = ufl_element.quadrature_scheme() if scheme is None: scheme = default_quadrature_scheme self._quad_scheme = scheme # Create quadrature (only interested in points) # TODO: KBO: What should we do about quadrature functions that live on ds, dS? # Get cell and facet names. domain, = ufl_element.domains() # Assuming single domain cellname = domain.cell().cellname() #facet_cellname = domain.cell().facet_cellname() points, weights = create_quadrature(cellname, degree, self._quad_scheme) # Save the quadrature points self._points = points # Create entity dofs. ufc_cell = reference_cell(cellname) self._entity_dofs = _create_entity_dofs(ufc_cell, len(points)) # The dual is a simply the PointEvaluation at the quadrature points # FIXME: KBO: Check if this gives expected results for code like evaluate_dof. self._dual = [ PointEvaluation(ufc_cell, tuple(point)) for point in points ] # Save the geometric dimension. # FIXME: KBO: Do we need to change this in order to integrate on facets? # MSA: Not the geometric dimension, but maybe the topological dimension somewhere? self._geometric_dimension = domain.geometric_dimension()
def __init__(self, ref_el, degree): """Constructor for the HDivTrace element. :arg ref_el: A reference element, which may be a tensor product cell. :arg degree: The degree of approximation. If on a tensor product cell, then provide a tuple of degrees if you want varying degrees. """ sd = ref_el.get_spatial_dimension() if sd in (0, 1): raise ValueError("Cannot take the trace of a %d-dim cell." % sd) # Store the degrees if on a tensor product cell if ref_el.get_shape() == TENSORPRODUCT: try: degree = tuple(degree) except TypeError: degree = (degree,) * len(ref_el.cells) assert len(ref_el.cells) == len(degree), ( "Number of specified degrees must be equal to the number of cells." ) else: if ref_el.get_shape() not in [TRIANGLE, TETRAHEDRON, QUADRILATERAL]: raise NotImplementedError( "Trace element on a %s not implemented" % type(ref_el) ) # Cannot have varying degrees for these reference cells if isinstance(degree, tuple): raise ValueError("Must have a tensor product cell if providing multiple degrees") # Initialize entity dofs and construct the DG elements # for the facets facet_sd = sd - 1 dg_elements = {} entity_dofs = {} topology = ref_el.get_topology() for top_dim, entities in topology.items(): cell = ref_el.construct_subelement(top_dim) entity_dofs[top_dim] = {} # We have a facet entity! if cell.get_spatial_dimension() == facet_sd: dg_elements[top_dim] = construct_dg_element(cell, degree) # Initialize for entity in entities: entity_dofs[top_dim][entity] = [] # Compute the dof numbering for all facet entities # and extract nodes offset = 0 pts = [] for facet_dim in sorted(dg_elements): element = dg_elements[facet_dim] nf = element.space_dimension() num_facets = len(topology[facet_dim]) for i in range(num_facets): entity_dofs[facet_dim][i] = list(range(offset, offset + nf)) offset += nf # Run over nodes and collect the points for point evaluations for dof in element.dual_basis(): facet_pt, = dof.get_point_dict() transform = ref_el.get_entity_transform(facet_dim, i) pts.append(tuple(transform(facet_pt))) # Setting up dual basis - only point evaluations nodes = [PointEvaluation(ref_el, pt) for pt in pts] dual = DualSet(nodes, ref_el, entity_dofs) # Degree of the element deg = max([e.degree() for e in dg_elements.values()]) super(HDivTrace, self).__init__(ref_el, dual, order=deg, formdegree=facet_sd, mapping="affine") # Set up facet elements self.dg_elements = dg_elements # Degree for quadrature rule self.polydegree = deg