def restrict_hcurl(element, domain, take_closure): restricted = restrict(element.wrappee, domain, take_closure) if restricted is null_element: return null_element else: if isinstance(restricted, finat.EnrichedElement): return finat.EnrichedElement( finat.HCurlElement(e) for e in restricted.elements) else: return finat.HCurlElement(restricted)
def restrict_tpe(element, domain, take_closure): # The restriction of a TPE to a codim subentity is the direct sum # of TPEs where the factors have been restricted in such a way # that the sum of those restrictions is codim. # # For example, to restrict an interval x interval to edges (codim 1) # we construct # # R(I, 0)⊗R(I, 1) ⊕ R(I, 1)⊗R(I, 0) # # If take_closure is true, the restriction wants to select dofs on # entities with dim >= codim >= 1 (for the edge example) # so we get # # R(I, 0)⊗R(I, 1) ⊕ R(I, 1)⊗R(I, 0) ⊕ R(I, 0)⊗R(I, 0) factors = element.factors dimension = element.cell.get_spatial_dimension() # Figure out which codim entity we're selecting codim = r_to_codim(domain, dimension) # And the range of codims. upper = 1 + (dimension if (take_closure and domain != "interior") else codim) # restrictions on each factor taken from n-tuple that sums to the # target codim (as long as the codim <= dim_factor) restrictions = tuple( candidate for candidate in chain(*(mis(len(factors), c) for c in range(codim, upper))) if all(d <= factor.cell.get_dimension() for d, factor in zip(candidate, factors))) elements = [] for decomposition in restrictions: # Recurse, but don't take closure in recursion (since we # handled it already). new_factors = tuple( restrict(factor, codim_to_r(codim, factor.cell.get_dimension()), take_closure=False) for factor, codim in zip(factors, decomposition)) # If one of the factors was empty then the whole TPE is empty, # so skip. if all(f is not null_element for f in new_factors): elements.append(finat.TensorProductElement(new_factors)) if elements: return finat.EnrichedElement(elements) else: return null_element
def hcurl_element(cell): if cell == "tet": return finat.Nedelec(FIAT.reference_element.UFCTetrahedron(), 3, variant="integral(3)") elif cell == "quad": interval = FIAT.reference_element.UFCInterval() return finat.FlattenedDimensions( finat.EnrichedElement([ finat.HCurlElement( finat.TensorProductElement([ finat.GaussLobattoLegendre(interval, 3), finat.GaussLegendre(interval, 3) ])), finat.HCurlElement( finat.TensorProductElement([ finat.GaussLegendre(interval, 3), finat.GaussLobattoLegendre(interval, 3) ])) ]))
def convert_enrichedelement(element, **kwargs): elements, deps = zip( *[_create_element(elem, **kwargs) for elem in element._elements]) return finat.EnrichedElement(elements), set.union(*deps)