Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Space charge Mayes IPAC2018 benchmark #429

Open
wants to merge 52 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
877484e
Examples for 3D space charge benchmarking
cemitch99 Jun 7, 2022
1b55a2e
Update input_kurth_10nC.in
cemitch99 Dec 5, 2022
50d3900
Add expanding test from Mayes IPAC2018
cemitch99 Sep 8, 2023
bb79449
Delete examples/kurth/input_kurth_10nC.in
cemitch99 Sep 8, 2023
c5ad4d6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 8, 2023
b934cb3
Correct file suffix.
cemitch99 Sep 9, 2023
5b0421c
Delete examples/ipac2018_mayes/input_expanding_ipac2018.py
cemitch99 Sep 9, 2023
94451ce
Adding field line-out prediction data.
cemitch99 Sep 26, 2023
557439f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 26, 2023
41f67d7
Add Gnuplot scripts for Mayes Fig. 1
cemitch99 Sep 27, 2023
f6d275e
Use latest pyAMReX
ax3l Sep 27, 2023
a3a7e9f
Plot Space-Charge Field
ax3l Sep 27, 2023
9a29e25
Merge remote-tracking branch 'mainline/development' into mayes_benchmark
ax3l Sep 28, 2023
c578df9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 28, 2023
fec4f2c
Correct Reference Frame and + Charge
cemitch99 Sep 28, 2023
55f63b1
MLMG: Expose Solver Parameters
ax3l Sep 28, 2023
efc8ee5
Improve Doc Strings: Ref Kin Energy
ax3l Sep 29, 2023
506a092
Plot multiple r runs together
ax3l Sep 29, 2023
0b197c6
r=0.2,0.5,1,10
ax3l Sep 29, 2023
ec0e65a
Add README doc for examples.
cemitch99 Mar 4, 2024
41571c8
Merge branch 'development' into mayes_benchmark
cemitch99 Mar 4, 2024
3341c6e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
66b652e
Update input_expanding_ipac2018.in
cemitch99 Mar 4, 2024
f748296
Update run_expanding_ipac2018.py
cemitch99 Mar 4, 2024
4f5a15b
Update run_fieldplots_ipac2018.py
cemitch99 Mar 4, 2024
ded7055
Update run_expanding_ipac2018.py
cemitch99 Mar 4, 2024
a656033
Update run_expanding_ipac2018.py
cemitch99 Mar 4, 2024
645680e
Update run_fieldplots_ipac2018.py
cemitch99 Mar 4, 2024
949f8e2
Update run_fieldplots_ipac2018.py
cemitch99 Mar 4, 2024
abc7ece
Resolve merge conflicts.
cemitch99 Mar 4, 2024
9c6c030
Update examples/CMakeLists.txt
cemitch99 Mar 4, 2024
54768c6
Update run_fieldplots_ipac2018.py
cemitch99 Mar 4, 2024
ffc3e02
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
ee089f6
Update CMakeLists.txt
cemitch99 Mar 4, 2024
44cf429
Update CMakeLists.txt
cemitch99 Mar 4, 2024
68899e3
Update CMakeLists.txt
cemitch99 Mar 4, 2024
6e7a232
Update CMakeLists.txt
cemitch99 Mar 4, 2024
a96319a
Add analysis scripts (draft).
cemitch99 Mar 4, 2024
e49c5e0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
951bab3
Update analysis_expanding_ipac2018.py
cemitch99 Mar 4, 2024
a14db92
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
a8ae329
Update analysis_fieldplots_ipac2018.py
cemitch99 Mar 4, 2024
70bb47c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
6297c5b
Update run_expanding_ipac2018.py
cemitch99 Mar 4, 2024
ae5f6ea
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 4, 2024
6d24c07
Update CMakeLists.txt
cemitch99 Mar 5, 2024
4b32436
Update CMakeLists.txt
cemitch99 Mar 5, 2024
0d7f934
Update CMakeLists.txt
cemitch99 Mar 5, 2024
59d898e
Update run_fieldplots_ipac2018.py
cemitch99 Mar 5, 2024
10e0ba9
Update CMakeLists.txt
cemitch99 Mar 5, 2024
d2dce7e
Merge branch 'development' into mayes_benchmark
cemitch99 Nov 12, 2024
328e11a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/usage/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Virtual Test Stands
examples/pytorch_surrogate_model/README.rst
examples/apochromatic/README.rst
examples/fodo_tune/README.rst
examples/ipac2018_mayes/README.rst


Unit tests
Expand Down
38 changes: 38 additions & 0 deletions docs/source/usage/parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,44 @@ define functions by intervals.
Alternatively the expression above can be written as ``if(x>0, a0*x**2 * (1-y*1.e2), 0)``.


