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 7 Feb 2005 by RCK
10
Module defining topological information for simplices in one, two, and
14
from factorial import factorial
22
class ShapeError( exceptions.Exception ):
23
"""FIAT defined exception type indicating an improper use of a shape."""
24
def __init__( self , args = None ):
28
# enumerated constants for shapes
33
# the dimension associated with each shape
38
# number of topological entities of each dimensions
39
# associated with each shape.
40
# 0 refers to the number of points that make up the simplex
41
# 1 refers to the number of edges
42
# 2 refers to the number of triangles/faces
43
# 3 refers to the number of tetrahedra
44
num_entities = { LINE: { 0: 2 , 1: 1 } , \
45
TRIANGLE: { 0: 3, 1: 3, 2:1 } , \
46
TETRAHEDRON: {0: 4, 1: 6, 2: 4, 3: 1} }
48
# canonical polynomial dimension associated with simplex
50
poly_dims = { LINE: lambda n: max(0,n + 1), \
51
TRIANGLE: lambda n: max(0,(n+1)*(n+2)/2) ,\
52
TETRAHEDRON: lambda n: max(0,(n+1)*(n+2)*(n+3)/6) }
55
# dictionaries of vertices
56
vertices = { LINE : {0: (-1.0,) , 1: (1.0,)} , \
57
TRIANGLE : {0:(-1.0,-1.0),\
60
TETRAHEDRON :{0:(-1.,-1.,-1.), \
66
# FYI -- this is the ordering scheme I'm thinking of.
67
# Should be verified against tetgen or
68
# whatever mesh generator we wind up using
69
tetrahedron_faces = {0:(1,2,3), \
74
tetrahedron_edges = {0:(1,2), \
81
# scaling factors mapping boundary entities of lower dimension to the reference
82
# shape of that dimension. For example, in 2d, two of the edges have length
83
# 2, which is the same length as the reference line. The third is 2 sqrt(2),
84
# so we get two scale factors of 1 and one of sqrt(2.0)
85
jac_factors = { LINE: { 0: { 0: 1.0, \
88
TRIANGLE: { 0: { 0: 1.0 , \
95
TETRAHEDRON : { 0: { 0: 1.0 ,
112
# dictionary of shapes -- for each shape, maps edge number to normal
113
# which is a tuple of floats.
114
normals = { LINE : { 0: (-1.0,) , 1:(1.0,) } , \
115
TRIANGLE : { 0: (rt2_inv,rt2_inv) , \
118
TETRAHEDRON : { 0: (rt3_inv,rt3_inv,rt3_inv) , \
119
1: (-1.0,0.0,0.0) , \
120
2: (0.0,-1.0,0.0) , \
121
3: (0.0,0.0,-1.0) } }
123
tangents = { TETRAHEDRON : { 0: (-rt2_inv,rt2_inv,0.0) , \
124
1: (0.0,-rt2_inv,rt2_inv) , \
125
2: (rt2_inv,0.0,-rt2_inv) , \
126
3: (0.0,0.0,-1.0) , \
130
def scale_factor( shape , d , ent_id ):
132
return jac_factors[ shape ][ d ][ ent_id ]
134
def dimension( shape ):
135
"""returns the topological dimension associated with shape."""
140
raise ShapeError, "Illegal shape: shapes.dimension"
142
def dimension_range( shape ):
143
"""returns the list starting at zero and ending with
144
the topological dimension of shape (inclusive).
145
Hence, dimension_range( s ) is syntactic sugar for
146
range(0,dimension(shape)+1)."""
147
return range(0,dimension(shape)+1);
149
def entity_range( shape , dim ):
150
"""Returns the range of topological entities of dimension dim
151
associated with shape.
152
For example, entity_range( LINE , 0 ) returns the list [0,1]
153
because there are two points associated with the line."""
156
return range(0,num_entities[ shape ][ dim ])
158
raise ShapeError, "Illegal shape or dimension"
160
def polynomial_dimension( shape , n ):
161
"""Returns the number of polynomials of total degree n on the
162
shape n. This (n+1) over the line, (n+1)(n+2)/2 over the
163
triangle, and (n+1)(n+2)(n+3)/6 in three dimensions."""
164
d = dimension( shape )
166
for i in xrange(0,d):
167
td = td * ( n + i + 1 )
168
return td / factorial( d )