def line(self, x0):
"""Returns the field line passing through x0.
Refs: http://folk.uib.no/fcihh/seminar/lec1.pdf and lect2.pdf
http://numbercrunch.de/blog/2013/05/visualizing-streamlines/
and especially: "Electric field lines don't work",
http://scitation.aip.org/content/aapt/journal/ajp/64/6/10.1119/1.18237
"""
if None in [XMIN, XMAX, YMIN, YMAX]:
raise ValueError('Domain must be set using init().')
# Set up integrator for the field line
streamline = lambda t, y: list(self.direction(y))
solver = ode(streamline).set_integrator('vode')
# Initialize the coordinate lists
x = [x0]
# Integrate in both the forward and backward directions
dt = 0.008
# Solve in both the forward and reverse directions
for sign in [1, -1]:
# Set the starting coordinates and time
solver.set_initial_value(x0, 0)
# Integrate field line over successive time steps
while solver.successful():
# Find the next step
solver.integrate(solver.t + sign*dt)
# Save the coordinates
if sign > 0:
x.append(solver.y)
else:
x.insert(0, solver.y)
# Check if line connects to a charge
flag = False
for c in self.charges:
if c.is_close(solver.y):
flag = True
break
# Terminate line at charge or if it leaves the area of interest
if flag or not (XMIN < solver.y[0] < XMAX) or \
not YMIN < solver.y[1] < YMAX:
break
return FieldLine(x)
评论列表
文章目录