Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
12 changes: 12 additions & 0 deletions docs/source/usage/parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ See there ``nslice`` option on lattice elements for slicing.
When running in envelope mode (when ``algo.track = "envelope"``), this model currently assumes that ``<xy> = <yt> = <tx> = 0``.

* ``"Gauss3D"``: Calculate 3D space charge forces as if the beam was a Gaussian distribution.

* ``"Gauss2p5D"``: Calculate 2.5D space charge forces as if the beam was a transverse Gaussian distribution.

These models are supported only in particle tracking mode (when ``algo.track = "particles"``).
Expand All @@ -923,6 +924,17 @@ See there ``nslice`` option on lattice elements for slicing.

Number of bins for longitudinal line density deposition.

* ``"2p5D"``: Space charge forces are computed in the plane ``(x,y)`` transverse to the reference particle velocity, while the transverse space charge kicks are weighted by the
longitudinal line density determined by charge deposition (2.5D model). Longitudinal space charge kicks are determined by the derivative of the line charge density.

This model is supported only in particle tracking mode (when ``algo.track = "particles"``).

This model supports the following sub-option:

* ``algo.space_charge.charge_z_bins`` (``int``, default: ``129``)

Number of bins for longitudinal line density deposition.

* ``amr.n_cell`` (3 integers) optional (default: 1 `blocking_factor <https://amrex-codes.github.io/amrex/docs_html/GridCreation.html>`__ per MPI process)

The number of grid points along each direction (on the **coarsest level**)
Expand Down
10 changes: 10 additions & 0 deletions docs/source/usage/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Collective Effects & Overall Simulation Parameters
When running in envelope mode (when ``algo.track = "envelope"``), this model currently assumes that ``<xy> = <yt> = <tx> = 0``.

* ``"Gauss3D"``: Calculate 3D space charge forces as if the beam was a Gaussian distribution.

* ``"Gauss2p5D"``: Calculate 2.5D space charge forces as if the beam was a transverse Gaussian distribution.

These models are supported only in particle tracking mode (when ``algo.track = "particles"``).
Expand All @@ -93,6 +94,15 @@ Collective Effects & Overall Simulation Parameters

Number of bins for longitudinal charge density deposition (default: ``129``).

* ``"2p5D"``: Space charge forces are computed in the plane ``(x,y)`` transverse to the reference particle velocity, while the transverse space charge kicks are weighted by the
longitudinal line density determined by charge deposition (2.5D model). Longitudinal space charge kicks are determined by the derivative of the line charge density.

These models are supported only in particle tracking mode (when ``algo.track = "particles"``).

.. py:property:: space_charge_z_bins

Number of bins for longitudinal charge density deposition (default: ``129``).

.. py:property:: poisson_solver

The numerical solver to solve the Poisson equation when calculating space charge effects.
Expand Down
3 changes: 2 additions & 1 deletion src/initialization/Algorithms.H
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ namespace impactx
True_3D, /**< 3D beam distribution */
Gauss3D, /**< Assume a 3D Gaussian beam distribution */
Gauss2p5D, /**< Assume a transverse 2D Gaussian beam distribution */
True_2D /**< Averaged 2D transverse beam distribution with a current along s */
True_2D, /**< Averaged 2D transverse beam distribution */
True_2p5D /**< Averaged 2D transverse beam distribution with a current along s */
);

