diff --git a/notebooks/plasmapy-particles-formulary-completed.ipynb b/notebooks/plasmapy-particles-formulary-completed.ipynb new file mode 100644 index 0000000..15921dd --- /dev/null +++ b/notebooks/plasmapy-particles-formulary-completed.ipynb @@ -0,0 +1,1178 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "5b8f9968", + "metadata": {}, + "source": [ + "# PlasmaPy Tutorial" + ] + }, + { + "cell_type": "markdown", + "id": "c8c364e5", + "metadata": {}, + "source": [ + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "[`plasmapy.particles`]: https://docs.plasmapy.org/en/stable/particles/index.html\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "[`plasmapy.dispersion`]: https://docs.plasmapy.org/en/stable/dispersion/index.html\n", + "\n", + "Thank you for coming to this interactive tutorial. 🌱 We are excited for you to be here! 😺\n", + "\n", + "PlasmaPy is an open source Python package for plasma research and education. We will go through some interactive examples of using [`plasmapy.particles`] ⚛ and [`plasmapy.formulary`] 🧮.\n", + "\n", + "Let's start with some preliminary imports & settings. To execute a cell in a Jupyter notebook, press `Shift + Enter`. If you have to restart the notebook, please re-execute the following cell.\n", + "\n", + "If using Google Colab, click **Run anyway** when prompted. (If prompted again, select **Restart runtime** when the installation finishes.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa326226", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "if 'google.colab' in str(get_ipython()):\n", + " if 'plasmapy' not in sys.modules:\n", + " !pip install plasmapy==2024.5.0\n", + "\n", + "import numpy as np\n", + "import astropy.units as u\n", + "from astropy import constants as const\n", + "from plasmapy.particles import *\n", + "from plasmapy.formulary import *" + ] + }, + { + "cell_type": "markdown", + "id": "6e8f0d92", + "metadata": {}, + "source": [ + "## Quick refresher on `astropy.units`" + ] + }, + { + "cell_type": "markdown", + "id": "93658d4f", + "metadata": {}, + "source": [ + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "\n", + "PlasmaPy makes heavy use of [`astropy.units`], which is my favorite part of the scientific pythoniverse! We typically import this subpackage as `u`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c20320a", + "metadata": {}, + "outputs": [], + "source": [ + "import astropy.units as u" + ] + }, + { + "cell_type": "markdown", + "id": "e9ccbb06", + "metadata": {}, + "source": [ + "We can create a physical quantity by multiplying or dividing a number or array with a unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8437650a", + "metadata": {}, + "outputs": [], + "source": [ + "60 * u.km" + ] + }, + { + "cell_type": "markdown", + "id": "ccc6659f", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "This operation creates a [`Quantity`] object: a number, sequence, or array that has been assigned a physical unit. We can create [`Quantity`] objects with compound units." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "4932159b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/latex": [ + "$88 \\; \\mathrm{\\frac{mi}{h}}$" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "88 * u.imperial.mile / u.hour" + ] + }, + { + "cell_type": "markdown", + "id": "97a8d49a", + "metadata": {}, + "source": [ + "## Particles" + ] + }, + { + "cell_type": "markdown", + "id": "0c7eeced", + "metadata": {}, + "source": [ + "[`plasmapy.particles`]: https://docs.plasmapy.org/en/stable/particles/index.html\n", + "\n", + "The [`plasmapy.particles`] subpackage contains functions to access basic particle data and classes to represent particles." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24125310", + "metadata": {}, + "outputs": [], + "source": [ + "from plasmapy.particles import *" + ] + }, + { + "cell_type": "markdown", + "id": "e224284a", + "metadata": {}, + "source": [ + "### Particle properties" + ] + }, + { + "cell_type": "markdown", + "id": "7696deba", + "metadata": {}, + "source": [ + "[representation of a particle]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.ParticleLike.html#particlelike\n", + "\n", + "There are several functions that provide information about different particles that might be present in a plasma. The input of these functions is a [representation of a particle], such as a string for the atomic symbol or the element name." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "006b8d3e", + "metadata": {}, + "outputs": [], + "source": [ + "atomic_number(\"Fe\")" + ] + }, + { + "cell_type": "markdown", + "id": "2aa5af34", + "metadata": {}, + "source": [ + "[atomic number]: https://en.wikipedia.org/wiki/Atomic_number\n", + "\n", + "We can provide a number that represents the [atomic number]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69958326", + "metadata": {}, + "outputs": [], + "source": [ + "element_name(26)" + ] + }, + { + "cell_type": "markdown", + "id": "cca89cef", + "metadata": {}, + "source": [ + "We can provide standard symbols or the names of particles." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16ca5b6f", + "metadata": {}, + "outputs": [], + "source": [ + "is_stable(\"e-\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35d8e49e", + "metadata": {}, + "outputs": [], + "source": [ + "charge_number(\"proton\")" + ] + }, + { + "cell_type": "markdown", + "id": "8f2e5b30", + "metadata": {}, + "source": [ + "[mass number]: https://en.wikipedia.org/wiki/Mass_number\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/units/quantity.html#quantity\n", + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "[`half_life`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.atomic.half_life.html#half-life\n", + "\n", + "We can represent isotopes with the atomic symbol followed by a hyphen and the [mass number]. Let's use [`half_life`] to return the half-life of a radioactive particle in seconds as a [`Quantity`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "94fcf452", + "metadata": {}, + "outputs": [], + "source": [ + "half_life(\"C-14\")" + ] + }, + { + "cell_type": "markdown", + "id": "58ab7782", + "metadata": {}, + "source": [ + "We typically represent an ion in a string by putting together the atomic symbol or isotope symbol, a space, the charge number, and the sign of the charge." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a65e15da", + "metadata": {}, + "outputs": [], + "source": [ + "charge_number(\"Fe-56 13+\")" + ] + }, + { + "cell_type": "markdown", + "id": "ce4886cf", + "metadata": {}, + "source": [ + "[particle-like]: https://docs.plasmapy.org/en/latest/glossary.html#term-particle-like\n", + "[`plasmapy.particles`]: https://docs.plasmapy.org/en/stable/particles/index.html\n", + "\n", + "Functions in [`plasmapy.particles`] are quite flexible in terms of string inputs representing particles. An input is [particle-like] if it can be used to represent a physical particle. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05e03a8b", + "metadata": {}, + "outputs": [], + "source": [ + "particle_mass(\"iron-56 +13\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dd9541b", + "metadata": {}, + "outputs": [], + "source": [ + "particle_mass(\"iron-56+++++++++++++\")" + ] + }, + { + "cell_type": "markdown", + "id": "d3adf3a6", + "metadata": {}, + "source": [ + "Most of these functions take additional arguments, with `Z` representing the charge number of an ion and `mass_numb` representing the mass number of an isotope. These arguments are often [keyword-only](https://docs.plasmapy.org/en/latest/glossary.html#term-keyword-only) to avoid ambiguity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61e0f960", + "metadata": {}, + "outputs": [], + "source": [ + "particle_mass(\"Fe\", Z=13, mass_numb=56)" + ] + }, + { + "cell_type": "markdown", + "id": "53a1d993", + "metadata": {}, + "source": [ + "### Particle objects" + ] + }, + { + "cell_type": "markdown", + "id": "3c2c3835", + "metadata": {}, + "source": [ + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle\n", + "\n", + "Up until now, we have been using functions that accept representations of particles and then return particle properties. With the [`Particle`] class, we can create objects that represent physical particles." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe9f824a", + "metadata": {}, + "outputs": [], + "source": [ + "proton = Particle(\"p+\")\n", + "electron = Particle(\"electron\")\n", + "iron56_nuclide = Particle(\"Fe\", Z=26, mass_numb=56)" + ] + }, + { + "cell_type": "markdown", + "id": "160df55b", + "metadata": {}, + "source": [ + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle\n", + "\n", + "Particle properties can be accessed via attributes of the [`Particle`] class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bebcc477", + "metadata": {}, + "outputs": [], + "source": [ + "proton.mass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "df0f2eed", + "metadata": {}, + "outputs": [], + "source": [ + "electron.charge" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "116cd6ad", + "metadata": {}, + "outputs": [], + "source": [ + "electron.charge_number" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99d22bd3", + "metadata": {}, + "outputs": [], + "source": [ + "iron56_nuclide.binding_energy" + ] + }, + { + "cell_type": "markdown", + "id": "8986cef8", + "metadata": {}, + "source": [ + "#### Antiparticles\n", + "\n", + "[`antiparticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle.antiparticle\n", + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle\n", + "\n", + "We can get antiparticles of fundamental particles by using the [`antiparticle`] attribute of a [`Particle`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6663952", + "metadata": {}, + "outputs": [], + "source": [ + "electron.antiparticle" + ] + }, + { + "cell_type": "markdown", + "id": "bf40e592", + "metadata": {}, + "source": [ + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle\n", + "\n", + "\n", + "We can also use the tilde (`~`) operator on a [`Particle`] to get its antiparticle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "180a1edf", + "metadata": {}, + "outputs": [], + "source": [ + "~proton" + ] + }, + { + "cell_type": "markdown", + "id": "8500bc48", + "metadata": {}, + "source": [ + "#### Ionization and recombination\n", + "\n", + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle\n", + "[`recombine()`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle.recombine\n", + "[`ionize()`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html#plasmapy.particles.particle_class.Particle.ionize\n", + "\n", + "The [`recombine()`] and [`ionize()`] methods of a [`Particle`] representing an ion or neutral atom will return a different [`Particle`] with fewer or more electrons." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "186b1dfa", + "metadata": {}, + "outputs": [], + "source": [ + "deuterium = Particle(\"D 0+\")\n", + "deuterium.ionize()" + ] + }, + { + "cell_type": "markdown", + "id": "4ee95241", + "metadata": {}, + "source": [ + "When provided with a number, these methods tell how many bound electrons to add or remove." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "242b53bd", + "metadata": {}, + "outputs": [], + "source": [ + "alpha = Particle(\"alpha\")\n", + "alpha.recombine(2)" + ] + }, + { + "cell_type": "markdown", + "id": "e5302bef", + "metadata": {}, + "source": [ + "### Custom particles" + ] + }, + { + "cell_type": "markdown", + "id": "4c8c2a63", + "metadata": {}, + "source": [ + "[`CustomParticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.CustomParticle.html\n", + "\n", + "Sometimes we want to use a particle with custom properties. For example, we might want to represent an average ion in a multi-species plasma or a dust particle. For that we can use [`CustomParticle`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35b94505", + "metadata": {}, + "outputs": [], + "source": [ + "cp = CustomParticle(9e-26 * u.kg, 2.18e-18 * u.C, symbol=\"Fe 13.6+\")" + ] + }, + { + "cell_type": "markdown", + "id": "dfc19404", + "metadata": {}, + "source": [ + "[`CustomParticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.CustomParticle.html\n", + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html\n", + "\n", + "Many of the attributes of [`CustomParticle`] are the same as in [`Particle`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a4b412b", + "metadata": {}, + "outputs": [], + "source": [ + "cp.mass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2da2b3b", + "metadata": {}, + "outputs": [], + "source": [ + "cp.charge" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecb450f6", + "metadata": {}, + "outputs": [], + "source": [ + "cp.symbol" + ] + }, + { + "cell_type": "markdown", + "id": "21a992a9", + "metadata": {}, + "source": [ + "[`numpy.nan`]: https://numpy.org/doc/stable/reference/constants.html#numpy.nan\n", + "\n", + "If we do not include one of the physical quantities, it gets set to [`numpy.nan`] (not a number) in the appropriate units." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a31c421a", + "metadata": {}, + "outputs": [], + "source": [ + "CustomParticle(9.27e-26 * u.kg).charge" + ] + }, + { + "cell_type": "markdown", + "id": "6292a1f3", + "metadata": {}, + "source": [ + "[`CustomParticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.CustomParticle.html\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "\n", + "[`CustomParticle`] objects can provided to most of the commonly used functions in [`plasmapy.formulary`], and we're planning to improve interoperability in future releases of PlasmaPy." + ] + }, + { + "cell_type": "markdown", + "id": "0f2b0634", + "metadata": {}, + "source": [ + "### Particle lists" + ] + }, + { + "cell_type": "markdown", + "id": "7939cfad", + "metadata": {}, + "source": [ + "[`ParticleList`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_collections.ParticleList.html\n", + "[`CustomParticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.CustomParticle.html\n", + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html\n", + "\n", + "The [`ParticleList`] class is a container for [`Particle`] and [`CustomParticle`] objects." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30cc7d36", + "metadata": {}, + "outputs": [], + "source": [ + "iron_ions = ParticleList([\"Fe 12+\", \"Fe 13+\", \"Fe 14+\"])" + ] + }, + { + "cell_type": "markdown", + "id": "d56ddb98", + "metadata": {}, + "source": [ + "[`ParticleList`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_collections.ParticleList.html\n", + "\n", + "By using a [`ParticleList`], we can access the properties of multiple particles at once." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2434f71b", + "metadata": {}, + "outputs": [], + "source": [ + "iron_ions.mass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14a431dd", + "metadata": {}, + "outputs": [], + "source": [ + "iron_ions.charge" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48cd1c7a", + "metadata": {}, + "outputs": [], + "source": [ + "iron_ions.symbols" + ] + }, + { + "cell_type": "markdown", + "id": "cccc6c60", + "metadata": {}, + "source": [ + "[`ParticleList`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_collections.ParticleList.html\n", + "[`CustomParticle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.CustomParticle.html\n", + "[`Particle`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_class.Particle.html\n", + "\n", + "We can also create a [`ParticleList`] by adding [`Particle`] and/or [`CustomParticle`] objects together." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b953065", + "metadata": {}, + "outputs": [], + "source": [ + "proton + electron" + ] + }, + { + "cell_type": "markdown", + "id": "b78ee7d2", + "metadata": {}, + "source": [ + "We can also get an average particle." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf01f619", + "metadata": {}, + "outputs": [], + "source": [ + "iron_ions.average_particle()" + ] + }, + { + "cell_type": "markdown", + "id": "e9038618", + "metadata": {}, + "source": [ + "[`ParticleList`]: https://docs.plasmapy.org/en/stable/api/plasmapy.particles.particle_collections.ParticleList.html\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "\n", + "[`ParticleList`] objects can also be provided to the most commonly used functions in [`plasmapy.formulary`], with more complete interoperability expected in the future." + ] + }, + { + "cell_type": "markdown", + "id": "efe199c8", + "metadata": {}, + "source": [ + "### Nuclear reactions" + ] + }, + { + "cell_type": "markdown", + "id": "58fb006b", + "metadata": {}, + "source": [ + "[`plasmapy.particles`]: https://docs.plasmapy.org/en/stable/particles/index.html\n", + "\n", + "We can use [`plasmapy.particles`] to calculate the energy of a nuclear reaction using the `>` operator. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8a9ab9e", + "metadata": {}, + "outputs": [], + "source": [ + "deuteron = Particle(\"D+\")\n", + "triton = Particle(\"T+\")\n", + "alpha = Particle(\"α\")\n", + "neutron = Particle(\"n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cb95c644", + "metadata": {}, + "outputs": [], + "source": [ + "energy = deuteron + triton > alpha + neutron" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7a4c236", + "metadata": {}, + "outputs": [], + "source": [ + "energy.to(\"MeV\")" + ] + }, + { + "cell_type": "markdown", + "id": "8bf7e515", + "metadata": {}, + "source": [ + "If the nuclear reaction is invalid, then an exception is raised that states the reason why." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "67b32a3a", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "deuteron + triton > alpha + 3 * neutron" + ] + }, + { + "cell_type": "markdown", + "id": "f065a288", + "metadata": {}, + "source": [ + "## PlasmaPy formulary\n", + "\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "\n", + "The [`plasmapy.formulary`] subpackage contains a broad variety of formulas needed by plasma scientists across disciplines, in particular to calculate plasma parameters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20c3b9b1", + "metadata": {}, + "outputs": [], + "source": [ + "from plasmapy.formulary import *" + ] + }, + { + "cell_type": "markdown", + "id": "955ce3dd", + "metadata": {}, + "source": [ + "### Plasma beta in the solar corona" + ] + }, + { + "cell_type": "markdown", + "id": "1bb15c25", + "metadata": {}, + "source": [ + "[Plasma beta]: https://en.wikipedia.org/wiki/Beta_(plasma_physics)\n", + "\n", + "[Plasma beta] ($β$) is one of the most fundamental plasma parameters. $β$ is the ratio of the plasma (gas) pressure to the magnetic pressure. How a plasma behaves depends strongly on $β$. When $β ≫ 1$, the magnetic field is not strong enough to exert much of a force on the plasma, so its motions start to resemble a gas. When $β ≪ 1$, magnetic tension and pressure are the dominant macroscopic forces. \n", + "\n", + "Let's use [`plasmapy.formulary`](https://docs.plasmapy.org/en/stable/formulary/index.html) to calculate plasma β in different regions of the solar atmosphere and see what we can learn." + ] + }, + { + "cell_type": "markdown", + "id": "24162ca9", + "metadata": {}, + "source": [ + "#### Solar corona" + ] + }, + { + "cell_type": "markdown", + "id": "60aa77b5", + "metadata": {}, + "source": [ + "Let's start by defining some plasma parameters for an active region in the solar corona." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4b98f58", + "metadata": {}, + "outputs": [], + "source": [ + "B_corona = 50 * u.G\n", + "n_corona = 1e9 * u.cm ** -3\n", + "T_corona = 1 * u.MK" + ] + }, + { + "cell_type": "markdown", + "id": "cdc0c334", + "metadata": {}, + "source": [ + "When we use these parameters in [`beta`](https://docs.plasmapy.org/en/stable/api/plasmapy.formulary.dimensionless.beta.html#plasmapy.formulary.dimensionless.beta), we find that $β$ is quite small so that the corona is magnetically dominated." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98b23229", + "metadata": {}, + "outputs": [], + "source": [ + "beta(T=T_corona, n=n_corona, B=B_corona)" + ] + }, + { + "cell_type": "markdown", + "id": "deb41bfa-bad5-4bdc-a0f2-75b4c0a16054", + "metadata": {}, + "source": [ + "#### Solar photosphere" + ] + }, + { + "cell_type": "markdown", + "id": "2442b569-a98d-4528-ab1a-374867be06f3", + "metadata": {}, + "source": [ + "Let's specify some characteristic plasma parameters for the solar photosphere, away from any sunspots." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1654acbb-056b-46e5-9fcf-900ab0fbd2b7", + "metadata": {}, + "outputs": [], + "source": [ + "T_photosphere = 5800 * u.K\n", + "B_photosphere = 400 * u.G\n", + "n_photosphere = 1e17 * u.cm ** -3" + ] + }, + { + "cell_type": "markdown", + "id": "be434e24-080a-449e-a3f2-6f18149ff362", + "metadata": {}, + "source": [ + "When we calculate for the photosphere, we find that it is an order of magnitude larger than 1, so plasma pressure forces are more important than magnetic tension and pressure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cf5b298-f68b-4bcb-bbf4-2fb93d8cdc6a", + "metadata": {}, + "outputs": [], + "source": [ + "beta(T_photosphere, n_photosphere, B_photosphere)" + ] + }, + { + "cell_type": "markdown", + "id": "dee08605", + "metadata": {}, + "source": [ + "### Plasma parameters in Earth's magnetosphere" + ] + }, + { + "cell_type": "markdown", + "id": "9587734f", + "metadata": {}, + "source": [ + "[magnetic reconnection]: https://en.wikipedia.org/wiki/Magnetic_reconnection\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "\n", + "The [*Magnetospheric Multiscale Mission*](https://www.nasa.gov/mission_pages/mms/overview/index.html) (*MMS*) is a constellation of four identical spacecraft. The goal of *MMS* is to investigate the small-scale physics of [magnetic reconnection] in Earth's magnetosphere. In order to do this, the spacecraft need to orbit in a tight configuration. But how tight does the tetrahedron have to be? Let's use [`plasmapy.formulary`] to find out." + ] + }, + { + "cell_type": "markdown", + "id": "706818eb", + "metadata": {}, + "source": [ + "#### Physics background" + ] + }, + { + "cell_type": "markdown", + "id": "e7f1ddf9", + "metadata": {}, + "source": [ + "[Magnetic reconnection]: https://en.wikipedia.org/wiki/Magnetic_reconnection\n", + "\n", + "[Magnetic reconnection] is the fundamental plasma process that converts stored magnetic energy into kinetic energy, thermal energy, and particle acceleration. Reconnection powers solar flares and is a key component of geomagnetic storms in Earth's magnetosphere. Reconnection can also degrade confinement in fusion devices such as tokamaks.\n", + "\n", + "The **inertial length** is the characteristic length scale for a particle to get accelerated or decelerated by electromagnetic forces in a plasma.\n", + "\n", + "When the reconnection layer thickness is shorter than the **ion inertial length**, $d_i ≡ c/ω_{pi}$, collisionless effects and the Hall effect enable reconnection to be fast (Zweibel & Yamada 2009). The inner electron diffusion region has a thickness of about the **electron inertial length**, $d_e ≡ c/ω_{pi}$. (Here, $ω_{pi}$ and $ω_{pe}$ are the ion and electron plasma frequencies.)\n", + "\n", + "**Our goal: calculate $d_i$ and $d_e$ to get an idea of how far the MMS spacecraft should be separated from each other to investigate reconnection.**" + ] + }, + { + "cell_type": "markdown", + "id": "749fba51", + "metadata": {}, + "source": [ + "### Length scales" + ] + }, + { + "cell_type": "markdown", + "id": "9db83228", + "metadata": {}, + "source": [ + "Let's choose some characteristic plasma parameters for the magnetosphere." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f317f40", + "metadata": {}, + "outputs": [], + "source": [ + "n = 1 * u.cm ** -3\n", + "B = 5 * u.nT\n", + "T = 10 ** 4.5 * u.K" + ] + }, + { + "cell_type": "markdown", + "id": "591bef20", + "metadata": {}, + "source": [ + "Let's calculate the ion inertial length, $d_i$. On length scales shorter than $d_i$, the Hall effect becomes important as the ions and electrons decouple from each other." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a717c75f", + "metadata": {}, + "outputs": [], + "source": [ + "inertial_length(n=n, particle=\"p+\").to(\"km\")" + ] + }, + { + "cell_type": "markdown", + "id": "5c56977f", + "metadata": {}, + "source": [ + "The ion diffusion regions should therefore be a few hundred kilometers thick. Let's calculate the electron inertial length next." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e5a4dd9", + "metadata": {}, + "outputs": [], + "source": [ + "inertial_length(n=n, particle=\"e-\").to(\"km\")" + ] + }, + { + "cell_type": "markdown", + "id": "bb4b8d8d", + "metadata": {}, + "source": [ + "The electron diffusion region should therefore have a characteristic length scale of a few kilometers, which is significantly smaller than the ion diffusion region." + ] + }, + { + "cell_type": "markdown", + "id": "2b2875fc", + "metadata": {}, + "source": [ + "We can also calculate the gyroradii for different particles " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96fee1ef", + "metadata": {}, + "outputs": [], + "source": [ + "gyroradius(B=B, particle=[\"e-\", \"p+\"], T=T).to(\"km\")" + ] + }, + { + "cell_type": "markdown", + "id": "1b2b32b3", + "metadata": {}, + "source": [ + "The four *MMS* spacecraft have separations of ten to hundreds of kilometers, and thus are well-positioned to investigate Hall physics during reconnection in the magnetosphere." + ] + }, + { + "cell_type": "markdown", + "id": "38e1aff3", + "metadata": {}, + "source": [ + "#### Frequencies" + ] + }, + { + "cell_type": "markdown", + "id": "fc1a183f", + "metadata": {}, + "source": [ + "We can also calculate some of the fundamental frequencies associated with magnetospheric plasma. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b9f9403", + "metadata": {}, + "outputs": [], + "source": [ + "plasma_frequency(n=n, particle=[\"p+\", \"e-\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5cc9c0ca", + "metadata": {}, + "outputs": [], + "source": [ + "gyrofrequency(B=B, particle=[\"p+\", \"e-\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88534868", + "metadata": {}, + "outputs": [], + "source": [ + "lower_hybrid_frequency(B=B, n_i=n, ion=\"p+\")" + ] + }, + { + "cell_type": "markdown", + "id": "8242486e-dcb4-4815-aa6f-04e6d6406546", + "metadata": {}, + "source": [ + "[`lower_hybrid_frequency`]: https://docs.plasmapy.org/en/stable/api/plasmapy.formulary.frequencies.lower_hybrid_frequency.html#lower-hybrid-frequency\n", + "[`plasmapy.formulary`]: https://docs.plasmapy.org/en/stable/formulary/index.html\n", + "\n", + "\n", + "Most of the functions in [`plasmapy.formulary`] have descriptions of the plasma parameters that include the formula and physical interpretation. If we ever forget what the [`lower_hybrid_frequency`] represents, we can check out its documentation page! " + ] + }, + { + "cell_type": "markdown", + "id": "04bf2ba1-c580-4ca5-b410-530ad3b4e31a", + "metadata": {}, + "source": [ + "## Final thoughts" + ] + }, + { + "cell_type": "markdown", + "id": "35962f6d-4897-4195-940d-990f36c313b3", + "metadata": {}, + "source": [ + "[PlasmaPy's online documentation]: https://docs.plasmapy.org\n", + "[contributor guide]: https://docs.plasmapy.org/en/latest/contributing\n", + "[getting ready to contribute]: https://docs.plasmapy.org/en/latest/contributing/getting_ready.html\n", + "[code contribution workflow]: https://docs.plasmapy.org/en/latest/contributing/workflow.html\n", + "[good first issues]: https://github.com/PlasmaPy/PlasmaPy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22\n", + "[raise an issue]: https://github.com/PlasmaPy/PlasmaPy/issues/new/choose \n", + "\n", + "Thank you for coming to this tutorial! If you'd like to learn more about PlasmaPy's current capabilities, please check out [PlasmaPy's online documentation].\n", + "\n", + "PlasmaPy is a community-developed project, and we invite you to contribute! Please check out our [contributor guide] to learn more, including the pages on [getting ready to contribute] and the [code contribution workflow]. We've labeled [good first issues] for new contributors. Possibilities include improving the documentation for a plasma parameter or adding a new example Jupyter notebook. \n", + "\n", + "If there is a feature that you would really like added to PlasmaPy, or if you find a bug or a place that the docs could be improved, please [raise an issue]! We deeply appreciate it, and doing so helps guide the future of the project.\n", + "\n", + "We thank you once again!" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.12.1" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}