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

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

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