First commit from local APL repo contents, for pushing to Github.

This commit is contained in:
Mike Zimmerman
2023-08-08 18:23:54 -04:00
commit da002a2597
115 changed files with 22429 additions and 0 deletions

46
build.xml Normal file
View File

@@ -0,0 +1,46 @@
<project name="dragion" default="dist" basedir=".">
<description>
TODO
</description>
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init">
<javac destdir="${build}">
<src path="../mowgli/src"/>
<src path="../lestat/src"/>
<src path="../dragion/src"/>
<classpath>
<pathelement path="lib/antlr4-runtime-4.7.2/antlr4-runtime-4.7.2.jar"/>
<pathelement path="lib/commons-cli-1.5.0/commons-cli-1.5.0.jar"/>
<pathelement path="lib/commons-io-2.11.0/commons-io-2.11.0.jar"/>
<pathelement path="lib/commons-math3-3.6.1/commons-math3-3.6.1.jar"/>
<pathelement path="lib/guava-28.1/guava-28.1-jre.jar"/>
<pathelement path="lib/jfreechart-1.5.3/jfreechart-1.5.3.jar"/>
<pathelement path="lib/jna-5.4.0/jna-5.4.0.jar"/>
<pathelement path="lib/tomlj-1.0.0/tomlj-1.0.0.jar"/>
<pathelement path="${user.home}/local/vtk-8.2/lib64/vtk.jar"/>
</classpath>
</javac>
</target>
<target name="dist" depends="compile">
<mkdir dir="${dist}/lib"/>
<jar jarfile="${dist}/lib/dragion-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>

1
doc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
other

20
doc/sphinx/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 2add6e08e92b233349ce3e889c403cb8
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,39 @@
Bipolar ions: uniform source and loss (unfinished)
==================================================
Problem Statement
-----------------
The bipolar balance equation (in the absence of aerosol particles) is
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}
where :math:`n_\pm` are respective ion concentrations and :math:`\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}` [Harrison and Tammet]. Sans aerosols, :math:`n_+=n_-`.
**dragion** can be tested against this bipolar balance equation with uniform ``VolumeSource`` and ``CollisionalSinkBipolar`` instances for each ion species.
The implementation is forthcoming, to be based on ``dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java``.
The ``VolumeSource`` objects uniformly distribute positive and negative ions across the simulation ``Box`` at a steady rate, representing the constant source term :math:`q`.
The ``CollisionalSinkBipolar`` algorithm simulates the respective loss terms :math:`- \alpha n_+n_-` by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing :math:`n_+n_-` in each grid cell
(2) removing :math:`\alpha \: n_+n_- \: \mathrm{d}t \: \mathrm{d}^3r \: / np2c` macroparticles of each species from the grid cell (leaving zero if exceeding existing number)
We would expect the simulated :math:`\frac{\mathrm{d}n}{\mathrm{d}t}` to equal :math:`0`, integrated over many timesteps; in other words, the simulated concentration should be constant and the positive and negative concentrations equal.
Numerical Validation
--------------------
Taking :math:`q = 4\times10^6 \mathrm{m}^{-3} \mathrm{s}^{-1}` and :math:`\frac{\mathrm{d}n_+}{\mathrm{d}t}=0` yields a steady-state concentration of :math:`n_{equil}=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG].
TODO

View File

@@ -0,0 +1,124 @@
Unipolar relaxation
===================
Problem Statement
-----------------
Consider an initially uncharged conducting sphere placed in a uniform, cold, unipolar ion bath.
After a while we bias the sphere to a polarity opposite that of the ions, and then immediately disconnect it, leaving the sphere electrically floating at a nonzero potential.
The resulting unipolar current can be derived from the electric field
.. math::
:nowrap:
\begin{eqnarray}
E_r=\frac{Q}{4 \pi \varepsilon_0 r^2}
\end{eqnarray}
and the definition of mobility
.. math::
:nowrap:
\begin{eqnarray}
\vec{v} = \mu \vec{E}
\end{eqnarray}
to get
.. math::
:nowrap:
\begin{eqnarray}
I = n q v_r A = n q \cdot \mu E_r \cdot 4 \pi R^2
\end{eqnarray}
where :math:`n` is ion concentration, :math:`q` is ion charge, and :math:`R` is radius of the sphere. This yields the differential equation for charge on the sphere
.. math::
:nowrap:
\begin{eqnarray}
\dot{Q}=n q \mu \cdot \frac{Q}{4 \pi \varepsilon_0 R^2} \cdot 4 \pi R^2=Q \frac{n q \mu}{\varepsilon_0}
\end{eqnarray}
Converting :math:`Q` to :math:`V` using the definition of capacitance
.. math::
:nowrap:
\begin{eqnarray}
C V = Q
\end{eqnarray}
and noting that
.. math::
:nowrap:
\begin{eqnarray}
\sigma = n |q| \mu
\end{eqnarray}
the solution is
.. math::
:nowrap:
\begin{eqnarray}
V(t) = V_0 \exp\left(-\frac{t}{\varepsilon_0/\sigma}\right)
\end{eqnarray}
The negative sign in the exponential comes from the sign of :math:`q` relative to :math:`V_0`.
Numerical Validation
--------------------
Runs simulating the relaxation phenomenon for a conducting sphere can be found in ``dragion/runs/sphere``.
Initially, positive unipolar ions are loaded uniformly into the domain, with concentration :math:`n=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG], and a sphere of radius :math:`R=0.5 \mathrm{m}` is biased to :math:`-10 \mathrm{V}` then left floating.
Note: this simulation does not include a uniform background source or collisional sink.
The resulting time-progression is illustrated by a sequence of 3D screenshots:
- :math:`t=0 \mathrm{s}`
.. image:: relaxation-sphere-3d_0.png
- :math:`t=500 \mathrm{s}`
.. image:: relaxation-sphere-3d_1.png
- :math:`t=1000 \mathrm{s}`
.. image:: relaxation-sphere-3d_2.png
As the sphere collects nearby ions its (negative) charge level and electric field strength diminish.
The voltage drop is exponential, and its slope (in log-voltage) can be used to back out an estimate of atmospheric conductivity, :math:`\sigma = \mathrm{slope} \cdot \varepsilon_0`.
Here is a plot of (log10) voltage over time:
.. image:: relaxation-sphere.png
Notice that overall the **dragion** sphere relaxes more slowly than predicted by theory.
However, there is a slight inflection in the simulated voltage at :math:`t=1200 \mathrm{s}`.
A comparison of slopes before and after this knee, and the full end-to-end slope provide estimates for conductivity, using :math:`\sigma = \mathrm{slope} \cdot \varepsilon_0`:
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
| Fit | Slope (relaxation rate) :math:`[\mathrm{s}^{-1}]` | :math:`\sigma [\mathrm{S}/\mathrm{m}]` |
+=====================================+====================================================+==================================================+
| End-to-end | -0.0011 | :math:`0.95\times10^{-14}` |
| | | |
| Before :math:`t=1200 \: \mathrm{s}` | -0.0009 | :math:`0.79\times10^{-14}` |
| | | |
| After :math:`t=1200 \:\mathrm{s}` | -0.0013 | :math:`1.2\times10^{-14}` |
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
| Theoretical | -0.0016 | :math:`1.4\times10^{-14}` |
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
*More discussion is needed. Why is there an inflection point? It is probably related to domain shape and size. Why is the late-time estimate the best?*
At very late times the near-surface ion concentration will be depleted, so without a background source charging will eventually halt. In this regime the assumption of steady near-surface concentration would be violated and the theoretical model breaks down.

View File

