-
Notifications
You must be signed in to change notification settings - Fork 31
2.5 Space Charge in Particle Tracking #1214
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
base: development
Are you sure you want to change the base?
Changes from all commits
7640a00
278114f
f5e02f6
98ccaee
a4aadb4
83de345
8b66049
3ff90aa
2f7c5b1
794c06f
7348362
2737981
1d06950
0f4f944
948c526
40aa722
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| /* Copyright 2022-2025 The Regents of the University of California, through Lawrence | ||
| * Berkeley National Laboratory (subject to receipt of any required | ||
| * approvals from the U.S. Dept. of Energy). All rights reserved. | ||
| * | ||
| * This file is part of ImpactX. | ||
| * | ||
| * Authors: Ji Qiang | ||
| * License: BSD-3-Clause-LBNL | ||
| */ | ||
| #ifndef IMPACT_DEPOSIT1D_PUSH_H | ||
| #define IMPACT_DEPOSIT1D_PUSH_H | ||
|
|
||
| #include "particles/ImpactXParticleContainer.H" | ||
|
|
||
| #include <AMReX_REAL.H> | ||
|
|
||
|
|
||
| namespace impactx::particles::spacecharge | ||
| { | ||
| /** Deposit charge using longitudinal binning for the calculation of space charge | ||
| * | ||
| * This function performs particle binning for particles in the beam along the | ||
| * longitudinal direction, for the purposes of computing space charge in | ||
| * so-called 2.5D models. | ||
| * | ||
| * @param[in] pc container of the particles that deposited rho | ||
| * @param[out] beam_profile deposited charge density | ||
| * @param[out] beam_profile_slope derivative of deposited charge density | ||
| * @param[in] bin_min location of lower endpoint for binning | ||
| * @param[in] bin_max location of upper endpoint for binning | ||
| * @param[in] num_bins number of longitudinal bins | ||
| */ | ||
| void Deposit1D ( | ||
| ImpactXParticleContainer & pc, | ||
| amrex::Real * beam_profile, | ||
| amrex::Real * beam_profile_slope, | ||
| amrex::Real bin_min, | ||
| amrex::Real bin_max, | ||
| int num_bins | ||
| ); | ||
|
|
||
| } // namespace impactx::particles::spacecharge | ||
|
|
||
| #endif // IMPACT_DEPOSIT1D_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* Copyright 2022-2025 The Regents of the University of California, through Lawrence | ||
| * Berkeley National Laboratory (subject to receipt of any required | ||
| * approvals from the U.S. Dept. of Energy). All rights reserved. | ||
| * | ||
| * This file is part of ImpactX. | ||
| * | ||
| * Authors: Ji Qiang | ||
| * License: BSD-3-Clause-LBNL | ||
| */ | ||
| #include "Deposit1D.H" | ||
|
|
||
| #include "diagnostics/ReducedBeamCharacteristics.H" | ||
| #include "particles/wakefields/ChargeBinning.H" | ||
|
|
||
| #include <AMReX_REAL.H> | ||
| #include <AMReX_BLProfiler.H> | ||
| #include <AMReX_GpuContainers.H> | ||
| #include <AMReX_ParmParse.H> | ||
|
|
||
| #include <cmath> | ||
|
|
||
|
|
||
| namespace impactx::particles::spacecharge | ||
| { | ||
|
|
||
| void Deposit1D ( | ||
| ImpactXParticleContainer & pc, | ||
| [[maybe_unused]] amrex::Real * beam_profile, | ||
| [[maybe_unused]] amrex::Real * beam_profile_slope, | ||
| amrex::Real bin_min, | ||
| amrex::Real bin_max, | ||
| int num_bins | ||
| ) | ||
| { | ||
| BL_PROFILE("impactx::spacecharge::Deposit1D"); | ||
|
|
||
| using namespace amrex::literals; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's always assert here that |
||
|
|
||
| // Set parameters for charge deposition | ||
| bool const is_unity_particle_weight = false; | ||
| bool const GetNumberDensity = true; | ||
|
|
||
| amrex::Real const bin_size = (bin_max - bin_min) / (num_bins - 1); // number of evaluation points | ||
| // Allocate memory for the charge profile | ||
| amrex::Gpu::DeviceVector<amrex::Real> charge_distribution(num_bins + 1, 0.0); | ||
| // Call charge deposition function | ||
| impactx::particles::wakefields::DepositCharge1D(pc, charge_distribution, bin_min, bin_size, is_unity_particle_weight); | ||
|
|
||
| // Sum up all partial charge histograms to each MPI process to calculate | ||
| // the global charge slope. | ||
| amrex::ParallelAllReduce::Sum( | ||
| charge_distribution.data(), | ||
| charge_distribution.size(), | ||
| amrex::ParallelDescriptor::Communicator() | ||
| ); | ||
|
|
||
| // Call charge density derivative function | ||
| amrex::Gpu::DeviceVector<amrex::Real> slopes(charge_distribution.size() - 1, 0.0); | ||
| impactx::particles::wakefields::DerivativeCharge1D(charge_distribution, slopes, bin_size,GetNumberDensity); | ||
|
|
||
| beam_profile = charge_distribution.data(); | ||
| beam_profile_slope = slopes.data(); | ||
|
|
||
| } | ||
|
|
||
| } // namespace impactx::particles::spacecharge | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,13 +10,16 @@ | |||||||||||||||||||||||||
| #include "GatherAndPush.H" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include "initialization/Algorithms.H" | ||||||||||||||||||||||||||
| #include "particles/wakefields/ChargeBinning.H" | ||||||||||||||||||||||||||
| #include "particles/spacecharge/Deposit1D.H" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include <ablastr/particles/NodalFieldGather.H> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include <AMReX_BLProfiler.H> | ||||||||||||||||||||||||||
| #include <AMReX_REAL.H> // for Real | ||||||||||||||||||||||||||
| #include <AMReX_SPACE.H> // for AMREX_D_DECL | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include <AMReX_GpuContainers.H> | ||||||||||||||||||||||||||
| #include <AMReX_ParmParse.H> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| namespace impactx::particles::spacecharge | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
|
|
@@ -35,6 +38,23 @@ | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| amrex::ParticleReal const charge = pc.GetRefParticle().charge; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Deposit 1D charge density in cases where it is required. | ||||||||||||||||||||||||||
| amrex::Real * beam_profile = nullptr; | ||||||||||||||||||||||||||
| amrex::Real * beam_profile_slope = nullptr; | ||||||||||||||||||||||||||
|
Comment on lines
+42
to
+43
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Allocate the profiles here. Note that
Suggested change
|
||||||||||||||||||||||||||
| int num_bins = 129; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| [[maybe_unused]] auto const [x_min, y_min, t_min, x_max, y_max, t_max] = | ||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Unused local variable Note
Variable x_min is not used.
Check noticeCode scanning / CodeQL Unused local variable Note
Variable y_min is not used.
Check noticeCode scanning / CodeQL Unused local variable Note
Variable x_max is not used.
Check noticeCode scanning / CodeQL Unused local variable Note
Variable y_max is not used.
|
||||||||||||||||||||||||||
| pc.MinAndMaxPositions(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| amrex::Real bin_min = t_min; | ||||||||||||||||||||||||||
| amrex::Real bin_max = t_max; | ||||||||||||||||||||||||||
| amrex::Real const bin_size = (bin_max - bin_min) / (num_bins - 1); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (space_charge == SpaceChargeAlgo::True_2p5D) { | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Deposit1D ( pc, beam_profile, beam_profile_slope, bin_min, bin_max, num_bins); | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // loop over refinement levels | ||||||||||||||||||||||||||
| int const nLevel = pc.finestLevel(); | ||||||||||||||||||||||||||
| for (int lev = 0; lev <= nLevel; ++lev) | ||||||||||||||||||||||||||
|
|
@@ -87,8 +107,6 @@ | |||||||||||||||||||||||||
| auto prob_lo_2D = gm.ProbLoArray(); | ||||||||||||||||||||||||||
| prob_lo_2D[2] = 0.0_rt; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // TODO: add in z-dependent scaling by current? | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE (int i) { | ||||||||||||||||||||||||||
| // access SoA Real data | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT x = part_x[i]; | ||||||||||||||||||||||||||
|
|
@@ -111,11 +129,56 @@ | |||||||||||||||||||||||||
| px += field_interp[0] * push_consts * dr[2] / (beta * c0_SI); | ||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // push position is done in the lattice elements | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| if (space_charge == SpaceChargeAlgo::True_2p5D) { | ||||||||||||||||||||||||||
| // flatten 3rd dimension | ||||||||||||||||||||||||||
| auto prob_lo_2D = gm.ProbLoArray(); | ||||||||||||||||||||||||||
| prob_lo_2D[2] = 0.0_rt; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // group together constants for the momentum push | ||||||||||||||||||||||||||
| amrex::ParticleReal const chargesign = charge / std::abs(charge); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE (int i) { | ||||||||||||||||||||||||||
| // access SoA Real data | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT x = part_x[i]; | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT y = part_y[i]; | ||||||||||||||||||||||||||
| amrex::ParticleReal z = 0.0_prt; // flatten 3rd dimension | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT px = part_px[i]; | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT py = part_py[i]; | ||||||||||||||||||||||||||
| amrex::ParticleReal & AMREX_RESTRICT pz = part_pz[i]; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // force gather | ||||||||||||||||||||||||||
| amrex::GpuArray<amrex::Real, 3> const field_interp = | ||||||||||||||||||||||||||
| ablastr::particles::doGatherVectorFieldNodal<2>( | ||||||||||||||||||||||||||
| x, y, z, | ||||||||||||||||||||||||||
| scf_arr_x, scf_arr_y, scf_arr_z, | ||||||||||||||||||||||||||
| invdr, | ||||||||||||||||||||||||||
| prob_lo_2D | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
|
Comment on lines
+155
to
+160
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After passing also
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Update momentae with the 2.5D SC force | ||||||||||||||||||||||||||
| int const idx = static_cast<int>((z - bin_min) / bin_size); // Find index position along z | ||||||||||||||||||||||||||
| #if (defined(AMREX_DEBUG) || defined(DEBUG)) && !defined(AMREX_USE_GPU) | ||||||||||||||||||||||||||
| if (idx < 0 || idx >= num_bins) | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| std::cerr << "Warning: Index out of range for 2.5D SC: " << idx << std::endl; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||
| [[maybe_unused]] amrex::ParticleReal const Fxy = beam_profile[idx] * chargesign; | ||||||||||||||||||||||||||
| [[maybe_unused]] amrex::ParticleReal const Fz = beam_profile_slope[idx] * charge; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // push momentum | ||||||||||||||||||||||||||
| px += field_interp[0] * Fxy * push_consts; | ||||||||||||||||||||||||||
| py += field_interp[1] * Fxy * push_consts; | ||||||||||||||||||||||||||
| pz += 0.0_rt; | ||||||||||||||||||||||||||
| //pz -= (eintz + pz_push_const) * Fz * push_consts; | ||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Commented-out code Note
This comment appears to contain commented-out code.
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // push position is done in the lattice elements | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| if (space_charge == SpaceChargeAlgo::True_3D) { | ||||||||||||||||||||||||||
| amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE (int i) { | ||||||||||||||||||||||||||
| // access SoA Real data | ||||||||||||||||||||||||||
|
|
@@ -130,7 +193,7 @@ | |||||||||||||||||||||||||
| amrex::GpuArray<amrex::Real, 3> const field_interp = | ||||||||||||||||||||||||||
| ablastr::particles::doGatherVectorFieldNodal( | ||||||||||||||||||||||||||
| x, y, z, | ||||||||||||||||||||||||||
| scf_arr_x, scf_arr_y, scf_arr_z, | ||||||||||||||||||||||||||
| invdr, | ||||||||||||||||||||||||||
| prob_lo | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's pass a
amrex::Gpu::DeviceVector<amrex::Real>by reference&here for each array.Omit
num_binsand take it frombeam_profile_slope.size()Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even better: pass no arrays and just return the profile array and
bin_size.Let's do the one-liner for slope calc afterwards, it is safe and not part of deposit.