Skip to content

Commit 83de345

Browse files
committed
Additional locations with True_2D -> True_2D || True_2p5D.
1 parent a4aadb4 commit 83de345

File tree

4 files changed

+58
-19
lines changed

4 files changed

+58
-19
lines changed

src/initialization/AmrCoreData.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ namespace impactx::initialization
150150
int const num_components_phi = 1;
151151
amrex::IntVect num_guards_phi{num_guards_rho + 1}; // todo: I think this just depends on max(MLMG, force calc)
152152
amrex::BoxArray phi_ba = cba;
153-
if (space_charge == SpaceChargeAlgo::True_2D) {
153+
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) {
154154
num_guards_phi[2] = 0;
155155
amrex::BoxList bl(amrex::IndexType{rho_nodal_flag});
156156
bl.reserve(cba.size());
@@ -169,7 +169,7 @@ namespace impactx::initialization
169169

170170
// space charge force
171171
amrex::IntVect num_guards_force(num_guards_rho);
172-
if (space_charge == SpaceChargeAlgo::True_2D) { num_guards_force[2] = 0; }
172+
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) { num_guards_force[2] = 0; }
173173
std::unordered_map<std::string, amrex::MultiFab> f_comp;
174174
for (std::string const comp : {"x", "y", "z"})
175175
{

src/particles/spacecharge/GatherAndPush.cpp

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
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

2123
namespace 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

src/particles/spacecharge/HandleSpacecharge.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ namespace impactx::particles::spacecharge
7979
amr_data->refRatio()
8080
);
8181

82-
// TODO for 2.5D: deposit charge/current in 1D array
83-
8482
// poisson solve in x,y,z
8583
spacecharge::PoissonSolve(
8684
*amr_data->track_particles.m_particle_container,

src/particles/spacecharge/PoissonSolve.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ namespace impactx::particles::spacecharge
7070
if (space_charge == SpaceChargeAlgo::True_2D && poisson_solver != "fft") {
7171
throw std::runtime_error("algo.poisson_solver must be fft for SpaceChargeAlgo::True_2D");
7272
}
73+
if (space_charge == SpaceChargeAlgo::True_2p5D && poisson_solver != "fft") {
74+
throw std::runtime_error("algo.poisson_solver must be fft for SpaceChargeAlgo::True_2p5D");
75+
}
7376

7477
// MLMG options
7578
amrex::Real mlmg_relative_tolerance = 1.e-7; // relative TODO: make smaller for SP
@@ -84,7 +87,7 @@ namespace impactx::particles::spacecharge
8487

8588
// flatten rho to 2D
8689
std::unordered_map<int, std::pair<amrex::MultiFab, amrex::MultiFab>> rho_2d; // pair: local & unique boxes
87-
if (space_charge == SpaceChargeAlgo::True_2D) {
90+
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) {
8891
auto geom_3d = pc.GetParGDB()->Geom();
8992
amrex::Box domain_3d = geom_3d[0].Domain(); // whole simulation index space (level 0)
9093
rho_2d = flatten_charge_to_2D(rho, domain_3d);
@@ -98,7 +101,7 @@ namespace impactx::particles::spacecharge
98101

99102
// create phi_2d and sort rho/phi pointers
100103
for (int lev = 0; lev <= finest_level; ++lev) {
101-
if (space_charge == SpaceChargeAlgo::True_2D) {
104+
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) {
102105
int nz = pc.GetParGDB()->Geom(lev).Domain().length(2);
103106
if (nz == 1) {
104107
sorted_phi.emplace_back(&phi[lev]);
@@ -119,7 +122,7 @@ namespace impactx::particles::spacecharge
119122
}
120123
}
121124

122-
const bool is_igf_2d = space_charge == SpaceChargeAlgo::True_2D;
125+
const bool is_igf_2d = (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D);
123126
const bool do_single_precision_comms = false;
124127
const bool eb_enabled = false;
125128
ablastr::fields::computePhi(
@@ -154,7 +157,7 @@ namespace impactx::particles::spacecharge
154157
}
155158

156159
// We may need to copy phi from phi_2d
157-
if (space_charge == SpaceChargeAlgo::True_2D) {
160+
if (space_charge == SpaceChargeAlgo::True_2D || space_charge == SpaceChargeAlgo::True_2p5D) {
158161
for (int lev=0; lev<=finest_level; lev++) {
159162
if (&(phi[lev]) != sorted_phi[lev]) {
160163
phi[lev].ParallelCopy(*sorted_phi[lev]);

0 commit comments

Comments
 (0)