.. _running-cpp-parameters-numerics:

Numerics and algorithms
-----------------------

* ``algo.particle_shape`` (``integer``; ``1``, ``2``, or ``3``)
The order of the shape factors (splines) for the macro-particles along all spatial directions: `1` for linear, `2` for quadratic, `3` for cubic.
Low-order shape factors result in faster simulations, but may lead to more noisy results.
High-order shape factors are computationally more expensive, but may increase the overall accuracy of the results.
For production runs it is generally safer to use high-order shape factors, such as cubic order.

* ``algo.space_charge`` (``boolean``, optional, default: ``false``)
Whether to calculate space charge effects.

* ``algo.mlmg_relative_tolerance`` (``float``, optional, default: ``1.e-7``)
The relative precision with which the electrostatic space-charge fields should be calculated.
More specifically, the space-charge fields are computed with an iterative Multi-Level Multi-Grid (MLMG) solver.
This solver can fail to reach the default precision within a reasonable time.

* ``algo.mlmg_absolute_tolerance`` (``float``, optional, default: ``0``, which means: ignored)
The absolute tolerance with which the space-charge fields should be calculated in units of V/m^2.
More specifically, the acceptable residual with which the solution can be considered converged.
In general this should be left as the default, but in cases where the simulation state changes very
little between steps it can occur that the initial guess for the MLMG solver is so close to the
converged value that it fails to improve that solution sufficiently to reach the
mlmg_relative_tolerance value."

* ``algo.mlmg_max_iters`` (``integer``, optional, default: ``100``)
Maximum number of iterations used for MLMG solver for space-charge fields calculation.
In case if MLMG converges but fails to reach the desired self_fields_required_precision,
this parameter may be increased.

* ``algo.mlmg_verbosity`` (``integer``, optional, default: ``1``)
The verbosity used for MLMG solver for space-charge fields calculation.
Currently MLMG solver looks for verbosity levels from 0-5.
A higher number results in more verbose output.


.. _running-cpp-parameters-diagnostics:

Diagnostics and output
Expand Down
34 changes: 34 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1024,3 +1024,37 @@ add_impactx_test(rotation-xy.py
examples/rotation/analysis_rotation_xy.py
OFF # no plot script yet
)

# Space charge fields (Gaussian bunch) #################################################
#
# w/ space charge
# copy nominal field data files
file(COPY ${ImpactX_SOURCE_DIR}/examples/ipac2018_mayes/Ex_Mayes.dat
DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gaussian-SCfields.py)
file(COPY ${ImpactX_SOURCE_DIR}/examples/ipac2018_mayes/Ez_Mayes.dat
DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gaussian-SCfields.py)
add_impactx_test(gaussian-SCfields.py
examples/ipac2018_mayes/run_fieldplots_ipac2018.py
OFF # ImpactX MPI-parallel
ON # ImpactX Python interface
# examples/ipac2018_mayes/analysis_fieldplots_ipac2018.py
OFF # no plot script yet
)

# Space charge in a coasting Gaussian bunch ############################################
#
# w/ space charge
add_impactx_test(gaussian-SCdrift
examples/ipac2018_mayes/input_expanding_ipac2018.in
ON # ImpactX MPI-parallel
OFF # ImpactX Python interface
examples/ipac2018_mayes/analysis_expanding_ipac2018.py
OFF # no plot script yet
)
add_impactx_test(gaussian-SCdrift.py
examples/ipac2018_mayes/run_expanding_ipac2018.py
OFF # ImpactX MPI-parallel
ON # ImpactX Python interface
examples/ipac2018_mayes/analysis_expanding_ipac2018.py
OFF # no plot script yet
)
202 changes: 202 additions & 0 deletions examples/ipac2018_mayes/Ex_Mayes.dat

Large diffs are not rendered by default.

