Browse Source

Primarily: fixed the gmsh module to use integer indices

also did some pep8/pyflakes cleanup
master
Stephen M. McQuay 10 years ago
parent
commit
1af176a6e0
  1. 11
      interp/baker/__init__.py
  2. 4
      interp/bootstrap.py
  3. 34
      interp/grid/__init__.py
  4. 9
      interp/grid/delaunay.py
  5. 206
      interp/grid/gmsh.py
  6. 9
      interp/tools.py
  7. 1
      test/baker2d.py
  8. 2012
      test/delaunay.py
  9. 1
      test/quadratic2d.py

11
interp/baker/__init__.py

@ -142,10 +142,10 @@ def interpolate(X, R, R_q, S=None, S_q=None, order=2):
order - order of interpolation - 1
"""
qlin=None
error_term=None
final=None
abc={}
qlin = None
error_term = None
final = None
abc = {}
# calculate values only for the simplex triangle
phi, qlin = qlinear(X, R, R_q)
@ -161,10 +161,9 @@ def interpolate(X, R, R_q, S=None, S_q=None, order=2):
raise np.linalg.LinAlgError("Pathological Vertex Config")
else:
final = qlin + error_term
elif order not in xrange(2,11):
elif order not in xrange(2, 11):
raise Exception('unsupported order "%d" for baker method' % order)
return Answer(qlin=qlin, error=error_term, final=final, abc=abc)

4
interp/bootstrap.py

@ -13,5 +13,7 @@ def save_history(historyPath=historyPath):
if os.path.exists(historyPath):
readline.read_history_file(historyPath)
rl = rlcompleter
atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath
del os, atexit, readline, rl, save_history, historyPath

34
interp/grid/__init__.py

@ -16,7 +16,18 @@ class grid(object):
pass
def get_simplex_extra_points(self, X, extra_points=8):
pass
# I need two things: find_simplex, and self.simplices
simplex_id = self.find_simplex(X)
simplex_verts_ids = set(self.simplices[simplex_id])
distances, kdt_ids \
= self.tree.query(X, extra_points + len(simplex_verts_ids))
kdt_ids = set(kdt_ids)
simplex_ids = list(simplex_verts_ids)
extra_points_ids = list(kdt_ids - simplex_verts_ids)
return simplex_ids, extra_points_ids
def interpolate(self, X, order=2, extra_points=3):
r, s = self.get_simplex_extra_points(X, extra_points=extra_points)
@ -25,27 +36,16 @@ class grid(object):
def dump_to_blender_files(self,
pfile='/tmp/points.p', cfile='/tmp/cells.p'):
if len(self.verts[0]) == 2:
pickle.dump([(p[0], p[1], 0.0) for p in self.verts],
if len(self.points[0]) == 2:
pickle.dump([(p[0], p[1], 0.0) for p in self.points.tolist()],
open(pfile, 'w'))
else:
pickle.dump([(p[0], p[1], p[2]) for p in self.verts],
pickle.dump([(p[0], p[1], p[2]) for p in self.points.tolist()],
open(pfile, 'w'))
pickle.dump([f.verts for f in self.cells.itervalues()],
open(cfile, 'w'))
def get_simplex_extra_points(X, points, triangulation, kdtree, extra_points=8):
simplex_id = triangulation.find_simplex(X)
simplex_verts_ids = set(triangulation.vertices[simplex_id])
distances, kdt_ids = kdtree.query(X, extra_points + len(simplex_verts_ids))
kdt_ids = set(kdt_ids)
simplex_ids = list(simplex_verts_ids)
extra_points_ids = list(kdt_ids - simplex_verts_ids)
pickle.dump([face for face in self.simplices.tolist()],
open(cfile, 'w'))
return simplex_ids, extra_points_ids
def contains(X, R):
"""

9
interp/grid/delaunay.py

