|
9 | 9 |
|
10 | 10 |
|
11 | 11 | class CubicHermiteDualSet(dual_set.DualSet): |
12 | | - """The dual basis for Lagrange elements. This class works for |
13 | | - simplices of any dimension. Nodes are point evaluation at |
14 | | - equispaced points.""" |
| 12 | + """The dual basis for Hermite elements. This class works for |
| 13 | + simplices of any dimension. Nodes are first order jet at |
| 14 | + vertices and point evaluation at barycenters of 2D entities.""" |
15 | 15 |
|
16 | 16 | def __init__(self, ref_el): |
17 | | - entity_ids = {} |
18 | | - nodes = [] |
19 | | - cur = 0 |
20 | | - |
21 | 17 | # make nodes by getting points |
22 | 18 | # need to do this dimension-by-dimension, facet-by-facet |
23 | 19 | top = ref_el.get_topology() |
24 | 20 | verts = ref_el.get_vertices() |
25 | | - sd = ref_el.get_spatial_dimension() |
26 | | - |
27 | | - # get jet at each vertex |
| 21 | + sd = ref_el.get_topological_dimension() |
| 22 | + entity_ids = {dim: {entity: [] for entity in top[dim]} for dim in top} |
| 23 | + nodes = [] |
28 | 24 |
|
29 | | - entity_ids[0] = {} |
| 25 | + # get first order jet at each vertex |
30 | 26 | for v in sorted(top[0]): |
| 27 | + cur = len(nodes) |
31 | 28 | nodes.append(functional.PointEvaluation(ref_el, verts[v])) |
32 | | - pd = functional.PointDerivative |
33 | | - for i in range(sd): |
34 | | - alpha = [0] * sd |
35 | | - alpha[i] = 1 |
36 | | - |
37 | | - nodes.append(pd(ref_el, verts[v], alpha)) |
| 29 | + if sd == 1: |
| 30 | + # in 1D use normal derivative to support manifolds |
| 31 | + nodes.append(functional.PointNormalDerivative(ref_el, v, verts[v])) |
| 32 | + else: |
| 33 | + nodes.extend(functional.PointDerivative(ref_el, verts[v], alpha) |
| 34 | + for alpha in polynomial_set.mis(sd, 1)) |
| 35 | + entity_ids[0][v].extend(range(cur, len(nodes))) |
38 | 36 |
|
39 | | - entity_ids[0][v] = list(range(cur, cur + 1 + sd)) |
40 | | - cur += sd + 1 |
41 | | - |
42 | | - # now only have dofs at the barycenter, which is the |
43 | | - # maximal dimension |
44 | 37 | # no edge dof |
45 | | - |
46 | | - entity_ids[1] = {} |
47 | | - for i in top[1]: |
48 | | - entity_ids |
49 | | - entity_ids[1][i] = [] |
50 | | - |
| 38 | + # now only add dofs at the barycenter of the 2D entities |
51 | 39 | if sd > 1: |
52 | 40 | # face dof |
53 | 41 | # point evaluation at barycenter |
54 | | - entity_ids[2] = {} |
55 | 42 | for f in sorted(top[2]): |
| 43 | + cur = len(nodes) |
56 | 44 | pt = ref_el.make_points(2, f, 3)[0] |
57 | | - n = functional.PointEvaluation(ref_el, pt) |
58 | | - nodes.append(n) |
59 | | - entity_ids[2][f] = list(range(cur, cur + 1)) |
60 | | - cur += 1 |
61 | | - |
62 | | - for dim in range(3, sd + 1): |
63 | | - entity_ids[dim] = {} |
64 | | - for facet in top[dim]: |
65 | | - entity_ids[dim][facet] = [] |
| 45 | + nodes.append(functional.PointEvaluation(ref_el, pt)) |
| 46 | + entity_ids[2][f].extend(range(cur, len(nodes))) |
66 | 47 |
|
67 | 48 | super().__init__(nodes, ref_el, entity_ids) |
68 | 49 |
|
|
0 commit comments