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 6 April 2005
9
"""points.py gives locations for edge, face, tetrahedron points
10
for each simplex shape.
11
The major functions to use are
12
make_lattice( shape , n )
14
make_points( shape , dim , entity_id , order )
15
These functions are used to put down a regular lattice over a simplex
16
or to extract the points associated with particular entities of a
17
particular topological dimension in the lattice of a particular
18
order. This is very useful in determining nodal locations for finite
19
element dual bases."""
22
from curry import curry
28
# these three functions are called within the function
29
# make_lattice (below)
30
def make_lattice_line(n):
31
return tuple( [ ( -1.0 + (2.0 * jj) / n , )\
32
for jj in range(0,n+1) ] )
34
def make_lattice_triangle(n):
35
return tuple( [ ( -1.0 + (2.0 * jj) / n , -1.0 + (2.0 * ii) / n ) \
36
for ii in xrange(0,n+1) \
37
for jj in xrange(0,n-ii+1)] )
39
def make_lattice_tetrahedron( n ):
40
return tuple( [ (-1.+(2.*jj)/n,-1.+(2.*ii)/n,-1.+(2.*kk)/n) \
41
for ii in xrange(0,n+1) \
42
for jj in xrange(0,n-ii+1) \
43
for kk in xrange(0,n-ii-jj+1) ] )
45
lattice_funcs = { shapes.LINE: make_lattice_line , \
46
shapes.TRIANGLE: make_lattice_triangle, \
47
shapes.TETRAHEDRON: make_lattice_tetrahedron }
49
def make_lattice( shape , n ):
52
return lattice_funcs[ shape ]( n )
54
raise shapes.ShapeError, "Illegal shape: points.make_lattice"
57
# Functions that map a single point on the line to an edge
59
pt_to_edge_triangle = { 0:lambda x: (-x[0],x[0]), \
60
1:lambda x: (-1.0,-x[0]), \
61
2:lambda x: (x[0],-1.0) }
64
tuple_pt_to_edge_triangle = { 0:lambda x: (-x[0],x[0]), \
65
1:lambda x: (-1.0,-x[0]), \
66
2:lambda x: (x[0],-1.0) }
68
tuple_pt_to_edge_tetrahedron = { 0: lambda x: (-x[0],x[0],-1.), \
69
1: lambda x: (-1.,-x[0],x[0]), \
70
2: lambda x: (x[0],-1.,-x[0]), \
71
3: lambda x: (-1.,-1.,-x[0]), \
72
4: lambda x: (-1.,x[0],-1.), \
73
5: lambda x: (x[0],-1.,-1.) }
76
tuple_pt_to_edge = { shapes.TRIANGLE: tuple_pt_to_edge_triangle , \
77
shapes.TETRAHEDRON: tuple_pt_to_edge_tetrahedron }
79
# Functions that map a single point on the line to an edge
81
pt_to_edge_tetrahedron = { 0: lambda x: (-x[0],x[0],-1.), \
82
1: lambda x: (-1.,-x[0],x[0]), \
83
2: lambda x: (x[0],-1.,-x[0]), \
84
3: lambda x: (-1.,-1.,-x[0]), \
85
4: lambda x: (-1.,x[0],-1.), \
86
5: lambda x: (x[0],-1.,-1.) }
88
# functions that take a point in the plane (ref triangle) and
89
# map it to the appropriate face of the ref tet
90
pt_to_face_tetrahedron = { 0: lambda x: (-x[0]-x[1]-1.,x[0],x[1]),
91
1: lambda x: (-1.,-x[0]-x[1]-1.,x[0]),
92
2: lambda x: (x[1],-1.,-x[0]-x[1]-1.), \
93
3: lambda x: (x[0],x[1],-1.) }
95
# dictionaries that dispatch on shape type
96
pt_to_edge = { shapes.TRIANGLE: pt_to_edge_triangle , \
97
shapes.TETRAHEDRON: pt_to_edge_tetrahedron }
99
pt_to_face = { shapes.TETRAHEDRON: pt_to_face_tetrahedron }
101
pt_maps = { shapes.LINE : { } , \
102
shapes.TRIANGLE: { 1 : pt_to_edge_triangle } , \
103
shapes.TETRAHEDRON: { 1 : pt_to_edge_tetrahedron , \
104
2 : pt_to_face_tetrahedron } }
108
# functions that get points of a particular order
109
# on a mesh component of particular dimension
110
# these are not needed in the public interface,
111
# which is simply the function make_points.
113
def make_vertex_points_line( vid , order ):
115
return ( shapes.vertices[shapes.LINE][vid] , )
117
raise RuntimeError, "Illegal vertex number"
119
def make_vertex_points_triangle( vid , order ):
122
return ( shapes.vertices[shapes.TRIANGLE][vid], )
124
raise RuntimeError, "Illegal vertex number"
126
def make_vertex_points_tetrahedron( vid , order ):
129
return ( shapes.vertices[shapes.TETRAHEDRON][vid], )
131
raise RuntimeError, "Illegal vertex number"
133
def make_edge_points_line( eid , order ):
135
raise RuntimeError, "Illegal edge number"
137
return tuple( map(lambda x: (x,) ,line_range(order)) )
139
def make_edge_points_triangle( eid , order ):
140
global pt_to_edge_triangle
142
return tuple( [ pt_to_edge_triangle[eid]( x ) \
143
for x in line_range( order ) ] )
145
raise RuntimeError, "Illegal edge number."
147
def make_edge_points_tetrahedron( eid , order ):
148
global pt_to_edge_tetrahedron
150
return tuple( [ pt_to_edge_tetrahedron[eid]( x ) \
151
for x in line_range( order ) ] )
153
raise RuntimeError, "Illegal edge number"
155
def make_face_points_tetrahedron( fid , order ):
157
return tuple( [ pt_to_face_tetrahedron[fid]( x ) \
159
make_interior_points_triangle( 0 , order ) ] )
161
raise RuntimeError, "Can't make triangle points"
164
def make_interior_points_triangle( iid , order ):
166
raise RuntimeError, "Illegal id"
167
return tuple( [ ( -1.0 + (2.0 * jj) / order , \
168
-1.0 + (2.0 * ii) / order ) \
169
for ii in range(1,order-1) \
170
for jj in range(1,order-ii)] )
172
def make_interior_points_tetrahedron( iid , n ):
174
raise RuntimeError, "Illegal id"
175
return tuple( [ (-1.+(2.*jj)/n,-1.+(2.*ii)/n,-1.+(2.*kk)/n) \
176
for ii in xrange(1,n) \
177
for jj in xrange(1,n-ii) \
178
for kk in xrange(1,n-ii-jj) ] )
182
f = curry( lambda m,i : (-1.0 + (2.0*i)/m,) , n )
183
return tuple( map( f , range(1,n) ) )
187
# f = curry( lambda m,i : -1.0 + (2.0*i)/m , n )
188
# return tuple( map( f , range(1,n) ) )
190
# dictionaries mapping dimension of mesh entities to
191
# functions for generating points of a particular order
192
# on those mesh entities
194
line_pts = { 0: make_vertex_points_line , \
195
1: make_edge_points_line }
197
tri_pts = { 0: make_vertex_points_triangle , \
198
1: make_edge_points_triangle , \
199
2: make_interior_points_triangle }
201
tet_pts = { 0: make_vertex_points_tetrahedron , \
202
1: make_edge_points_tetrahedron , \
203
2: make_face_points_tetrahedron , \
204
3: make_interior_points_tetrahedron }
206
pt_funcs = { shapes.LINE: line_pts , \
207
shapes.TRIANGLE: tri_pts , \
208
shapes.TETRAHEDRON: tet_pts }
210
def make_points( shape , dim , entity_id , order ):
211
"""Main public interface for getting points associated with mesh
212
components on reference domain. You give it a shape
213
( defined in shapes.py) the topological dimension of the
214
entity (0 for vertices, 1 for lines, etc), the id of the mesh
215
entity of that dimension, and the order of points, and it gives
216
you the appropriate tuple."""
219
return pt_funcs[ shape ][ dim ]( entity_id , order )
221
raise RuntimeError, "Can't make those points"
224
def barycentric_to_ref_tri( pt_bary ):