@ -1,7 +1,6 @@
import scipy.spatial
from interp.grid import grid as basegrid
from interp.grid import get_simplex_extra_points
class dgrid(basegrid):
@ -9,8 +8,8 @@ class dgrid(basegrid):
self.points = points
self.values = values
self.triangulation = scipy.spatial.Delaunay(points)
self.kdtree = scipy.spatial.KDTree(points)
self.simplices = self.triangulation.vertices
self.tree = scipy.spatial.KDTree(points)
def get_simplex_extra_points(self, X, extra_points=8):
return get_simplex_extra_points(X, self.points, self.triangulation,
self.kdtree, extra_points=extra_points)
def find_simplex(self, X):
return self.triangulation.find_simplex(X)

206
interp/grid/gmsh.py

@ -1,101 +1,121 @@
from itertools import combinations
from itertools import combinations
import numpy as np
from scipy.spatial import KDTree
from interp.grid import grid
from interp.grid import cell
import logging
log = logging.getLogger('interp')
from scipy.spatial import KDTree
from interp.grid import grid, contains
THREE_NODE_TRIANGLE = 2
FOUR_NODE_TET = 4
EDGES_FOR_FACE_CONNECTIVITY = 2
EDGES_FOR_VOLUME_CONNECTIVITY = 3
FOUR_NODE_TET = 4
MAX_SEARCH_COUNT = 256
class ggrid(grid):
def __init__(self, filename, dimension = 3):
"""
construct an interp.grid.grid-compliant grid
object out of a {2,3}D gmsh file
"""
self.dim = dimension
log.debug("dimension: %d", self.dim)
gmsh_file = open(filename, 'r')
gmsh_file.readline() # $MeshFormat
gmsh_file.readline()
gmsh_file.readline() # $EndMeshFormat
gmsh_file.readline() # $Nodes
node_count = int(gmsh_file.readline())
self.verts = np.empty((node_count, dimension))
self.q = np.empty(node_count)
for i in xrange(node_count):
cur_line = gmsh_file.readline()
(index, x,y,z) = cur_line.split()
index = int(index) - 1
self.verts[i][0] = float(x)
self.verts[i][1] = float(y)
if self.dim == 3:
self.verts[i][2] = float(z)
self.tree = KDTree(self.verts)
# initialize rest of structures about to be populated (cells,
# cells_for_vert)
grid.__init__(self)
gmsh_file.readline() # $EndNodes
gmsh_file.readline() # $Elements
# temporary dict used to compute cell connectivity
neighbors = {}
element_count = int(gmsh_file.readline())
for i in xrange(element_count):
cur_line = gmsh_file.readline()
cur_line = cur_line.split()
cur_cell_index, node_type, rest = (int(cur_line[0]),
int(cur_line[1]),
[int(j) for j in cur_line[2:]])
if (node_type == THREE_NODE_TRIANGLE and self.dim == 2) \
or (node_type == FOUR_NODE_TET and self.dim == 3):
points_for_cur_cell = [i-1 for i in rest[rest[0]+1:]]
cur_cell = cell(cur_cell_index)
for cur_point in points_for_cur_cell:
self.cells_for_vert[cur_point].append(cur_cell)
cur_cell.verts = points_for_cur_cell
self.cells[cur_cell_index] = cur_cell
edges = [tuple(sorted(i)) for i in combinations(points_for_cur_cell, self.dim)]
for edge in edges:
if edge in neighbors:
neighbors[edge].append(cur_cell_index)
else:
neighbors[edge] = [cur_cell_index]
for k,v in neighbors.iteritems():
if len(v) > 1:
self.cells[v[0]].add_neighbor(self.cells[v[1]])
self.cells[v[1]].add_neighbor(self.cells[v[0]])
def __init__(self, filename, values=None, dimension=3):
"""
construct an interp.grid.grid-compliant grid
object out of a {2,3}D gmsh file
"""
self.dim = dimension
self.values = None
gmsh_file = open(filename, 'r')
gmsh_file.readline() # $MeshFormat
fmt = gmsh_file.readline()
self.version, self.file_type, self.data_size = fmt.split()
gmsh_file.readline() # $EndMeshFormat
gmsh_file.readline() # $Nodes
node_count = int(gmsh_file.readline())
self.points = np.empty((node_count, dimension), dtype=np.float64)
self.q = np.empty(node_count)
for i in xrange(node_count):
cur_line = gmsh_file.readline()
(index, x, y, z) = cur_line.split()
index = int(index) - 1
self.points[i][0] = float(x)
self.points[i][1] = float(y)
if self.dim == 3:
self.points[i][2] = float(z)
self.tree = KDTree(self.points)
gmsh_file.readline() # $EndNodes
gmsh_file.readline() # $Elements
neighbors = {}
simplices = []
self.point_to_simplex = [[] for i in xrange(len(self.points))]
simplex_counter = 0
element_count = int(gmsh_file.readline())
for simplex_id in xrange(element_count):
cur_line = gmsh_file.readline()
cur_line = cur_line.split()
simplex_index, node_type, rest = (int(cur_line[0]),
int(cur_line[1]),
[int(j) for j in cur_line[2:]])
if (node_type == THREE_NODE_TRIANGLE and self.dim == 2) \
or (node_type == FOUR_NODE_TET and self.dim == 3):
points_for_simplex = [i - 1 for i in rest[rest[0] + 1:]]
for point in points_for_simplex:
self.point_to_simplex[point].append(simplex_counter)
simplices.append(points_for_simplex)
simplex_counter += 1
self.simplex_to_simplex = [[] for i in xrange(len(simplices))]
for simplex in xrange(len(simplices)):
edges = [tuple(sorted(i)) for i in \
combinations(simplices[simplex], self.dim)]
for edge in edges:
if edge in neighbors:
neighbors[edge].append(simplex)
else:
neighbors[edge] = [simplex]
for k, v in neighbors.iteritems():
if len(v) > 1:
self.simplex_to_simplex[v[0]].append(v[1])
self.simplex_to_simplex[v[1]].append(v[0])
self.simplices = np.array(simplices, dtype=np.int32)
def find_simplex(self, X, max_search_count=MAX_SEARCH_COUNT):
# get closest point
(dist, indicies) = self.tree.query(X, 2)
closest_point = indicies[0]
simplex = None
checked_cells = []
cells_to_check = list(self.point_to_simplex[closest_point])
attempts = 0
while not simplex and cells_to_check:
cur_cell = cells_to_check.pop(0)
checked_cells.append(cur_cell)
R = self.points[self.simplices[cur_cell]]
if contains(X, R):
simplex = cur_cell
continue
attempts += 1
if attempts >= max_search_count:
raise Exception("Is the search becoming exhaustive?"
" (%dth attempt)" % attempts)
for neighbor in self.simplex_to_simplex[cur_cell]:
if (neighbor not in checked_cells) \
and (neighbor not in cells_to_check):
cells_to_check.append(neighbor)
if not simplex:
raise Exception('no containing simplex found')
return simplex

