Browse Source

Primarily: fixed the gmsh module to use integer indices

also did some pep8/pyflakes cleanup
master
Stephen M. McQuay 9 years ago
parent
commit
1af176a6e0
9 changed files with 1154 additions and 1133 deletions
  1. +5
    -6
      interp/baker/__init__.py
  2. +3
    -1
      interp/bootstrap.py
  3. +17
    -17
      interp/grid/__init__.py
  4. +4
    -5
      interp/grid/delaunay.py
  5. +113
    -93
      interp/grid/gmsh.py
  6. +6
    -3
      interp/tools.py
  7. +0
    -1
      test/baker2d.py
  8. +1006
    -1006
      test/delaunay.py
  9. +0
    -1
      test/quadratic2d.py

+ 5
- 6
interp/baker/__init__.py View File

@@ -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)




+ 3
- 1
interp/bootstrap.py View File

@@ -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

+ 17
- 17
interp/grid/__init__.py View File

@@ -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):
"""


+ 4
- 5
interp/grid/delaunay.py View File

@@ -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)

+ 113
- 93
interp/grid/gmsh.py View File

@@ -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

+ 6
- 3
interp/tools.py View File

@@ -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


+ 0
- 1
test/baker2d.py View File

@@ -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)


+ 1006
- 1006
test/delaunay.py
File diff suppressed because it is too large
View File


+ 0
- 1
test/quadratic2d.py View File

@@ -3,7 +3,6 @@
import unittest

from interp.baker import interpolate
from interp.grid import grid
from interp.grid import contains




Loading…
Cancel
Save