Primarily: fixed the gmsh module to use integer indices

also did some pep8/pyflakes cleanup
This commit is contained in:
Stephen M. McQuay 2011-09-27 15:23:42 -06:00
parent 0ae558f660
commit 1af176a6e0
9 changed files with 1131 additions and 1110 deletions

View File

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

View File

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

View File

@ -16,7 +16,18 @@ class grid(object):
pass pass
def get_simplex_extra_points(self, X, extra_points=8): 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): def interpolate(self, X, order=2, extra_points=3):
r, s = self.get_simplex_extra_points(X, extra_points=extra_points) 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, def dump_to_blender_files(self,
pfile='/tmp/points.p', cfile='/tmp/cells.p'): pfile='/tmp/points.p', cfile='/tmp/cells.p'):
if len(self.verts[0]) == 2: if len(self.points[0]) == 2:
pickle.dump([(p[0], p[1], 0.0) for p in self.verts], pickle.dump([(p[0], p[1], 0.0) for p in self.points.tolist()],
open(pfile, 'w')) open(pfile, 'w'))
else: 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')) open(pfile, 'w'))
pickle.dump([f.verts for f in self.cells.itervalues()], pickle.dump([face for face in self.simplices.tolist()],
open(cfile, 'w')) 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)
return simplex_ids, extra_points_ids
def contains(X, R): def contains(X, R):
""" """

View File

@ -1,7 +1,6 @@
import scipy.spatial import scipy.spatial
from interp.grid import grid as basegrid from interp.grid import grid as basegrid
from interp.grid import get_simplex_extra_points
class dgrid(basegrid): class dgrid(basegrid):
@ -9,8 +8,8 @@ class dgrid(basegrid):
self.points = points self.points = points
self.values = values self.values = values
self.triangulation = scipy.spatial.Delaunay(points) 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): def find_simplex(self, X):
return get_simplex_extra_points(X, self.points, self.triangulation, return self.triangulation.find_simplex(X)
self.kdtree, extra_points=extra_points)

View File

@ -3,99 +3,119 @@ from itertools import combinations
import numpy as np import numpy as np
from scipy.spatial import KDTree from scipy.spatial import KDTree
from interp.grid import grid from interp.grid import grid, contains
from interp.grid import cell
import logging
log = logging.getLogger('interp')
THREE_NODE_TRIANGLE = 2 THREE_NODE_TRIANGLE = 2
FOUR_NODE_TET = 4 FOUR_NODE_TET = 4
MAX_SEARCH_COUNT = 256
EDGES_FOR_FACE_CONNECTIVITY = 2
EDGES_FOR_VOLUME_CONNECTIVITY = 3
class ggrid(grid): class ggrid(grid):
def __init__(self, filename, values=None, dimension=3):
def __init__(self, filename, dimension = 3):
""" """
construct an interp.grid.grid-compliant grid construct an interp.grid.grid-compliant grid
object out of a {2,3}D gmsh file object out of a {2,3}D gmsh file
""" """
self.dim = dimension self.dim = dimension
log.debug("dimension: %d", self.dim) self.values = None
gmsh_file = open(filename, 'r') gmsh_file = open(filename, 'r')
gmsh_file.readline() # $MeshFormat gmsh_file.readline() # $MeshFormat
gmsh_file.readline() fmt = gmsh_file.readline()
self.version, self.file_type, self.data_size = fmt.split()
gmsh_file.readline() # $EndMeshFormat gmsh_file.readline() # $EndMeshFormat
gmsh_file.readline() # $Nodes gmsh_file.readline() # $Nodes
node_count = int(gmsh_file.readline()) node_count = int(gmsh_file.readline())
self.verts = np.empty((node_count, dimension)) self.points = np.empty((node_count, dimension), dtype=np.float64)
self.q = np.empty(node_count) self.q = np.empty(node_count)
for i in xrange(node_count): for i in xrange(node_count):
cur_line = gmsh_file.readline() cur_line = gmsh_file.readline()
(index, x,y,z) = cur_line.split() (index, x, y, z) = cur_line.split()
index = int(index) - 1 index = int(index) - 1
self.verts[i][0] = float(x) self.points[i][0] = float(x)
self.verts[i][1] = float(y) self.points[i][1] = float(y)
if self.dim == 3: if self.dim == 3:
self.verts[i][2] = float(z) self.points[i][2] = float(z)
self.tree = KDTree(self.points)
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() # $EndNodes
gmsh_file.readline() # $Elements gmsh_file.readline() # $Elements
# temporary dict used to compute cell connectivity
neighbors = {} neighbors = {}
simplices = []
self.point_to_simplex = [[] for i in xrange(len(self.points))]
simplex_counter = 0
element_count = int(gmsh_file.readline()) element_count = int(gmsh_file.readline())
for i in xrange(element_count): for simplex_id in xrange(element_count):
cur_line = gmsh_file.readline() cur_line = gmsh_file.readline()
cur_line = cur_line.split() cur_line = cur_line.split()
cur_cell_index, node_type, rest = (int(cur_line[0]), simplex_index, node_type, rest = (int(cur_line[0]),
int(cur_line[1]), int(cur_line[1]),
[int(j) for j in cur_line[2:]]) [int(j) for j in cur_line[2:]])
if (node_type == THREE_NODE_TRIANGLE and self.dim == 2) \ if (node_type == THREE_NODE_TRIANGLE and self.dim == 2) \
or (node_type == FOUR_NODE_TET and self.dim == 3): or (node_type == FOUR_NODE_TET and self.dim == 3):
points_for_cur_cell = [i-1 for i in rest[rest[0]+1:]] 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
cur_cell = cell(cur_cell_index) self.simplex_to_simplex = [[] for i in xrange(len(simplices))]
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 simplex in xrange(len(simplices)):
edges = [tuple(sorted(i)) for i in \
combinations(simplices[simplex], self.dim)]
for edge in edges: for edge in edges:
if edge in neighbors: if edge in neighbors:
neighbors[edge].append(cur_cell_index) neighbors[edge].append(simplex)
else: else:
neighbors[edge] = [cur_cell_index] neighbors[edge] = [simplex]
for k,v in neighbors.iteritems(): for k, v in neighbors.iteritems():
if len(v) > 1: if len(v) > 1:
self.cells[v[0]].add_neighbor(self.cells[v[1]]) self.simplex_to_simplex[v[0]].append(v[1])
self.cells[v[1]].add_neighbor(self.cells[v[0]]) 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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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