1010from FIAT .check_format_variant import check_format_variant
1111from FIAT .quadrature_schemes import create_quadrature
1212from FIAT .quadrature import FacetQuadratureRule
13+ import numpy
1314
1415
1516class BDMDualSet (dual_set .DualSet ):
@@ -26,7 +27,7 @@ def __init__(self, ref_el, degree, variant, interpolant_deg):
2627 entity_ids [dim ][entity ] = []
2728
2829 if variant == "integral" :
29- facet = ref_el .get_facet_element ( )
30+ facet = ref_el .construct_subelement ( sd - 1 )
3031 # Facet nodes are \int_F v\cdot n p ds where p \in P_{q}
3132 # degree is q
3233 Q_ref = create_quadrature (facet , interpolant_deg + degree )
@@ -56,14 +57,18 @@ def __init__(self, ref_el, degree, variant, interpolant_deg):
5657 if degree > 1 :
5758 if interpolant_deg is None :
5859 interpolant_deg = degree
59- cur = len (nodes )
60- Q = create_quadrature (ref_el , interpolant_deg + degree - 1 )
61- Nedel = nedelec .Nedelec (ref_el , degree - 1 , variant )
62- Nedfs = Nedel .get_nodal_basis ()
63- Ned_at_qpts = Nedfs .tabulate (Q .get_points ())[(0 ,) * sd ]
64- nodes .extend (functional .FrobeniusIntegralMoment (ref_el , Q , phi )
65- for phi in Ned_at_qpts )
66- entity_ids [sd ][0 ] = list (range (cur , len (nodes )))
60+
61+ cell = ref_el .construct_subelement (sd )
62+ Q_ref = create_quadrature (cell , interpolant_deg + degree - 1 )
63+ Nedel = nedelec .Nedelec (cell , degree - 1 , variant )
64+ Ned_at_qpts = Nedel .tabulate (0 , Q_ref .get_points ())[(0 ,) * sd ]
65+ for entity in top [sd ]:
66+ Q = FacetQuadratureRule (ref_el , sd , entity , Q_ref )
67+ Jinv = numpy .linalg .inv (Q .jacobian ())
68+ phis = numpy .tensordot (Jinv .T , Ned_at_qpts , (1 , 1 )).transpose ((1 , 0 , 2 ))
69+ cur = len (nodes )
70+ nodes .extend (functional .FrobeniusIntegralMoment (ref_el , Q , phi ) for phi in phis )
71+ entity_ids [sd ][entity ] = list (range (cur , len (nodes )))
6772
6873 super ().__init__ (nodes , ref_el , entity_ids )
6974
@@ -89,6 +94,11 @@ class BrezziDouglasMarini(finite_element.CiarletElement):
8994 """
9095
9196 def __init__ (self , ref_el , degree , variant = None ):
97+
98+ splitting , variant , interpolant_deg = check_format_variant (variant , degree )
99+ if splitting is not None :
100+ ref_el = splitting (ref_el )
101+
92102 if degree < 1 :
93103 raise ValueError (f"{ type (self ).__name__ } elements only valid for k >= 1" )
94104
@@ -99,7 +109,6 @@ def __init__(self, ref_el, degree, variant=None):
99109 elif variant == "fdm" :
100110 dual = demkowicz .FDMDual (ref_el , degree , "HDiv" , type (self ))
101111 else :
102- variant , interpolant_deg = check_format_variant (variant , degree )
103112 dual = BDMDualSet (ref_el , degree , variant , interpolant_deg )
104113 formdegree = sd - 1 # (n-1)-form
105114 super ().__init__ (poly_set , dual , degree , formdegree , mapping = "contravariant piola" )
0 commit comments