1
# Written by Robert C. Kirby
2
# Copyright 2005 by The University of Chicago
3
# Distributed under the LGPL license
4
# This work is partially supported by the US Department of Energy
5
# under award number DE-FG02-04ER25650
7
# last modified 2 May 2005
9
import dualbasis, polynomial, functionalset, functional, shapes, points, \
10
quadrature, Numeric, RaviartThomas
12
# (P_k)^d \circplus { p \in (P_k^H)^d : p(x)\cdot x = 0 }
13
# Only defined on tetrahedra
14
# Arnold decomposes as curl^t of RT plus grad P_k
15
# indexint starts at zero
17
def NedelecSpace( k ):
18
shape = shapes.TETRAHEDRON
19
d = shapes.dimension( shape )
20
Vh = RaviartThomas.RTSpace( shape , k )
22
Wh = polynomial.OrthogonalPolynomialSet( shape , k + 1 )
24
curl_trans_rts = [ polynomial.curl_transpose( v ) \
27
curl_trans_rts_coeffs = Numeric.array( [ ctv.dof \
28
for ctv in curl_trans_rts ] )
29
curlTVh = polynomial.PolynomialSet( Vh.base , curl_trans_rts_coeffs )
31
grad_whs = [ polynomial.gradient( w ) for w in Wh ]
32
grad_whs_coeffs = Numeric.array( [ gw.dof for gw in grad_whs ] )
33
gradWh = polynomial.PolynomialSet( Wh.base , grad_whs_coeffs )
35
return polynomial.poly_set_union( curlTVh , gradWh )
37
class NedelecDual( dualbasis.DualBasis ):
38
def __init__( self , U , k ):
39
shape = shapes.TETRAHEDRON
40
# tangent at k+1 points on each edge
42
edge_pts = [ points.make_points( shape , \
44
for i in shapes.entity_range( shape , \
47
mdcb = functional.MakeDirectionalComponentBatch
48
ls_per_edge = [ mdcb( edge_pts[i] , \
49
shapes.tangents[shape][i] ) \
50
for i in shape.entity_range( shape , 1 ) ]
52
edge_ls = reduce( lambda a,b:a+b , ls_per_edge )
54
# cross with normal at dim(P_{k-1}) points per face
55
face_pts = [ points.make_points( shape , \
57
for i in shapes.entity_range( shape , \
60
# internal moments of dim( P_{k-2}) points
61
internal_pts = points.make_points( shape , \
68
for i in shapes.entity_range(shape,1):
71
entity_ids[1][i].append(cur)
74
for i in shapes.entity_range(shape,2):
76
for j in range(len(face_pts[0])):
77
entity_ids[2][i].append[cur]
82
for i in len( face_pts ):
83
entity_ids[3][0].append( cur )
87
class Nedelec( polynomial.FiniteElement ):
88
def __init__( self , k ):
90
Udual = NedelecDual( k , U )
91
polynomial.FiniteElement.__init__( self , Udual , U )