def as_fiat_cell(cell): """Convert a ufl cell to a FIAT cell. :arg cell: the :class:`ufl.Cell` to convert.""" if not isinstance(cell, ufl.AbstractCell): raise ValueError("Expecting a UFL Cell") return FIAT.ufc_cell(cell)
def reference_cell(cell): # really want to be using cells only, but sometimes only cellname is passed # in. FIAT handles the cases. # I hope nothing is still passing in just dimension... if isinstance(cell, int): error("%s was passed into reference_cell(). Need cell or cellname." % str(cell)) return FIAT.ufc_cell(cell)
def create_quadrature(shape, num_points): """ Generate quadrature rule (points, weights) for given shape with num_points points in each direction. """ if isinstance(shape, int) and shape == 0: return ([()], array([1.0,])) if shape in cellname2dim and cellname2dim[shape] == 0: return ([()], array([1.0,])) quad_rule = FIAT.make_quadrature(reference_cell(shape), num_points) return quad_rule.get_points(), quad_rule.get_weights()
def create_quadrature(shape, degree, scheme="default"): """ Generate quadrature rule (points, weights) for given shape that will integrate an polynomial of order 'degree' exactly. """ if isinstance(shape, int) and shape == 0: return (numpy.zeros((1, 0)), numpy.ones((1,))) if shape in cellname2dim and cellname2dim[shape] == 0: return (numpy.zeros((1, 0)), numpy.ones((1,))) if scheme == "vertex": # The vertex scheme, i.e., averaging the function value in the vertices # and multiplying with the simplex volume, is only of order 1 and # inferior to other generic schemes in terms of error reduction. # Equation systems generated with the vertex scheme have some # properties that other schemes lack, e.g., the mass matrix is # a simple diagonal matrix. This may be prescribed in certain cases. if degree > 1: from warnings import warn warn(("Explicitly selected vertex quadrature (degree 1), " + "but requested degree is %d.") % degree) if shape == "tetrahedron": return (array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]), array([1.0 / 24.0, 1.0 / 24.0, 1.0 / 24.0, 1.0 / 24.0]) ) elif shape == "triangle": return (array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]]), array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0]) ) elif shape == "interval": # Trapezoidal rule. return (array([[0.0], [1.0]]), array([1.0 / 2.0, 1.0 / 2.0]) ) quad_rule = FIAT.create_quadrature(reference_cell(shape), degree, scheme) points = numpy.asarray(quad_rule.get_points()) weights = numpy.asarray(quad_rule.get_weights()) return points, weights
def create_quadrature(cell, num_points): """ Generate quadrature rule (points, weights) for given shape with num_points points in each direction. """ if isinstance(cell, int) and cell == 0: return ([()], array([1.0,])) if isinstance(cell, str): cellname = cell else: cellname = cell.cellname() if cellname == "vertex": return ([()], array([1.0,])) quad_rule = FIAT.make_quadrature(reference_cell(cell), num_points) return quad_rule.get_points(), quad_rule.get_weights()
def _(element, vector_is_mixed): if element.family() == "Real": # Real element is just DG0 cell = element.cell() return create_element(ufl.FiniteElement("DG", cell, 0), vector_is_mixed) cell = as_fiat_cell(element.cell()) if element.family() == "Quadrature": degree = element.degree() scheme = element.quadrature_scheme() if degree is None or scheme is None: raise ValueError("Quadrature scheme and degree must be specified!") quad_rule = FIAT.create_quadrature(cell, degree, scheme) return FIAT.QuadratureElement(cell, quad_rule.get_points()) lmbda = supported_elements[element.family()] if lmbda is None: if element.cell().cellname() != "quadrilateral": raise ValueError("%s is supported, but handled incorrectly" % element.family()) # Handle quadrilateral short names like RTCF and RTCE. element = element.reconstruct(cell=quad_tpc) return FlattenedDimensions(create_element(element, vector_is_mixed)) kind = element.variant() if kind is None: kind = 'equispaced' # default variant if element.family() == "Lagrange": if kind == 'equispaced': lmbda = FIAT.Lagrange elif kind == 'spectral' and element.cell().cellname() == 'interval': lmbda = FIAT.GaussLobattoLegendre else: raise ValueError("Variant %r not supported on %s" % (kind, element.cell())) elif element.family() == "Discontinuous Lagrange": if kind == 'equispaced': lmbda = FIAT.DiscontinuousLagrange elif kind == 'spectral' and element.cell().cellname() == 'interval': lmbda = FIAT.GaussLegendre else: raise ValueError("Variant %r not supported on %s" % (kind, element.cell())) return lmbda(cell, element.degree())
def create_quadrature(cell, degree, scheme="default"): """Create a quadrature rule. :arg cell: The FIAT cell. :arg degree: The degree of polynomial that should be integrated exactly by the rule. :kwarg scheme: optional scheme to use (either ``"default"``, or ``"canonical"``). .. note :: If the cell is a tensor product cell, the degree should be a tuple, indicating the degree in each direction of the tensor product. """ if scheme not in ("default", "canonical"): raise ValueError("Unknown quadrature scheme '%s'" % scheme) rule = FIAT.create_quadrature(cell, degree, scheme) if len(rule.get_points()) > 900: raise RuntimeError("Requested a quadrature rule with %d points" % len(rule.get_points())) return rule
def test_mesh_topology_against_fiat(mesh_factory, ghost_mode): """Test that mesh cells have topology matching to FIAT reference cell they were created from. """ func, args = mesh_factory xfail_ghosted_quads_hexes(func, ghost_mode) mesh = func(*args) assert mesh.ordered() tdim = mesh.topology().dim() # Create FIAT cell cell_name = CellType.type2string(mesh.type().cell_type()) fiat_cell = FIAT.ufc_cell(cell_name) # Initialize all mesh entities and connectivities mesh.init() for cell in cells(mesh): # Get mesh-global (MPI-local) indices of cell vertices vertex_global_indices = cell.entities(0) # Loop over all dimensions of reference cell topology for d, d_topology in fiat_cell.get_topology().items(): # Get entities of dimension d on the cell entities = cell.entities(d) if len(entities) == 0: # Fixup for highest dimension entities = (cell.index(),) # Loop over all entities of fixed dimension d for entity_index, entity_topology in d_topology.items(): # Check that entity vertices map to cell vertices in right order entity = MeshEntity(mesh, d, entities[entity_index]) entity_vertices = entity.entities(0) assert all(vertex_global_indices[numpy.array(entity_topology)] == entity_vertices)
def __init__(self, cell, degree): super(DiscontinuousTaylor, self).__init__(FIAT.DiscontinuousTaylor(cell, degree))
def __init__(self, cell, degree): super(KongMulderVeldhuizen, self).__init__(FIAT.KongMulderVeldhuizen(cell, degree)) if Citations is not None: Citations().register("Chin1999higher") Citations().register("Geevers2018new")
def __init__(self, cell, degree): super(Serendipity, self).__init__(FIAT.Serendipity(cell, degree))
def reference_cell(cellname): "Return FIAT reference cell" return FIAT.ufc_cell(cellname)
def __init__(self, cell, degree): super(FacetBubble, self).__init__(FIAT.FacetBubble(cell, degree))
def reference_cell(cellname): """Return FIAT reference cell.""" return FIAT.ufc_cell(cellname)
def __init__(self, cell, degree): fiat_element = FIAT.FDMHermite(cell, degree) super(FDMHermite, self).__init__(fiat_element)
def __init__(self, cell, degree, variant=None): super(NedelecSecondKind, self).__init__( FIAT.NedelecSecondKind(cell, degree, variant=variant))
def __init__(self, cell, degree): super(TrimmedSerendipityCurl, self).__init__(FIAT.TrimmedSerendipityCurl(cell, degree))
def reference_cell(dim): if isinstance(dim, int): return FIAT.ufc_simplex(dim) else: return FIAT.ufc_simplex(cellname2dim[dim])
def __init__(self, cell, degree): super(BrezziDouglasFortinMarini, self).__init__(FIAT.BrezziDouglasFortinMarini(cell, degree))
def cell(request): dim = request.param return FIAT.ufc_simplex(dim)
def __init__(self, cell, degree): fiat_element = FIAT.GaussLegendre(cell, degree) super(GaussLegendre, self).__init__(fiat_element)
def test_create_quadrature_extr_interval(extr_interval, basedeg, extrdeg, scheme): q = FIAT.create_quadrature(extr_interval, (basedeg, extrdeg), scheme) assert numpy.allclose(q.integrate(lambda x: x[0]**basedeg * x[1]**extrdeg), 1/(basedeg + 1) * 1/(extrdeg + 1))
def _(element, vector_is_mixed): return FIAT.DiscontinuousElement( create_element(element._element, vector_is_mixed))
def test_create_quadrature_extr_triangle(extr_triangle, basedeg, extrdeg, scheme): q = FIAT.create_quadrature(extr_triangle, (basedeg, extrdeg), scheme) assert numpy.allclose(q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg), 1/(basedeg + 2) * 1/(extrdeg + 1))
def __init__(self, cell, degree): super(Regge, self).__init__(FIAT.Regge(cell, degree))
def test_create_quadrature_quadrilateral(quadrilateral, degree, scheme): q = FIAT.create_quadrature(quadrilateral, degree, scheme) assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), (2**(degree + 2) - 2) / ((degree + 1)*(degree + 2)))
def __init__(self, cell, degree): super().__init__(FIAT.Bernstein(cell, degree))
def test_create_quadrature_hexahedron(hexahedron, degree, scheme): q = FIAT.create_quadrature(hexahedron, degree, scheme) assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), -3 * (2**(degree + 3) - 3**(degree + 2) - 1) / ((degree + 1)*(degree + 2)*(degree + 3)))
def __init__(self, cell, degree): super(CrouzeixRaviart, self).__init__(FIAT.CrouzeixRaviart(cell, degree))
def test_create_quadrature_extr_quadrilateral(extr_quadrilateral, basedeg, extrdeg, scheme): q = FIAT.create_quadrature(extr_quadrilateral, (basedeg, extrdeg), scheme) assert numpy.allclose(q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg), (2**(basedeg + 2) - 2) / ((basedeg + 1)*(basedeg + 2)) * 1/(extrdeg + 1))
def __init__(self, cell, degree): super(DiscontinuousLagrange, self).__init__(FIAT.DiscontinuousLagrange(cell, degree))
def test_invalid_quadrature_degree(cell, scheme): with pytest.raises(ValueError): FIAT.create_quadrature(cell, -1, scheme)
def __init__(self, cell, degree): super(DPC, self).__init__(FIAT.DPC(cell, degree))
def test_invalid_quadrature_degree_tensor_prod(cell): with pytest.raises(ValueError): FIAT.create_quadrature(cell, (-1, -1))
def __init__(self, cell, degree, variant=None): super(RaviartThomas, self).__init__(FIAT.RaviartThomas(cell, degree, variant=variant))
def test_tensor_product_composition(interval, triangle, extr_triangle, scheme): degree = (4, 4) qa = FIAT.create_quadrature(triangle, degree[0], scheme) qb = FIAT.create_quadrature(interval, degree[1], scheme) q = FIAT.create_quadrature(extr_triangle, degree, scheme) assert len(q.get_points()) == len(qa.get_points())*len(qb.get_points())
def __init__(self, cell, degree, variant=None): super(BrezziDouglasMarini, self).__init__( FIAT.BrezziDouglasMarini(cell, degree, variant=variant))
def test_create_quadrature_interval(interval, degree, scheme): q = FIAT.create_quadrature(interval, degree, scheme) assert numpy.allclose(q.integrate(lambda x: x[0]**degree), 1/(degree + 1))
def __init__(self, cell, degree, variant=None): super(Nedelec, self).__init__(FIAT.Nedelec(cell, degree, variant=variant))
def test_create_quadrature_triangle(triangle, degree, scheme): q = FIAT.create_quadrature(triangle, degree, scheme) assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(degree + 2))
def test_quad(base, extr, horiz_expected, vert_expected): elem_A = FIAT.supported_elements[base[0]](UFCInterval(), base[1]) elem_B = FIAT.supported_elements[extr[0]](UFCInterval(), extr[1]) elem = FIAT.TensorProductElement(elem_A, elem_B) assert horiz_expected == entity_support_dofs(elem, (1, 0)) assert vert_expected == entity_support_dofs(elem, (0, 1))
def test_create_quadrature_tetrahedron(tetrahedron, degree, scheme): q = FIAT.create_quadrature(tetrahedron, degree, scheme) assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(2*degree + 6))
def __init__(self, cell, degree): fiat_element = FIAT.FDMLagrange(cell, degree) super(FDMLagrange, self).__init__(fiat_element)
def _(element, vector_is_mixed): return FIAT.RestrictedElement( create_element(element.sub_element(), vector_is_mixed), restriction_domain=element.restriction_domain())
def _(element, vector_is_mixed): return FIAT.Hcurl(create_element(element._element, vector_is_mixed))
def __init__(self, cell, degree): if Citations is not None: Citations().register("Arnold2003") super(ArnoldWintherNC, self).__init__(FIAT.ArnoldWintherNC(cell, degree))
def __init__(self, elements): nodal_enriched = FIAT.NodalEnrichedElement(*(elem.fiat_equivalent for elem in elements)) super().__init__(nodal_enriched)
V = dolfinx.FunctionSpace(mesh, ("Lagrange", 1)) u = ufl.TrialFunction(V) v = ufl.TestFunction(V) f = dolfinx.Function(V) def rhs(x): return sin(pi*x[0])*sin(pi*x[1]) f.interpolate(rhs) a_eqn = inner(grad(u), grad(v)) L_eqn = inner(f, v) a = a_eqn*ufl.dx(metadata={"quadrature_rule": "runtime"}) L = L_eqn*ufl.dx(metadata={"quadrature_rule": "runtime"}) degree = 2 q = FIAT.create_quadrature(FIAT.reference_element.UFCQuadrilateral(), degree) qr_pts = q.get_points().flatten() qr_w = q.get_weights().flatten() A = libcutfemx.custom_assemble_matrix(a, [(cells, [qr_pts], [qr_w])]) A.assemble() b = libcutfemx.custom_assemble_vector(L, [(cells, [qr_pts], [qr_w])]) print(A.norm()) print(numpy.linalg.norm(b.array)) vec = ksp_solve(A, b) u = vec_to_function(vec, V, "u") write("poisson.xdmf", mesh, u) # Reference
def __init__(self, cell, degree): super(Lagrange, self).__init__(FIAT.Lagrange(cell, degree))
def __init__(self, cell, degree): super(HellanHerrmannJohnson, self).__init__(FIAT.HellanHerrmannJohnson(cell, degree))