/** Return the currently active space charge algorithm */
Expand Down
4 changes: 4 additions & 0 deletions src/initialization/Algorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ namespace impactx
{
return SpaceChargeAlgo::True_2D;
}
else if (space_charge == "2p5D")
{
return SpaceChargeAlgo::True_2p5D;
}
else
{
throw std::runtime_error("algo.space_charge = " + space_charge + " is not a valid option");
Expand Down
12 changes: 10 additions & 2 deletions src/particles/spacecharge/GatherAndPush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@
amrex::ParticleReal const push_consts = dt * charge * inv_gamma2 / pz_ref_SI;

// gather to each particle and push momentum
if (space_charge == SpaceChargeAlgo::True_2D) {
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) {
// flatten 3rd dimension
auto prob_lo_2D = gm.ProbLoArray();
prob_lo_2D[2] = 0.0_rt;

// TODO: add in z-dependent scaling by current?
if (space_charge == SpaceChargeAlgo::True_2p5D) {
// TODO: calculate z-dependent scaling by current
}

amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE (int i) {
// access SoA Real data
Expand All @@ -112,6 +114,12 @@
py += field_interp[1] * push_consts * dr[2] / (beta * c0_SI);
pz += 0.0_rt;
//pz += field_interp[2] * push_consts; // TODO: non-zero in 2.5D, but we will add a toggle to turn it off there, too
if (space_charge == SpaceChargeAlgo::True_2p5D) {
// TODO: apply z-dependent scaling by current and longitudinal kick
px += 0.0_rt;
py += 0.0_rt;
pz += 0.0_rt;
}

// push position is done in the lattice elements
});
Expand Down
6 changes: 3 additions & 3 deletions src/particles/spacecharge/HandleSpacecharge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace impactx::particles::spacecharge
// turn off if less than 2 particles
if (amr_data->track_particles.m_particle_container->TotalNumberOfParticles(true, false) < 2) { return; }

if (space_charge != SpaceChargeAlgo::True_2D)
if (space_charge != SpaceChargeAlgo::True_2D && space_charge != SpaceChargeAlgo::True_2p5D)
{
// transform from x',y',t to x,y,z
transformation::CoordinateTransformation(
Expand All @@ -60,7 +60,7 @@ namespace impactx::particles::spacecharge
{
Gauss2p5dPush(*amr_data->track_particles.m_particle_container, slice_ds);
}
else if (space_charge == SpaceChargeAlgo::True_3D || space_charge == SpaceChargeAlgo::True_2D)
else if (space_charge == SpaceChargeAlgo::True_3D || space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D)
{
// Note: The following operations assume that
// the particles are in x, y, z coordinates.
Expand Down Expand Up @@ -107,7 +107,7 @@ namespace impactx::particles::spacecharge
);
}

if (space_charge != SpaceChargeAlgo::True_2D)
if (space_charge != SpaceChargeAlgo::True_2D && space_charge != SpaceChargeAlgo::True_2p5D)
{
// transform from x,y,z to x',y',t
transformation::CoordinateTransformation(
Expand Down
8 changes: 4 additions & 4 deletions src/python/ImpactX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,14 +285,14 @@ void init_ImpactX (py::module& m)
else
{
std::string const space_charge = std::get<std::string>(space_charge_v);
if (space_charge != "false" && space_charge != "off" && space_charge != "2D" && space_charge != "3D" && space_charge != "Gauss3D" && space_charge != "Gauss2p5D" ) {
throw std::runtime_error("Space charge model must be 2D, 3D, Gauss3D or Gauss2p5D but is: " + space_charge);
if (space_charge != "false" && space_charge != "off" && space_charge != "2D" && space_charge != "3D" && space_charge != "Gauss3D" && space_charge != "Gauss2p5D" && space_charge != "2p5D") {
throw std::runtime_error("Space charge model must be 2D, 3D, Gauss3D, Gauss2p5D, or 2p5D but is: " + space_charge);
}
amrex::ParmParse pp_algo("algo");
pp_algo.add("space_charge", space_charge);
}
},
"The model to be used when calculating space charge effects. Either off, 2D, or 3D."
"The model to be used when calculating space charge effects. Either off, 2D, 3D, Gauss3D, Gauss2p5D, or 2p5D."
)
.def_property("space_charge_gauss_nint",
[](ImpactX & /* ix */) {
Expand Down Expand Up @@ -320,7 +320,7 @@ void init_ImpactX (py::module& m)
amrex::ParmParse pp_algo("algo.space_charge");
pp_algo.add("gauss_charge_z_bins", gauss_charge_z_bins);
},
"Number of steps for computing the integrals (default: ``129``)."
"Number of longitudinal bins for computing the linear charge density (default: ``129``)."
)
.def_property("space_charge_gauss_taylor_delta",
[](ImpactX & /* ix */) {
Expand Down
Loading