Représentation des équipotentielles et des lignes de champ
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## I - Cas d'une charge ponctuelle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A - Position du problème"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Considérons un point de charge $q$ en un point $M$ de l'espace. Nous avons vu en cours que le champ électrostatique créé en tout point $P$ de l'espace s'exprime : \n",
"$$ \\overrightarrow{E} = \\dfrac{1}{4\\pi\\varepsilon_0}\\dfrac{q}{MP^3}\\overrightarrow{MP}$$\n",
"De même on peut exprimer le potentiel : \n",
"$$ V = \\dfrac{1}{4\\pi\\varepsilon_0}\\dfrac{q}{MP}$$\n",
"\n",
"\n",
"Afin de représenter grâce à une algorithme python les lignes de champ et les équipotentielles on dispose de deux fonctions pré-programmées dans la bibliothèque `matplotlib.pyplot` : `contour` et `streamplot`.\\\n",
"Voici leurs caractéristiques : "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function streamplot in module matplotlib.pyplot:\n",
"\n",
"streamplot(x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, transform=None, zorder=None, start_points=None, maxlength=4.0, integration_direction='both', *, data=None)\n",
" Draw streamlines of a vector flow.\n",
" \n",
" Parameters\n",
" ----------\n",
" x, y : 1D/2D arrays\n",
" Evenly spaced strictly increasing arrays to make a grid. If 2D, all\n",
" rows of *x* must be equal and all columns of *y* must be equal; i.e.,\n",
" they must be as if generated by ``np.meshgrid(x_1d, y_1d)``.\n",
" u, v : 2D arrays\n",
" *x* and *y*-velocities. The number of rows and columns must match\n",
" the length of *y* and *x*, respectively.\n",
" density : float or (float, float)\n",
" Controls the closeness of streamlines. When ``density = 1``, the domain\n",
" is divided into a 30x30 grid. *density* linearly scales this grid.\n",
" Each cell in the grid can have, at most, one traversing streamline.\n",
" For different densities in each direction, use a tuple\n",
" (density_x, density_y).\n",
" linewidth : float or 2D array\n",
" The width of the stream lines. With a 2D array the line width can be\n",
" varied across the grid. The array must have the same shape as *u*\n",
" and *v*.\n",
" color : color or 2D array\n",
" The streamline color. If given an array, its values are converted to\n",
" colors using *cmap* and *norm*. The array must have the same shape\n",
" as *u* and *v*.\n",
" cmap : `~matplotlib.colors.Colormap`\n",
" Colormap used to plot streamlines and arrows. This is only used if\n",
" *color* is an array.\n",
" norm : `~matplotlib.colors.Normalize`\n",
" Normalize object used to scale luminance data to 0, 1. If ``None``,\n",
" stretch (min, max) to (0, 1). This is only used if *color* is an array.\n",
" arrowsize : float\n",
" Scaling factor for the arrow size.\n",
" arrowstyle : str\n",
" Arrow style specification.\n",
" See `~matplotlib.patches.FancyArrowPatch`.\n",
" minlength : float\n",
" Minimum length of streamline in axes coordinates.\n",
" start_points : Nx2 array\n",
" Coordinates of starting points for the streamlines in data coordinates\n",
" (the same coordinates as the *x* and *y* arrays).\n",
" zorder : int\n",
" The zorder of the stream lines and arrows.\n",
" Artists with lower zorder values are drawn first.\n",
" maxlength : float\n",
" Maximum length of streamline in axes coordinates.\n",
" integration_direction : {'forward', 'backward', 'both'}, default: 'both'\n",
" Integrate the streamline in forward, backward or both directions.\n",
" data : indexable object, optional\n",
" If given, the following parameters also accept a string ``s``, which is\n",
" interpreted as ``data[s]`` (unless this raises an exception):\n",
" \n",
" *x*, *y*, *u*, *v*, *start_points*\n",
" \n",
" Returns\n",
" -------\n",
" StreamplotSet\n",
" Container object with attributes\n",
" \n",
" - ``lines``: `.LineCollection` of streamlines\n",
" \n",
" - ``arrows``: `.PatchCollection` containing `.FancyArrowPatch`\n",
" objects representing the arrows half-way along stream lines.\n",
" \n",
" This container will probably change in the future to allow changes\n",
" to the colormap, alpha, etc. for both lines and arrows, but these\n",
" changes should be backward compatible.\n",
"\n"
]
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"help(plt.streamplot)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function contour in module matplotlib.pyplot:\n",
"\n",
"contour(*args, data=None, **kwargs)\n",
" Plot contour lines.\n",
" \n",
" Call signature::\n",
" \n",
" contour([X, Y,] Z, [levels], **kwargs)\n",
" \n",
" `.contour` and `.contourf` draw contour lines and filled contours,\n",
" respectively. Except as noted, function signatures and return values\n",
" are the same for both versions.\n",
" \n",
" Parameters\n",
" ----------\n",
" X, Y : array-like, optional\n",
" The coordinates of the values in *Z*.\n",
" \n",
" *X* and *Y* must both be 2D with the same shape as *Z* (e.g.\n",
" created via `numpy.meshgrid`), or they must both be 1-D such\n",
" that ``len(X) == N`` is the number of columns in *Z* and\n",
" ``len(Y) == M`` is the number of rows in *Z*.\n",
" \n",
" *X* and *Y* must both be ordered monotonically.\n",
" \n",
" If not given, they are assumed to be integer indices, i.e.\n",
" ``X = range(N)``, ``Y = range(M)``.\n",
" \n",
" Z : (M, N) array-like\n",
" The height values over which the contour is drawn.\n",
" \n",
" levels : int or array-like, optional\n",
" Determines the number and positions of the contour lines / regions.\n",
" \n",
" If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries\n",
" to automatically choose no more than *n+1* \"nice\" contour levels\n",
" between *vmin* and *vmax*.\n",
" \n",
" If array-like, draw contour lines at the specified levels.\n",
" The values must be in increasing order.\n",
" \n",
" Returns\n",
" -------\n",
" `~.contour.QuadContourSet`\n",
" \n",
" Other Parameters\n",
" ----------------\n",
" corner_mask : bool, default: :rc:`contour.corner_mask`\n",
" Enable/disable corner masking, which only has an effect if *Z* is\n",
" a masked array. If ``False``, any quad touching a masked point is\n",
" masked out. If ``True``, only the triangular corners of quads\n",
" nearest those points are always masked out, other triangular\n",
" corners comprising three unmasked points are contoured as usual.\n",
" \n",
" colors : color string or sequence of colors, optional\n",
" The colors of the levels, i.e. the lines for `.contour` and the\n",
" areas for `.contourf`.\n",
" \n",
" The sequence is cycled for the levels in ascending order. If the\n",
" sequence is shorter than the number of levels, it's repeated.\n",
" \n",
" As a shortcut, single color strings may be used in place of\n",
" one-element lists, i.e. ``'red'`` instead of ``['red']`` to color\n",
" all levels with the same color. This shortcut does only work for\n",
" color strings, not for other ways of specifying colors.\n",
" \n",
" By default (value *None*), the colormap specified by *cmap*\n",
" will be used.\n",
" \n",
" alpha : float, default: 1\n",
" The alpha blending value, between 0 (transparent) and 1 (opaque).\n",
" \n",
" cmap : str or `.Colormap`, default: :rc:`image.cmap`\n",
" A `.Colormap` instance or registered colormap name. The colormap\n",
" maps the level values to colors.\n",
" \n",
" If both *colors* and *cmap* are given, an error is raised.\n",
" \n",
" norm : `~matplotlib.colors.Normalize`, optional\n",
" If a colormap is used, the `.Normalize` instance scales the level\n",
" values to the canonical colormap range [0, 1] for mapping to\n",
" colors. If not given, the default linear scaling is used.\n",
" \n",
" vmin, vmax : float, optional\n",
" If not *None*, either or both of these values will be supplied to\n",
" the `.Normalize` instance, overriding the default color scaling\n",
" based on *levels*.\n",
" \n",
" origin : {*None*, 'upper', 'lower', 'image'}, default: None\n",
" Determines the orientation and exact position of *Z* by specifying\n",
" the position of ``Z[0, 0]``. This is only relevant, if *X*, *Y*\n",
" are not given.\n",
" \n",
" - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner.\n",
" - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.\n",
" - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left\n",
" corner.\n",
" - 'image': Use the value from :rc:`image.origin`.\n",
" \n",
" extent : (x0, x1, y0, y1), optional\n",
" If *origin* is not *None*, then *extent* is interpreted as in\n",
" `.imshow`: it gives the outer pixel boundaries. In this case, the\n",
" position of Z[0, 0] is the center of the pixel, not a corner. If\n",
" *origin* is *None*, then (*x0*, *y0*) is the position of Z[0, 0],\n",
" and (*x1*, *y1*) is the position of Z[-1, -1].\n",
" \n",
" This argument is ignored if *X* and *Y* are specified in the call\n",
" to contour.\n",
" \n",
" locator : ticker.Locator subclass, optional\n",
" The locator is used to determine the contour levels if they\n",
" are not given explicitly via *levels*.\n",
" Defaults to `~.ticker.MaxNLocator`.\n",
" \n",
" extend : {'neither', 'both', 'min', 'max'}, default: 'neither'\n",
" Determines the ``contourf``-coloring of values that are outside the\n",
" *levels* range.\n",
" \n",
" If 'neither', values outside the *levels* range are not colored.\n",
" If 'min', 'max' or 'both', color the values below, above or below\n",
" and above the *levels* range.\n",
" \n",
" Values below ``min(levels)`` and above ``max(levels)`` are mapped\n",
" to the under/over values of the `.Colormap`. Note that most\n",
" colormaps do not have dedicated colors for these by default, so\n",
" that the over and under values are the edge values of the colormap.\n",
" You may want to set these values explicitly using\n",
" `.Colormap.set_under` and `.Colormap.set_over`.\n",
" \n",
" .. note::\n",
" \n",
" An existing `.QuadContourSet` does not get notified if\n",
" properties of its colormap are changed. Therefore, an explicit\n",
" call `.QuadContourSet.changed()` is needed after modifying the\n",
" colormap. The explicit call can be left out, if a colorbar is\n",
" assigned to the `.QuadContourSet` because it internally calls\n",
" `.QuadContourSet.changed()`.\n",
" \n",
" Example::\n",
" \n",
" x = np.arange(1, 10)\n",
" y = x.reshape(-1, 1)\n",
" h = x * y\n",
" \n",
" cs = plt.contourf(h, levels=[10, 30, 50],\n",
" colors=['#808080', '#A0A0A0', '#C0C0C0'], extend='both')\n",
" cs.cmap.set_over('red')\n",
" cs.cmap.set_under('blue')\n",
" cs.changed()\n",
" \n",
" xunits, yunits : registered units, optional\n",
" Override axis units by specifying an instance of a\n",
" :class:`matplotlib.units.ConversionInterface`.\n",
" \n",
" antialiased : bool, optional\n",
" Enable antialiasing, overriding the defaults. For\n",
" filled contours, the default is *True*. For line contours,\n",
" it is taken from :rc:`lines.antialiased`.\n",
" \n",
" nchunk : int >= 0, optional\n",
" If 0, no subdivision of the domain. Specify a positive integer to\n",
" divide the domain into subdomains of *nchunk* by *nchunk* quads.\n",
" Chunking reduces the maximum length of polygons generated by the\n",
" contouring algorithm which reduces the rendering workload passed\n",
" on to the backend and also requires slightly less RAM. It can\n",
" however introduce rendering artifacts at chunk boundaries depending\n",
" on the backend, the *antialiased* flag and value of *alpha*.\n",
" \n",
" linewidths : float or array-like, default: :rc:`contour.linewidth`\n",
" *Only applies to* `.contour`.\n",
" \n",
" The line width of the contour lines.\n",
" \n",
" If a number, all levels will be plotted with this linewidth.\n",
" \n",
" If a sequence, the levels in ascending order will be plotted with\n",
" the linewidths in the order specified.\n",
" \n",
" If None, this falls back to :rc:`lines.linewidth`.\n",
" \n",
" linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional\n",
" *Only applies to* `.contour`.\n",
" \n",
" If *linestyles* is *None*, the default is 'solid' unless the lines\n",
" are monochrome. In that case, negative contours will take their\n",
" linestyle from :rc:`contour.negative_linestyle` setting.\n",
" \n",
" *linestyles* can also be an iterable of the above strings\n",
" specifying a set of linestyles to be used. If this\n",
" iterable is shorter than the number of contour levels\n",
" it will be repeated as necessary.\n",
" \n",
" hatches : list[str], optional\n",
" *Only applies to* `.contourf`.\n",
" \n",
" A list of cross hatch patterns to use on the filled areas.\n",
" If None, no hatching will be added to the contour.\n",
" Hatching is supported in the PostScript, PDF, SVG and Agg\n",
" backends only.\n",
" \n",
" data : indexable object, optional\n",
" If given, all parameters also accept a string ``s``, which is\n",
" interpreted as ``data[s]`` (unless this raises an exception).\n",
" \n",
" Notes\n",
" -----\n",
" 1. `.contourf` differs from the MATLAB version in that it does not draw\n",
" the polygon edges. To draw edges, add line contours with calls to\n",
" `.contour`.\n",
" \n",
" 2. `.contourf` fills intervals that are closed at the top; that is, for\n",
" boundaries *z1* and *z2*, the filled region is::\n",
" \n",
" z1 < Z <= z2\n",
" \n",
" except for the lowest interval, which is closed on both sides (i.e.\n",
" it includes the lowest value).\n",
" \n",
" 3. `.contour` and `.contourf` use a `marching squares\n",
" `_ algorithm to\n",
" compute contour locations. More information can be found in\n",
" the source ``src/_contour.h``.\n",
"\n"
]
}
],
"source": [
"help(plt.contour)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dans ces deux fonctions apparaîssent `x` et `y` deux `array` qui permettent de constituer une grille. Voici le principe de fonctionnement d'un algorithme qui permet de représenter les lignes de champ et les équipotentielles.\n",
"\n",
"L'espace se ramène à un plan cartésien à 2 dimensions $(x,y)$. Pour effectuer des calculs numérique il faut dans un premier temps penser à définir les limites de cet espace. On les notera `xmin`, `xmax` ; `ymin`, `ymax`.\\\n",
"Chaque point $P$ de cet espace est repérer par un doublet $(x_P,y_P)$, il faut alors définir numériquement chacune des positions possible de $P$ dans les limites de l'espace choisi. \\\n",
"C'est ici qu'intervient une fonction python : `meshgrid`, \"grille maillée\" en français. Cette fonction prend en argument deux listes `array` de même dimension et créé un point à chaque intersection des points de chaque liste.\\\n",
"Par exemple :"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"XX=[[-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]\n",
" [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"xmin = -5.0\n",
"xmax = 5.0\n",
"ymin = -5.0\n",
"ymax = 5.0\n",
"\n",
"X = np.arange(xmin,xmax,1)\n",
"Y = np.arange(ymin,ymax,1)\n",
"\n",
"XX,YY = np.meshgrid(X,Y)\n",
"\n",
"plt.figure()\n",
"plt.plot(XX,YY,'g.')\n",
"plt.grid(True)\n",
"plt.show()\n",
"plt.close()\n",
"\n",
"print('XX='+str(XX))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On dispose ainsi des coordonnées de chaque point $P$ en lequel on peut alors faire le calcul du champ et du potentiel. \\\n",
"Il suffit alors de définir la valeur de la charge ainsi que ses coordonnées et de savoir exprimer les distances $PM$ entre la charge et le point $P$ de calcul du champ. \n",
"\n",
"Apparaît alors une difficulté : si le point $M$ et le point $P$ sont confondus, alors les expressions des champs et des potentiels diverges.\\\n",
"On considèrera alors que si $PM < h$ alors $PM = h$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### B - Mise en oeuvre"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On souhaite dans un premier temps déterminer la carte de champ et de potentiel d'une charge ponctuelle unique $q$ et afin de ne pas avoir de problème d'ordre de grandeur dans les valeurs numérique on prendra $q = 10^{-7} \\; C$.\\\n",
"L'espace sera limité à un plan de $6\\times6 \\; m^2$ centrée en $O$. La charge étant placé au centre. \\\n",
"Le maillage d'espace sera choisi : $h = 0,1$ afin d'avoir une représentation la moins grossière possible en limitant également le temps de calcul."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Importer l'ensemble des bibliothèques nécessaires à la résolution du problème. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Définir les limites de l'espace cartésien, ainsi que le maillage spacial. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"xmin = \n",
"xmax =\n",
"ymin = \n",
"ymax =\n",
"\n",
"h = # un pas plus petit augmente la durée de calcul. \n",
"\n",
"\n",
"X = \n",
"Y = \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. Définir la charge ainsi que ces coordonnées."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"q = \n",
"x1 = \n",
"y1 = "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4. Définir une fonction `Potentiel` prennant en argument la charge et ses coordonnées, ainsi que tous les points de maillages, et retournant la valeur du potentiel $V$ en chaque point $P$ de l'espace. \n",
"$\\dfrac{1}{4\\pi\\varepsilon_0} \\approx 9,0.10^9\\; S.I$."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"5. Compléter et commenter la suite d'instructions suivantes, permettant de représenter les surfaces équipotentielles et la charge à l'origine de ce potentiel."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m V =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"V = \n",
"\n",
"plt.figure()\n",
"\n",
"equ = plt.contour(XX,YY,V,np.linspace(-2000,2000,30),cmap='Reds',linewidths=1)\n",
"\n",
"matplotlib.rcParams['contour.negative_linestyle'] = 'solid'\n",
"plt.clabel(equ, fontsize=10, inline=1,fmt='%1.0f')\n",
"plt.colorbar(equ)\n",
"\n",
"plt.axis('square')\n",
"\n",
"ax = plt.gca()\n",
"radius = 3e5*q\n",
"color = 'red' if q > 0 else 'blue'\n",
"circle = plt.Circle((x1,y1), radius, color = color)\n",
"ax.add_artist(circle)\n",
"\n",
"plt.grid(True)\n",
"\n",
"plt.xlabel()\n",
"plt.ylabel()\n",
"\n",
"plt.xlim()\n",
"plt.ylim()\n",
"\n",
"plt.show()\n",
"plt.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"6. Définir une fonction `ChampE` permettant de calculer en chaque point du maillage les coordonnées `Ex` et `Ey` du champ électrique."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"6. Compléter et commenter les lignes de code suitantes."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"Ex,Ey = "
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "streamplot() missing 4 required positional arguments: 'x', 'y', 'u', and 'v'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mch\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstreamplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlinewidth\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mdensity\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mminlength\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'square'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mTypeError\u001b[0m: streamplot() missing 4 required positional arguments: 'x', 'y', 'u', and 'v'"
]
},
{
"data": {
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"\n",
"ch = plt.streamplot(linewidth=0.5,density=1,minlength=0.05)\n",
"\n",
"plt.axis('square')\n",
"\n",
"ax = plt.gca()\n",
"radius = 3e5*q\n",
"color = 'red' if q > 0 else 'blue'\n",
"circle = plt.Circle((x1,y1), radius, color = color)\n",
"ax.add_artist(circle)\n",
"\n",
"plt.grid()\n",
"\n",
"plt.xlabel()\n",
"plt.ylabel()\n",
"\n",
"plt.xlim()\n",
"plt.ylim()\n",
"plt.show()\n",
"plt.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"7. Ecrire une succession d'instructions permettant de représenter sur un même graphe les équipotentielles et les lignes de champ."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### II - Cas de plusieurs charges ponctuelles"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On souhaite maintenant écrire un algorithme python permettant de représenter les lignes de champ et les équipotentielles créées par 4 charges $q_1$ à $q_4$ placées aux sommets d'un carré $(-1,1)$, $(-1,-1)$, $(1,1)$ et $(1,-1)$. Les charges $q_1$ à $q_4$ pouvant être alternativement négatives ou positives. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"8. Ecrire ces algorithmes."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m xmin =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"xmin = \n",
"xmax =\n",
"ymin = \n",
"ymax =\n",
"\n",
"#-------------------------------------------------------------- \n",
"h =# un pas plus petit augmente la durée de calcul. \n",
"\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"q = [] #Ensemble des valeurs de charge (à compléter à souhait)\n",
"x1 = [] #Ensemble des valeurs des abcisses x des charges.\n",
"y1 = []\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"#définir ici la fonction Potentiel\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"#définir ici la fonction ChampE\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"V = PotentielV() #application de la fonction potentiel aux données.\n",
"\n",
"Ex,Ey = ChampE() #application de la fonction pour les données précédentes.\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"q = [] #Ensemble des valeurs de charge (à compléter à souhait)\n",
"\n",
" #application de la fonction potentiel aux données.\n",
"\n",
" #application de la fonction pour les données précédentes.\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"q = [] #Ensemble des valeurs de charge (à compléter à souhait)\n",
"\n",
" #application de la fonction potentiel aux données.\n",
"\n",
" #application de la fonction pour les données précédentes.\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"q = [] #Ensemble des valeurs de charge (à compléter à souhait)\n",
"\n",
" #application de la fonction potentiel aux données.\n",
"\n",
" #application de la fonction pour les données précédentes.\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"q = [] #Ensemble des valeurs de charge (à compléter à souhait)\n",
"\n",
" #application de la fonction potentiel aux données.\n",
"\n",
" #application de la fonction pour les données précédentes.\n",
"\n",
"#-------------------------------------------------------------- \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}