Skip to content

Commit 5816acc

Browse files
ax3lcemitch99
andauthored
Introduce HandleSpacecharge (#842)
* Introduce `HandleSpacecharge` Similar to our `HandleWakefield` logic for particle tracking, this simplifies the central particle tracking loop by cleanly hiding implementation details in a separate function. * Fix Doxygen String Co-authored-by: Chad Mitchell <[email protected]> --------- Co-authored-by: Chad Mitchell <[email protected]>
1 parent 220531e commit 5816acc

File tree

10 files changed

+162
-81
lines changed

10 files changed

+162
-81
lines changed

src/particles/spacecharge/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ target_sources(lib
22
PRIVATE
33
ForceFromSelfFields.cpp
44
GatherAndPush.cpp
5+
HandleSpacecharge.cpp
56
PoissonSolve.cpp
67
)

src/particles/spacecharge/ForceFromSelfFields.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <unordered_map>
2020

2121

22-
namespace impactx::spacecharge
22+
namespace impactx::particles::spacecharge
2323
{
2424
/** Calculate the space charge force field from the electric potential
2525
*
@@ -36,6 +36,6 @@ namespace impactx::spacecharge
3636
const amrex::Vector<amrex::Geometry>& geom
3737
);
3838

39-
} // namespace impactx
39+
} // namespace impactx::particles::spacecharge
4040

4141
#endif // IMPACTX_FORCEFROMSELFFIELDS_H

src/particles/spacecharge/ForceFromSelfFields.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <AMReX_SPACE.H> // for AMREX_D_DECL
1515

1616

17-
namespace impactx::spacecharge
17+
namespace impactx::particles::spacecharge
1818
{
1919
void ForceFromSelfFields (
2020
std::unordered_map<int, std::unordered_map<std::string, amrex::MultiFab> > & space_charge_field,
@@ -60,4 +60,4 @@ namespace impactx::spacecharge
6060
}
6161
}
6262
}
63-
} // namespace impactx::spacecharge
63+
} // namespace impactx::particles::spacecharge

src/particles/spacecharge/GatherAndPush.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <string>
2121

2222

23-
namespace impactx::spacecharge
23+
namespace impactx::particles::spacecharge
2424
{
2525
/** Gather force fields and push particles in x,y,z
2626
*
@@ -41,6 +41,6 @@ namespace impactx::spacecharge
4141
amrex::ParticleReal slice_ds
4242
);
4343

44-
} // namespace impactx
44+
} // namespace impactx::particles::spacecharge
4545

4646
#endif // IMPACTX_GATHER_AND_PUSH_H

src/particles/spacecharge/GatherAndPush.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <AMReX_SPACE.H> // for AMREX_D_DECL
1717

1818

19-
namespace impactx::spacecharge
19+
namespace impactx::particles::spacecharge
2020
{
2121
void GatherAndPush (
2222
ImpactXParticleContainer & pc,
@@ -105,4 +105,4 @@ namespace impactx::spacecharge
105105
} // end loop over all particle boxes
106106
} // env mesh-refinement level loop
107107
}
108-
} // namespace impactx::spacecharge
108+
} // namespace impactx::particles::spacecharge
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Copyright 2022-2025 The Regents of the University of California, through Lawrence
2+
* Berkeley National Laboratory (subject to receipt of any required
3+
* approvals from the U.S. Dept. of Energy). All rights reserved.
4+
*
5+
* This file is part of ImpactX.
6+
*
7+
* Authors: Axel Huebl, Chad Mitchell
8+
* License: BSD-3-Clause-LBNL
9+
*/
10+
#ifndef IMPACTX_HANDLE_SPACECHARGE_H
11+
#define IMPACTX_HANDLE_SPACECHARGE_H
12+
13+
#include "initialization/AmrCoreData.H"
14+
15+
#include <AMReX_REAL.H>
16+
17+
#include <functional>
18+
#include <memory>
19+
20+
21+
namespace impactx::particles::spacecharge
22+
{
23+
/** Function to handle space charge including charge deposition, Poisson solve,
24+
* field calculation, interpolation, and particle push.
25+
*
26+
* @param[in,out] amr_data AMR data like particle container and fields
27+
* @param[in] ResizeMesh function to call to resize the mesh
28+
* @param[in] slice_ds slice spacing along s
29+
*/
30+
void HandleSpacecharge (
31+
std::unique_ptr<initialization::AmrCoreData> & amr_data,
32+
std::function<void()> ResizeMesh,
33+
amrex::Real slice_ds
34+
);
35+
36+
} // namespace impactx::particles::spacecharge
37+
38+
#endif // IMPACTX_HANDLE_SPACECHARGE_H
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* Copyright 2022-2025 The Regents of the University of California, through Lawrence
2+
* Berkeley National Laboratory (subject to receipt of any required
3+
* approvals from the U.S. Dept. of Energy). All rights reserved.
4+
*
5+
* This file is part of ImpactX.
6+
*
7+
* Authors: Axel Huebl, Chad Mitchell
8+
* License: BSD-3-Clause-LBNL
9+
*/
10+
#include "HandleSpacecharge.H"
11+
12+
#include "initialization/AmrCoreData.H"
13+
#include "particles/ImpactXParticleContainer.H"
14+
#include "particles/spacecharge/ForceFromSelfFields.H"
15+
#include "particles/spacecharge/GatherAndPush.H"
16+
#include "particles/spacecharge/PoissonSolve.H"
17+
#include "particles/transformation/CoordinateTransformation.H"
18+
19+
#include <AMReX_ParmParse.H>
20+
#include <AMReX_REAL.H>
21+
22+
#include <memory>
23+
24+
25+
namespace impactx::particles::spacecharge
26+
{
27+
void HandleSpacecharge (
28+
std::unique_ptr<initialization::AmrCoreData> & amr_data,
29+
std::function<void()> ResizeMesh,
30+
amrex::Real slice_ds
31+
)
32+
{
33+
BL_PROFILE("impactx::particles::wakefields::HandleSpacecharge")
34+
35+
amrex::ParmParse const pp_algo("algo");
36+
bool space_charge = false;
37+
pp_algo.query("space_charge", space_charge);
38+
39+
// turn off if disabled by user
40+
if (!space_charge) { return; }
41+
42+
// turn off if less than 2 particles
43+
if (amr_data->track_particles.m_particle_container->TotalNumberOfParticles(true, false) < 2) { return; }
44+
45+
// transform from x',y',t to x,y,z
46+
transformation::CoordinateTransformation(
47+
*amr_data->track_particles.m_particle_container,
48+
CoordSystem::t
49+
);
50+
51+
// Note: The following operation assume that
52+
// the particles are in x, y, z coordinates.
53+
54+
// Resize the mesh, based on `amr_data->track_particles.m_particle_container` extent
55+
ResizeMesh();
56+
57+
// Redistribute particles in the new mesh in x, y, z
58+
amr_data->track_particles.m_particle_container->Redistribute();
59+
60+
// charge deposition
61+
amr_data->track_particles.m_particle_container->DepositCharge(
62+
amr_data->track_particles.m_rho,
63+
amr_data->refRatio()
64+
);
65+
66+
// poisson solve in x,y,z
67+
spacecharge::PoissonSolve(
68+
*amr_data->track_particles.m_particle_container,
69+
amr_data->track_particles.m_rho,
70+
amr_data->track_particles.m_phi,
71+
amr_data->refRatio()
72+
);
73+
74+
// calculate force in x,y,z
75+
spacecharge::ForceFromSelfFields(
76+
amr_data->track_particles.m_space_charge_field,
77+
amr_data->track_particles.m_phi,
78+
amr_data->Geom()
79+
);
80+
81+
// gather and space-charge push in x,y,z , assuming the space-charge
82+
// field is the same before/after transformation
83+
// TODO: This is currently using linear order.
84+
spacecharge::GatherAndPush(
85+
*amr_data->track_particles.m_particle_container,
86+
amr_data->track_particles.m_space_charge_field,
87+
amr_data->Geom(),
88+
slice_ds
89+
);
90+
91+
// transform from x,y,z to x',y',t
92+
transformation::CoordinateTransformation(
93+
*amr_data->track_particles.m_particle_container,
94+
CoordSystem::s
95+
);
96+
97+
// for later: original Impact implementation as an option
98+
// Redistribute particles in x',y',t
99+
// TODO: only needed if we want to gather and push space charge
100+
// in x',y',t
101+
// TODO: change geometry beforehand according to transformation
102+
//m_amr_data->track_particles.m_particle_container->Redistribute();
103+
//
104+
// in original Impact, we gather and space-charge push in x',y',t ,
105+
// assuming that the distribution did not change
106+
}
107+
108+
} // namespace impactx::particles::spacecharge

src/particles/spacecharge/PoissonSolve.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <unordered_map>
1818

1919

20-
namespace impactx::spacecharge
20+
namespace impactx::particles::spacecharge
2121
{
2222
/** Calculate the electric potential from charge density
2323
*
@@ -36,6 +36,6 @@ namespace impactx::spacecharge
3636
amrex::Vector<amrex::IntVect> rel_ref_ratio
3737
);
3838

39-
} // namespace impactx
39+
} // namespace impactx::particles::spacecharge
4040

4141
#endif // IMPACTX_POISSONSOLVE_H

src/particles/spacecharge/PoissonSolve.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <cmath>
2222

2323

24-
namespace impactx::spacecharge
24+
namespace impactx::particles::spacecharge
2525
{
2626
void PoissonSolve (
2727
ImpactXParticleContainer const & pc,
@@ -121,4 +121,4 @@ namespace impactx::spacecharge
121121
phi_at_level.FillBoundary(pc.GetParGDB()->Geom()[lev].periodicity());
122122
}
123123
}
124-
} // impactx::spacecharge
124+
} // impactx::particles::spacecharge

src/tracking/particles.cpp

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313
#include "particles/ImpactXParticleContainer.H"
1414
#include "particles/Push.H"
1515
#include "diagnostics/DiagnosticOutput.H"
16-
#include "particles/spacecharge/ForceFromSelfFields.H"
17-
#include "particles/spacecharge/GatherAndPush.H"
18-
#include "particles/spacecharge/PoissonSolve.H"
19-
#include "particles/transformation/CoordinateTransformation.H"
16+
#include "particles/spacecharge/HandleSpacecharge.H"
2017
#include "particles/wakefields/HandleWakefield.H"
2118

2219
#include <AMReX.H>
@@ -114,71 +111,8 @@ namespace impactx
114111
// Wakefield calculation: call wakefield function to apply wake effects
115112
particles::wakefields::HandleWakefield(*amr_data->track_particles.m_particle_container, element_variant, slice_ds);
116113

117-
// Space-charge calculation: turn off if there is only 1 particle
118-
if (space_charge &&
119-
amr_data->track_particles.m_particle_container->TotalNumberOfParticles(true, false)) {
120-
121-
// transform from x',y',t to x,y,z
122-
transformation::CoordinateTransformation(
123-
*amr_data->track_particles.m_particle_container,
124-
CoordSystem::t);
125-
126-
// Note: The following operation assume that
127-
// the particles are in x, y, z coordinates.
128-
129-
// Resize the mesh, based on `m_particle_container` extent
130-
ResizeMesh();
131-
132-
// Redistribute particles in the new mesh in x, y, z
133-
amr_data->track_particles.m_particle_container->Redistribute();
134-
135-
// charge deposition
136-
amr_data->track_particles.m_particle_container->DepositCharge(
137-
amr_data->track_particles.m_rho,
138-
amr_data->refRatio()
139-
);
140-
141-
// poisson solve in x,y,z
142-
spacecharge::PoissonSolve(
143-
*amr_data->track_particles.m_particle_container,
144-
amr_data->track_particles.m_rho,
145-
amr_data->track_particles.m_phi,
146-
amr_data->refRatio()
147-
);
148-
149-
// calculate force in x,y,z
150-
spacecharge::ForceFromSelfFields(
151-
amr_data->track_particles.m_space_charge_field,
152-
amr_data->track_particles.m_phi,
153-
amr_data->Geom()
154-
);
155-
156-
// gather and space-charge push in x,y,z , assuming the space-charge
157-
// field is the same before/after transformation
158-
// TODO: This is currently using linear order.
159-
spacecharge::GatherAndPush(
160-
*amr_data->track_particles.m_particle_container,
161-
amr_data->track_particles.m_space_charge_field,
162-
amr_data->Geom(),
163-
slice_ds
164-
);
165-
166-
// transform from x,y,z to x',y',t
167-
transformation::CoordinateTransformation(
168-
*amr_data->track_particles.m_particle_container,
169-
CoordSystem::s
170-
);
171-
}
172-
173-
// for later: original Impact implementation as an option
174-
// Redistribute particles in x',y',t
175-
// TODO: only needed if we want to gather and push space charge
176-
// in x',y',t
177-
// TODO: change geometry beforehand according to transformation
178-
//m_particle_container->Redistribute();
179-
//
180-
// in original Impact, we gather and space-charge push in x',y',t ,
181-
// assuming that the distribution did not change
114+
// Space-charge calculation
115+
particles::spacecharge::HandleSpacecharge(amr_data, [this](){ this->ResizeMesh(); }, slice_ds);
182116

183117
// push all particles with external maps
184118
Push(*amr_data->track_particles.m_particle_container, element_variant, step, period);

0 commit comments

Comments
 (0)