Parcourir la source

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

master
Stephen Mardson McQuay il y a 9 ans
Parent
révision
f4b2c95cf5
5 fichiers modifiés avec 152 ajouts et 20 suppressions
  1. +14
    -1
      bin/driver-random.py
  2. +56
    -15
      lib/baker.py
  3. +5
    -3
      test/baker.test.py
  4. +76
    -0
      test/baker3d.test.py
  5. +1
    -1
      tools/multi/smp.py

+ 14
- 1
bin/driver-random.py Voir le fichier

@@ -35,9 +35,22 @@ if __name__ == '__main__':
print >> sys.stderr, "wrote output to %s" % options.output

errors = []
success = 0
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)
errors.append(cur_error)

print rms(errors)
print "%s of %s won" % (success, options.destination_total)

+ 56
- 15
lib/baker.py Voir le fichier

@@ -16,11 +16,14 @@ def get_phis(X, r):

# baker: eq 7
A = np.array([
[1, 1, 1 ],
[ 1, 1, 1],
[r[0][0], r[1][0], r[2][0]],
[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:
phi = np.linalg.solve(A,b)
except:
@@ -29,6 +32,39 @@ def get_phis(X, r):

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

tree -- the kdtree search object (built from the g mesh)

"""

(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]
nq = [g.q[i] for i in indicies]

phi = get_phis(X, nn[:3])
qlin = nq[0] * phi[0] + nq[1] * phi[1] + nq[2] * phi[2]
# calculate values only for the triangle
phi = get_phis(X, nn[:3])
qlin = qlinear(X, nn[:3], nq[:3])# nq[0] * phi[0] + nq[1] * phi[1] + nq[2] * phi[2]

error_term = 0.0

@@ -91,16 +142,6 @@ def run_baker(X, g, tree, extra_points = 3, verbose = False):
+ b * phi[1] * phi[2]\
+ c * phi[2] * phi[0]

exact = exact_func(X[0], X[1])
q_final = qlin + error_term

if verbose:
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)
return qlin, error_term, q_final

+ 5
- 3
test/baker.test.py Voir le fichier

@@ -2,6 +2,7 @@

import unittest
import baker
import grid

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

self.assertEqual(result, right_answer)


+ 76
- 0
test/baker3d.test.py Voir le fichier

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

+ 1
- 1
tools/multi/smp.py Voir le fichier

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

if __name__ == '__main__':

Chargement…
Annuler
Enregistrer