summaryrefslogtreecommitdiff
path: root/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
diff options
context:
space:
mode:
Diffstat (limited to 'FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py')
-rw-r--r--FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
new file mode 100644
index 0000000..d77f92e
--- /dev/null
+++ b/FSF-2020/calculus-of-several-variables/div-curl-grad-and-all-that/Curl and Div/DivCurl_file10_gauss.py
@@ -0,0 +1,51 @@
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.patches import Circle
+
+def E(q, r0, x, y):
+ """Return the electric field vector E=(Ex,Ey) due to charge q at r0."""
+ den = np.hypot(x-r0[0], y-r0[1])**3
+ return q * (x - r0[0]) / den, q * (y - r0[1]) / den
+
+# Grid of x, y points
+nx, ny = 64, 64
+x = np.linspace(-2, 2, nx)
+y = np.linspace(-2, 2, ny)
+X, Y = np.meshgrid(x, y)
+
+# Create a multipole with nq charges of alternating sign, equally spaced
+# on the unit circle.
+nq = 2**int(sys.argv[1])
+charges = []
+for i in range(nq):
+ q = i%2 * 2 - 1
+ charges.append((q, (np.cos(2*np.pi*i/nq), np.sin(2*np.pi*i/nq))))
+
+# Electric field vector, E=(Ex, Ey), as separate components
+Ex, Ey = np.zeros((ny, nx)), np.zeros((ny, nx))
+for charge in charges:
+ ex, ey = E(*charge, x=X, y=Y)
+ Ex += ex
+ Ey += ey
+
+fig = plt.figure()
+plt.rcParams['axes.facecolor'] = 'black'
+ax = fig.add_subplot(111)
+
+# Plot the streamlines with an appropriate colormap and arrow style
+color = 2 * np.log(np.hypot(Ex, Ey))
+ax.streamplot(x, y, Ex, Ey, color=color, linewidth=1, cmap=plt.cm.inferno,
+ density=2, arrowstyle='->', arrowsize=1.5)
+
+# Add filled circles for the charges themselves
+charge_colors = {True: '#aa0000', False: '#0000aa'}
+for q, pos in charges:
+ ax.add_artist(Circle(pos, 0.05, color=charge_colors[q>0]))
+
+ax.set_xlabel('$x$')
+ax.set_ylabel('$y$')
+ax.set_xlim(-2,2)
+ax.set_ylim(-2,2)
+ax.set_aspect('equal')
+plt.show()