@@ -0,0 +1,49 @@
Unipolar ions: uniform source and loss
======================================
Problem Statement
-----------------
The bipolar balance equation (in the absence of aerosol particles) is
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}
where :math:`n_\pm` are respective ion concentrations and :math:`\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}` [Harrison and Tammet]. Sans aerosols, :math:`n_+=n_-`, so that a single species reads
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n}{\mathrm{d}t} = q - \alpha n^2
\end{eqnarray}
**dragion** can be tested against this unipolar balance equation with a uniform ``VolumeSource`` and ``CollisionalSinkUnipolar``; the implementation is in ``dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java``.
The ``VolumeSource`` uniformly distributes particles across the simulation ``Box`` at a steady rate, representing the constant source term :math:`q`.
The ``CollisionalSinkUnipolar`` algorithm simulates the loss term :math:`- \alpha n^2` by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing :math:`n^2` in each grid cell
(2) removing :math:`\alpha \: n^2 \: \mathrm{d}t \: \mathrm{d}^3r \: / np2c` macroparticles from each grid cell (leaving zero if exceeding existing number)
We would expect the simulated :math:`\frac{\mathrm{d}n}{\mathrm{d}t}` to equal :math:`0`, integrated over many timesteps; in other words, the simulated concentration should be constant.
Numerical Validation
--------------------
Taking :math:`q = 4\times10^6 \mathrm{m}^{-3} \mathrm{s}^{-1}` and :math:`\frac{\mathrm{d}n_+}{\mathrm{d}t}=0` yields a steady-state unipolar concentration of :math:`n_{equil}=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG].
The ``SourceSinkTest`` starts with an empty 5 m simulation box. As time progresses the ``VolumeSource`` fills the domain with macroparticles, until the "real" concentration reaches :math:`n_{equil}`.
Crucial simulation parameters are the macroparticle "size", controlled by :math:`np2c` and the grid spacing used for particle-particle collisions. For this numerical experiment the collision grid cell-size is the domain length divided by 64.
At :math:`np2c=10^7` the mean concentration peaks rapidly but then unphysically falls off: the number of macroparticles per grid-cell is far too low, with cell size / particle size ratio :math:=`(5 \mathrm{m}/64)^3/(n_{equil}/np2c) = 0.1`. Reducing :math:`np2c` by two orders of 10 increases the # particles per grid cell to :math:`~10`, and the expected steady-state concentration is maintained.
.. image:: coll-equil.png

View File

@@ -0,0 +1,45 @@
Getting started
===============
Dependencies
------------
VTK
^^^^^^^
You will need to compile [VTK 8.2](vtk.org/download) from source, with Java bindings enabled. Typically on MacOS or Linux, using [CMake](https://cmake.org/), this looks like::
wget https://www.vtk.org/files/release/8.2/VTK-8.2.0.tar.gz
tar xf VTK-8.2.0.tar.gz
cd VTK-8.2.0
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=$VTK_HOME -DVTK_WRAP_JAVA=TRUE ..
make install
Note that ``$VTK_HOME`` must be defined prior to invocation of cmake. The VTK Java bindings jar-file ``vtk.jar`` and a multitude of dynamically linked sub-libraries are installed into ``$VTK_HOME/lib``.
mowgli
^^^^^^
Implementation of surfaces, distribution samplers, and other low-level building blocks are currently part of the **mowgli** library. Clone it from <http://hardin.jhuapl.edu:8080/scm/zimmemi1/mowgli>. Further documentation can be found *here*.
lestat
^^^^^^
TODO: copy from lestat getting-started docs
Installation and test run
-------------------------
Get the code from <http://hardin.jhuapl.edu:8080/scm/zimmemi1/dragion>. Assume that it is cloned into `~/dragion`.
For now the classpath and runtime library path are passed explicitly to the JRE from the command line (this will probably chang>
To print a helpful message, try::
DYLD_LIBRARY_PATH=~/local/vtk-8.2/lib \
java -Djava.library.path=/Users/zimmemi1/local/vtk-8.2/lib \
-classpath ~/dragion/bin:~/dragion/lib/commons-math3-3.6.1/commons-math3-3.6.1.jar:~/dragion/lib/guava-28.1/guava-28.1->
dragion.Main

View File

@@ -0,0 +1,28 @@
.. dragion documentation master file, created by
sphinx-quickstart on Thu Aug 25 16:19:38 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
dragion
=======
A Java API for modeling electrostatic interactions between atmospheric ions and charged surfaces, including:
- arbitrarily shaped homogeneous dielectrics and (biased or floating) conductors
- self-consistent surface charging through ion collection
- ion diffusion and mobility (in the presence of external and surface fields)
- volumetric ion sources and collisional loss process
.. toctree::
:maxdepth: 2
:caption: Contents:
getstarted.rst
physvalid.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1,10 @@
Physics validation
==================
.. toctree::
:maxdepth: 1
examples/unipolar_source_loss.rst
examples/bipolar_source_loss.rst
examples/relaxation_sphere.rst

View File

@@ -0,0 +1,701 @@
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Georgia, serif;
font-size: 17px;
background-color: #fff;
color: #000;
margin: 0;
padding: 0;
}
div.document {
width: 940px;
margin: 30px auto 0 auto;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 220px;
}
div.sphinxsidebar {
width: 220px;
font-size: 14px;
line-height: 1.5;
}
hr {
border: 1px solid #B1B4B6;
}
div.body {
background-color: #fff;
color: #3E4349;
padding: 0 30px 0 30px;
}
div.body > .section {
text-align: left;
}
div.footer {
width: 940px;
margin: 20px auto 30px auto;
font-size: 14px;
color: #888;
text-align: right;
}
div.footer a {
color: #888;
}
p.caption {
font-family: inherit;
font-size: inherit;
}
div.relations {
display: none;
}
div.sphinxsidebar a {
color: #444;
text-decoration: none;
border-bottom: 1px dotted #999;
}
div.sphinxsidebar a:hover {
border-bottom: 1px solid #999;
}
div.sphinxsidebarwrapper {
padding: 18px 10px;
}
div.sphinxsidebarwrapper p.logo {
padding: 0;
margin: -10px 0 0 0px;
text-align: center;
}
div.sphinxsidebarwrapper h1.logo {
margin-top: -10px;
text-align: center;
margin-bottom: 5px;
text-align: left;
}
div.sphinxsidebarwrapper h1.logo-name {
margin-top: 0px;
}
div.sphinxsidebarwrapper p.blurb {
margin-top: 0;
font-style: normal;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Georgia, serif;
color: #444;
font-size: 24px;
font-weight: normal;
margin: 0 0 5px 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-size: 20px;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
border: none;
}
div.sphinxsidebar p {
color: #555;
margin: 10px 0;
}
div.sphinxsidebar ul {
margin: 10px 0;
padding: 0;
color: #000;
}
div.sphinxsidebar ul li.toctree-l1 > a {
font-size: 120%;
}
div.sphinxsidebar ul li.toctree-l2 > a {
font-size: 110%;
}
div.sphinxsidebar input {
border: 1px solid #CCC;
font-family: Georgia, serif;
font-size: 1em;
}
div.sphinxsidebar hr {
border: none;
height: 1px;
color: #AAA;
background: #AAA;
text-align: left;
margin-left: 0;
width: 50%;
}
div.sphinxsidebar .badge {
border-bottom: none;
}
div.sphinxsidebar .badge:hover {
border-bottom: none;
}
/* To address an issue with donation coming after search */
div.sphinxsidebar h3.donation {
margin-top: 10px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #004B6B;
text-decoration: underline;
}
a:hover {
color: #6D4100;
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Georgia, serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
}
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
div.body h2 { font-size: 180%; }
div.body h3 { font-size: 150%; }
div.body h4 { font-size: 130%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #DDD;
padding: 0 4px;
text-decoration: none;
}
a.headerlink:hover {
color: #444;
background: #EAEAEA;
}
div.body p, div.body dd, div.body li {
line-height: 1.4em;
}
div.admonition {
margin: 20px 0px;
padding: 10px 30px;
background-color: #EEE;
border: 1px solid #CCC;
}
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fafafa;
}
div.admonition p.admonition-title {
font-family: Georgia, serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
padding: 0;
line-height: 1;
}
div.admonition p.last {
margin-bottom: 0;
}
div.highlight {
background-color: #fff;
}
dt:target, .highlight {
background: #FAF3E8;
}
div.warning {
background-color: #FCC;
border: 1px solid #FAA;
}
div.danger {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.error {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.caution {
background-color: #FCC;
border: 1px solid #FAA;
}
div.attention {
background-color: #FCC;
border: 1px solid #FAA;
}
div.important {
background-color: #EEE;
border: 1px solid #CCC;
}
div.note {
background-color: #EEE;
border: 1px solid #CCC;
}
div.tip {
background-color: #EEE;
border: 1px solid #CCC;
}
div.hint {
background-color: #EEE;
border: 1px solid #CCC;
}
div.seealso {
background-color: #EEE;
border: 1px solid #CCC;
}
div.topic {
background-color: #EEE;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre, tt, code {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
.hll {
background-color: #FFC;
margin: 0 -12px;
padding: 0 12px;
display: block;
}
img.screenshot {
}
tt.descname, tt.descclassname, code.descname, code.descclassname {
font-size: 0.95em;
}
tt.descname, code.descname {
padding-right: 0.08em;
}
img.screenshot {
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils {
border: 1px solid #888;
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils td, table.docutils th {
border: 1px solid #888;
padding: 0.25em 0.7em;
}
table.field-list, table.footnote {
border: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
table.footnote {
margin: 15px 0;
width: 100%;
border: 1px solid #EEE;
background: #FDFDFD;
font-size: 0.9em;
}
table.footnote + table.footnote {
margin-top: -15px;
border-top: none;
}
table.field-list th {
padding: 0 0.8em 0 0;
}
table.field-list td {
padding: 0;
}
table.field-list p {
margin-bottom: 0.8em;
}
/* Cloned from
* https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
*/
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
table.footnote td.label {
width: .1px;
padding: 0.3em 0 0.3em 0.5em;
}
table.footnote td {
padding: 0.3em 0.5em;
}
dl {
margin: 0;
padding: 0;
}
dl dd {
margin-left: 30px;
}
blockquote {
margin: 0 0 0 30px;
padding: 0;
}
ul, ol {
/* Matches the 30px from the narrow-screen "li > ul" selector below */
margin: 10px 0 10px 30px;
padding: 0;
}
pre {
background: #EEE;
padding: 7px 30px;
margin: 15px 0px;
line-height: 1.3em;
}
div.viewcode-block:target {
background: #ffd;
}
dl pre, blockquote pre, li pre {
margin-left: 0;
padding-left: 30px;
}
tt, code {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
}
tt.xref, code.xref, a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fff;
}
a.reference {
text-decoration: none;
border-bottom: 1px dotted #004B6B;
}
/* Don't put an underline on images */
a.image-reference, a.image-reference:hover {
border-bottom: none;
}
a.reference:hover {
border-bottom: 1px solid #6D4100;
}
a.footnote-reference {
text-decoration: none;
font-size: 0.7em;
vertical-align: top;
border-bottom: 1px dotted #004B6B;
}
a.footnote-reference:hover {
border-bottom: 1px solid #6D4100;
}
a:hover tt, a:hover code {
background: #EEE;
}
@media screen and (max-width: 870px) {
div.sphinxsidebar {
display: none;
}
div.document {
width: 100%;
}
div.documentwrapper {
margin-left: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
}
div.bodywrapper {
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
}
ul {
margin-left: 0;
}
li > ul {
/* Matches the 30px from the "ul, ol" selector above */
margin-left: 30px;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.bodywrapper {
margin: 0;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
@media screen and (max-width: 875px) {
body {
margin: 0;
padding: 20px 30px;
}
div.documentwrapper {
float: none;
background: #fff;
}
div.sphinxsidebar {
display: block;
float: none;
width: 102.5%;
margin: 50px -30px -20px -30px;
padding: 10px 20px;
background: #333;
color: #FFF;
}
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
div.sphinxsidebar h3 a {
color: #fff;
}
div.sphinxsidebar a {
color: #AAA;
}
div.sphinxsidebar p.logo {
display: none;
}
div.document {
width: 100%;
margin: 0;
}
div.footer {
display: none;
}
div.bodywrapper {
margin: 0;
}
div.body {
min-height: 0;
padding: 0;
}
.rtd_doc_footer {
display: none;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
/* misc. */
.revsys-inline {
display: none!important;
}
/* Make nested-list/multi-paragraph items look better in Releases changelog
* pages. Without this, docutils' magical list fuckery causes inconsistent
* formatting between different release sub-lists.
*/
div#changelog > div.section > ul > li > p:only-child {
margin-bottom: 0;
}
/* Hide fugly table cell borders in ..bibliography:: directive output */
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
border: none;
/* Below needed in some edge cases; if not applied, bottom shadows appear */
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
/* relbar */
.related {
line-height: 30px;
width: 100%;
font-size: 0.9rem;
}
.related.top {
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
.related.bottom {
border-top: 1px solid #EEE;
}
.related ul {
padding: 0;
margin: 0;
list-style: none;
}
.related li {
display: inline;
}
nav#rellinks {
float: right;
}
nav#rellinks li+li:before {
content: "|";
}
nav#breadcrumbs li+li:before {
content: "\00BB";
}
/* Hide certain items when printing */
@media print {
div.related {
display: none;
}
}

View File

@@ -0,0 +1,906 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
dl.footnote > dt,
dl.citation > dt {
float: left;
margin-right: 0.5em;
}
dl.footnote > dd,
dl.citation > dd {
margin-bottom: 0em;
}
dl.footnote > dd:after,
dl.citation > dd:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dt:after {
content: ":";
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd > :first-child {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
white-space: nowrap;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
margin: 1em 0;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: absolute;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View File

@@ -0,0 +1 @@
/* This file intentionally left blank. */

View File

@@ -0,0 +1,358 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
this.initOnKeyListeners();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
var url = new URL(window.location);
url.searchParams.delete('highlight');
window.history.replaceState({}, '', url);
},
/**
* helper function to focus on search bar
*/
focusSearchBar : function() {
$('input[name=q]').first().focus();
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
// only install a listener if it is really needed
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
return;
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box, textarea, dropdown or button
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& activeElementType !== 'BUTTON') {
if (event.altKey || event.ctrlKey || event.metaKey)
return;
if (!event.shiftKey) {
switch (event.key) {
case 'ArrowLeft':
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
break;
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
break;
case 'ArrowRight':
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS)
break;
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
break;
case 'Escape':
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
break;
Documentation.hideSearchWords();
return false;
}
}
// some keyboard layouts may need Shift to get /
switch (event.key) {
case '/':
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS)
break;
Documentation.focusSearchBar();
return false;
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View File

@@ -0,0 +1,14 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
SHOW_SEARCH_SUMMARY: true,
ENABLE_SEARCH_SHORTCUTS: true,
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,297 @@
/*
* language_data.js
* ~~~~~~~~~~~~~~~~
*
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
/* Non-minified version is copied as a separate JS file, is available */
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

View File

@@ -0,0 +1,82 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #8f5902; font-style: italic } /* Comment */
.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
.highlight .g { color: #000000 } /* Generic */
.highlight .k { color: #004461; font-weight: bold } /* Keyword */
.highlight .l { color: #000000 } /* Literal */
.highlight .n { color: #000000 } /* Name */
.highlight .o { color: #582800 } /* Operator */
.highlight .x { color: #000000 } /* Other */
.highlight .p { color: #000000; font-weight: bold } /* Punctuation */
.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #8f5902 } /* Comment.Preproc */
.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */
.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */
.highlight .gd { color: #a40000 } /* Generic.Deleted */
.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
.highlight .gr { color: #ef2929 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #745334 } /* Generic.Prompt */
.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */
.highlight .ld { color: #000000 } /* Literal.Date */
.highlight .m { color: #990000 } /* Literal.Number */
.highlight .s { color: #4e9a06 } /* Literal.String */
.highlight .na { color: #c4a000 } /* Name.Attribute */
.highlight .nb { color: #004461 } /* Name.Builtin */
.highlight .nc { color: #000000 } /* Name.Class */
.highlight .no { color: #000000 } /* Name.Constant */
.highlight .nd { color: #888888 } /* Name.Decorator */
.highlight .ni { color: #ce5c00 } /* Name.Entity */
.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #000000 } /* Name.Function */
.highlight .nl { color: #f57900 } /* Name.Label */
.highlight .nn { color: #000000 } /* Name.Namespace */
.highlight .nx { color: #000000 } /* Name.Other */
.highlight .py { color: #000000 } /* Name.Property */
.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #000000 } /* Name.Variable */
.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */
.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */
.highlight .mb { color: #990000 } /* Literal.Number.Bin */
.highlight .mf { color: #990000 } /* Literal.Number.Float */
.highlight .mh { color: #990000 } /* Literal.Number.Hex */
.highlight .mi { color: #990000 } /* Literal.Number.Integer */
.highlight .mo { color: #990000 } /* Literal.Number.Oct */
.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */
.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */
.highlight .sc { color: #4e9a06 } /* Literal.String.Char */
.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */
.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */
.highlight .se { color: #4e9a06 } /* Literal.String.Escape */
.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */
.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */
.highlight .sx { color: #4e9a06 } /* Literal.String.Other */
.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */
.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */
.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */
.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #000000 } /* Name.Function.Magic */
.highlight .vc { color: #000000 } /* Name.Variable.Class */
.highlight .vg { color: #000000 } /* Name.Variable.Global */
.highlight .vi { color: #000000 } /* Name.Variable.Instance */
.highlight .vm { color: #000000 } /* Name.Variable.Magic */
.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */

View File

@@ -0,0 +1,525 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
htmlToText : function(htmlString) {
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var htmlElement = $(htmlString, virtualDocument);
htmlElement.find('.headerlink').remove();
docContent = htmlElement.find('[role=main]')[0];
if(docContent === undefined) {
console.warn("Content block not found. Sphinx search tries to obtain it " +
"via '[role=main]'. Could you check your theme or template.");
return "";
}
return docContent.textContent || docContent.innerText;
},
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null,
dataType: "script", cache: true,
complete: function(jqxhr, textstatus) {
if (textstatus != "success") {
document.getElementById("searchindexloader").src = url;
}
}});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
var i;
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
}
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
/**
* execute search (requires search index to be loaded)
*/
query : function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = this._index.terms;
var titleterms = this._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(this.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li></li>');
var requestUrl = "";
var linkUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
}
listItem.append($('<a/>').attr('href',
linkUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
} else if (DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY) {
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
var summary = Search.makeSearchSummary(data, searchterms, hlterms);
if (summary) {
listItem.append(summary);
}
}
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}});
} else {
// just display title
Search.output.append(listItem);
setTimeout(function() {
displayNextItem();
}, 5);
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
/**
* search for object names
*/
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var docnames = this._index.docnames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var i;
var results = [];
for (var prefix in objects) {
for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) {
var match = objects[prefix][iMatch];
var name = match[4];
var fullname = (prefix ? prefix + '.' : '') + name;
var fullnameLower = fullname.toLowerCase()
if (fullnameLower.indexOf(object) > -1) {
var score = 0;
var parts = fullnameLower.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
var anchor = match[3];
if (anchor === '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2])) {
score += Scorer.objPrio[match[2]];
} else {
score += Scorer.objPrioDefault;
}
results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
}
}
}
return results;
},
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
*/
escapeRegExp : function(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
},
/**
* search for full-text terms in the index
*/
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
var docnames = this._index.docnames;
var filenames = this._index.filenames;
var titles = this._index.titles;
var i, j, file;
var fileMap = {};
var scoreMap = {};
var results = [];
// perform the search on the required terms
for (i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
var files = [];
var _o = [
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// add support for partial matches
if (word.length > 2) {
var word_regex = this.escapeRegExp(word);
for (var w in terms) {
if (w.match(word_regex) && !terms[word]) {
_o.push({files: terms[w], score: Scorer.partialTerm})
}
}
for (var w in titleterms) {
if (w.match(word_regex) && !titleterms[word]) {
_o.push({files: titleterms[w], score: Scorer.partialTitle})
}
}
}
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
break;
}
// found search word in contents
$u.each(_o, function(o) {
var _files = o.files;
if (_files === undefined)
return
if (_files.length === undefined)
_files = [_files];
files = files.concat(_files);
// set score for the word in each file to Scorer.term
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {};
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap && fileMap[file].indexOf(word) === -1)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (file in fileMap) {
var valid = true;
// check if all requirements are matched
var filteredTermCount = // as search terms with length < 3 are discarded: ignore
searchterms.filter(function(term){return term.length > 2}).length
if (
fileMap[file].length != searchterms.length &&
fileMap[file].length != filteredTermCount
) continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
titleterms[excluded[i]] == file ||
$u.contains(terms[excluded[i]] || [], file) ||
$u.contains(titleterms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it to the result list
if (valid) {
// select one (max) score for the file.
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
}
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(htmlText, keywords, hlwords) {
var text = Search.htmlToText(htmlText);
if (text == "") {
return null;
}
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<p class="context"></p>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
};
$(document).ready(function() {
Search.init();
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Bipolar ions: uniform source and loss (unfinished) &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Unipolar relaxation" href="relaxation_sphere.html" />
<link rel="prev" title="Unipolar ions: uniform source and loss" href="unipolar_source_loss.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="bipolar-ions-uniform-source-and-loss-unfinished">
<h1>Bipolar ions: uniform source and loss (unfinished)<a class="headerlink" href="#bipolar-ions-uniform-source-and-loss-unfinished" title="Permalink to this headline"></a></h1>
<section id="problem-statement">
<h2>Problem Statement<a class="headerlink" href="#problem-statement" title="Permalink to this headline"></a></h2>
<p>The bipolar balance equation (in the absence of aerosol particles) is</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}</div><p>where <span class="math notranslate nohighlight">\(n_\pm\)</span> are respective ion concentrations and <span class="math notranslate nohighlight">\(\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}\)</span> [Harrison and Tammet]. Sans aerosols, <span class="math notranslate nohighlight">\(n_+=n_-\)</span>.</p>
<p><strong>dragion</strong> can be tested against this bipolar balance equation with uniform <code class="docutils literal notranslate"><span class="pre">VolumeSource</span></code> and <code class="docutils literal notranslate"><span class="pre">CollisionalSinkBipolar</span></code> instances for each ion species.</p>
<p>The implementation is forthcoming, to be based on <code class="docutils literal notranslate"><span class="pre">dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java</span></code>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">VolumeSource</span></code> objects uniformly distribute positive and negative ions across the simulation <code class="docutils literal notranslate"><span class="pre">Box</span></code> at a steady rate, representing the constant source term <span class="math notranslate nohighlight">\(q\)</span>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">CollisionalSinkBipolar</span></code> algorithm simulates the respective loss terms <span class="math notranslate nohighlight">\(- \alpha n_+n_-\)</span> by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing <span class="math notranslate nohighlight">\(n_+n_-\)</span> in each grid cell
(2) removing <span class="math notranslate nohighlight">\(\alpha \: n_+n_- \: \mathrm{d}t \: \mathrm{d}^3r \: / np2c\)</span> macroparticles of each species from the grid cell (leaving zero if exceeding existing number)</p>
<p>We would expect the simulated <span class="math notranslate nohighlight">\(\frac{\mathrm{d}n}{\mathrm{d}t}\)</span> to equal <span class="math notranslate nohighlight">\(0\)</span>, integrated over many timesteps; in other words, the simulated concentration should be constant and the positive and negative concentrations equal.</p>
</section>
<section id="numerical-validation">
<h2>Numerical Validation<a class="headerlink" href="#numerical-validation" title="Permalink to this headline"></a></h2>
<p>Taking <span class="math notranslate nohighlight">\(q = 4\times10^6 \mathrm{m}^{-3} \mathrm{s}^{-1}\)</span> and <span class="math notranslate nohighlight">\(\frac{\mathrm{d}n_+}{\mathrm{d}t}=0\)</span> yields a steady-state concentration of <span class="math notranslate nohighlight">\(n_{equil}=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}\)</span> [Lorenz, MMRTG].</p>
<p>TODO</p>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../getstarted.html">Getting started</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../physvalid.html">Physics validation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="unipolar_source_loss.html">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Bipolar ions: uniform source and loss (unfinished)</a></li>
<li class="toctree-l2"><a class="reference internal" href="relaxation_sphere.html">Unipolar relaxation</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="../physvalid.html">Physics validation</a><ul>
<li>Previous: <a href="unipolar_source_loss.html" title="previous chapter">Unipolar ions: uniform source and loss</a></li>
<li>Next: <a href="relaxation_sphere.html" title="next chapter">Unipolar relaxation</a></li>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="../_sources/examples/bipolar_source_loss.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,209 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Unipolar relaxation &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="prev" title="Unipolar ions: uniform source and loss" href="unipolar_source_loss.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="unipolar-relaxation">
<h1>Unipolar relaxation<a class="headerlink" href="#unipolar-relaxation" title="Permalink to this headline"></a></h1>
<section id="problem-statement">
<h2>Problem Statement<a class="headerlink" href="#problem-statement" title="Permalink to this headline"></a></h2>
<p>Consider an initially uncharged conducting sphere placed in a uniform, cold, unipolar ion bath.
After a while we bias the sphere to a polarity opposite that of the ions, and then immediately disconnect it, leaving the sphere electrically floating at a nonzero potential.
The resulting unipolar current can be derived from the electric field</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
E_r=\frac{Q}{4 \pi \varepsilon_0 r^2}
\end{eqnarray}</div><p>and the definition of mobility</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\vec{v} = \mu \vec{E}
\end{eqnarray}</div><p>to get</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
I = n q v_r A = n q \cdot \mu E_r \cdot 4 \pi R^2
\end{eqnarray}</div><p>where <span class="math notranslate nohighlight">\(n\)</span> is ion concentration, <span class="math notranslate nohighlight">\(q\)</span> is ion charge, and <span class="math notranslate nohighlight">\(R\)</span> is radius of the sphere. This yields the differential equation for charge on the sphere</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\dot{Q}=n q \mu \cdot \frac{Q}{4 \pi \varepsilon_0 R^2} \cdot 4 \pi R^2=Q \frac{n q \mu}{\varepsilon_0}
\end{eqnarray}</div><p>Converting <span class="math notranslate nohighlight">\(Q\)</span> to <span class="math notranslate nohighlight">\(V\)</span> using the definition of capacitance</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
C V = Q
\end{eqnarray}</div><p>and noting that</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\sigma = n |q| \mu
\end{eqnarray}</div><p>the solution is</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
V(t) = V_0 \exp\left(-\frac{t}{\varepsilon_0/\sigma}\right)
\end{eqnarray}</div><p>The negative sign in the exponential comes from the sign of <span class="math notranslate nohighlight">\(q\)</span> relative to <span class="math notranslate nohighlight">\(V_0\)</span>.</p>
</section>
<section id="numerical-validation">
<h2>Numerical Validation<a class="headerlink" href="#numerical-validation" title="Permalink to this headline"></a></h2>
<p>Runs simulating the relaxation phenomenon for a conducting sphere can be found in <code class="docutils literal notranslate"><span class="pre">dragion/runs/sphere</span></code>.</p>
<p>Initially, positive unipolar ions are loaded uniformly into the domain, with concentration <span class="math notranslate nohighlight">\(n=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}\)</span> [Lorenz, MMRTG], and a sphere of radius <span class="math notranslate nohighlight">\(R=0.5 \mathrm{m}\)</span> is biased to <span class="math notranslate nohighlight">\(-10 \mathrm{V}\)</span> then left floating.
Note: this simulation does not include a uniform background source or collisional sink.</p>
<p>The resulting time-progression is illustrated by a sequence of 3D screenshots:</p>
<ul class="simple">
<li><p><span class="math notranslate nohighlight">\(t=0 \mathrm{s}\)</span></p></li>
</ul>
<img alt="../_images/relaxation-sphere-3d_0.png" src="../_images/relaxation-sphere-3d_0.png" />
<ul class="simple">
<li><p><span class="math notranslate nohighlight">\(t=500 \mathrm{s}\)</span></p></li>
</ul>
<img alt="../_images/relaxation-sphere-3d_1.png" src="../_images/relaxation-sphere-3d_1.png" />
<ul class="simple">
<li><p><span class="math notranslate nohighlight">\(t=1000 \mathrm{s}\)</span></p></li>
</ul>
<img alt="../_images/relaxation-sphere-3d_2.png" src="../_images/relaxation-sphere-3d_2.png" />
<p>As the sphere collects nearby ions its (negative) charge level and electric field strength diminish.
The voltage drop is exponential, and its slope (in log-voltage) can be used to back out an estimate of atmospheric conductivity, <span class="math notranslate nohighlight">\(\sigma = \mathrm{slope} \cdot \varepsilon_0\)</span>.</p>
<p>Here is a plot of (log10) voltage over time:</p>
<img alt="../_images/relaxation-sphere.png" src="../_images/relaxation-sphere.png" />
<p>Notice that overall the <strong>dragion</strong> sphere relaxes more slowly than predicted by theory.
However, there is a slight inflection in the simulated voltage at <span class="math notranslate nohighlight">\(t=1200 \mathrm{s}\)</span>.
A comparison of slopes before and after this knee, and the full end-to-end slope provide estimates for conductivity, using <span class="math notranslate nohighlight">\(\sigma = \mathrm{slope} \cdot \varepsilon_0\)</span>:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 27%" />
<col style="width: 37%" />
<col style="width: 36%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Fit</p></th>
<th class="head"><p>Slope (relaxation rate) <span class="math notranslate nohighlight">\([\mathrm{s}^{-1}]\)</span></p></th>
<th class="head"><p><span class="math notranslate nohighlight">\(\sigma [\mathrm{S}/\mathrm{m}]\)</span></p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>End-to-end</p>
<p>Before <span class="math notranslate nohighlight">\(t=1200 \: \mathrm{s}\)</span></p>
<p>After <span class="math notranslate nohighlight">\(t=1200 \:\mathrm{s}\)</span></p>
</td>
<td><p>-0.0011</p>
<p>-0.0009</p>
<p>-0.0013</p>
</td>
<td><p><span class="math notranslate nohighlight">\(0.95\times10^{-14}\)</span></p>
<p><span class="math notranslate nohighlight">\(0.79\times10^{-14}\)</span></p>
<p><span class="math notranslate nohighlight">\(1.2\times10^{-14}\)</span></p>
</td>
</tr>
<tr class="row-odd"><td><p>Theoretical</p></td>
<td><p>-0.0016</p></td>
<td><p><span class="math notranslate nohighlight">\(1.4\times10^{-14}\)</span></p></td>
</tr>
</tbody>
</table>
<p><em>More discussion is needed. Why is there an inflection point? It is probably related to domain shape and size. Why is the late-time estimate the best?</em></p>
<p>At very late times the near-surface ion concentration will be depleted, so without a background source charging will eventually halt. In this regime the assumption of steady near-surface concentration would be violated and the theoretical model breaks down.</p>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../getstarted.html">Getting started</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../physvalid.html">Physics validation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="unipolar_source_loss.html">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Unipolar relaxation</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="../physvalid.html">Physics validation</a><ul>
<li>Previous: <a href="unipolar_source_loss.html" title="previous chapter">Unipolar ions: uniform source and loss</a></li>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="../_sources/examples/relaxation_sphere.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Unipolar ions: uniform source and loss &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Physics validation" href="relaxation_sphere.html" />
<link rel="prev" title="Physics validation" href="../physvalid.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="unipolar-ions-uniform-source-and-loss">
<h1>Unipolar ions: uniform source and loss<a class="headerlink" href="#unipolar-ions-uniform-source-and-loss" title="Permalink to this headline"></a></h1>
<section id="problem-statement">
<h2>Problem Statement<a class="headerlink" href="#problem-statement" title="Permalink to this headline"></a></h2>
<p>The bipolar balance equation (in the absence of aerosol particles) is</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}</div><p>where <span class="math notranslate nohighlight">\(n_\pm\)</span> are respective ion concentrations and <span class="math notranslate nohighlight">\(\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}\)</span> [Harrison and Tammet]. Sans aerosols, <span class="math notranslate nohighlight">\(n_+=n_-\)</span>, so that a single species reads</p>
<div class="math notranslate nohighlight">
\begin{eqnarray}
\frac{\mathrm{d}n}{\mathrm{d}t} = q - \alpha n^2
\end{eqnarray}</div><p><strong>dragion</strong> can be tested against this unipolar balance equation with a uniform <code class="docutils literal notranslate"><span class="pre">VolumeSource</span></code> and <code class="docutils literal notranslate"><span class="pre">CollisionalSinkUnipolar</span></code>; the implementation is in <code class="docutils literal notranslate"><span class="pre">dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java</span></code>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">VolumeSource</span></code> uniformly distributes particles across the simulation <code class="docutils literal notranslate"><span class="pre">Box</span></code> at a steady rate, representing the constant source term <span class="math notranslate nohighlight">\(q\)</span>.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">CollisionalSinkUnipolar</span></code> algorithm simulates the loss term <span class="math notranslate nohighlight">\(- \alpha n^2\)</span> by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing <span class="math notranslate nohighlight">\(n^2\)</span> in each grid cell
(2) removing <span class="math notranslate nohighlight">\(\alpha \: n^2 \: \mathrm{d}t \: \mathrm{d}^3r \: / np2c\)</span> macroparticles from each grid cell (leaving zero if exceeding existing number)</p>
<p>We would expect the simulated <span class="math notranslate nohighlight">\(\frac{\mathrm{d}n}{\mathrm{d}t}\)</span> to equal <span class="math notranslate nohighlight">\(0\)</span>, integrated over many timesteps; in other words, the simulated concentration should be constant.</p>
</section>
<section id="numerical-validation">
<h2>Numerical Validation<a class="headerlink" href="#numerical-validation" title="Permalink to this headline"></a></h2>
<p>Taking <span class="math notranslate nohighlight">\(q = 4\times10^6 \mathrm{m}^{-3} \mathrm{s}^{-1}\)</span> and <span class="math notranslate nohighlight">\(\frac{\mathrm{d}n_+}{\mathrm{d}t}=0\)</span> yields a steady-state unipolar concentration of <span class="math notranslate nohighlight">\(n_{equil}=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}\)</span> [Lorenz, MMRTG].</p>
<p>The <code class="docutils literal notranslate"><span class="pre">SourceSinkTest</span></code> starts with an empty 5 m simulation box. As time progresses the <code class="docutils literal notranslate"><span class="pre">VolumeSource</span></code> fills the domain with macroparticles, until the “real” concentration reaches <span class="math notranslate nohighlight">\(n_{equil}\)</span>.</p>
<p>Crucial simulation parameters are the macroparticle “size”, controlled by <span class="math notranslate nohighlight">\(np2c\)</span> and the grid spacing used for particle-particle collisions. For this numerical experiment the collision grid cell-size is the domain length divided by 64.
At <span class="math notranslate nohighlight">\(np2c=10^7\)</span> the mean concentration peaks rapidly but then unphysically falls off: the number of macroparticles per grid-cell is far too low, with cell size / particle size ratio :math:=`(5 mathrm{m}/64)^3/(n_{equil}/np2c) = 0.1`. Reducing <span class="math notranslate nohighlight">\(np2c\)</span> by two orders of 10 increases the # particles per grid cell to <span class="math notranslate nohighlight">\(~10\)</span>, and the expected steady-state concentration is maintained.</p>
<img alt="../_images/coll-equil.png" src="../_images/coll-equil.png" />
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../getstarted.html">Getting started</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../physvalid.html">Physics validation</a><ul class="current">
<li class="toctree-l2 current"><a class="current reference internal" href="#">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l2"><a class="reference internal" href="relaxation_sphere.html">Physics validation</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="../physvalid.html">Physics validation</a><ul>
<li>Previous: <a href="../physvalid.html" title="previous chapter">Physics validation</a></li>
<li>Next: <a href="relaxation_sphere.html" title="next chapter">Physics validation</a></li>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="../_sources/examples/unipolar_source_loss.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="getstarted.html">Getting started</a></li>
<li class="toctree-l1"><a class="reference internal" href="physvalid.html">Physics validation</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,151 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Getting started &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Physics validation" href="physvalid.html" />
<link rel="prev" title="dragion" href="index.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="getting-started">
<h1>Getting started<a class="headerlink" href="#getting-started" title="Permalink to this headline"></a></h1>
<section id="dependencies">
<h2>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this headline"></a></h2>
<section id="vtk">
<h3>VTK<a class="headerlink" href="#vtk" title="Permalink to this headline"></a></h3>
<p>You will need to compile [VTK 8.2](vtk.org/download) from source, with Java bindings enabled. Typically on MacOS or Linux, using [CMake](<a class="reference external" href="https://cmake.org/">https://cmake.org/</a>), this looks like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>wget https://www.vtk.org/files/release/8.2/VTK-8.2.0.tar.gz
tar xf VTK-8.2.0.tar.gz
cd VTK-8.2.0
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=$VTK_HOME -DVTK_WRAP_JAVA=TRUE ..
make install
</pre></div>
</div>
<p>Note that <code class="docutils literal notranslate"><span class="pre">$VTK_HOME</span></code> must be defined prior to invocation of cmake. The VTK Java bindings jar-file <code class="docutils literal notranslate"><span class="pre">vtk.jar</span></code> and a multitude of dynamically linked sub-libraries are installed into <code class="docutils literal notranslate"><span class="pre">$VTK_HOME/lib</span></code>.</p>
</section>
<section id="mowgli">
<h3>mowgli<a class="headerlink" href="#mowgli" title="Permalink to this headline"></a></h3>
<p>Implementation of surfaces, distribution samplers, and other low-level building blocks are currently part of the <strong>mowgli</strong> library. Clone it from &lt;<a class="reference external" href="http://hardin.jhuapl.edu:8080/scm/zimmemi1/mowgli">http://hardin.jhuapl.edu:8080/scm/zimmemi1/mowgli</a>&gt;. Further documentation can be found <em>here</em>.</p>
</section>
<section id="lestat">
<h3>lestat<a class="headerlink" href="#lestat" title="Permalink to this headline"></a></h3>
<p>TODO: copy from lestat getting-started docs</p>
</section>
</section>
<section id="installation-and-test-run">
<h2>Installation and test run<a class="headerlink" href="#installation-and-test-run" title="Permalink to this headline"></a></h2>
<p>Get the code from &lt;<a class="reference external" href="http://hardin.jhuapl.edu:8080/scm/zimmemi1/dragion">http://hardin.jhuapl.edu:8080/scm/zimmemi1/dragion</a>&gt;. Assume that it is cloned into <cite>~/dragion</cite>.</p>
<p>For now the classpath and runtime library path are passed explicitly to the JRE from the command line (this will probably chang&gt;</p>
<p>To print a helpful message, try:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DYLD_LIBRARY_PATH</span><span class="o">=~/</span><span class="n">local</span><span class="o">/</span><span class="n">vtk</span><span class="o">-</span><span class="mf">8.2</span><span class="o">/</span><span class="n">lib</span> \
<span class="n">java</span> <span class="o">-</span><span class="n">Djava</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">path</span><span class="o">=/</span><span class="n">Users</span><span class="o">/</span><span class="n">zimmemi1</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">vtk</span><span class="o">-</span><span class="mf">8.2</span><span class="o">/</span><span class="n">lib</span> \
<span class="o">-</span><span class="n">classpath</span> <span class="o">~/</span><span class="n">dragion</span><span class="o">/</span><span class="nb">bin</span><span class="p">:</span><span class="o">~/</span><span class="n">dragion</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">commons</span><span class="o">-</span><span class="n">math3</span><span class="o">-</span><span class="mf">3.6.1</span><span class="o">/</span><span class="n">commons</span><span class="o">-</span><span class="n">math3</span><span class="o">-</span><span class="mf">3.6.1</span><span class="o">.</span><span class="n">jar</span><span class="p">:</span><span class="o">~/</span><span class="n">dragion</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">guava</span><span class="o">-</span><span class="mf">28.1</span><span class="o">/</span><span class="n">guava</span><span class="o">-</span><span class="mf">28.1</span><span class="o">-&gt;</span>
<span class="n">dragion</span><span class="o">.</span><span class="n">Main</span>
</pre></div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Getting started</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#dependencies">Dependencies</a></li>
<li class="toctree-l2"><a class="reference internal" href="#installation-and-test-run">Installation and test run</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="physvalid.html">Physics validation</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">dragion</a></li>
<li>Next: <a href="physvalid.html" title="next chapter">Physics validation</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="_sources/getstarted.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>dragion &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Getting started" href="getstarted.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="dragion">
<h1>dragion<a class="headerlink" href="#dragion" title="Permalink to this headline"></a></h1>
<p>A Java API for modeling electrostatic interactions between atmospheric ions and charged surfaces, including:</p>
<ul class="simple">
<li><p>arbitrarily shaped homogeneous dielectrics and (biased or floating) conductors</p></li>
<li><p>self-consistent surface charging through ion collection</p></li>
<li><p>ion diffusion and mobility (in the presence of external and surface fields)</p></li>
<li><p>volumetric ion sources and collisional loss process</p></li>
</ul>
<div class="toctree-wrapper compound">
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="getstarted.html">Getting started</a><ul>
<li class="toctree-l2"><a class="reference internal" href="getstarted.html#dependencies">Dependencies</a></li>
<li class="toctree-l2"><a class="reference internal" href="getstarted.html#installation-and-test-run">Installation and test run</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="physvalid.html">Physics validation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="examples/unipolar_source_loss.html">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples/bipolar_source_loss.html">Bipolar ions: uniform source and loss (unfinished)</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples/relaxation_sphere.html">Unipolar relaxation</a></li>
</ul>
</li>
</ul>
</div>
</section>
<section id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
</ul>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="#">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="getstarted.html">Getting started</a></li>
<li class="toctree-l1"><a class="reference internal" href="physvalid.html">Physics validation</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="#">Documentation overview</a><ul>
<li>Next: <a href="getstarted.html" title="next chapter">Getting started</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="_sources/index.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

Binary file not shown.

View File

@@ -0,0 +1,122 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Physics validation &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Unipolar ions: uniform source and loss" href="examples/unipolar_source_loss.html" />
<link rel="prev" title="Getting started" href="getstarted.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="physics-validation">
<h1>Physics validation<a class="headerlink" href="#physics-validation" title="Permalink to this headline"></a></h1>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="examples/unipolar_source_loss.html">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l1"><a class="reference internal" href="examples/bipolar_source_loss.html">Bipolar ions: uniform source and loss (unfinished)</a></li>
<li class="toctree-l1"><a class="reference internal" href="examples/relaxation_sphere.html">Unipolar relaxation</a></li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="getstarted.html">Getting started</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Physics validation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="examples/unipolar_source_loss.html">Unipolar ions: uniform source and loss</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples/bipolar_source_loss.html">Bipolar ions: uniform source and loss (unfinished)</a></li>
<li class="toctree-l2"><a class="reference internal" href="examples/relaxation_sphere.html">Unipolar relaxation</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="getstarted.html" title="previous chapter">Getting started</a></li>
<li>Next: <a href="examples/unipolar_source_loss.html" title="next chapter">Unipolar ions: uniform source and loss</a></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
<a href="_sources/physvalid.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; dragion documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/searchtools.js"></script>
<script src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<script src="searchindex.js" defer></script>
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<noscript>
<div class="admonition warning">
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
</noscript>
<p>
Searching for multiple words only shows matches that contain
all words.
</p>
<form action="" method="get">
<input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">dragion</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="getstarted.html">Getting started</a></li>
<li class="toctree-l1"><a class="reference internal" href="physvalid.html">Physics validation</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2022, zimmemi1.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.5.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

60
doc/sphinx/index.rst Normal file
View File

@@ -0,0 +1,60 @@
.. dragion documentation master file, created by
sphinx-quickstart on Thu Aug 25 16:19:38 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
dragion
=======
A Java API for modeling electrostatic interactions between atmospheric ions and charged surfaces, including:
- arbitrarily shaped homogeneous dielectrics
- biased and floating conductors
- self-consistent surface charging through ion collection
- ion diffusion
- ion mobility (in the presence of external and surface fields)
- volumetric ion sources
- collisional ion loss
----
Getting started
===============
Get the code from <http://hardin.jhuapl.edu:8080/scm/zimmemi1/dragion>. Assume that it is cloned into `~/dragion`.
You will need to compile [VTK 8.2](vtk.org/download) from source, with Java bindings enabled. Typically on MacOS or Linux, using [CMake](https://cmake.org/), this looks like::
wget https://www.vtk.org/files/release/8.2/VTK-8.2.0.tar.gz
tar xf VTK-8.2.0.tar.gz
cd VTK-8.2.0
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=~/local/vtk-8.2 -DVTK_WRAP_JAVA=TRUE ..
make install
This installs vtk.jar and a multitude of dynamically linked VTK sub-libraries into `~/local/vtk-8.2/lib`.
For now the classpath and runtime library path are passed explicitly to the JRE from the command line (this will probably change in a future release, i.e. by packing all required libs and natives into a single runnable jar).
To print a helpful message, try::
DYLD_LIBRARY_PATH=~/local/vtk-8.2/lib \
java -Djava.library.path=/Users/zimmemi1/local/vtk-8.2/lib \
-classpath ~/dragion/bin:~/dragion/lib/commons-math3-3.6.1/commons-math3-3.6.1.jar:~/dragion/lib/guava-28.1/guava-28.1-jre.jar:~/local/vtk-8.2/lib/vtk.jar:~/dragion/lib/tomlj-1.0.0/tomlj-1.0.0.jar:~/dragion/lib/commons-cli-1.5.0/commons-cli-1.5.0.jar:~/dragion/lib/antlr4-runtime-4.7.2/antlr4-runtime-4.7.2.jar \
dragion.Main
.. toctree::
:maxdepth: 2
:caption: Contents:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

35
doc/sphinx/make.bat Normal file
View File

@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

52
doc/sphinx/source/conf.py Normal file
View File

@@ -0,0 +1,52 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'dragion'
copyright = '2022, zimmemi1'
author = 'zimmemi1'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

View File

@@ -0,0 +1,39 @@
Bipolar ions: uniform source and loss (unfinished)
==================================================
Problem Statement
-----------------
The bipolar balance equation (in the absence of aerosol particles) is
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}
where :math:`n_\pm` are respective ion concentrations and :math:`\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}` [Harrison and Tammet]. Sans aerosols, :math:`n_+=n_-`.
**dragion** can be tested against this bipolar balance equation with uniform ``VolumeSource`` and ``CollisionalSinkBipolar`` instances for each ion species.
The implementation is forthcoming, to be based on ``dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java``.
The ``VolumeSource`` objects uniformly distribute positive and negative ions across the simulation ``Box`` at a steady rate, representing the constant source term :math:`q`.
The ``CollisionalSinkBipolar`` algorithm simulates the respective loss terms :math:`- \alpha n_+n_-` by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing :math:`n_+n_-` in each grid cell
(2) removing :math:`\alpha \: n_+n_- \: \mathrm{d}t \: \mathrm{d}^3r \: / np2c` macroparticles of each species from the grid cell (leaving zero if exceeding existing number)
We would expect the simulated :math:`\frac{\mathrm{d}n}{\mathrm{d}t}` to equal :math:`0`, integrated over many timesteps; in other words, the simulated concentration should be constant and the positive and negative concentrations equal.
Numerical Validation
--------------------
Taking :math:`q = 4\times10^6 \mathrm{m}^{-3} \mathrm{s}^{-1}` and :math:`\frac{\mathrm{d}n_+}{\mathrm{d}t}=0` yields a steady-state concentration of :math:`n_{equil}=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG].
TODO

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,124 @@
Unipolar relaxation
===================
Problem Statement
-----------------
Consider an initially uncharged conducting sphere placed in a uniform, cold, unipolar ion bath.
After a while we bias the sphere to a polarity opposite that of the ions, and then immediately disconnect it, leaving the sphere floating at an attractive nonzero potential.
The resulting unipolar current can be derived from the electric field
.. math::
:nowrap:
\begin{eqnarray}
E_r=\frac{Q}{4 \pi \varepsilon_0 r^2}
\end{eqnarray}
and the definition of mobility
.. math::
:nowrap:
\begin{eqnarray}
\vec{v} = \mu \vec{E}
\end{eqnarray}
to get
.. math::
:nowrap:
\begin{eqnarray}
I = n q v_r A = n q \cdot \mu E_r \cdot 4 \pi R^2
\end{eqnarray}
where :math:`n` is ion concentration, :math:`q` is ion charge, and :math:`R` is radius of the sphere. This yields the differential equation for charge on the sphere
.. math::
:nowrap:
\begin{eqnarray}
\dot{Q}=n q \mu \cdot \frac{Q}{4 \pi \varepsilon_0 R^2} \cdot 4 \pi R^2=Q \frac{n q \mu}{\varepsilon_0}
\end{eqnarray}
Converting :math:`Q` to :math:`V` using the definition of capacitance
.. math::
:nowrap:
\begin{eqnarray}
C V = Q
\end{eqnarray}
and noting that
.. math::
:nowrap:
\begin{eqnarray}
\sigma = n |q| \mu
\end{eqnarray}
the solution is
.. math::
:nowrap:
\begin{eqnarray}
V(t) = V_0 \exp\left(-\frac{t}{\varepsilon_0/\sigma}\right)
\end{eqnarray}
The negative sign in the exponential comes from the sign of :math:`q` relative to :math:`V_0`.
Numerical Validation
--------------------
Runs simulating the relaxation phenomenon for a conducting sphere can be found in ``dragion/runs/sphere``.
Initially, positive unipolar ions are loaded uniformly into the domain, with concentration :math:`n=\sqrt{\frac{q}{\alpha}}=2\times10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG], and a sphere of radius :math:`R=0.5 \mathrm{m}` is biased to :math:`-10 \mathrm{V}` then left floating.
Note: this simulation does not include a uniform background source or collisional sink.
The resulting time-progression is illustrated by a sequence of 3D screenshots:
- :math:`t=0 \mathrm{s}`
.. image:: relaxation-sphere-3d_0.png
- :math:`t=500 \mathrm{s}`
.. image:: relaxation-sphere-3d_1.png
- :math:`t=1000 \mathrm{s}`
.. image:: relaxation-sphere-3d_2.png
As the sphere collects nearby ions its (negative) charge level and electric field strength diminish.
The voltage drop is exponential, and its slope (in log-voltage) can be used to back out an estimate of atmospheric conductivity, :math:`\sigma = \mathrm{slope} \cdot \varepsilon_0`.
Here is a plot of (log10) voltage over time:
.. image:: relaxation-sphere.png
Notice that overall the **dragion** sphere relaxes more slowly than predicted by theory.
However, there is a slight inflection in the simulated voltage at :math:`t=1200 \mathrm{s}`.
A comparison of slopes before and after this knee, and the full end-to-end slope provide estimates for conductivity, using :math:`\sigma = \mathrm{slope} \cdot \varepsilon_0`:
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
| Fit | Slope (relaxation rate) :math:`[\mathrm{s}^{-1}]` | :math:`\sigma [\mathrm{S}/\mathrm{m}]` |
+=====================================+====================================================+==================================================+
| End-to-end | -0.0011 | :math:`0.95\times10^{-14}` |
| | | |
| Before :math:`t=1200 \: \mathrm{s}` | -0.0009 | :math:`0.79\times10^{-14}` |
| | | |
| After :math:`t=1200 \:\mathrm{s}` | -0.0013 | :math:`1.2\times10^{-14}` |
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
| Theoretical | -0.0016 | :math:`1.4\times10^{-14}` |
+-------------------------------------+----------------------------------------------------+--------------------------------------------------+
*More discussion is needed. Why is there an inflection point? It is probably related to domain shape and size. Why is the late-time estimate the best?*
At very late times the near-surface ion concentration will be depleted, so without a background source charging will eventually halt. In this regime the assumption of steady near-surface concentration would be violated and the theoretical model breaks down.

View File

@@ -0,0 +1,53 @@
Unipolar ions: uniform source and loss
======================================
Problem Statement
-----------------
The bipolar balance equation (in the absence of aerosol particles) is
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n_+}{\mathrm{d}t} = q - \alpha n_+ n_- \\
\frac{\mathrm{d}n_-}{\mathrm{d}t} = q - \alpha n_+ n_-
\end{eqnarray}
where :math:`n_\pm` are respective ion concentrations and :math:`\alpha\sim10^{-12} \: \mathrm{m}^3 \: \mathrm{s}^{-1}` [Harrison and Tammet]. Sans aerosols, :math:`n_+=n_-`, so that a single species reads
.. math::
:nowrap:
\begin{eqnarray}
\frac{\mathrm{d}n}{\mathrm{d}t} = q - \alpha n^2
\end{eqnarray}
**dragion** can be tested against this unipolar balance equation with a uniform ``VolumeSource`` and ``CollisionalSinkUnipolar``; the implementation is in ``dragion/simulations/unipolar/sourcesinktest/SourceSinkTest.java``.
The ``VolumeSource`` uniformly distributes particles across the simulation ``Box`` at a steady rate, representing the constant source term :math:`q`.
The ``CollisionalSinkUnipolar`` algorithm simulates the loss term :math:`- \alpha n^2` by overlaying a uniform grid on the simulation domain, and at each timestep
(1) computing :math:`n^2` in each grid cell
(2) removing :math:`n^2 \: \alpha \: \mathrm{d}t \: \mathrm{d}^3r \: / \: np2c` macroparticles per grid cell (leaving zero if exceeding the existing number)
We would expect the simulated :math:`\frac{\mathrm{d}n}{\mathrm{d}t}` to equal :math:`0`, integrated over many timesteps; in other words, the simulated concentration should be constant, with ion production in numerical balance with loss.
Numerical Validation
--------------------
Taking :math:`q = 4 \times 10^6 \: \mathrm{m}^{-3} \: \mathrm{s}^{-1}` and :math:`\mathrm{d}n/\mathrm{d}t = 0` yields a theoretical steady-state unipolar concentration of :math:`n_{equil}=\sqrt{q / \alpha = 2 \times 10^9 \: \mathrm{m}^{-3}` [Lorenz, MMRTG].
The ``SourceSinkTest`` starts with an empty 5 m simulation box. The ``VolumeSource`` fills the domain with macroparticles, until the ion concentration reaches :math:`n_{equil}` and the ``CollisionalSinkUnipolar`` removes as many ions as are added, on average.
Crucial simulation parameters are the macroparticle "size", controlled by :math:`np2c`, and the grid spacing used for particle-particle collisions. For this numerical experiment the collision cell-size is the domain length divided by 64.
At :math:`np2c=10^7` the mean concentration peaks rapidly but proceeds to fall off unphysically: the number of macroparticles per grid-cell is far too low, with cell size / particle size ratio :math:=`(5 \mathrm{m}/64)^3/(n_{equil}/np2c) = 0.1`.
Reducing :math:`np2c` by two orders of magnitude increases the # particles per grid cell to :math:`\sim 10`, and the expected steady-state concentration is recovered, with small oscillations about the mean.
.. image:: coll-equil.png

View File

@@ -0,0 +1,45 @@
Getting started
===============
Dependencies
------------
VTK
^^^^^^^
You will need to compile [VTK 8.2](vtk.org/download) from source, with Java bindings enabled. Typically on MacOS or Linux, using [CMake](https://cmake.org/), this looks like::
wget https://www.vtk.org/files/release/8.2/VTK-8.2.0.tar.gz
tar xf VTK-8.2.0.tar.gz
cd VTK-8.2.0
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=$VTK_HOME -DVTK_WRAP_JAVA=TRUE ..
make install
Note that ``$VTK_HOME`` must be defined prior to invocation of cmake. The VTK Java bindings jar-file ``vtk.jar`` and a multitude of dynamically linked sub-libraries are installed into ``$VTK_HOME/lib``. This location will be part of the classpath when running dragion.
mowgli
^^^^^^
Implementation of surfaces, distribution samplers, and other low-level building blocks are currently part of the **mowgli** library. Clone it from <http://hardin.jhuapl.edu:8080/scm/zimmemi1/mowgli>. Further documentation can be found *here*.
lestat
^^^^^^
TODO: copy from lestat getting-started docs
Installation and test run
-------------------------
Get the code from <http://hardin.jhuapl.edu:8080/scm/zimmemi1/dragion>. Assume that it is cloned into `~/dragion`.
For now the classpath and runtime library path are passed explicitly to the JRE from the command line (this will probably chang>
To print a helpful message, try::
DYLD_LIBRARY_PATH=~/local/vtk-8.2/lib \
java -Djava.library.path=/Users/zimmemi1/local/vtk-8.2/lib \
-classpath ~/dragion/bin:~/dragion/lib/commons-math3-3.6.1/commons-math3-3.6.1.jar:~/dragion/lib/guava-28.1/guava-28.1->
dragion.Main

View File

@@ -0,0 +1,28 @@
.. dragion documentation master file, created by
sphinx-quickstart on Thu Aug 25 16:19:38 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
dragion
=======
A Java API for modeling electrostatic interactions between atmospheric ions and charged surfaces, including:
- arbitrarily shaped homogeneous dielectrics and (biased or floating) conductors
- self-consistent surface charging through ion collection
- ion diffusion and mobility (in the presence of external and surface fields)
- volumetric ion sources and collisional loss process
.. toctree::
:maxdepth: 2
:caption: Contents:
getstarted.rst
physvalid.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1,10 @@
Physics validation
==================
.. toctree::
:maxdepth: 1
examples/unipolar_source_loss.rst
examples/bipolar_source_loss.rst
examples/relaxation_sphere.rst

497
doc/tm/relaxation-sphere.tm Normal file
View File

@@ -0,0 +1,497 @@
<TeXmacs|1.99.12>
<style|generic>
<\body>
<paragraph|Isolated sphere>
For a uniformly charged (and electrically isolated) sphere,
<\equation*>
E<rsub|r>=<frac|Q|4*\<pi\>*\<varepsilon\><rsub|0> r<rsup|2>>
</equation*>
where initially <math|Q=Q<rsub|0>>.
<\equation*>
<wide|v|\<vect\>>=\<mu\>*<wide|E|\<vect\>>
</equation*>
<\equation*>
I=-n*q*<wide|v|\<vect\>><rsub|r>\<cdot\><wide|A|\<vect\>>=n*q*\<mu\>*E<rsub|r>\<cdot\>4*\<pi\>*R<rsup|2>
</equation*>
Note that <math|q=Z e> must have opposite sign of <math|E<rsub|r>> (and
<math|Q<rsub|0>>) to be attracted.
<\equation*>
<wide|Q|\<dot\>>=n*q*\<mu\>*<frac|Q|4*\<pi\>*\<varepsilon\><rsub|0>
R<rsup|2>>\<cdot\>4*\<pi\>*R<rsup|2>
</equation*>
If <math|n> is steady and uniform then
<\equation*>
Q=Q<rsub|0> exp<around*|(|-<frac|n <around*|\||q|\|>
\<mu\>|\<varepsilon\><rsub|0>>*t|)>
</equation*>
Note that <math|\<sigma\>\<equiv\>n <around*|\||q|\|> \<mu\>> so that
<\equation*>
Q=Q<rsub|0> exp<around*|(|-<frac|\<sigma\>|\<varepsilon\><rsub|0>>*t|)>
</equation*>
\;
<paragraph|With constant windspeed>
The timestep equation is
<\equation*>
v<around*|(|t|)>=v<around*|(|0|)>*exp<around*|(|-<frac|\<mathd\>t|\<tau\><rsub|c>>|)>+<around*|(|\<mu\>*E+u|)><around*|(|1-exp<around*|(|-<frac|\<mathd\>t|\<tau\><rsub|c>>|)>|)>
</equation*>
and with <math|\<mathd\>t\<gg\>\<tau\><rsub|c>>,
<\equation*>
v<around*|(|t|)>=\<mu\>*E+u
</equation*>
Total current (positive = to the ball) is
<\equation*>
I=-<big|int>n*q*<wide|v|\<vect\>>\<cdot\>\<mathd\><wide|A|\<vect\>>=-<big|int>n*q*<around*|(|\<mu\>*<wide|E|\<vect\>>+<wide|u|\<vect\>>|)>\<cdot\>\<mathd\><wide|A|\<vect\>>
</equation*>
The electric field/mobility part is
<\equation*>
I<rsub|\<mu\>>=-<big|int>n*q*<around*|(|\<mu\>*<wide|E|\<vect\>>|)>\<cdot\>\<mathd\><wide|A|\<vect\>>=-n*q*<around*|(|4*\<pi\>*R<rsup|2>
\<mu\>*E<rsub|r>|)>=-n*q\<cdot\>4*\<pi\>*R<rsup|2>
\<mu\>\<cdot\><frac|Q|4*\<pi\>*\<varepsilon\><rsub|0>*R<rsup|2>>=-<frac|n*q*\<mu\>|\<varepsilon\><rsub|0>>*Q=-<frac|\<sigma\>|\<varepsilon\><rsub|0>>*Q
</equation*>
and the wind contribution is
<\equation*>
I<rsub|u>=-<big|int>n*q*<around*|(|<wide|u|\<vect\>>|)>\<cdot\>\<mathd\><wide|A|\<vect\>>=-n*q*v<rsub|wind><below|<big|int>|hemi>*<wide|x|^>\<cdot\>\<mathd\><wide|A|\<vect\>>*
</equation*>
<\equation*>
<below|<big|int>|hemi>*<wide|x|^>\<cdot\>\<mathd\><wide|A|\<vect\>>*=R<rsup|2><below|<above|<big|int>|\<pi\>/2>|0>\<mathd\><around*|(|cos
\<theta\>|)><below|<above|<big|int>|2*\<pi\>>|0>\<mathd\>\<phi\>
<wide|x|^>\<cdot\><wide|r|^>=2*\<pi\>*R<rsup|2><below|<above|<big|int>|\<pi\>/2>|0>\<mathd\><around*|(|cos
\<theta\>|)> cos \<theta\>=2*\<pi\>*R<rsup|2><around*|{|<frac|1|2>*cos<rsup|2>
<frac|\<pi\>|2>-<frac|1|2>*cos<rsup|2> 0|}>=-\<pi\>*R<rsup|2>
</equation*>
<\equation*>
I<rsub|u>=n*q*v<rsub|wind>*\<pi\>*R<rsup|2>
</equation*>
so the total current becomes
<\equation*>
I=-<frac|\<sigma\>|\<varepsilon\><rsub|0>>*Q+n*q
v<rsub|wind>*\<pi\>*R<rsup|2>
</equation*>
where
<\equation*>
\<tau\><rsub|\<sigma\>>=<frac|\<varepsilon\><rsub|0>|\<sigma\>>
</equation*>
Grouping terms,
<\equation*>
<wide|Q|\<dot\>>=-<frac|Q|\<tau\><rsub|\<sigma\>>>+I<rsub|wind>
</equation*>
<\equation*>
Q=C \<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*\<tau\><rsub|\<sigma\>>
</equation*>
here\
<\equation*>
Q<rsub|0>=C +I<rsub|wind>*\<tau\><rsub|\<sigma\>><space|1em>\<longrightarrow\>\<space\>\<space\><application-space|1em>C=Q<rsub|0>-I<rsub|wind>*\<tau\><rsub|\<sigma\>>
</equation*>
<\equation*>
Q=Q<rsub|0> \<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|)>
</equation*>
<paragraph|Wake/collection-area correction>
<\with|color|pastel brown>
There is an extra factor <math|w> on the <math|Q>-term when the windspeed
is great (because of the wake),
<\equation*>
<wide|Q|\<dot\>>=-<frac|1|w>*<frac|Q|\<tau\><rsub|\<sigma\>>>+I<rsub|wind>
</equation*>
<\equation*>
Q=C \<bbb-e\><rsup|-t/w*\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*w**\<tau\><rsub|\<sigma\>>
</equation*>
<\equation*>
Q<rsub|0>=C +I<rsub|wind>*w**\<tau\><rsub|\<sigma\>><space|1em>\<longrightarrow\>\<space\>\<space\><application-space|1em>C=Q<rsub|0>-I<rsub|wind>*w**\<tau\><rsub|\<sigma\>>
</equation*>
<\equation*>
Q=Q<rsub|0> \<bbb-e\><rsup|-t/w*\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*w**\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/w*\<tau\><rsub|\<sigma\>>>|)>
</equation*>
</with>
The quasisteady velocity field is
<\equation*>
<wide|v|\<vect\>>=\<mu\>*<wide|E|\<vect\>>+<wide|u|\<vect\>>=\<mu\>*E*<wide|r|^>+<around*|\||u|\|>*<wide|u|^>
</equation*>
<\equation*>
<wide|v|\<vect\>>\<cdot\><wide|r|^>=\<mu\>*E*<around*|(|<wide|r|^>\<cdot\><wide|r|^>|)>+<around*|\||u|\|>*<around*|(|<wide|u|^>\<cdot\><wide|r|^>|)>=\<mu\>*E-<around*|\||u|\|>*cos
\<eta\>
</equation*>
where <math|cos \<eta\>\<equiv\>-<wide|u|^>\<cdot\><wide|r|^>>. The only
particles at <math|r=R> that can reach the ball have
<math|<wide|v|\<vect\>>\<cdot\><wide|r|^>\<less\>0>,
<\equation*>
\<mu\>*E-<around*|\||u|\|>*cos \<eta\>\<less\>0
</equation*>
<\equation*>
cos \<eta\>\<less\><frac|\<mu\>*E|<around*|\||u|\|>>
</equation*>
Total current to the ball is
<\equation*>
I=-<below|<big|int>|<wide|v|\<vect\>>\<cdot\>\<mathd\><wide|A|\<vect\>>\<less\>0>n*q*<wide|v|\<vect\>>\<cdot\>\<mathd\><wide|A|\<vect\>>=+2*\<pi\><below|<above|<big|int>|cos
\<eta\><rsub|max>>|0>n*q*<around*|(|\<mu\>*E-<around*|\||u|\|>*cos
\<eta\>|)>R<rsup|2>*\<mathd\> <around*|(|cos \<eta\>|)>
</equation*>
where
<\equation*>
cos \<eta\><rsub|max>=<frac|\<mu\>*E|<around*|\||u|\|>><space|1em>limited
to -1\<less\>cos \<eta\><rsub|max>\<less\>1
</equation*>
With <math|<around*|\||u|\|>=0> the entire sphere has the possibility of
collecting particles; <math|\<eta\><rsub|max>=\<pi\>>.
With <math|\<mu\>*E=0> (a grounded sphere), or in the high-wind limit
<math|<around*|\||u|\|>\<gg\>\<mu\>*E>, only half the sphere (the windward
side) is collecting; <math|\<eta\><rsub|max>=<frac|\<pi\>|2>>.
Assuming positive carriers, an attracting sphere has <math|E\<less\>0>;
<math|\<eta\><rsub|max>\<gtr\>\<pi\>/2> and some of the back side is
shielded. The wind will eventually force a sign flip to <math|E\<gtr\>0>,
so that <math|\<eta\><rsub|max>\<less\>\<pi\>/2> and some of the front side
is shielded.
The mobility current is
<\equation*>
I<rsub|mob>=2*\<pi\>*n*q*\<mu\>*E*R<rsup|2><below|<above|<big|int>|\<eta\><rsub|max>>|0>*\<mathd\>
<around*|(|cos \<eta\>|)>=2*\<pi\>*n*q*\<mu\>*E*R<rsup|2>*<around*|(|cos
\<eta\><rsub|max>-1|)>
</equation*>
and the wind current is
<\equation*>
I<rsub|wind>=-2*\<pi\>*n*q*<around*|\||u|\|>*R<rsup|2>*<below|<above|<big|int>|\<eta\><rsub|max>>|0><around*|(|cos
\<eta\>|)>*\<mathd\> <around*|(|cos \<eta\>|)>=-2*\<pi\>*n*q*<around*|\||u|\|>*R<rsup|2><around*|(|<frac|cos<rsup|2>
\<eta\><rsub|max>|2>-<frac|1|2>|)>
</equation*>
so the total current is
<\equation*>
I=I<rsub|mob>+I<rsub|wind>=2*\<pi\>*n*q*R<rsup|2>*<around*|[|\<mu\>*E*<around*|(|cos
\<eta\><rsub|max>-1|)>-<frac|<around*|\||u|\|>|2>*<around*|(|cos<rsup|2>
\<eta\><rsub|max>-1|)>|]>
</equation*>
<\equation*>
<frac|\<mathd\>Q|\<mathd\>t>=2*\<pi\>*n*q*R<rsup|2>*<around*|[|\<mu\>*E*<around*|(|cos
\<eta\><rsub|max>-1|)>-<frac|<around*|\||u|\|>|2>*<around*|(|cos<rsup|2>
\<eta\><rsub|max>-1|)>|]>
</equation*>
<paragraph|Solving>
By the relation between sphere charge and surface electric field,
<\equation*>
<frac|\<mathd\>Q|\<mathd\>t>=4*\<pi\>*\<varepsilon\><rsub|0>*R<rsup|2>*<frac|\<mathd\>E|\<mathd\>t>
</equation*>
<\equation*>
<frac|\<mathd\>E|\<mathd\>t>=<frac|n*q|2*\<varepsilon\><rsub|0>>*<around*|[|\<mu\>*E*<around*|(|cos
\<eta\><rsub|max>-1|)>-<frac|<around*|\||u|\|>|2>*<around*|(|cos<rsup|2>
\<eta\><rsub|max>-1|)>|]>
</equation*>
<\with|color|pastel grey>
Without the clamps on <math|cos \<eta\><rsub|max>>,
<\equation*>
<frac|\<mathd\>E|\<mathd\>t>=<frac|n*q|2*\<varepsilon\><rsub|0>>*<around*|[|\<mu\>*E*<around*|(|<frac|\<mu\>*E|<around*|\||u|\|>>-1|)>-<frac|<around*|\||u|\|>|2>*<around*|(|<frac|\<mu\>*E|<around*|\||u|\|>>-1|)>|]>
</equation*>
<\equation*>
<frac|\<mathd\>E|\<mathd\>t>=A*E<rsup|2>+B*E+C
</equation*>
<\equation*>
A=C*<frac|\<mu\><rsup|2>|<around*|\||u|\|>>
</equation*>
<\equation*>
B=<frac|n*q|2*\<varepsilon\><rsub|0>>*<around*|(|-\<mu\>-<frac|\<mu\>|2>|)>=-<frac|3|2>*C*\<mu\>
</equation*>
<\equation*>
C=<frac|n*q|2*\<varepsilon\><rsub|0>>
</equation*>
</with>
\;
<paragraph|Regimes>
<\equation*>
Q<rsub|0>=C*\<Phi\><rsub|0>=4*\<pi\>*\<varepsilon\><rsub|0>*R*\<Phi\><rsub|0>
</equation*>
<\equation*>
\<tau\><rsub|\<sigma\>>=<frac|\<varepsilon\><rsub|0>|\<sigma\>>
</equation*>
<\equation*>
I<rsub|wind>=n*Z*q<rsub|e>*v<rsub|wind> \<pi\>*R<rsup|2>
</equation*>
The only dimensionless ratio is
<\equation*>
\<frak-I\>\<equiv\><frac|I<rsub|wind>*\<tau\><rsub|\<sigma\>>|Q<rsub|0>>
</equation*>
A traditional relaxation probe has <math|\<frak-I\>=0> and pure wind has
<math|\<frak-I\>\<rightarrow\>\<infty\>>.
The ratio of charges is
<\equation*>
\<frak-I\>=<frac|n*Z*q<rsub|e>*v<rsub|wind> \<pi\>*R<rsup|2>
<frac|\<varepsilon\><rsub|0>|\<sigma\>>|4*\<pi\>*\<varepsilon\><rsub|0>*R*\<Phi\><rsub|0>>=<frac|<frac|\<sigma\>|\<mu\>>*v<rsub|wind>*R|\<sigma\>*4*\<Phi\><rsub|0>>\<propto\><frac|v<rsub|wind>*R|\<mu\>
\<Phi\><rsub|0>>=<frac|v<rsub|wind>|\<mu\>*E<rsub|0>>
</equation*>
and checking units,
<\equation*>
<around*|[|<frac|v<rsub|wind>*R|\<mu\>
\<Phi\><rsub|0>>|]>=<around*|[|<frac|v<rsub|wind>|\<mu\>*E<rsub|0>>|]>=1
</equation*>
\;
<paragraph|Conductivity from slope (no area correction)>
<\equation*>
Q=Q<rsub|0> \<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|)>
</equation*>
\;
At early-enough times
\;
<\equation*>
Q=Q<rsub|0> <around*|(|1-<frac|t|\<tau\><rsub|\<sigma\>>>|)>+I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-<around*|(|1-<frac|t|\<tau\><rsub|\<sigma\>>>|)>|)>
</equation*>
<\equation*>
Q=Q<rsub|0> <around*|(|1-<frac|t|\<tau\><rsub|\<sigma\>>>|)>+I<rsub|wind>*t
</equation*>
then
<\equation*>
slope=<frac|\<mathd\>|\<mathd\>t> log
<around*|(|Q|)>=<frac|\<mathd\>|\<mathd\>t> log <around*|(|Q<rsub|0>
<around*|(|1-<frac|t|\<tau\><rsub|\<sigma\>>>|)>+I<rsub|wind>*t|)>=<frac|\<mathd\>|\<mathd\>t>
log <around*|(|Q<rsub|0> +<around*|(|I<rsub|wind>-<frac|Q<rsub|0>|\<tau\><rsub|\<sigma\>>>|)>*t|)>
</equation*>
<\equation*>
slope=<frac|<around*|(|I<rsub|wind>-<frac|Q<rsub|0>|\<tau\><rsub|\<sigma\>>>|)>|Q<rsub|0>+<around*|(|I<rsub|wind>-<frac|Q<rsub|0>|\<tau\><rsub|\<sigma\>>>|)>*t>
</equation*>
and at <math|t=0> this becomes
<\equation*>
slope=<frac|I<rsub|wind>|Q<rsub|0>>-<frac|\<sigma\>|\<varepsilon\><rsub|0>>
</equation*>
\;
\;
At late-enough times
<\equation*>
slope=<frac|\<mathd\>|\<mathd\>t> log
<around*|(|I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|)>|)>=<frac|1|I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|)>>*<frac|\<mathd\>|\<mathd\>t>
I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|)>
</equation*>
<\equation*>
=<frac|1|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>>*<around*|(|+<frac|\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|\<tau\><rsub|\<sigma\>>>|)>=<frac|\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>|1-\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>>*<frac|\<sigma\>|\<varepsilon\><rsub|0>>\<approx\><frac|\<sigma\>|\<varepsilon\><rsub|0>>*\<bbb-e\><rsup|-t/\<tau\><rsub|\<sigma\>>>
</equation*>
<paragraph|Saturation potential>
The saturation potential occurs when <math|<frac|\<mathd\>\<Phi\>|\<mathd\>t>=0>,
giving
<\equation*>
0=Q<rsub|0> \<bbb-e\><rsup|-t<rsub|sat>/\<tau\><rsub|\<sigma\>>>+I<rsub|wind>*\<tau\><rsub|\<sigma\>>*<around*|(|1-\<bbb-e\><rsup|-t<rsub|sat>/\<tau\><rsub|\<sigma\>>>|)>
</equation*>
<\equation*>
t<rsub|sat>=\<tau\><rsub|\<sigma\>>*log<around*|(|1-<frac|Q<rsub|0>|I<rsub|wind>*\<tau\><rsub|\<sigma\>>>|)>
</equation*>
There is no saturation if
<\equation*>
<frac|Q<rsub|0>|I<rsub|wind>*\<tau\><rsub|\<sigma\>>>\<geqslant\>1
</equation*>
\;
Otherwise <math|\<tau\><rsub|\<sigma\>>> can be found by use of the product
log function (Wolfram Alpha),
<\equation*>
\<tau\><rsub|\<sigma\>>=<frac|1|<frac|Q<rsub|0>|I<rsub|wind>>-t<rsub|sat>*W<around*|(|<frac|I<rsub|wind
>t<rsub|sat>|Q<rsub|0>> exp<around*|(|<frac|I<rsub|wind
>t<rsub|sat>|Q<rsub|0>>|)>|)>>
</equation*>
\;
<paragraph|Oscillating field>
Assuming <math|\<mathd\>t\<gg\>\<tau\><rsub|c>>, the constant-wind charging
equation for a sphere is
<\equation*>
<wide|Q|\<dot\>>=-<frac|\<sigma\>|\<varepsilon\><rsub|0>>*Q+n*q
v<rsub|wind>*A<rsub|eff>
</equation*>
Replacing
<\equation*>
v<rsub|wind>\<rightarrow\>\<mu\>*E<rsub|ext>*cos<around*|(|\<omega\>*t|)>
</equation*>
gives
<\equation*>
<wide|Q|\<dot\>>=\<sigma\>*E<rsub|ext>*cos<around*|(|\<omega\>*t|)>*A<rsub|eff>-<frac|\<sigma\>|\<varepsilon\><rsub|0>>*Q
</equation*>
<\equation*>
<wide|Q|\<dot\>>=<frac|\<sigma\>|\<varepsilon\><rsub|0>><around*|(|\<varepsilon\><rsub|0>*E<rsub|ext>*cos<around*|(|\<omega\>*t|)>*A<rsub|eff>-Q|)>*
</equation*>
<\equation*>
<wide|Q|\<dot\>>=<frac|Q<rsub|ext>*cos<around*|(|\<omega\>*t|)>-Q|\<tau\><rsub|\<sigma\>>>
</equation*>
where
<\equation*>
Q<rsub|ext>\<equiv\>\<varepsilon\><rsub|0>*E<rsub|ext>*A<rsub|eff>
</equation*>
Assuming for now that <math|A<rsub|eff>> is independent of time (though we
know it is generally not, cf. uniform wind derivation), the solution is
[Wolfram Alpha]
<\equation*>
Q<around*|(|t|)>=<frac|Q<rsub|ext>*<around*|(|\<omega\>*\<tau\><rsub|\<sigma\>>*sin<around*|(|\<omega\>*t|)>+cos<around*|(|\<omega\>*t|)>|)>|1+\<omega\><rsup|2>*\<tau\><rsub|\<sigma\>><rsup|2>>+C*exp<around*|(|-<frac|t|\<tau\><rsub|\<sigma\>>>|)>
</equation*>
where <math|C> is an integration constant.
</body>
<\initial>
<\collection>
<associate|page-height|auto>
<associate|page-type|letter>
<associate|page-width|auto>
</collection>
</initial>
<\references>
<\collection>
<associate|auto-1|<tuple|1|?>>
<associate|auto-2|<tuple|2|?>>
<associate|auto-3|<tuple|3|?>>
<associate|auto-4|<tuple|4|?>>
<associate|auto-5|<tuple|5|?>>
<associate|auto-6|<tuple|6|?>>
<associate|auto-7|<tuple|7|?>>
<associate|auto-8|<tuple|8|?>>
</collection>
</references>
<\auxiliary>
<\collection>
<\associate|toc>
<with|par-left|<quote|4tab>|Isolated sphere
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-1><vspace|0.15fn>>
<with|par-left|<quote|4tab>|With constant windspeed
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-2><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Wake/collection-area correction
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-3><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Solving
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-4><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Regimes
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-5><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Conductivity from slope (no area
correction) <datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-6><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Saturation potential
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-7><vspace|0.15fn>>
</associate>
</collection>
</auxiliary>

164
doc/tm/scales.tm Normal file
View File

@@ -0,0 +1,164 @@
<TeXmacs|1.99.12>
<style|generic>
<\body>
<paragraph|Fundamental scales>
<\equation*>
R=object size
</equation*>
<with|color|pastel grey|<\equation*>
L=domain size
</equation*>>
<\equation*>
\<Phi\><rsub|0>=characteristic electric potential
</equation*>
<\equation*>
\<mu\>=mobility
</equation*>
<\equation*>
n=concentration
</equation*>
<\equation*>
\<mathd\>t=timestep
</equation*>
5 quantities, 3 units [m,s,C] <math|\<longrightarrow\>> 2 ratios
<paragraph|Dimensionless ratios>
<with|color|pastel brown|<\equation*>
\<frak-S\>=<frac|R|L>
</equation*>>
<\equation*>
\<frak-M\>\<equiv\><frac|v*\<mathd\>t|R>=<frac|\<mu\>*E*\<mathd\>t|R>=<frac|\<mu\>*\<Phi\><rsub|0>\<cdot\>\<mathd\>t|R\<cdot\>R>=<frac|\<mu\>*\<Phi\><rsub|0>*\<mathd\>t|R<rsup|2>>
</equation*>
<\equation*>
\<frak-N\>\<equiv\>n*R<rsup|3>
</equation*>
<paragraph|Conductivity>
Adding fundamental charge scale <math|e>,
<\equation*>
\<space\>\<sigma\>=<frac|j|E>=<frac|n*e*v|E>=<frac|n*e\<cdot\>\<mu\>*E|E>=n*e*\<mu\>
</equation*>
<\equation*>
\<frak-M\>=<frac|\<mu\>*\<Phi\><rsub|0>*\<mathd\>t|R<rsup|2>>=<frac|\<sigma\>*\<Phi\><rsub|0>*\<mathd\>t|n*e*R<rsup|2>>=<frac|\<sigma\>*\<Phi\><rsub|0>*\<mathd\>t|\<frak-N\>*e>*R
</equation*>
<\equation*>
\<frak-M\>*\<frak-N\>=<frac|\<sigma\>*\<Phi\><rsub|0>*\<mathd\>t|*e>*R=<frac|\<sigma\>*Q<rsub|0>*\<mathd\>t|*4*\<pi\>*\<varepsilon\><rsub|0>*R*e>*R\<propto\>*<frac|\<sigma\>*\<mathd\>t|\<varepsilon\><rsub|0>>*<frac|Q<rsub|0>|e>=<frac|\<mathd\>t|\<tau\>>*<frac|Q<rsub|0>|e>
</equation*>
where <math|\<tau\>=<frac|\<varepsilon\><rsub|0>|\<sigma\>>>. Slope of
relaxation probe trace is <math|slope=\<tau\><rsup|-1>=<frac|\<sigma\>|\<varepsilon\><rsub|0>>>.
<paragraph|Alternative (independent) ratios>
<\equation*>
\<cal-T\>\<equiv\><frac|\<mathd\>t|\<tau\>>
</equation*>
<\equation*>
\<cal-Q\>=<frac|Q<rsub|0>|e>
</equation*>
<\equation*>
\<cal-N\>\<equiv\>n*R<rsup|3>
</equation*>
<paragraph|Timestep constraint>
<\equation*>
v*\<mathd\>t\<less\>R
</equation*>
<\equation*>
\<mu\>*E*\<mathd\>t\<less\>R
</equation*>
<\equation*>
<frac|\<mu\>*\<Phi\><rsub|0>|R>*\<mathd\>t\<less\>R
</equation*>
<\equation*>
\<mathd\>t\<less\><frac|R<rsup|2>|\<mu\>*\<Phi\><rsub|0>>
</equation*>
<\equation*>
<frac|\<mathd\>t|\<tau\>>\<less\><frac|R<rsup|2>|\<tau\>*\<mu\>*\<Phi\><rsub|0>>
</equation*>
<\equation*>
<frac|\<mathd\>t|\<tau\>>\<less\><frac|\<sigma\>*R<rsup|2>|\<varepsilon\><rsub|0>*\<mu\>*\<Phi\><rsub|0>>
</equation*>
<\equation*>
<frac|\<mathd\>t|\<tau\>>\<less\><frac|n*e*\<mu\>*R<rsup|2>|\<varepsilon\><rsub|0>*\<mu\>*\<Phi\><rsub|0>>
</equation*>
<\equation*>
<frac|\<mathd\>t|\<tau\>>\<less\><frac|n*e*R<rsup|2>|\<varepsilon\><rsub|0>*\<Phi\><rsub|0>>
</equation*>
<\equation*>
\<Phi\>=\<Phi\><rsub|0>*exp<around*|(|<frac|t|\<tau\>>|)>=\<Phi\><rsub|0>*exp<around*|(|<frac|i*\<mathd\>t|\<tau\>>|)>=\<Phi\><rsub|0>*exp<around*|(|i*<frac|n*e*R<rsup|2>|\<varepsilon\><rsub|0>*\<Phi\><rsub|0>>|)>
</equation*>
\;
</body>
<\initial>
<\collection>
<associate|page-height|auto>
<associate|page-type|letter>
<associate|page-width|auto>
</collection>
</initial>
<\references>
<\collection>
<associate|auto-1|<tuple|1|?>>
<associate|auto-2|<tuple|2|?>>
<associate|auto-3|<tuple|3|?>>
<associate|auto-4|<tuple|4|?>>
<associate|auto-5|<tuple|5|?>>
</collection>
</references>
<\auxiliary>
<\collection>
<\associate|toc>
<with|par-left|<quote|4tab>|Fundamental scales
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-1><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Dimensionless ratios
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-2><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Conductivity
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-3><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Alternative (independent) ratios
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-4><vspace|0.15fn>>
<with|par-left|<quote|4tab>|Timestep constraint
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
<no-break><pageref|auto-5><vspace|0.15fn>>
</associate>
</collection>
</auxiliary>

82
doc/tm/timestep.tm Normal file
View File

@@ -0,0 +1,82 @@
<TeXmacs|1.99.12>
<style|generic>
<\body>
<\equation*>
m*<frac|\<mathd\>v|\<mathd\>t>=q*E-m*\<nu\>*<around*|(|v-u|)>
</equation*>
<\equation*>
\<sigma\>=<frac|n*q<rsup|2>|m*\<nu\>>=n*q*\<mu\><application-space|1em>\<rightarrow\><application-space|1em>\<mu\>=<frac|q|m*\<nu\>><application-space|1em>\<rightarrow\><application-space|1em>m*\<nu\>=<frac|q|\<mu\>>
</equation*>
\;
<\equation*>
m*<frac|\<mathd\>v|\<mathd\>t>=q*<around*|(|E-<frac|v-u|\<mu\>>|)>
</equation*>
<\equation*>
<frac|\<mathd\>v|\<mathd\>t>=a*v+b
</equation*>
<\equation*>
a=-<frac|q|m*\<mu\>>
</equation*>
<\equation*>
b=<frac|q|m>*<around*|(|E+<frac|u|\<mu\>>|)>
</equation*>
The solution is
<\equation*>
v<around*|(|t|)>=C*exp<around*|(|a*t|)>-<frac|b|a>
</equation*>
<\equation*>
v<around*|(|t|)>=C*exp<around*|(|-<frac|q|m*\<mu\>>*t|)>-<frac|<frac|q|m>*<around*|(|E+<frac|u|\<mu\>>|)>|-<frac|q|m*\<mu\>>>=C*exp<around*|(|-<frac|t|\<tau\><rsub|c>>|)>+\<mu\>*E+u
</equation*>
where
<\equation*>
\<tau\><rsub|c>=<frac|m*\<mu\>|q>
</equation*>
The initial condition is
<\equation*>
v<around*|(|0|)>=C*+\<mu\>*E+u
</equation*>
<\equation*>
C=v<around*|(|0|)>-<around*|(|\<mu\>*E+u|)>
</equation*>
<\equation*>
v<around*|(|t|)>=v<around*|(|0|)>*exp<around*|(|-<frac|t|\<tau\><rsub|c>>|)>+<around*|(|\<mu\>*E+u|)><around*|(|1-exp<around*|(|-<frac|t|\<tau\><rsub|c>>|)>|)>
</equation*>
<\equation*>
v<around*|(|t+\<mathd\>t|)>=v<around*|(|t|)>*exp<around*|(|-<frac|\<mathd\>t|\<tau\><rsub|c>>|)>+<around*|(|\<mu\>*E+u|)><around*|(|1-exp<around*|(|-<frac|\<mathd\>t|\<tau\><rsub|c>>|)>|)>
</equation*>
The original timestep implemented by <with|font-shape|italic|Dragion> was
the <math|t\<rightarrow\>\<infty\>> limit,
<\equation*>
v<around*|(|t|)>=\<mu\>*E+u
</equation*>
\;
</body>
<\initial>
<\collection>
<associate|page-height|auto>
<associate|page-type|letter>
<associate|page-width|auto>
</collection>
</initial>

View File

@@ -0,0 +1 @@
Unexpected error. File contents could not be restored from local history during undo/redo.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,457 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache Commons Math includes the following code provided to the ASF under the
Apache License 2.0:
- The inverse error function implementation in the Erf class is based on CUDA
code developed by Mike Giles, Oxford-Man Institute of Quantitative Finance,
and published in GPU Computing Gems, volume 2, 2010 (grant received on
March 23th 2013)
- The LinearConstraint, LinearObjectiveFunction, LinearOptimizer,
RelationShip, SimplexSolver and SimplexTableau classes in package
org.apache.commons.math3.optimization.linear include software developed by
Benjamin McCann (http://www.benmccann.com) and distributed with
the following copyright: Copyright 2009 Google Inc. (grant received on
March 16th 2009)
- The class "org.apache.commons.math3.exception.util.LocalizedFormatsTest" which
is an adapted version of "OrekitMessagesTest" test class for the Orekit library
- The "org.apache.commons.math3.analysis.interpolation.HermiteInterpolator"
has been imported from the Orekit space flight dynamics library.
===============================================================================
APACHE COMMONS MATH DERIVATIVE WORKS:
The Apache commons-math library includes a number of subcomponents
whose implementation is derived from original sources written
in C or Fortran. License terms of the original sources
are reproduced below.
===============================================================================
For the lmder, lmpar and qrsolv Fortran routine from minpack and translated in
the LevenbergMarquardtOptimizer class in package
org.apache.commons.math3.optimization.general
Original source copyright and license statement:
Minpack Copyright Notice (1999) University of Chicago. All rights reserved
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the
following conditions are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
3. The end-user documentation included with the
redistribution, if any, must include the following
acknowledgment:
"This product includes software developed by the
University of Chicago, as Operator of Argonne National
Laboratory.
Alternately, this acknowledgment may appear in the software
itself, if and wherever such third-party acknowledgments
normally appear.
4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
BE CORRECTED.
5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
POSSIBILITY OF SUCH LOSS OR DAMAGES.
===============================================================================
Copyright and license statement for the odex Fortran routine developed by
E. Hairer and G. Wanner and translated in GraggBulirschStoerIntegrator class
in package org.apache.commons.math3.ode.nonstiff:
Copyright (c) 2004, Ernst Hairer
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
Copyright and license statement for the original Mersenne twister C
routines translated in MersenneTwister class in package
org.apache.commons.math3.random:
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
The initial code for shuffling an array (originally in class
"org.apache.commons.math3.random.RandomDataGenerator", now replaced by
a method in class "org.apache.commons.math3.util.MathArrays") was
inspired from the algorithm description provided in
"Algorithms", by Ian Craw and John Pulham (University of Aberdeen 1999).
The textbook (containing a proof that the shuffle is uniformly random) is
available here:
http://citeseerx.ist.psu.edu/viewdoc/download;?doi=10.1.1.173.1898&rep=rep1&type=pdf
===============================================================================
License statement for the direction numbers in the resource files for Sobol sequences.
-----------------------------------------------------------------------------
Licence pertaining to sobol.cc and the accompanying sets of direction numbers
-----------------------------------------------------------------------------
Copyright (c) 2008, Frances Y. Kuo and Stephen Joe
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the
University of New South Wales and the University of Waikato
and its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================
The initial commit of package "org.apache.commons.math3.ml.neuralnet" is
an adapted version of code developed in the context of the Data Processing
and Analysis Consortium (DPAC) of the "Gaia" project of the European Space
Agency (ESA).
===============================================================================
The initial commit of the class "org.apache.commons.math3.special.BesselJ" is
an adapted version of code translated from the netlib Fortran program, rjbesl
http://www.netlib.org/specfun/rjbesl by R.J. Cody at Argonne National
Laboratory (USA). There is no license or copyright statement included with the
original Fortran sources.
===============================================================================
The BracketFinder (package org.apache.commons.math3.optimization.univariate)
and PowellOptimizer (package org.apache.commons.math3.optimization.general)
classes are based on the Python code in module "optimize.py" (version 0.5)
developed by Travis E. Oliphant for the SciPy library (http://www.scipy.org/)
Copyright © 2003-2009 SciPy Developers.
SciPy license
Copyright © 2001, 2002 Enthought, Inc.
All rights reserved.
Copyright © 2003-2013 SciPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Enthought nor the names of the SciPy Developers may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===============================================================================

View File

@@ -0,0 +1,9 @@
Apache Commons Math
Copyright 2001-2016 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
This product includes software developed for Orekit by
CS Systèmes d'Information (http://www.c-s.fr/)
Copyright 2010-2012 CS Systèmes d'Information

View File

@@ -0,0 +1,32 @@
Apache Commons Math 3.6.1 RELEASE NOTES
The Apache Commons Math team is pleased to announce the release of
commons-math3-3.6.1
The Apache Commons Math project is a library of lightweight, self-contained
mathematics and statistics components addressing the most common practical
problems not immediately available in the Java programming language or
commons-lang.
This is a minor bug fix release. It incorporates three bug fixes since version
3.6. The minimum version of the Java platform required to compile and use
Commons Math 3.6.1 is Java 5.
Changes in this version include:
Fixed Bugs:
o MATH-1316: Fix code example in User Guide > Statistics > Multiple linear regression.
o MATH-1342: Fix ODE integrators when multiple events are nearly simultaneous.
Changes:
o MATH-1317: Add uniformity unit tests to "RandomGeneratorAbstractTest".
For complete information on Apache Commons Math, including instructions on how
to submit bug reports, patches, or suggestions for improvement, see the Apache
Commons Math website:
http://commons.apache.org/proper/commons-math/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/jna-5.4.0/jna-5.4.0.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,13 @@
function [phi,x,y,z] = diagread(filename)
fid = fopen(filename, 'rt');
dum = fscanf(fid, '%s', 1);
phi = str2num(fgetl(fid));
dum = fscanf(fid, '%s', 1);
x = str2num(fgetl(fid));
dum = fscanf(fid, '%s', 1);
y = str2num(fgetl(fid));
dum = fscanf(fid, '%s', 1);
z = str2num(fgetl(fid));
fclose(fid);

View File

@@ -0,0 +1,136 @@
package dragion.physics;
import java.util.Iterator;
import java.util.List;
import lestat.particles.Particle;
import mowgli.grid.CellScalar;
import mowgli.grid.Grid;
import mowgli.grid.InterpolationFactor;
import mowgli.shapes.Box;
public class CollisionalSinkUnipolar
{
final Grid grid;
final CellScalar sinkrate; // number / m^3 / s
final CellScalar density; // number / m^3
final CellScalar numberToLose; // number per cell; soy un perdedor so why don't you kill me...
public Grid getGrid()
{
return grid;
}
public CellScalar getSinkrate()
{
return sinkrate;
}
// public CellScalar getNumberToLose()
// {
// return numberToLose;
// }
public CellScalar getDensity()
{
return density;
}
public static final double alpha = 1e-12;
public CollisionalSinkUnipolar(Box bbox, int gridres)
{
this.grid = Grid.approximateSubdivide(bbox, gridres);
this.sinkrate = new CellScalar(grid, "sinkrate [#/m^3/s]");
this.density = new CellScalar(grid, "density [#/m^3]");
this.numberToLose = new CellScalar(grid, "numberToLose [#/timestep]");
}
public double checkPPC(double den, double np2c)
{
double cellvol = grid.getDx() * grid.getDy() * grid.getDz();
double ptclvol = np2c/den;
double ptclPerCell = cellvol/ptclvol;
return ptclPerCell;
}
public void collide(List<Particle> particles, double dt)
{
density.zero();
double[][][] density = this.density.getData();
Iterator<Particle> it = particles.iterator();
while (it.hasNext())
{
Particle p = it.next();
InterpolationFactor fac = grid.computeInterpolationFactor(p.getPos());
int i = fac.ilower;
int j = fac.jlower;
int k = fac.klower;
if (fac.isGood())
{
density[i][j][k] += p.getSpecies().getNp2c() / grid.getCellVolume(); // number density contribution per particle
}
else
{
throw new Error("Bad interpolation factor: position = " + p.getPos());
}
}
sinkrate.zero();
double[][][] sinkrate = this.sinkrate.getData();
//numberToLose.zero();
double[][][] numberToLose = this.numberToLose.getData();
for (int i = 0; i < grid.getNxc(); i++)
{
for (int j = 0; j < grid.getNyc(); j++)
{
for (int k = 0; k < grid.getNzc(); k++)
{
sinkrate[i][j][k] = density[i][j][k] * density[i][j][k] * alpha; // number / m^3 / s
numberToLose[i][j][k] += sinkrate[i][j][k] * dt * grid.getCellVolume();
}
}
}
it = particles.iterator();
while (it.hasNext())
{
Particle p = it.next();
InterpolationFactor fac = grid.computeInterpolationFactor(p.getPos());
int i = fac.ilower;
int j = fac.jlower;
int k = fac.klower;
if (fac.isGood())
{
if (numberToLose[i][j][k] > 0)
{
if (numberToLose[i][j][k] > p.getSpecies().getNp2c())
{
it.remove();
numberToLose[i][j][k] -= p.getSpecies().getNp2c();
}
else
{
if (Math.random() < numberToLose[i][j][k] / p.getSpecies().getNp2c())
{
it.remove();
numberToLose[i][j][k] -= p.getSpecies().getNp2c();
}
}
}
}
else
{
throw new Error("Bad interpolation factor: position = " + p.getPos());
}
}
}
}

View File

@@ -0,0 +1,75 @@
package dragion.physics;
import java.util.Collection;
import java.util.stream.Stream;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.apache.commons.math3.special.Erf;
import lestat.particles.Advancer;
import lestat.particles.Particle;
import mowgli.Constants;
public class DriftDiffusionAdvancer implements Advancer
{
final double mobility;
final double temperature;
//final Vector3D windvel;
final boolean usetemp;
//final boolean usewind;
public DriftDiffusionAdvancer(double mobility, double temperature)//, Vector3D windvel)
{
this.mobility = mobility;
this.temperature = temperature;
// this.windvel = windvel;
this.usetemp = (mobility != 0) || (temperature != 0);
// this.usewind = !windvel.equals(Vector3D.ZERO);
}
@Override
public void advance(Collection<Particle> particles, double dt)
{
Stream<Particle> stream = particles.parallelStream();
stream.forEach((p) ->
{
//
// drift part
Vector3D vnew = p.getEfld().scalarMultiply(mobility);
//
// diffusion part... lots of Math.* method calls here so maybe some room for optimization
if (usetemp)
{
double D = mobility * Constants.boltzmann * temperature / Constants.qe; // diffusion coefficient
double lam = Math.sqrt(4 * D * dt); // characteristic diffusive jump length
double c = 2 * Math.random() - 1;
double dr = Math.pow(lam * Math.sqrt(Math.PI), 3) * Erf.erfInv(c);
double phi = 2 * Math.PI * Math.random();
double th = Math.acos(1 - 2 * Math.random());
double dxp = dr * Math.cos(phi) * Math.sin(th);
double dyp = dr * Math.sin(phi) * Math.sin(th);
double dzp = dr * Math.cos(th);
Vector3D jumplen = new Vector3D(dxp, dyp, dzp);
Vector3D vdiff = jumplen.scalarMultiply(1. / dt);
vnew = vnew.add(vdiff);
}
//
// wind advection part
// if (usewind)
// {
// vnew = vnew.add(windvel);
// }
//
p.setVel(vnew);
//
Vector3D xold = p.getPos();
p.setOldPos(xold);
//
Vector3D xnew = xold.add(vnew.scalarMultiply(dt));
p.setPos(xnew);
});
}
}

View File

@@ -0,0 +1,50 @@
package dragion.physics;
import java.util.Collection;
import java.util.stream.Stream;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import lestat.particles.Advancer;
import lestat.particles.Particle;
public class FluidAdvancer implements Advancer
{
final Vector3D windvel;
final double mobility;
final double charge;
final double mass;
public FluidAdvancer(Vector3D windvel, double mobility, double charge, double mass)
{
this.windvel = windvel;
this.mobility = mobility;
this.charge = charge;
this.mass = mass;
}
@Override
public void advance(Collection<Particle> plist, double dt)
{
double tauc = mass * mobility / charge;
double expterm = Math.exp(-dt/tauc);
Stream<Particle> stream = plist.parallelStream();
stream.forEach((p) ->
{
Vector3D vold = p.getVel();
Vector3D euterm = p.getEfld().scalarMultiply(mobility).add(windvel);
Vector3D vnew = vold.scalarMultiply(expterm).add(euterm.scalarMultiply(1-expterm));
//
Vector3D xold = p.getPos();
Vector3D xnew = xold.add(vnew.scalarMultiply(dt));
//
p.setVel(vnew);
p.setOldPos(xold);
p.setPos(xnew);
});
}
}

View File

@@ -0,0 +1,106 @@
package dragion.physics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import lestat.particles.Particle;
import lestat.particles.Species;
import lestat.particles.emitcollect.Emitter;
import lestat.particles.emitcollect.RateDiscretizer;
import lestat.solvers.CompositeSolver;
import mowgli.samplers.QuadUniformSampler;
import mowgli.shapes.Box;
import mowgli.shapes.Box.Side;
import mowgli.shapes.Quad;
import mowgli.surfaces.EmbreeIntersector;
import mowgli.surfaces.Surface;
public class SideFluxInjector implements Emitter
{
final Box bbox;
final CompositeSolver solver;
final Species species;
final Function<Vector3D, Double> density;
final Function<Vector3D, Vector3D> windvel;
final double mobility;
Multimap<Side, Quad> allquads = ArrayListMultimap.create();
Map<Quad, QuadUniformSampler> samplers = new HashMap<>();
Map<Quad, RateDiscretizer> discretizers = new HashMap<>();
protected boolean checkInside(EmbreeIntersector intersector, Quad quad)
{
return (intersector.isInside(quad.getP1()) || intersector.isInside(quad.getP2()) || intersector.isInside(quad.getP3()) || intersector.isInside(quad.getP4()) || intersector.isInside(quad.getCenter()));
}
public SideFluxInjector(Box bbox, CompositeSolver solver, Species species, int subdiv, Function<Vector3D, Double> density, double mobility, EmbreeIntersector intersector, Function<Vector3D, Vector3D> windvel)
{
this.bbox = bbox;
this.solver = solver;
this.species = species;
this.density = density;
this.mobility = mobility;
this.windvel = windvel;
Map<Side, Quad> sides = Box.inwardPointingSides(bbox); // normals are inward pointing
for (Side side : sides.keySet())
{
Quad parent = sides.get(side);
// int subdiv = (int) Math.floor(Math.log(parent.getLength() / approxPanelSize) / Math.log(2)); // log2(parent length / panel size)
Quad[] children = Quad.subdivide(parent, subdiv);
for (Quad child : children)
{
if (!checkInside(intersector, child))
{
allquads.put(side, child);
samplers.put(child, new QuadUniformSampler(child));
discretizers.put(child, new RateDiscretizer());
}
}
}
}
@Override
public Collection<Particle> emit(double dt)
{
List<Particle> particles = new ArrayList<>();
for (Quad quad : allquads.values())
{
// estimate flux as (mobility * efld + windvel) * area at quad center
Vector3D ctr = quad.getCenter();
Vector3D ctrefld = solver.synthesizeElectricField(ctr);
double n0 = density.apply(ctr);
Vector3D ctrwindvel = windvel.apply(ctr);
Vector3D ctrvel = ctrefld.scalarMultiply(mobility).add(ctrwindvel);
double ctrvelprp = ctrvel.dotProduct(quad.getNormal());
if (ctrvelprp > 0) // normals are inward-pointing
{
RateDiscretizer discretizer = discretizers.get(quad);
discretizer.setRate(n0 * ctrvelprp * quad.getArea() / species.getNp2c());
int ntoemit = discretizer.update(dt);
//
for (int i = 0; i < ntoemit; i++)
{
double dtpart = dt * Math.random();
Vector3D oldpos = samplers.get(quad).get();
Vector3D newpos = oldpos.add(ctrvel.scalarMultiply(dtpart));
Particle p = new Particle(newpos, ctrvel, species);
p.setOldPos(oldpos);
particles.add(p);
}
}
}
return particles;
}
}

View File

@@ -0,0 +1,10 @@
package dragion.physics;
import java.util.function.BiFunction;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
public interface SourceFunction extends BiFunction<Vector3D, Double, Double>
{
}

Some files were not shown because too many files have changed in this diff Show More