Skip to content

Commit 79c59f3

Browse files
committed
Envelope: Space Charge Match 2D (Draft)
1 parent 317e274 commit 79c59f3

File tree

2 files changed

+65
-46
lines changed

2 files changed

+65
-46
lines changed

src/ImpactX.H

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ namespace impactx
178178
};
179179

180180
amrex::ParticleReal
181-
evaluate_lattice (ImpactX *, amrex::ParticleReal const & q1_k); //, amrex::ParticleReal q2_k);
181+
evaluate_lattice (ImpactX *, amrex::ParticleReal const & q1_k, amrex::ParticleReal const & q2_k);
182182

183183
void my_run ();
184184

src/ImpactX.cpp

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -153,24 +153,22 @@ namespace impactx {
153153
}
154154

155155
amrex::ParticleReal
156-
evaluate_lattice (ImpactX * sim, amrex::ParticleReal const & q1_k) //, amrex::ParticleReal q2_k)
156+
evaluate_lattice (ImpactX * sim, amrex::ParticleReal const & q1_k, amrex::ParticleReal const & q2_k)
157157
{
158-
amrex::ParticleReal q2_k = 3.5;
158+
// Example from:
159+
// https://impactx.readthedocs.io/en/latest/usage/examples/fodo_space_charge/README.html
159160

160-
// ns = 10 // TODO: number of slices per ds in the element
161+
int nslice = 50;
161162

162-
auto dr1 = elements::Drift{2.7};
163-
auto q1 = elements::Quad{0.1, q1_k};
164-
auto dr2 = elements::Drift{1.4};
165-
auto q2 = elements::Quad{0.2, q2_k};
166-
auto dr3 = elements::Drift{1.4};
167-
auto q3 = elements::Quad{0.1, q1_k};
168-
auto dr4 = elements::Drift{2.7};
163+
auto dr1 = elements::Drift{7.44e-2};
164+
auto q1 = elements::Quad{6.10e-2, q1_k};
165+
auto dr2 = elements::Drift{14.88e-2};
166+
auto q2 = elements::Quad{6.10e-2, q2_k};
169167

170168
/*
171169
// quadrupole triplet
172170
// https://impactx.readthedocs.io/en/latest/usage/examples/optimize_triplet/README.html
173-
active_sim->m_lattice = {
171+
sim->m_lattice = {
174172
elements::Drift{2.7},
175173
elements::Quad{0.1, q1_k},
176174
elements::Drift{1.4},
@@ -191,41 +189,50 @@ namespace impactx {
191189

192190
// envelope mode
193191
//std::cout << "before ref\n";
194-
auto ref = sim->amr_data->track_envelope.m_ref.value();
192+
RefPart & ref = sim->amr_data->track_envelope.m_ref.value();
195193
//std::cout << "before env\n";
196194
auto env = sim->amr_data->track_envelope.m_env.value();
197195
//std::cout << "before cm\n";
198196
auto cm = env.m_env;
199197

200198
auto & intensity = env.m_beam_intensity;
201-
intensity = 1.0e-6; // a big value
199+
intensity = 0.5; // Ampere
202200

203-
// push reference particle in global coordinates
204-
dr1(ref);
205-
// push Covariance Matrix in external fields
206-
dr1(cm, ref);
207-
208-
q1(ref);
209-
q1(cm, ref);
210-
211-
dr2(ref);
212-
dr2(cm, ref);
213-
214-
q2(ref);
215-
q2(cm, ref);
216-
217-
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, q2.ds());
201+
// sub-steps for space charge within the element
202+
for (int slice_step = 0; slice_step < nslice; ++slice_step)
203+
{
204+
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, dr1.ds() / nslice);
205+
dr1(ref);
206+
dr1(cm, ref);
207+
}
218208

219-
dr3(ref);
220-
dr3(cm, ref);
209+
for (int slice_step = 0; slice_step < nslice; ++slice_step)
210+
{
211+
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, q1.ds() / nslice);
212+
q1(ref);
213+
q1(cm, ref);
214+
}
221215

222-
envelope::spacecharge::space_charge3D_push(ref, cm, intensity, dr3.ds());
216+
for (int slice_step = 0; slice_step < nslice; ++slice_step)
217+
{
218+
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, dr2.ds() / nslice);
219+
dr2(ref);
220+
dr2(cm, ref);
221+
}
223222

224-
q3(ref);
225-
q3(cm, ref);
223+
for (int slice_step = 0; slice_step < nslice; ++slice_step)
224+
{
225+
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, q2.ds() / nslice);
226+
q2(ref);
227+
q2(cm, ref);
228+
}
226229

227-
dr4(ref);
228-
dr4(cm, ref);
230+
for (int slice_step = 0; slice_step < nslice; ++slice_step)
231+
{
232+
envelope::spacecharge::space_charge2D_push(ref, cm, intensity, dr1.ds() / nslice);
233+
dr1(ref);
234+
dr1(cm, ref);
235+
}
229236

230237
/*
231238
// particles
@@ -258,46 +265,58 @@ namespace impactx {
258265

259266
sim.init_grids();
260267

261-
// TODO: replace with beam params from https://impactx.readthedocs.io/en/latest/usage/examples/optimize_triplet/README.html
268+
// TODO: replace with beam params from https://impactx.readthedocs.io/en/latest/usage/examples/fodo_space_charge/README.html
262269
sim.initBeamDistributionFromInputs();
263270

264271
// design the accelerator lattice
265272
// sim.initLatticeElementsFromInputs();
266273

267274
// initial quad strengths
268-
amrex::ParticleReal q1_k = -3.0;
269-
//amrex::ParticleReal q2_k = 3.0;
270-
amrex::Print() << "q1_k = " << q1_k << std::endl;
275+
amrex::ParticleReal q1_k = -80.0;
276+
amrex::ParticleReal q2_k = 120.0;
277+
amrex::Print() << "q1_k = " << q1_k << "\n"
278+
<< "q2_k = " << q2_k
279+
<< std::endl;
271280

272281
#define MYMODE 2
273282

274283
#if MYMODE == 0
275284
// non-differentiable run:
276-
amrex::ParticleReal ddx = std::numeric_limits<amrex::ParticleReal>::quiet_NaN();
277-
amrex::ParticleReal const alpha_x = evaluate_lattice(&sim, q1_k);
285+
amrex::ParticleReal dq1_k = std::numeric_limits<amrex::ParticleReal>::quiet_NaN();
286+
amrex::ParticleReal dq2_k = std::numeric_limits<amrex::ParticleReal>::quiet_NaN();
287+
amrex::ParticleReal const alpha_x = evaluate_lattice(&sim, q1_k, q2_k);
278288
amrex::Print() << "final alpha_x = " << alpha_x << std::endl;
279289

280290
#elif MYMODE == 1
281291
// forward differentiable run
282292
// note: seeded direction, this is AD and NOT a finite difference
283293
amrex::ParticleReal dq1_k = 1.0;
294+
amrex::ParticleReal dq2_k = 1.0;
284295
amrex::ParticleReal ddx = __enzyme_fwddiff(
285296
&evaluate_lattice,
286297
enzyme_const, &sim,
287-
enzyme_dup, &q1_k, &dq1_k
298+
enzyme_dup,
299+
&q1_k, &dq1_k,
300+
&q2_k, &dq2_k
288301
);
289302

290303
#elif MYMODE == 2
291304
// reverse differentiable run:
292-
amrex::ParticleReal ddx = 0.0; // accumulator, zero-init!
305+
amrex::ParticleReal dq1_k = 0.0; // accumulator, zero-init!
306+
amrex::ParticleReal dq2_k = 0.0; // accumulator, zero-init!
293307
__enzyme_autodiff(
294308
&evaluate_lattice,
295309
enzyme_const, &sim,
296-
enzyme_dup, &q1_k, &ddx
310+
enzyme_dup,
311+
&q1_k, &dq1_k,
312+
&q2_k, &dq2_k
297313
);
298314
#endif
299315

300-
amrex::Print() << "ddx = " << ddx << std::endl;
316+
amrex::Print() << "final alpha_x = " << alpha_x << std::endl;
317+
amrex::Print() << "dq1_k = " << dq1_k << "\n"
318+
<< "dq2_k = " << dq2_k
319+
<< std::endl;
301320

302321
sim.finalize();
303322
}

0 commit comments

Comments
 (0)