202 changes: 202 additions & 0 deletions examples/ipac2018_mayes/Ez_Mayes.dat

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions examples/ipac2018_mayes/Mayes_Fig1a_Script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
set xtics font 'helvetica,25'
set ytics font 'helvetica,25'
set xlabel 'x/\sigmax' font 'helvetica,30' offset 0,-1
set ylabel 'Ex (MV/m)' font 'helvetica,30' offset -1,0
set lmargin 12
set bmargin 6
set xrange [-6:6]
set yrange [-10:10]
set nokey
set mxtics 5
set mytics 5
f(x)=8.0*exp(-x**2/2.0)
plot f(x) w filledcu y1=0.0 lt 3 fs transparent solid 0.25
replot 'Ex_Mayes.dat' u 1:2 w l lw 2 lt 1
replot 'Ex_Mayes.dat' u 1:3 w l lw 2 lt 6
replot 'Ex_Mayes.dat' u 1:4 w l lw 2 lt 8
replot 'Ex_Mayes.dat' u 1:5 w l lw 2 lt 7
17 changes: 17 additions & 0 deletions examples/ipac2018_mayes/Mayes_Fig1b_Script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
set xtics font 'helvetica,25'
set ytics font 'helvetica,25'
set xlabel 'z/\sigmaz' font 'helvetica,30' offset 0,-1
set ylabel 'Ez (MV/m)' font 'helvetica,30' offset -1,0
set lmargin 12
set bmargin 6
set xrange [-6:6]
set yrange [-10:10]
set nokey
set mxtics 5
set mytics 5
f(x)=8.0*exp(-x**2/2.0)
plot f(x) w filledcu y1=0.0 lt 3 fs transparent solid 0.25
replot 'Ez_Mayes.dat' u 1:2 w l lw 2 lt 1
replot 'Ez_Mayes.dat' u 1:3 w l lw 2 lt 6
replot 'Ez_Mayes.dat' u 1:4 w l lw 2 lt 8
replot 'Ez_Mayes.dat' u 1:5 w l lw 2 lt 7
114 changes: 114 additions & 0 deletions examples/ipac2018_mayes/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.. _examples-gaussian-SCfields:

Space Charge Fields in a 3D Gaussian Bunch
===========================================

This example is based on Fig. 1 of:

C. E. Mayes, R. D. Ryne, and D. C. Sagan, "3D Space Charge in BMAD", in Proc. IPAC2018, Vancouver, BC, Canada,
doi:10.18429/JACoW-IPAC2018-THPAK085

This is a test of the ImpactX Poisson solver. The space charge fields are computed within a 1 nC electron bunch with a 3D Gaussian charge distribution
(at rest) and compared with analytical results for several values of transverse:longitudinal beam aspect ratio (Fig. 1).

In this test, the initial and final values of :math:`\sigma_x`, :math:`\sigma_y`, :math:`\sigma_t`, :math:`\epsilon_x`, :math:`\epsilon_y`, and :math:`\epsilon_t` must agree with nominal values.


Run
---

This example can be run only as a:

* **Python** script: ``python3 run_fieldplots_ipac2018.py``

For `MPI-parallel <https://www.mpi-forum.org>`__ runs, prefix these lines with ``mpiexec -n 4 ...`` or ``srun -n 4 ...``, depending on the system.

.. tab-set::

.. tab-item:: Python: Script

.. literalinclude:: run_fieldplots_ipac2018.py
:language: python3
:caption: You can copy this file from ``examples/ipac2018_mayes/run_fieldplots_ipac2018.py``.

Analyze
-------

We run the following script to analyze correctness:

.. dropdown:: Script ``analysis_fieldplots_ipac2018.py``

.. literalinclude:: analysis_fieldplots_ipac2018.py
:language: python3
:caption: You can copy this file from ``examples/ipac2018_mayes/analysis_fieldplots_ipac2018.py``.



.. _examples-guassian-SCdrift:

Space Charge in a Coasting 3D Gaussian Bunch
=============================================

This example is based on Fig. 4 of:

C. E. Mayes, R. D. Ryne, and D. C. Sagan, "3D Space Charge in BMAD", in Proc. IPAC2018, Vancouver, BC, Canada,
doi:10.18429/JACoW-IPAC2018-THPAK085

A cold (zero momentum spread) 1 nC electron bunch with a 3D Gaussian distribution and a (total) reference energy of 10 MeV is allowed to expand in a drift of length 1 m.
The final phase space is compared against the expected result (Fig. 4).

In this test, the initial and final values of :math:`\sigma_x`, :math:`\sigma_y`, :math:`\sigma_t`, :math:`\epsilon_x`, :math:`\epsilon_y`, and :math:`\epsil>


Run
---

This example can be run **either** as:

* **Python** script: ``python3 run_expanding_ipac2018.py`` or
* ImpactX **executable** using an input file: ``impactx input_expanding_ipac2018.in``

For `MPI-parallel <https://www.mpi-forum.org>`__ runs, prefix these lines with ``mpiexec -n 4 ...`` or ``srun -n 4 ...``, depending on the system.

.. tab-set::

.. tab-item:: Python: Script

.. literalinclude:: run_expanding_ipac2018.py
:language: python3
:caption: You can copy this file from ``examples/ipac2018_mayes/run_expanding_ipac2018.py``.