9
interp/tools.py

@ -45,8 +45,9 @@ def baker_exact_3D(X):
np.sin(z * np.pi / 2.0)), 2)
return answer
def exact_me(X, f):
a = np.array([f(i) for i in X])
def exact_me(points, f):
a = np.array([f(i) for i in points])
return a
@ -71,10 +72,12 @@ def improved_answer(answer, exact):
else:
return False
def identical_points(a,b):
def identical_points(a, b):
return all(set(j[i] for j in a) \
== set(j[i] for j in b) for i in xrange(len(a[0])))
def improved(qlin, err, final, exact):
if np.abs(final - exact) <= np.abs(qlin - exact):
return True

1
test/baker2d.py

@ -75,7 +75,6 @@ class Test(unittest.TestCase):
R, R_q = (self.all_points[:size_of_simplex],
self.q[:size_of_simplex])
answer = baker.interpolate(self.X, R, R_q)
good_answer = Answer(qlin=0.5, final=None, error=None, abc={})
self.assertEqual(answer, good_answer)

2012
test/delaunay.py
File diff suppressed because it is too large
View File

1
test/quadratic2d.py

@ -3,7 +3,6 @@
import unittest
from interp.baker import interpolate
from interp.grid import grid
from interp.grid import contains

Loading…
Cancel
Save