-
Notifications
You must be signed in to change notification settings - Fork 1
/
cst.py
99 lines (66 loc) · 2.68 KB
/
cst.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
""" Implementation of the charge simulation technique. """
import sys
from numpy import *
import pylab
import h5py
from scipy.sparse.linalg import LinearOperator, bicgstab, bicg, gmres
from refinement import Box, containing_box
import mpolar
from plotter import bounding_box, plot_projections
def paraboloid(a, ztip, nz, ntheta, phase_shift=False):
""" Generates points in a paraboloid z - z0 = a * r**2 with ntheta points
in each circular cross-section located at points z. If phase_shift is
True the points are phase-shifted pi / ntheta radians. """
theta = linspace(0, 2 * pi, ntheta)[:-1]
z = linspace(ztip, 0, nz + 1)[1:-1]
if phase_shift:
theta = theta + (theta[1] - theta[0]) / 2
rho = sqrt((z - ztip) / a)
rx = rho * cos(theta[:, newaxis])
ry = rho * sin(theta[:, newaxis])
rz = z + 0 * theta[:, newaxis]
return c_[r_[0, ravel(rx)], r_[0, ravel(ry)], r_[ztip, ravel(rz)]].T
def direct_with_electrode(r, q, reval, conductor_thickness):
u = array([1, 1, -1])[:, newaxis]
rx = concatenate((r, r * u), axis=1)
qx = r_[q, -q]
phi = mpolar.direct(rx, qx, reval, conductor_thickness)
return phi
def build_linop(r, reval, conductor_thickness):
def f_phi(q):
return direct_with_electrode(r, q, reval, conductor_thickness)
return LinearOperator((reval.shape[1], r.shape[1]), f_phi, dtype='float64')
def build_poisson_matrix(r, reval, conductor_thickness):
def main():
ztip = -0.01
rp = paraboloid(800.0, ztip, 16, 16)
rp_phi = paraboloid(1.0, ztip, 16, 16, phase_shift=True)
np = rp.shape[1]
print rp.shape, rp_phi.shape
fname, step = sys.argv[1:3]
fp = h5py.File(fname, "r")
g = fp['main']
r = array(g[step]['r'])
q = array(g[step]['q'])
phi0 = array(g[step]['phi'])
CONDUCTOR_THICKNESS = fp['main'].attrs['conductor_thickness']
MAX_CHARGES_PER_BOX = fp['main'].attrs['max_charges_per_box']
MULTIPOLAR_TERMS = fp['main'].attrs['multipolar_terms']
HAS_PLANAR_ELECTRODE = fp['main'].attrs['has_plane_electrode']
print "%d charges" % len(q)
r[:, 2] += ztip
rt = concatenate((rp, r), axis=1)
# 1. Compute the potential created at the sources and in the phi points
# of the electrode
phi = direct_with_electrode(r, q, rt, CONDUCTOR_THICKNESS)
phip = phi[:np]
print phip
# 2. Solve the charges that will make phi zero in the paraboloid points.
linop = build_linop(rp, rp_phi, CONDUCTOR_THICKNESS)
qp, info = gmres(linop, -phip, tol=1e-6)
print qp
r0, r1 = bounding_box(rt)
plot_projections(rt.T, r_[qp, 0 * q], r0, r1, plot3d=True)
pylab.show()
if __name__ == '__main__':
main()