.. tab-item:: Executable: Input File

.. literalinclude:: input_expanding_ipac2018.in
:language: ini
:caption: You can copy this file from ``examples/ipac2018_mayes/input_expanding_ipac2018.in``.


Analyze
-------

We run the following script to analyze correctness:

.. dropdown:: Script ``analysis_expanding_ipac2018.py``

.. literalinclude:: analysis_expanding_ipac2018.py
:language: python3
:caption: You can copy this file from ``examples/ipac2018_mayes/analysis_expanding_ipac2018.py``.


Visualize
---------

You can run the following script to visualize the final beam distribution:

.. dropdown:: Script ``plot_expanding_ipac2018.py``

.. literalinclude:: plot_expanding_ipac2018.py
:language: python3
:caption: You can copy this file from ``examples/ipac2018_mayes/plot_expanding_ipac2018.py``.

.. figure:: https://user-images.githubusercontent.com/1353258/294003440-b16185c7-2573-48d9-8998-17e116721ab5.png
:alt: Final beam distribution when running with full resolution (see inline comments in the input file/script).

Final beam distribution when running with full resolution (see inline comments in the input file/script).
98 changes: 98 additions & 0 deletions examples/ipac2018_mayes/analysis_expanding_ipac2018.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python3
#
# Copyright 2022-2023 ImpactX contributors
# Authors: Axel Huebl, Chad Mitchell
# License: BSD-3-Clause-LBNL
#


import numpy as np
import openpmd_api as io
from scipy.stats import moment


def get_moments(beam):
"""Calculate standard deviations of beam position & momenta
and emittance values

Returns
-------
sigx, sigy, sigt, emittance_x, emittance_y, emittance_t
"""
sigx = moment(beam["position_x"], moment=2) ** 0.5 # variance -> std dev.
sigpx = moment(beam["momentum_x"], moment=2) ** 0.5
sigy = moment(beam["position_y"], moment=2) ** 0.5
sigpy = moment(beam["momentum_y"], moment=2) ** 0.5
sigt = moment(beam["position_t"], moment=2) ** 0.5
sigpt = moment(beam["momentum_t"], moment=2) ** 0.5

epstrms = beam.cov(ddof=0)
emittance_x = (sigx**2 * sigpx**2 - epstrms["position_x"]["momentum_x"] ** 2) ** 0.5
emittance_y = (sigy**2 * sigpy**2 - epstrms["position_y"]["momentum_y"] ** 2) ** 0.5
emittance_t = (sigt**2 * sigpt**2 - epstrms["position_t"]["momentum_t"] ** 2) ** 0.5

return (sigx, sigy, sigt, emittance_x, emittance_y, emittance_t)


# initial/final beam
series = io.Series("diags/openPMD/monitor.h5", io.Access.read_only)
last_step = list(series.iterations)[-1]
initial = series.iterations[1].particles["beam"].to_df()
final = series.iterations[last_step].particles["beam"].to_df()

# compare number of particles
num_particles = 10000
assert num_particles == len(initial)
assert num_particles == len(final)

print("Initial Beam:")
sigx, sigy, sigt, emittance_x, emittance_y, emittance_t = get_moments(initial)
print(f" sigx={sigx:e} sigy={sigy:e} sigt={sigt:e}")
print(
f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}"
)

atol = 0.0 # ignored
rtol = 1.0e12 * num_particles**-0.5 # from random sampling of a smooth distribution
print(f" rtol={rtol} (ignored: atol~={atol})")

assert np.allclose(
[sigx, sigy, sigt, emittance_x, emittance_y, emittance_t],
[
7.5451170454175073e-005,
7.5441588239210947e-005,
9.9775878164077539e-004,
1.9959540393751392e-009,
2.0175015289132990e-009,
2.0013820193294972e-006,
],
rtol=rtol,
atol=atol,
)


print("")
print("Final Beam:")
sigx, sigy, sigt, emittance_x, emittance_y, emittance_t = get_moments(final)
print(f" sigx={sigx:e} sigy={sigy:e} sigt={sigt:e}")
print(
f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}"
)

atol = 0.0 # ignored
rtol = 1.0e12 * num_particles**-0.5 # from random sampling of a smooth distribution
print(f" rtol={rtol} (ignored: atol~={atol})")

assert np.allclose(
[sigx, sigy, sigt, emittance_x, emittance_y, emittance_t],
[
7.4790118496224206e-005,
7.5357525169680140e-005,
9.9775879288128088e-004,
1.9959539836392703e-009,
2.0175014668882125e-009,
2.0013820380883801e-006,
],
rtol=rtol,
atol=atol,
)
Loading
Loading