working on adding 3D baker. also starting to massage together a good baker method test (2D), and added a stub file for 3D testing

This commit is contained in:
Stephen Mardson McQuay 2010-01-29 11:56:52 -07:00
parent 961b3b7b26
commit f4b2c95cf5
5 changed files with 152 additions and 20 deletions

View File

@ -35,9 +35,22 @@ if __name__ == '__main__':
print >> sys.stderr, "wrote output to %s" % options.output print >> sys.stderr, "wrote output to %s" % options.output
errors = [] errors = []
success = 0
for x in mesh_dest.points: for x in mesh_dest.points:
(final, exact) = baker.run_baker(x, mesh_source, tree, options.extra, options.verbose) lin, error, final = baker.run_baker(x, mesh_source, tree, options.extra, options.verbose)
exact = exact_func(x[0], x[1])
if np.abs(exact - final) < np.abs(exact - lin):
success += 1
if options.verbose:
print "current point : %s" % x
print "exact : %0.4f" % exact
print "qlin : %0.4f" % lin
print "q_final : %0.4f" % final
print "qlinerr : %0.4f" % (exact - lin,)
print "q_final_err : %0.4f" % (exact - final,)
cur_error = np.abs(final - exact) cur_error = np.abs(final - exact)
errors.append(cur_error) errors.append(cur_error)
print rms(errors) print rms(errors)
print "%s of %s won" % (success, options.destination_total)

View File

@ -16,11 +16,14 @@ def get_phis(X, r):
# baker: eq 7 # baker: eq 7
A = np.array([ A = np.array([
[1, 1, 1 ], [ 1, 1, 1],
[r[0][0], r[1][0], r[2][0]], [r[0][0], r[1][0], r[2][0]],
[r[0][1], r[1][1], r[2][1]], [r[0][1], r[1][1], r[2][1]],
]) ])
b = np.array([1, X[0], X[1]]) b = np.array([ 1,
X[0],
X[1]
])
try: try:
phi = np.linalg.solve(A,b) phi = np.linalg.solve(A,b)
except: except:
@ -29,6 +32,39 @@ def get_phis(X, r):
return phi return phi
def get_phis_3D(X, r):
"""
The get_phis function is used to get barycentric coordonites for a point on a triangle.
X -- the destination point (3D)
X = [0,0,0]
r -- the four points that make up the tetrahedron (3D)
r = [[-1, -1], [0, 2], [1, -1]]
this will return [0.333, 0.333, 0.333]
"""
# baker: eq 7
A = np.array([
[ 1, 1, 1, 1 ],
[r[0][0], r[1][0], r[2][0], r[3][0]],
[r[0][1], r[1][1], r[2][1], r[3][1]],
[r[0][2], r[1][2], r[2][2], r[3][2]],
])
b = np.array([ 1,
X[0],
X[1],
X[2]
])
try:
phi = np.linalg.solve(A,b)
except:
print >> sys.stderr, "warning: calculation of phis yielded a linearly dependant system"
phi = np.dot(np.linalg.pinv(A), b)
return phi
def qlinear(X, r, q): def qlinear(X, r, q):
""" """
this calculates the linear portion of q from X to r this calculates the linear portion of q from X to r
@ -42,6 +78,19 @@ def qlinear(X, r, q):
qlin = sum([q_i * phi_i for q_i, phi_i in zip(q[:len(phis)], phis)]) qlin = sum([q_i * phi_i for q_i, phi_i in zip(q[:len(phis)], phis)])
return qlin return qlin
def qlinear_3D(X, r, q):
"""
this calculates the linear portion of q from X to r
X = destination point
r = simplex points
q = CFD quantities of interest at the simplex points(r)
"""
phis = get_phis_3D(X, r)
qlin = sum([q_i * phi_i for q_i, phi_i in zip(q[:len(phis)], phis)])
return qlin
def run_baker(X, g, tree, extra_points = 3, verbose = False): def run_baker(X, g, tree, extra_points = 3, verbose = False):
""" """
This is the main function to call to get an interpolation to X from the tree This is the main function to call to get an interpolation to X from the tree
@ -52,6 +101,7 @@ def run_baker(X, g, tree, extra_points = 3, verbose = False):
g -- the grid object g -- the grid object
tree -- the kdtree search object (built from the g mesh) tree -- the kdtree search object (built from the g mesh)
""" """
(dist, indicies) = tree.query(X, 3 + extra_points) (dist, indicies) = tree.query(X, 3 + extra_points)
@ -59,8 +109,9 @@ def run_baker(X, g, tree, extra_points = 3, verbose = False):
nn = [g.points[i] for i in indicies] nn = [g.points[i] for i in indicies]
nq = [g.q[i] for i in indicies] nq = [g.q[i] for i in indicies]
# calculate values only for the triangle
phi = get_phis(X, nn[:3]) phi = get_phis(X, nn[:3])
qlin = nq[0] * phi[0] + nq[1] * phi[1] + nq[2] * phi[2] qlin = qlinear(X, nn[:3], nq[:3])# nq[0] * phi[0] + nq[1] * phi[1] + nq[2] * phi[2]
error_term = 0.0 error_term = 0.0
@ -91,16 +142,6 @@ def run_baker(X, g, tree, extra_points = 3, verbose = False):
+ b * phi[1] * phi[2]\ + b * phi[1] * phi[2]\
+ c * phi[2] * phi[0] + c * phi[2] * phi[0]
exact = exact_func(X[0], X[1])
q_final = qlin + error_term q_final = qlin + error_term
if verbose: return qlin, error_term, q_final
print "current point : %s" % X
print "exact : %0.4f" % exact
print "qlin : %0.4f" % qlin
print "qlinerr : %0.4f" % np.abs(exact - qlin)
print "q_final : %0.4f" % q_final
print "q_final_err : %0.4f" % np.abs(exact - q_final)
print
return (q_final, exact)

