{"id":92,"date":"2025-05-24T04:22:31","date_gmt":"2025-05-24T04:22:31","guid":{"rendered":"https:\/\/synchrotron-light.net\/wp\/?page_id=92"},"modified":"2025-07-20T05:12:43","modified_gmt":"2025-07-20T05:12:43","slug":"chapter-2-introduction-to-special-relativity","status":"publish","type":"page","link":"https:\/\/synchrotron-light.net\/wp\/?page_id=92","title":{"rendered":"Chapter 2: Introduction to special relativity"},"content":{"rendered":"<p>Below is a set of python codes associated with Chapter 2 of Daniele Pelliccia and David M. Paganin, &#8220;Synchrotron Light: A Physics Journey from Laboratory to Cosmos&#8221; (Oxford University Press, 2025).<\/p>\n<p>In order to run any of these python codes, you will need to include the following header file.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">import numpy as np\r\nimport matplotlib.pyplot as plt\r\nfrom matplotlib.patches import Circle\r\n\r\nsynchrotron_style = {\r\n    'font.family': 'FreeSerif',\r\n    'font.size': 30,\r\n    'axes.linewidth': 2.0,\r\n    'axes.edgecolor': 'black',\r\n    'grid.color': '#5b5b5b',\r\n    'grid.linewidth': 1.2,\r\n}<\/pre>\n<h2>Plot of the Lorentz factor<\/h2>\n<p>See Fig. 2.7.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">c = 1. # set the speed of light in natural units\r\nv = np.linspace(0, c, 50000, endpoint=False) # define an array containing the value of the velocity\r\ngamma = 1.0\/ np.sqrt(1.0 - v**2\/c**2)\r\n\r\nfig = plt.figure(figsize=(9,6))\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    \r\n    plt.rcParams.update(synchrotron_style)\r\n    plt.semilogy(v,gamma, lw=4)\r\n    plt.xlabel('v\/c', fontsize=30)\r\n    plt.ylabel('$\\gamma$', fontsize=30)\r\n\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-100 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.7.png\" alt=\"\" width=\"594\" height=\"403\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.7.png 594w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.7-480x326.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 594px, 100vw\" \/><\/p>\n<h2 id=\"An-infinity-of-stacked-carts\">An infinity of stacked carts<\/h2>\n<p>See computational exercise on page 29, together with Figs. 2.14-2.15.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true \">ncarts = 500\r\n\r\nV = 0.01 # start with a velocity that is 1% of the speed of light\r\nv_th = np.zeros(ncarts) # Theory \r\nv_gal = np.zeros(ncarts) # Galileo transformation\r\nv_lor = np.zeros(ncarts) # Lorentz transformation\r\n\r\n# Set the first velocity to V\r\nv_th[0] = V\r\nv_gal[0] = V\r\nv_lor[0] = V\r\n\r\nfor i in range(1,ncarts,1):\r\n    \r\n    v_th[i] = ( (1+v_th[0])**i - (1-v_th[0])**i ) \/ ( (1+v_th[0])**i + (1-v_th[0])**i )\r\n    v_lor[i] = (v_lor[i-1]+V) \/ (1+ v_lor[i-1]*V)\r\n    v_gal[i] = v_gal[i-1]+V<\/pre>\n<pre class=\"theme:obsidian lang:python decode:true\">fig = plt.figure(figsize=(10,10))\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    plt.plot(v_lor, color='r', lw=6, alpha=0.75, label = 'Numerical computation')\r\n    plt.plot(v_th, 'k', lw=2, label = 'Theory')\r\n    plt.plot(v_gal, lw=3, label = 'Non-relativistic limit')\r\n    plt.ylim(-0.1,1.5)\r\n    plt.legend(fontsize = 32, frameon=True, loc = 'lower right', framealpha=0.9)\r\n    plt.xticks(fontsize = 32)\r\n    plt.yticks(fontsize = 32)\r\n    plt.xlabel('Number of carts', fontsize=32, labelpad=10)\r\n    plt.ylabel(\"$v\/c$\", rotation=90, fontsize=32, labelpad=10)\r\n\r\n    plt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-105 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.15.png\" alt=\"\" width=\"655\" height=\"630\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.15.png 655w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.15-480x462.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 655px, 100vw\" \/><\/p>\n<h2 id=\"Relativistic-aberration\">Relativistic aberration<\/h2>\n<p>See Fig. 2.17.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">gamma = 1000 # Set gamma = 100 to generate Fig. 2.17(a)\r\nbeta = np.sqrt(1-gamma**(-2))\r\nthetap = np.linspace(0, 2*np.pi, 1000, endpoint=False)\r\ntheta = np.arcsin( np.sin(thetap)\/ (gamma*(1+beta*np.cos(thetap)) ))\r\n\r\nr = np.ones(thetap.shape[0])\r\n\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    fig = plt.figure(figsize=(5,5))\r\n    ax = fig.add_subplot(111, projection='polar')\r\n    ax.plot(thetap, r, 'o', alpha=0.5, label=\"$\\\\theta'$\")\r\n    ax.plot(theta, r, 'o', ms = 6, markerfacecolor='r', markeredgecolor='r', alpha = 0.4, label=\"$\\\\theta$\") # markeredgecolor='r'\r\n    ax.set_yticklabels([])\r\n    ax.tick_params(axis='x', which='major', pad=15)\r\n    plt.xticks(fontsize = 24)    \r\n\r\n    plt.legend(fontsize = 24, frameon=True)\r\n\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-102 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.17.png\" alt=\"\" width=\"364\" height=\"351\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.17.png 364w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.17-300x289.png 300w\" sizes=\"(max-width: 364px) 100vw, 364px\" \/><\/p>\n<h2 id=\"Longitudinal-Doppler-effect\">Longitudinal Doppler effect<\/h2>\n<p>See Fig. 2.20 for a plot of the dependency of the ratio <span class=\"wp-katex-eq\" data-display=\"false\">\\omega&#039; \/ \\omega<\/span> as a function of the velocity, for four values of the direction angle <span class=\"wp-katex-eq\" data-display=\"false\">\\theta<\/span>.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">c = 1. # set the speed of light in natural units\r\nv = np.linspace(0, c, 500, endpoint=False) # define an array containing the value of the velocity\r\nbeta = v\/c\r\ngamma = 1.0\/ np.sqrt(1.0 - v**2\/c**2)\r\n\r\ntheta1 = 0 \r\ntheta2 = np.pi\/4\r\ntheta3 = np.pi\/2\r\ntheta4 = np.pi\r\n\r\nfig = plt.figure(figsize=(9,12))\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    \r\n    plt.rcParams.update(synchrotron_style)\r\n    \r\n    plt.semilogy(beta, np.ones(beta.shape[0]), 'k--', lw =4)\r\n    \r\n    plt.semilogy(beta,1.0\/(gamma*(1-beta*np.cos(theta1))), 'r', lw=4, label=\"$\\\\theta = 0$\")\r\n    plt.semilogy(beta,1.0\/(gamma*(1-beta*np.cos(theta2))), 'b',lw=4, label=\"$\\\\theta = \\pi\/4$\")\r\n    plt.semilogy(beta,1.0\/(gamma*(1-beta*np.cos(theta3))), 'g',lw=4, label=\"$\\\\theta = \\pi\/2$\")\r\n    plt.semilogy(beta,1.0\/(gamma*(1-beta*np.cos(theta4))), 'brown',lw=4, label=\"$\\\\theta = \\pi$\")\r\n    \r\n    plt.xlabel('$\\\\beta$', fontsize=46, labelpad=0)\r\n    plt.ylabel(\"$\\\\frac{\\omega}{\\omega'}$\", rotation=0, fontsize=56, labelpad=10)\r\n    \r\n    plt.xticks(fontsize = 32)\r\n    plt.yticks(fontsize = 32)\r\n    plt.legend(fontsize = 32, frameon=True, framealpha=01.0)\r\n\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-104 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.20.png\" alt=\"\" width=\"608\" height=\"748\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.20.png 608w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.20-480x591.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 608px, 100vw\" \/><\/p>\n<h2 id=\"Acceleration-of-a-particle-pushed-by-a-uniform-force\">Acceleration of a particle pushed by a uniform force<\/h2>\n<p>See Figs. 2.23 and 2.24.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">me = 9.109e-31 #kg\r\nmp = 1.673e-27 #kg\r\ne = 1.602e-19  #C\r\nc = 3.0e8  #m\/s\r\nE = 1 #V\/m\r\n\r\nt = np.logspace(-5, 2, 5000)\r\n\r\n# Define velocity as a dimensionless fraction of c\r\nue = 1.0\/np.sqrt(1+(me*c\/(e*E*t))**2)\r\nup = 1.0\/np.sqrt(1+(mp*c\/(e*E*t))**2)\r\n\r\ngamma_e = 1.0\/np.sqrt(1.-ue**2)\r\ngamma_p = 1.0\/np.sqrt(1.-up**2)\r\n\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    \r\n    plt.rcParams.update(synchrotron_style)\r\n    \r\n    fig, axs = plt.subplots(2, 1,figsize=(10,16))\r\n    axs[0].semilogx(t, ue, 'grey', lw = 4, label = 'Electron')\r\n    axs[0].semilogx(t, up, 'k', lw = 4, label = 'Proton')\r\n    \r\n    axs[1].loglog(t, gamma_e*me*c**2*1e9, 'grey', lw = 4, label = 'Electron')\r\n    axs[1].loglog(t, gamma_p*mp*c**2*1e9, 'k', lw = 4, label = 'Proton')\r\n    \r\n    axs[0].tick_params(axis='both', which='major', labelsize=34, pad = 10)\r\n    axs[1].tick_params(axis='both', which='major', labelsize=34, pad = 10)\r\n\r\n    axs[0].set_xlabel('time (s)', fontsize=38)\r\n    axs[1].set_xlabel('time (s)', fontsize=38)\r\n    axs[0].set_ylabel('u\/c', fontsize=38)\r\n    axs[1].set_ylabel('Energy (nJ)', fontsize=38)    \r\n    \r\n    axs[0].legend(fontsize = 32, frameon=True, loc='upper left', handlelength=1, bbox_to_anchor=(0.00001, 1.025))\r\n    axs[1].legend(fontsize = 32, frameon=True, loc='upper left', handlelength=1, bbox_to_anchor=(0.00001, 1.025))\r\n\r\n    plt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-107 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.23.png\" alt=\"\" width=\"682\" height=\"964\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.23.png 682w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.23-480x678.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 682px, 100vw\" \/><\/p>\n<h2 id=\"Bonus-content:-relativistic-contraction-of-field-lines\">Bonus content: relativistic contraction of field lines<\/h2>\n<p>Let us suppose a charge is moving along the <span class=\"wp-katex-eq\" data-display=\"false\">x<\/span>-axis with constant speed <span class=\"wp-katex-eq\" data-display=\"false\">v<\/span> which is a sizeable fraction of the speed of light. How does the Coulomb field lines transform for an observer that is at rest compared to the moving charge? We expect the lines to be contracted by a factor <span class=\"wp-katex-eq\" data-display=\"false\">\\gamma<\/span> in the direction of motion.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">''' \r\nDefine a function that generates the electric field components as a function of the charge q,\r\nposition of the charge r_0 = (x_0, y_0), and the coordinate arrays x and y.\r\n\r\nTo avoid potential numerical rounding errors with set 1\/(4 pi epsilon_0) to be 1\r\n'''\r\ndef E(q, x,y, gamma):\r\n    den = np.hypot(x, y)**3 # denominator\r\n    E_x = q * (x) \/ den\r\n    E_y = q * (y) \/ den\r\n   \r\n    return E_x, E_y\r\n<\/pre>\n<pre class=\"theme:obsidian lang:python decode:true \"># Plot the field generated by a charge of 1 coulomb located at the origin\r\nbeta = 0.9\r\ngamma = (1.0-beta**2)**(-0.5)\r\n\r\n# Define coordinates on a grid\r\nnx, ny = 128, 128\r\nlimit = 10\r\nx = np.linspace(-limit, limit, nx)\r\ny = np.linspace(-limit, limit, ny)\r\nX, Y = np.meshgrid(x\/gamma, y)\r\n\r\n# Generate field\r\nq = 1e-9\r\nposition = [0,0]\r\nEx, Ey = E(q, x=X,y=Y, gamma=gamma)\r\n\r\nfig = plt.figure(figsize=(10,10))\r\nax = fig.add_subplot(111)\r\n\r\n# Set the colour as the amplitude of the field. We take the log to ease the visualisation.\r\ncolor = np.log(np.hypot(Ex, Ey))\r\n\r\n# Draw streamplot\r\nsp = ax.streamplot(X, Y, Ex, Ey, color=color, cmap=plt.cm.afmhot, \\\r\n              density=3, arrowstyle='-&gt;', arrowsize=1.5)\r\n# Add a circle at the position of the charge. The command \"zorder\" forces the circle to be on top of the lines\r\nax.add_artist(Circle(position, 0.02*limit, facecolor='red', edgecolor='black', zorder=10))\r\n\r\n# Set limits and aspect ratio\r\nax.set_xlim(-limit,limit)\r\nax.set_ylim(-limit,limit)\r\n#ax.set_aspect('equal')\r\n\r\n# Add a colorbar and scale its size to match the chart size\r\ncbar = fig.colorbar(sp.lines, ax=ax, fraction=0.046, pad=0.04)\r\n\r\nax.set_xlabel('$x$')\r\nax.set_ylabel('$y$')\r\ncbar.ax.set_ylabel('Log Field Amplitude')\r\n\r\nplt.show()\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-109 size-full\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.b.png\" alt=\"\" width=\"668\" height=\"593\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.b.png 668w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/05\/shynchrotron-light-2.b-480x426.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 668px, 100vw\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Below is a set of python codes associated with Chapter 2 of Daniele Pelliccia and David M. Paganin, &#8220;Synchrotron Light: A Physics Journey from Laboratory to Cosmos&#8221; (Oxford University Press, 2025). In order to run any of these python codes, you will need to include the following header file. import numpy as np import matplotlib.pyplot [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":79,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-92","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/92","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=92"}],"version-history":[{"count":25,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/92\/revisions"}],"predecessor-version":[{"id":810,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/92\/revisions\/810"}],"up":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/79"}],"wp:attachment":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}