1010#include " GatherAndPush.H"
1111
1212#include " initialization/Algorithms.H"
13+ #include " particles/wakefields/ChargeBinning.H"
1314
1415#include < ablastr/particles/NodalFieldGather.H>
1516
1617#include < AMReX_BLProfiler.H>
1718#include < AMReX_REAL.H> // for Real
1819#include < AMReX_SPACE.H> // for AMREX_D_DECL
19-
20+ #include < AMReX_GpuContainers.H>
21+ #include < AMReX_ParmParse.H>
2022
2123namespace impactx ::particles::spacecharge
2224{
@@ -87,9 +89,44 @@ namespace impactx::particles::spacecharge
8789 auto prob_lo_2D = gm.ProbLoArray ();
8890 prob_lo_2D[2 ] = 0 .0_rt;
8991
90- if (space_charge == SpaceChargeAlgo::True_2p5D) {
91- // TODO: calculate z-dependent scaling by current
92- }
92+ /* if (space_charge == SpaceChargeAlgo::True_2p5D) {
93+ // Calculate z-dependent scaling by current
94+ int tp5d_bins = 129;
95+ amrex::ParmParse pp_algo("algo.space_charge");
96+ pp_algo.queryAddWithParser("gauss_charge_z_bins", tp5d_bins);
97+
98+ // Set parameters for charge deposition
99+ bool const is_unity_particle_weight = false;
100+ bool const GetNumberDensity = true;
101+
102+ // Measure beam size, extract the min, max of particle positions
103+ [[maybe_unused]] auto const [x_min, y_min, t_min, x_max, y_max, t_max] =
104+ pc.MinAndMaxPositions();
105+
106+ int const num_bins = tp5d_bins; // Set resolution
107+ amrex::Real const bin_min = t_min;
108+ amrex::Real const bin_max = t_max;
109+ amrex::Real const bin_size = (bin_max - bin_min) / (num_bins - 1); // number of evaluation points
110+ // Allocate memory for the charge profile
111+ amrex::Gpu::DeviceVector<amrex::Real> charge_distribution(num_bins + 1, 0.0);
112+ // Call charge deposition function
113+ impactx::particles::wakefields::DepositCharge1D(pc, charge_distribution, bin_min, bin_size, is_unity_particle_weight);
114+
115+ // Sum up all partial charge histograms to each MPI process to calculate
116+ // the global charge slope.
117+ amrex::ParallelAllReduce::Sum(
118+ charge_distribution.data(),
119+ charge_distribution.size(),
120+ amrex::ParallelDescriptor::Communicator()
121+ );
122+
123+ // Call charge density derivative function
124+ amrex::Gpu::DeviceVector<amrex::Real> slopes(charge_distribution.size() - 1, 0.0);
125+ impactx::particles::wakefields::DerivativeCharge1D(charge_distribution, slopes, bin_size,GetNumberDensity);
126+
127+ amrex::Real const * const beam_profile_slope = slopes.data();
128+ amrex::Real const * const beam_profile = charge_distribution.data();
129+ } */
93130
94131 amrex::ParallelFor (np, [=] AMREX_GPU_DEVICE (int i) {
95132 // access SoA Real data
@@ -110,15 +147,16 @@ namespace impactx::particles::spacecharge
110147 );
111148
112149 // push momentum
113- px += field_interp[ 0 ] * push_consts * dr[ 2 ] / (beta * c0_SI);
114- py += field_interp[1 ] * push_consts * dr[2 ] / (beta * c0_SI);
115- pz += 0 .0_rt ;
116- // pz += field_interp[2] * push_consts; // TODO: non-zero in 2.5D, but we will add a toggle to turn it off there, too
117- if (space_charge == SpaceChargeAlgo::True_2p5D) {
150+ if (space_charge == SpaceChargeAlgo::True_2D) {
151+ px += field_interp[0 ] * push_consts * dr[2 ] / (beta * c0_SI);
152+ py += field_interp[ 1 ] * push_consts * dr[ 2 ] / (beta * c0_SI) ;
153+ pz += 0 .0_rt;
154+ } else if (space_charge == SpaceChargeAlgo::True_2p5D) {
118155 // TODO: apply z-dependent scaling by current and longitudinal kick
119- px += 0 .0_rt ;
120- py += 0 .0_rt ;
156+ px += field_interp[ 0 ] * push_consts * dr[ 2 ] ;
157+ py += field_interp[ 1 ] * push_consts * dr[ 2 ] ;
121158 pz += 0 .0_rt;
159+ } else {
122160 }
123161
124162 // push position is done in the lattice elements
0 commit comments