Primarily: fixed the gmsh module to use integer indices
also did some pep8/pyflakes cleanup
This commit is contained in:
parent
0ae558f660
commit
1af176a6e0
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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)
|
|
||||||
|
@ -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]])
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
2012
test/delaunay.py
2012
test/delaunay.py
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user