A02_Boris_3Drtz Test
====================
.. raw:: html
.. container:: ap-lang ap-lang-zh
.. rubric:: 测试目标
本页说明 ``tests/002_pusher/A02_Boris_3Drtz`` 中的参考测试。该测试调用
``sub_A02_Boris_3Drtz_push_v_x(x, v, E, B, k, dt)``,检查非相对论柱坐标
``(r,\theta,z)`` Boris 推进器(同时更新位置和速度)在与 A01 对应的
四个均匀场算例下的轨道、速度和解析参考解的一致性。
.. rubric:: 跟 A01 的关键差异
- **接口**:A02 是 ``(x, v, E, B, k, dt)``——子程序内部完成位置更新,
不需要调用方再做 ``r = r + v*dt``。
- **坐标系**:位置 ``x = (r, \theta, z)``,速度 ``v = (v_r, v_\theta, v_z)``,
电磁场 ``E``、``B`` 也按柱坐标分量传入。
- **初值位移**:四个 case 都把粒子的初始 Cartesian 位置从原点平移到
``(x_0, 0, 0)``,其中 ``x_0 = 1.0``,以避开 ``r = 0`` 奇点。
- **case 1 初始速度调整**:A02 case 1 用 ``v_init = (0, v_0, 0)`` Cartesian
(A01 用 ``(v_0, 0, 0)``),让回旋圆心位于 +x 方向,整个轨道 ``r`` 始终大于 ``x_0``。
- **每步重算 cylindrical 场**:均匀 Cartesian 场 ``E_x = E_0``
在柱坐标里随 ``\theta`` 旋转,每步从 Cartesian 输入按
``E_r = E_0 \cos\theta``、``E_\phi = -E_0 \sin\theta`` 重算。
.. rubric:: 程序结构
- ``source_f90/main.f90`` 设置参数并依次运行四个 case。
- ``source_f90/sub_case*.f90`` 给出每个物理算例、解析参考解和误差输出;
模拟值从柱坐标 ``(r, \theta, z, v_r, v_\theta, v_z)`` 转换回 Cartesian
``(x, y, z, v_x, v_y, v_z)`` 后再跟 A01 同款的 Cartesian 解析解比较。
- ``source_py/plot_savefig.py`` 读取 ``build/*.dat``,打印最大误差并保存图片
(与 A01 同款,因为输出列格式一致)。
- ``make.sh`` 使用 ``gfortran -cpp -O3 -fdefault-real-8`` 编译测试程序。
.. rubric:: 运行方式
.. code-block:: bash
cd tests/002_pusher/A02_Boris_3Drtz
bash clean.sh && bash make.sh && bash run.sh && bash plot.sh
``run.sh`` 会生成 ``build/case*.dat``;``plot.sh`` 会生成 ``figs_cases/*.png``。
文档中的静态图是从一次参考运行复制到 ``docs/source/images/tests/002_pusher`` 的结果。
.. rubric:: 输出字段
每个 ``.dat`` 文件的列与 A01 完全一致:
``step, t, x, y, z, vx, vy, vz, v2``,随后是解析位置和解析速度,
最后两列为 ``err_v = |v - v_ana|`` 和 ``err_r = |r - r_ana|``。
注意这里的 ``(x, y, z, vx, vy, vz)`` 是 **柱坐标模拟值转回 Cartesian** 后的结果,
方便直接跟 A01 的解析解逐分量比对。
.. list-table:: 测试算例
:header-rows: 1
:widths: 18 42 40
* - Case
- 设置(Cartesian)
- 主要检查
* - ``case01_gyro``
- ``E = 0``,``B`` 沿 ``z``,``v_{init} = (0, v_0, 0)``
- 偏移圆心的回旋轨道和 ``v^2`` 守恒。
* - ``case02_Eonly``
- 只有均匀电场 ``E = (E_x, 0, 0)``,``v_{init} = 0``
- 沿 ``+x`` 的匀加速解析解,``\theta`` 全程为 0。
* - ``case03_ExB``
- 均匀 ``E = (E_x, 0, 0)``、``B = (0, 0, B_0)``,带初速
- 回旋运动叠加 :math:`E \times B` drift;``\theta`` 随轨迹变化。
* - ``case04_ExB_drift``
- 选择初速 ``(0, -E_x/B_0, 0)`` 消去回旋分量
- 纯 :math:`E \times B` drift;``\theta`` 单调向 ``-\pi/2`` 趋近。
.. rubric:: 参考结果
与 A01 在同样的物理参数下对比,A02 给出几乎相同量级的逐 case 误差:
.. list-table::
:header-rows: 1
:widths: 18 22 22 22 22
* - Case
- A01 max ``|v - v_{ana}|``
- A02 max ``|v - v_{ana}|``
- A01 max ``|r - r_{ana}|``
- A02 max ``|r - r_{ana}|``
* - gyro
- 3.83e-7
- 9.66e-7
- 1.00e+5
- 1.00e+5
* - Eonly
- 2.19e-13
- 2.19e-13
- 4.00e-3
- 4.00e-3
* - ExB
- 6.00e-7
- 6.00e-7
- 8.60e-4
- 8.60e-4
* - drift
- 6.00e-7
- 6.00e-7
- 1.25e-6
- 1.25e-6
位置误差 **逐 case 完全一致**,验证柱坐标 Boris 在物理上等价于 Cartesian Boris。
case 1 的速度误差略大(cos/sin/sqrt/atan2 引入的额外舍入),其余三个 case 完全相同。
.. rubric:: 参考图
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case01_gyro_traj_xy.png
:align: center
:width: 78%
``case01_gyro`` 的 ``x-y`` 轨道(柱坐标模拟值转回 Cartesian 后),
数值轨道应跟随解析回旋轨道。
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case01_gyro_v2_t.png
:align: center
:width: 78%
``case01_gyro`` 的 ``v^2`` 随时间变化,用于观察磁场旋转步的速度模保持情况。
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case02_Eonly_x_t.png
:align: center
:width: 78%
``case02_Eonly`` 的 ``x(t)``,``\theta`` 全程为 0,曲线退化成 1D 匀加速。
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case03_ExB_traj_xy.png
:align: center
:width: 78%
``case03_ExB`` 的 ``x-y`` 轨道,柱坐标 Boris 仍能正确给出回旋 + drift 的摆线轨迹。
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case04_drift_traj_xy.png
:align: center
:width: 78%
``case04_ExB_drift`` 的 ``x-y`` 轨道,沿 ``-y`` 方向匀速漂移,
无回旋分量。
.. rubric:: 参考文献
[1] J.P. Boris, Relativistic plasma simulation-optimization of a hybrid code,
in: Proceedings of the Fourth Conference on Numerical Simulation of Plasmas,
Naval Research Laboratory, Washington, D.C., 1970, pp.3-67.
[2] G.L. Delzanno, E. Camporeale, On particle movers in cylindrical geometry
for Particle-In-Cell simulations, Journal of Computational Physics,
253 (2013) 259-277. DOI: `10.1016/j.jcp.2013.07.007 `_
.. container:: ap-lang ap-lang-en
.. rubric:: Test Goal
This page documents the reference test under
``tests/002_pusher/A02_Boris_3Drtz``. The test calls
``sub_A02_Boris_3Drtz_push_v_x(x, v, E, B, k, dt)`` and checks the
non-relativistic cylindrical ``(r,\theta,z)`` Boris pusher (which advances
both position and velocity in one call) against analytic reference motion
in the same four uniform-field cases as A01.
.. rubric:: Key Differences from A01
- **Interface**: A02 takes ``(x, v, E, B, k, dt)``. The subroutine performs
the position update internally; the caller does not append
``r = r + v*dt``.
- **Coordinates**: position ``x = (r, \theta, z)`` and velocity
``v = (v_r, v_\theta, v_z)``; the ``E`` and ``B`` inputs are also in
cylindrical components.
- **Initial offset**: all four cases shift the Cartesian starting position
from the origin to ``(x_0, 0, 0)`` with ``x_0 = 1.0`` to avoid the
``r = 0`` singularity.
- **Case 1 initial velocity**: A02 case 1 uses Cartesian
``v_{init} = (0, v_0, 0)`` (A01 uses ``(v_0, 0, 0)``) so the gyro center
sits on the +x side and the orbit always satisfies ``r \ge x_0``.
- **Per-step field conversion**: a uniform Cartesian ``E_x = E_0`` field
has ``\theta``-dependent cylindrical components, recomputed each step as
``E_r = E_0 \cos\theta``, ``E_\phi = -E_0 \sin\theta``.
.. rubric:: Program Structure
- ``source_f90/main.f90`` sets the parameters and runs the four cases.
- ``source_f90/sub_case*.f90`` defines each case and the analytic reference
solution; simulated cylindrical state is converted back to Cartesian
``(x, y, z, v_x, v_y, v_z)`` before being compared to the same Cartesian
analytic solution used in A01.
- ``source_py/plot_savefig.py`` reads ``build/*.dat``, prints maximum
errors, and saves figures (identical to A01 because the column format
matches).
- ``make.sh`` compiles the test with ``gfortran -cpp -O3 -fdefault-real-8``.
.. rubric:: Run Command
.. code-block:: bash
cd tests/002_pusher/A02_Boris_3Drtz
bash clean.sh && bash make.sh && bash run.sh && bash plot.sh
``run.sh`` writes ``build/case*.dat``. ``plot.sh`` writes
``figs_cases/*.png``. The static figures below are copied from one
reference run into ``docs/source/images/tests/002_pusher``.
.. rubric:: Output Fields
Each ``.dat`` file uses the same columns as A01:
``step, t, x, y, z, vx, vy, vz, v2``, followed by analytic position and
velocity columns, with the final two columns being
``err_v = |v - v_{ana}|`` and ``err_r = |r - r_{ana}|``. Note that
``(x, y, z, vx, vy, vz)`` are the **simulated cylindrical state converted
back to Cartesian** so they can be directly compared with the same
Cartesian analytic solutions used in A01.
.. list-table:: Test Cases
:header-rows: 1
:widths: 18 42 40
* - Case
- Setup (Cartesian)
- Main check
* - ``case01_gyro``
- ``E = 0``, ``B`` along ``z``, ``v_{init} = (0, v_0, 0)``
- Gyro orbit (with offset center) and ``v^2`` conservation.
* - ``case02_Eonly``
- Uniform ``E = (E_x, 0, 0)``, ``v_{init} = 0``
- Constant-acceleration along ``+x``; ``\theta`` stays at 0.
* - ``case03_ExB``
- Uniform ``E = (E_x, 0, 0)``, ``B = (0, 0, B_0)``, with initial velocity
- Gyro motion plus :math:`E \times B` drift; ``\theta`` varies along the trajectory.
* - ``case04_ExB_drift``
- Initial velocity ``(0, -E_x/B_0, 0)`` chosen to remove the gyro component
- Pure :math:`E \times B` drift; ``\theta`` approaches ``-\pi/2``.
.. rubric:: Reference Results
Run under the same physical parameters as A01, A02 produces case-by-case
errors of essentially the same magnitude:
.. list-table::
:header-rows: 1
:widths: 18 22 22 22 22
* - Case
- A01 max ``|v - v_{ana}|``
- A02 max ``|v - v_{ana}|``
- A01 max ``|r - r_{ana}|``
- A02 max ``|r - r_{ana}|``
* - gyro
- 3.83e-7
- 9.66e-7
- 1.00e+5
- 1.00e+5
* - Eonly
- 2.19e-13
- 2.19e-13
- 4.00e-3
- 4.00e-3
* - ExB
- 6.00e-7
- 6.00e-7
- 8.60e-4
- 8.60e-4
* - drift
- 6.00e-7
- 6.00e-7
- 1.25e-6
- 1.25e-6
Position errors are **identical case-by-case**, confirming that the
cylindrical Boris is physically equivalent to the Cartesian one. The
slightly larger velocity error in case 1 reflects extra rounding from
``cos/sin/sqrt/atan2``; the other three cases match exactly.
.. rubric:: Reference Figures
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case01_gyro_traj_xy.png
:align: center
:width: 78%
``case01_gyro`` trajectory in the ``x-y`` plane (cylindrical simulation
converted back to Cartesian) tracking the analytic gyro orbit.
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case01_gyro_v2_t.png
:align: center
:width: 78%
``case01_gyro`` time history of ``v^2``.
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case02_Eonly_x_t.png
:align: center
:width: 78%
``case02_Eonly`` comparison of ``x(t)`` with the electric-only analytic
solution. ``\theta`` stays at 0, so the trajectory is effectively 1D.
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case03_ExB_traj_xy.png
:align: center
:width: 78%
``case03_ExB`` trajectory showing the cylindrical Boris correctly
reproducing the gyro + :math:`E \times B` cycloid.
.. figure:: ../../images/tests/002_pusher/A02_Boris_3Drtz/case04_drift_traj_xy.png
:align: center
:width: 78%
``case04_ExB_drift`` trajectory drifting uniformly in ``-y`` with no
gyro component.
.. rubric:: References
[1] J.P. Boris, Relativistic plasma simulation-optimization of a hybrid code,
in: Proceedings of the Fourth Conference on Numerical Simulation of Plasmas,
Naval Research Laboratory, Washington, D.C., 1970, pp.3-67.
[2] G.L. Delzanno, E. Camporeale, On particle movers in cylindrical geometry
for Particle-In-Cell simulations, Journal of Computational Physics,
253 (2013) 259-277. DOI: `10.1016/j.jcp.2013.07.007 `_