Skip to content

Commit d248490

Browse files
roelof-groenewaldaveksler1pre-commit-ci[bot]ax3l
authored
Use RK4 to integrate the B-field in time in the hybrid-PIC algorithm (BLAST-WarpX#4461)
* add external current support to the hybrid-PIC solver * add RZ support for `FiniteDifferenceSolver::CalculateCurrentAmpere` * allow an initial Bz field to be set in RZ * code cleanup and addition of CI test * revert unwanted changes * WIP transition to use RK4 in B-field time integration in hybrid-PIC algorithm Co-authored-by: Avigdor Veksler <[email protected]> * fix some clang-tidy issues * Complete BfieldEvolveRK (#2) * continued transition to RK4 in B-field time integration in hybrid-PIC algorithm * RK-integration over all levels * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update some of the CI tests * more CI test updates * Various code cleanups * more updates to CI tests and checksum benchmarks * more updates to CI tests and checksum benchmarks; remove commented code * update documentation * fix 1 for RZ CI test after merging of BLAST-WarpX#4464 * Avoid using `const` with `Real` passed by value Co-authored-by: Axel Huebl <[email protected]> * reduce default number of substeps to 10 * formatting fix --------- Co-authored-by: Avigdor Veksler <[email protected]> Co-authored-by: Avigdor Veksler <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Axel Huebl <[email protected]>
1 parent 3b1dff5 commit d248490

File tree

17 files changed

+258
-89
lines changed

17 files changed

+258
-89
lines changed

Docs/source/theory/kinetic_fluid_hybrid_model.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ be interpolated to the correct time, using :math:`\vec{J}_i^n = 1/2(\vec{J}_i^{n
116116
The electron pressure is simply calculated using :math:`\rho^n` and the B-field is also already
117117
known at the correct time since it was calculated for :math:`t=t_n` at the end of the last step.
118118
Once :math:`\vec{E}^n` is calculated, it is used to push :math:`\vec{B}^n` forward in time
119-
(using the Maxwell-Faraday equation, i.e. the same as in the regular PIC routine with ``WarpX::EvolveB()``)
120-
to :math:`\vec{B}^{n+1/2}`.
119+
(using the Maxwell-Faraday equation) to :math:`\vec{B}^{n+1/2}`.
121120

122121
Second half step
123122
""""""""""""""""
@@ -147,10 +146,11 @@ Sub-stepping
147146
^^^^^^^^^^^^
148147

149148
It is also well known that hybrid PIC routines require the B-field to be
150-
updated with a smaller timestep than needed for the particles. The update steps
151-
as outlined above are therefore wrapped in loops that enable the B-field to be
152-
sub-stepped. The exact number of sub-steps used can be specified by the user
153-
through a runtime simulation parameter (see :ref:`input parameters section <running-cpp-parameters-hybrid-model>`).
149+
updated with a smaller timestep than needed for the particles. A 4th order
150+
Runge-Kutta scheme is used to update the B-field. The RK scheme is repeated a
151+
number of times during each half-step outlined above. The number of sub-steps
152+
used can be specified by the user through a runtime simulation parameter
153+
(see :ref:`input parameters section <running-cpp-parameters-hybrid-model>`).
154154

155155
.. _theory-hybrid-model-elec-temp:
156156

Docs/source/usage/parameters.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2256,7 +2256,7 @@ Maxwell solver: kinetic-fluid hybrid
22562256
* ``hybrid_pic_model.n_floor`` (`float`) optional (default ``1``)
22572257
If ``algo.maxwell_solver`` is set to ``hybrid``, this sets the plasma density floor, in :math:`m^{-3}`, which is useful since the generalized Ohm's law used to calculate the E-field includes a :math:`1/n` term.
22582258

2259-
* ``hybrid_pic_model.substeps`` (`int`) optional (default ``100``)
2259+
* ``hybrid_pic_model.substeps`` (`int`) optional (default ``10``)
22602260
If ``algo.maxwell_solver`` is set to ``hybrid``, this sets the number of sub-steps to take during the B-field update.
22612261

22622262
.. note::

Examples/Tests/ohm_solver_EM_modes/PICMI_inputs.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class EMModes(object):
5858
# Plasma resistivity - used to dampen the mode excitation
5959
eta = [[1e-7, 1e-7], [1e-7, 1e-5], [1e-7, 1e-4]]
6060
# Number of substeps used to update B
61-
substeps = [[250, 500], [250, 750], [250, 1000]]
61+
substeps = 20
6262

6363
def __init__(self, test, dim, B_dir, verbose):
6464
"""Get input parameters for the specific case desired."""
@@ -149,7 +149,6 @@ def get_simulation_parameters(self):
149149

150150
self.NPPC = self.NPPC[self.dim-1]
151151
self.eta = self.eta[self.dim-1][idx]
152-
self.substeps = self.substeps[self.dim-1][idx]
153152

154153
def get_plasma_quantities(self):
155154
"""Calculate various plasma parameters based on the simulation input."""

Examples/Tests/ohm_solver_EM_modes/PICMI_inputs_rz.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class CylindricalNormalModes(object):
5353
# Plasma resistivity - used to dampen the mode excitation
5454
eta = 5e-4
5555
# Number of substeps used to update B
56-
substeps = 250
56+
substeps = 20
5757

5858
def __init__(self, test, verbose):
5959
"""Get input parameters for the specific case desired."""

Examples/Tests/ohm_solver_EM_modes/analysis_rz.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def process(it):
154154
amps = np.abs(F_kw[2, 1, len(kz)//2-2:len(kz)//2+2])
155155
print("Amplitude sample: ", amps)
156156
assert np.allclose(
157-
amps, np.array([61.4170941, 19.39380715, 101.08640009, 11.09261815])
157+
amps, np.array([61.50945919, 19.74831134, 101.01820349, 10.8974811])
158158
)
159159

160160
if sim.test:

Examples/Tests/ohm_solver_ion_Landau_damping/PICMI_inputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class IonLandauDamping(object):
5656
# Plasma resistivity - used to dampen the mode excitation
5757
eta = 1e-7
5858
# Number of substeps used to update B
59-
substeps = 100
59+
substeps = 10
6060

6161

6262
def __init__(self, test, dim, m, T_ratio, verbose):

Examples/Tests/ohm_solver_ion_beam_instability/PICMI_inputs.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class HybridPICBeamInstability(object):
5454
# Plasma resistivity - used to dampen the mode excitation
5555
eta = 1e-7
5656
# Number of substeps used to update B
57-
substeps = 400
57+
substeps = 10
5858

5959
# Beam parameters
6060
n_beam = [0.02, 0.1]
@@ -95,11 +95,9 @@ def __init__(self, test, dim, resonant, verbose):
9595
diag_period = 1 / 4.0 # Output interval (ion cyclotron periods)
9696
self.diag_steps = int(diag_period / self.DT)
9797

98-
# if this is a test case run for only 25 cyclotron periods and use
99-
# fewer substeps to speed up the simulation
98+
# if this is a test case run for only 25 cyclotron periods
10099
if self.test:
101100
self.LT = 25.0
102-
self.substeps = 100
103101

104102
self.total_steps = int(np.ceil(self.LT / self.DT))
105103

Examples/Tests/ohm_solver_ion_beam_instability/analysis.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,11 @@
190190
# assert's fail, the full benchmark should be rerun (same as the test but
191191
# without the `--test` argument) and the growth rates (up to saturation)
192192
# compared to the theoretical ones to determine if the physics test passes.
193-
# At creation, the full test had the following errors when ran on 8 procs:
194-
# m4_rms_error = 4.476; m5_rms_error = 9.211; m6_rms_error = 3.252
195-
assert m4_rms_error < 1.55
196-
assert m5_rms_error < 0.75
197-
assert m6_rms_error < 0.40
193+
# At creation, the full test (3d) had the following errors (ran on 1 V100):
194+
# m4_rms_error = 3.329; m5_rms_error = 1.052; m6_rms_error = 2.583
195+
assert np.isclose(m4_rms_error, 1.515, atol=0.01)
196+
assert np.isclose(m5_rms_error, 0.718, atol=0.01)
197+
assert np.isclose(m6_rms_error, 0.357, atol=0.01)
198198

199199
# checksum check
200200
import os

Examples/Tests/ohm_solver_magnetic_reconnection/PICMI_inputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class ForceFreeSheetReconnection(object):
5959
# Plasma resistivity - used to dampen the mode excitation
6060
eta = 6e-3 # normalized resistivity
6161
# Number of substeps used to update B
62-
substeps = 750
62+
substeps = 20
6363

6464
def __init__(self, test, verbose):
6565

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
22
"lev=0": {
3-
"Bx": 0.0846232979356012,
4-
"By": 0.0748927888009307,
3+
"Bx": 0.08460920626188952,
4+
"By": 0.07485331147996604,
55
"Bz": 256.0,
6-
"Ex": 1960.2420822749025,
7-
"Ey": 2368.794327568534,
8-
"Ez": 4873.496044339846
6+
"Ex": 1954.3267519602405,
7+
"Ey": 2363.4281756166347,
8+
"Ez": 4873.508158589938
99
},
1010
"ions": {
11-
"particle_momentum_x": 1.615113301362171e-19,
12-
"particle_momentum_y": 1.6152332353795267e-19,
13-
"particle_momentum_z": 1.6134581585733078e-19,
14-
"particle_position_x": 3678.484650863704,
11+
"particle_momentum_x": 1.6151135948675135e-19,
12+
"particle_momentum_y": 1.6152336151551518e-19,
13+
"particle_momentum_z": 1.6134581268392543e-19,
14+
"particle_position_x": 3678.484650899751,
1515
"particle_weight": 4.220251350277737e+21
1616
}
1717
}

0 commit comments

Comments
 (0)