def create_quadrature_monkey_patched(ref_el, degree, scheme="default"): """Monkey patched FIAT.quadrature_schemes.create_quadrature() for implementing lumped scheme""" # Our "special" scheme if scheme == "lumped": if isinstance(ref_el, UFCTriangle) and degree == 2: x = array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.5, 0.0], [0.5, 0.5], [0.0, 0.5]]) w = array([ 1 / 12., ] * 6) return QuadratureRule(ref_el, x, w) elif isinstance(ref_el, UFCTetrahedron) and degree == 2: x = array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.0, 0.5, 0.0], [0.5, 0.0, 0.5], [0.5, 0.5, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 1.0]]) w = array([ 1 / 60., ] * 10) return QuadratureRule(ref_el, x, w) raise NotImplementedError( "Scheme {} of degree {} on {} not implemented".format( scheme, degree, ref_el)) # Fallback to FIAT's normal operation return create_quadrature(ref_el, degree, scheme=scheme)
def __init__(self, ref_el): entity_ids = {} nodes = [] cur = 0 # make nodes by getting points # need to do this dimension-by-dimension, facet-by-facet top = ref_el.get_topology() verts = ref_el.get_vertices() sd = ref_el.get_spatial_dimension() if ref_el.get_shape() != TRIANGLE: raise ValueError("Bell only defined on triangles") pd = functional.PointDerivative # get jet at each vertex entity_ids[0] = {} for v in sorted(top[0]): nodes.append(functional.PointEvaluation(ref_el, verts[v])) # first derivatives for i in range(sd): alpha = [0] * sd alpha[i] = 1 nodes.append(pd(ref_el, verts[v], alpha)) # second derivatives alphas = [[2, 0], [1, 1], [0, 2]] for alpha in alphas: nodes.append(pd(ref_el, verts[v], alpha)) entity_ids[0][v] = list(range(cur, cur + 6)) cur += 6 # we need an edge quadrature rule for the moment from FIAT.quadrature_schemes import create_quadrature from FIAT.jacobi import eval_jacobi rline = ufc_simplex(1) q1d = create_quadrature(rline, 8) q1dpts = q1d.get_points() leg4_at_qpts = eval_jacobi(0, 0, 4, 2.0 * q1dpts - 1) imond = functional.IntegralMomentOfNormalDerivative entity_ids[1] = {} for e in sorted(top[1]): entity_ids[1][e] = [18 + e] nodes.append(imond(ref_el, e, q1d, leg4_at_qpts)) entity_ids[2] = {0: []} super(BellDualSet, self).__init__(nodes, ref_el, entity_ids)
def __init__(self, ref_el): entity_ids = {} nodes = [] cur = 0 # make nodes by getting points # need to do this dimension-by-dimension, facet-by-facet top = ref_el.get_topology() verts = ref_el.get_vertices() sd = ref_el.get_spatial_dimension() if ref_el.get_shape() != TRIANGLE: raise ValueError("Bell only defined on triangles") pd = functional.PointDerivative # get jet at each vertex entity_ids[0] = {} for v in sorted(top[0]): nodes.append(functional.PointEvaluation(ref_el, verts[v])) # first derivatives for i in range(sd): alpha = [0] * sd alpha[i] = 1 nodes.append(pd(ref_el, verts[v], alpha)) # second derivatives alphas = [[2, 0], [1, 1], [0, 2]] for alpha in alphas: nodes.append(pd(ref_el, verts[v], alpha)) entity_ids[0][v] = list(range(cur, cur + 6)) cur += 6 # we need an edge quadrature rule for the moment from FIAT.quadrature_schemes import create_quadrature from FIAT.jacobi import eval_jacobi rline = ufc_simplex(1) q1d = create_quadrature(rline, 8) q1dpts = q1d.get_points() leg4_at_qpts = eval_jacobi(0, 0, 4, 2.0*q1dpts - 1) imond = functional.IntegralMomentOfNormalDerivative entity_ids[1] = {} for e in sorted(top[1]): entity_ids[1][e] = [18+e] nodes.append(imond(ref_el, e, q1d, leg4_at_qpts)) entity_ids[2] = {0: []} super(BellDualSet, self).__init__(nodes, ref_el, entity_ids)
def test_bernstein_2nd_derivatives(): ref_el = ufc_simplex(2) degree = 3 elem = Bernstein(ref_el, degree) rule = create_quadrature(ref_el, degree) points = rule.get_points() actual = elem.tabulate(2, points) assert numpy.allclose(D02, actual[(0, 2)]) assert numpy.allclose(D11, actual[(1, 1)]) assert numpy.allclose(D20, actual[(2, 0)])
def entity_support_dofs(elem, entity_dim): """Return the map of entity id to the degrees of freedom for which the corresponding basis functions take non-zero values :arg elem: FIAT finite element :arg entity_dim: Dimension of the cell subentity. """ if not hasattr(elem, "_entity_support_dofs"): elem._entity_support_dofs = {} cache = elem._entity_support_dofs try: return cache[entity_dim] except KeyError: pass ref_el = elem.get_reference_element() dim = ref_el.get_spatial_dimension() entity_cell = ref_el.construct_subelement(entity_dim) quad = create_quadrature(entity_cell, max(2 * elem.degree(), 1)) weights = quad.get_weights() eps = 1.e-8 # Is this a safe value? result = {} for f in elem.entity_dofs()[entity_dim].keys(): entity_transform = ref_el.get_entity_transform(entity_dim, f) points = list(map(entity_transform, quad.get_points())) # Integrate the square of the basis functions on the facet. vals = numpy.double(elem.tabulate(0, points)[(0, ) * dim]) # Ints contains the square of the basis functions # integrated over the facet. if elem.value_shape(): # Vector-valued functions. ints = numpy.dot(numpy.einsum("...ij,...ij->...j", vals, vals), weights) else: ints = numpy.dot(vals**2, weights) result[f] = [dof for dof, i in enumerate(ints) if i > eps] cache[entity_dim] = result return result
def entity_support_dofs(elem, entity_dim): """Return the map of entity id to the degrees of freedom for which the corresponding basis functions take non-zero values :arg elem: FIAT finite element :arg entity_dim: Dimension of the cell subentity. """ if not hasattr(elem, "_entity_support_dofs"): elem._entity_support_dofs = {} cache = elem._entity_support_dofs try: return cache[entity_dim] except KeyError: pass ref_el = elem.get_reference_element() dim = ref_el.get_spatial_dimension() entity_cell = ref_el.construct_subelement(entity_dim) quad = create_quadrature(entity_cell, max(2*elem.degree(), 1)) weights = quad.get_weights() eps = 1.e-8 # Is this a safe value? result = {} for f in elem.entity_dofs()[entity_dim].keys(): entity_transform = ref_el.get_entity_transform(entity_dim, f) points = list(map(entity_transform, quad.get_points())) # Integrate the square of the basis functions on the facet. vals = numpy.double(elem.tabulate(0, points)[(0,) * dim]) # Ints contains the square of the basis functions # integrated over the facet. if elem.value_shape(): # Vector-valued functions. ints = numpy.dot(numpy.einsum("...ij,...ij->...j", vals, vals), weights) else: ints = numpy.dot(vals**2, weights) result[f] = [dof for dof, i in enumerate(ints) if i > eps] cache[entity_dim] = result return result