14
14
15
15
class LagrangeDualSet (dual_set .DualSet ):
16
16
"""The dual basis for Lagrange elements. This class works for
17
- simplices of any dimension. Nodes are point evaluation at
17
+ simplicial complexes of any dimension. Nodes are point evaluation at
18
18
recursively-defined points.
19
+
20
+ :arg ref_el: The simplicial complex.
21
+ :arg degree: The polynomial degree.
22
+ :arg point_variant: The point distribution variant passed on to recursivenodes.
23
+ :arg sort_entities: A flag to sort entities by support vertex ids.
24
+ If false then entities are sorted first by dimension and then by
25
+ entity id. The DOFs are always sorted by the entity ordering
26
+ and then lexicographically by lattice multiindex.
19
27
"""
20
- def __init__ (self , ref_el , degree , point_variant = "equispaced" ):
21
- entity_ids = {}
28
+ def __init__ (self , ref_el , degree , point_variant = "equispaced" , sort_entities = False ):
22
29
nodes = []
30
+ entity_ids = {}
23
31
entity_permutations = {}
24
-
25
- # make nodes by getting points
26
- # need to do this dimension-by-dimension, facet-by-facet
27
32
top = ref_el .get_topology ()
28
-
29
- cur = 0
30
33
for dim in sorted (top ):
31
34
entity_ids [dim ] = {}
32
35
entity_permutations [dim ] = {}
33
36
perms = {0 : [0 ]} if dim == 0 else make_entity_permutations_simplex (dim , degree - dim )
34
37
for entity in sorted (top [dim ]):
35
- pts_cur = ref_el .make_points (dim , entity , degree , variant = point_variant )
36
- nodes_cur = [functional .PointEvaluation (ref_el , x )
37
- for x in pts_cur ]
38
- nnodes_cur = len (nodes_cur )
39
- nodes += nodes_cur
40
- entity_ids [dim ][entity ] = list (range (cur , cur + nnodes_cur ))
41
- cur += nnodes_cur
42
38
entity_permutations [dim ][entity ] = perms
43
39
40
+ entities = [(dim , entity ) for dim in sorted (top ) for entity in sorted (top [dim ])]
41
+ if sort_entities :
42
+ # sort the entities by support vertex ids
43
+ support = [top [dim ][entity ] for dim , entity in entities ]
44
+ entities = [entity for verts , entity in sorted (zip (support , entities ))]
45
+
46
+ # make nodes by getting points
47
+ # need to do this entity-by-entity
48
+ for dim , entity in entities :
49
+ cur = len (nodes )
50
+ pts_cur = ref_el .make_points (dim , entity , degree , variant = point_variant )
51
+ nodes .extend (functional .PointEvaluation (ref_el , x ) for x in pts_cur )
52
+ entity_ids [dim ][entity ] = list (range (cur , len (nodes )))
44
53
super (LagrangeDualSet , self ).__init__ (nodes , ref_el , entity_ids , entity_permutations )
45
54
46
55
@@ -58,12 +67,16 @@ class Lagrange(finite_element.CiarletElement):
58
67
variant='equispaced,Iso(2)' with degree=1 gives the P2:P1 iso element.
59
68
variant='Alfeld' can be used to obtain a barycentrically refined
60
69
macroelement for Scott-Vogelius.
70
+ :arg sort_entities: A flag to sort entities by support vertex ids.
71
+ If false then entities are sorted first by dimension and then by
72
+ entity id. The DOFs are always sorted by the entity ordering
73
+ and then lexicographically by lattice multiindex.
61
74
"""
62
- def __init__ (self , ref_el , degree , variant = "equispaced" ):
75
+ def __init__ (self , ref_el , degree , variant = "equispaced" , sort_entities = False ):
63
76
splitting , point_variant = parse_lagrange_variant (variant )
64
77
if splitting is not None :
65
78
ref_el = splitting (ref_el )
66
- dual = LagrangeDualSet (ref_el , degree , point_variant = point_variant )
79
+ dual = LagrangeDualSet (ref_el , degree , point_variant = point_variant , sort_entities = sort_entities )
67
80
if ref_el .shape == LINE :
68
81
# In 1D we can use the primal basis as the expansion set,
69
82
# avoiding any round-off coming from a basis transformation
0 commit comments