View File

@ -2,6 +2,7 @@
import unittest import unittest
import baker import baker
import grid
import numpy as np import numpy as np
import scipy.spatial import scipy.spatial
@ -62,11 +63,12 @@ class TestSequenceFunctions(unittest.TestCase):
[-1,-1], # 8 [-1,-1], # 8
] ]
q = [1, 0, 0, 0, 0, 0, 0, 0, 0] q = [1, 0, 0, 0, 0, 0, 0, 0, 0]
mesh = grid.grid(all_points, q)
tree = scipy.spatial.KDTree(all_points) tree = scipy.spatial.KDTree(all_points)
baker.run_baker(X, (final, exact) = baker.run_baker(X, mesh, tree)
print final, exact
result = 3 result = 3
right_answer = 5 right_answer = 3
self.assertEqual(result, right_answer) self.assertEqual(result, right_answer)

76
test/baker3d.test.py Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/python
import unittest
import baker
import numpy as np
import scipy.spatial
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.l = [[-1, 1], [-1, 0], [-1, 1], [0, -1], [0, 0], [0, 1], [1, -1], [1, 0], [1, 1]]
self.r = [[1,2,3], [2,2,3], [1,3,3], [1,2,9]]
self.approx_fmt = "%0.6f"
def testGetPhis(self):
X = [0,0]
r = [[-1, -1], [0, 2], [1, -1]]
result = baker.get_phis(X, r)
result = [self.approx_fmt % i for i in result]
right_answer = [self.approx_fmt % i for i in [1/3.0, 1/3.0, 1/3.0]]
for a,b in zip(result, right_answer):
self.assertEqual(a,b)
def testGetPhis2(self):
X = [0.5,0.25]
r = [[0, 0], [1, 0], [1, 1]]
result = baker.get_phis(X, r)
right_answer = [0.5, 0.25, 0.25]
for a,b in zip(result, right_answer):
self.assertEqual(a,b)
def testQlinear(self):
X = [0.5, 0.25]
r = [[0, 0], [1, 0], [1, 1]]
q = [1, 0, 0]
result = baker.qlinear(X, r, q)
right_answer = 0.5
self.assertEqual(result, right_answer)
def testRunBaker(self):
X = [0.5, 0.25]
all_points = [
[ 0, 0], # 0
[ 1, 0], # 1
[ 1, 1], # 2
[ 0, 1], # 3
[ 1,-1], # 4
[ 0,-1], # 5
[-1, 1], # 6
[-1, 0], # 7
[-1,-1], # 8
]
q = [1, 0, 0, 0, 0, 0, 0, 0, 0]
tree = scipy.spatial.KDTree(all_points)
baker.run_baker(X,
result = 3
right_answer = 5
self.assertEqual(result, right_answer)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

View File

@ -6,7 +6,7 @@ def f(l, i, d):
d['a'] = 'shutup' d['a'] = 'shutup'
print 'hello world', i, d print 'hello world', i, d
j = 0.0 j = 0.0
for i in xrange(1000000): for i in xrange(10000000):
j = j + j/2.0 j = j + j/2.0
if __name__ == '__main__': if __name__ == '__main__':