ImpactX
Loading...
Searching...
No Matches
Integrators.H
Go to the documentation of this file.
1/* Copyright 2022-2023 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: Chad Mitchell, Axel Huebl
8 * License: BSD-3-Clause-LBNL
9 */
10#ifndef IMPACTX_INTEGRATORS_H_
11#define IMPACTX_INTEGRATORS_H_
12
13#include <AMReX_Extension.H> // for AMREX_RESTRICT
14#include <AMReX_REAL.H> // for ParticleReal
15
16
18{
19
34 template <typename T_Element>
37 RefPart & refpart,
38 amrex::ParticleReal const zin,
39 amrex::ParticleReal const zout,
40 int const nsteps,
41 T_Element const & element
42 )
43 {
44 using namespace amrex::literals; // for _rt and _prt
45
46 // initialize numerical integration parameters
47 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
48 amrex::ParticleReal const tau1 = dz * 0.5_prt;
49 amrex::ParticleReal const tau2 = dz;
50
51 // initialize the value of the independent variable
52 amrex::ParticleReal zeval = zin;
53
54 // loop over integration steps
55 for(int j=0; j < nsteps; ++j)
56 {
57 element.map1(tau1,refpart,zeval);
58 element.map2(tau2,refpart,zeval);
59 element.map1(tau1,refpart,zeval);
60 }
61 }
62
77 template <typename T_Element>
80 RefPart & refpart,
81 amrex::ParticleReal const zin,
82 amrex::ParticleReal const zout,
83 int const nsteps,
84 T_Element const & element
85 )
86 {
87 using namespace amrex::literals; // for _rt and _prt
88
89 // initialize numerical integration parameters
90 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
91 amrex::ParticleReal const tau1 = dz * 0.5_prt;
92 amrex::ParticleReal const tau2 = dz * 0.5_prt;
93 amrex::ParticleReal const tau3 = dz;
94
95 // initialize the value of the independent variable
96 amrex::ParticleReal zeval = zin;
97
98 // loop over integration steps
99 for(int j=0; j < nsteps; ++j)
100 {
101 element.map1(tau1,refpart,zeval);
102 element.map2(tau2,refpart,zeval);
103 element.map3(tau3,refpart,zeval);
104 element.map2(tau2,refpart,zeval);
105 element.map1(tau1,refpart,zeval);
106 }
107 }
108
126 template <typename T_Element>
129 RefPart & refpart,
130 amrex::ParticleReal const zin,
131 amrex::ParticleReal const zout,
132 int const nsteps,
133 T_Element const & element
134 )
135 {
136 using namespace amrex::literals; // for _rt and _prt
137
138 // initialize numerical integration parameters
139 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
140 constexpr amrex::ParticleReal alpha = -0.2599210498948732; // C++26: 1_prt - std::pow(2_prt,1_prt/3_prt);
141 amrex::ParticleReal const tau2 = dz / (1_prt + alpha);
142 amrex::ParticleReal const tau1 = tau2*0.5_prt;
143 amrex::ParticleReal const tau3 = alpha*tau1;
144 amrex::ParticleReal const tau4 = (alpha - 1_prt)*tau2;
145
146 // initialize the value of the independent variable
147 amrex::ParticleReal zeval = zin;
148
149 // loop over integration steps
150 for (int j=0; j < nsteps; ++j)
151 {
152 element.map1(tau1,refpart,zeval);
153 element.map2(tau2,refpart,zeval);
154 element.map1(tau3,refpart,zeval);
155 element.map2(tau4,refpart,zeval);
156 element.map1(tau3,refpart,zeval);
157 element.map2(tau2,refpart,zeval);
158 element.map1(tau1,refpart,zeval);
159 }
160 }
161
176 template <typename T_Real, typename T_Element>
180 amrex::ParticleReal const zin,
181 amrex::ParticleReal const zout,
182 int const nsteps,
183 T_Element const & element
184 )
185 {
186 using namespace amrex::literals; // for _rt and _prt
187
188 // initialize numerical integration parameters
189 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
190 amrex::ParticleReal const tau1 = dz * 0.5_prt;
191 amrex::ParticleReal const tau2 = dz;
192
193 // initialize the value of the independent variable
194 amrex::ParticleReal zeval = zin;
195
196 // loop over integration steps
197 for(int j=0; j < nsteps; ++j)
198 {
199 element.map1(tau1,particle,zeval);
200 element.map2(tau2,particle,zeval);
201 element.map1(tau1,particle,zeval);
202 }
203 }
204
205
223 template <typename T_Real, typename T_Element>
227 amrex::ParticleReal const zin,
228 amrex::ParticleReal const zout,
229 int const nsteps,
230 T_Element const & element
231 )
232 {
233 using namespace amrex::literals; // for _rt and _prt
234
235 // initialize numerical integration parameters
236 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
237 constexpr amrex::ParticleReal alpha = -0.2599210498948732; // C++26: 1_prt - std::pow(2_prt,1_prt/3_prt);
238 amrex::ParticleReal const tau2 = dz/(1_prt + alpha);
239 amrex::ParticleReal const tau1 = tau2*0.5_prt;
240 amrex::ParticleReal const tau3 = alpha*tau1;
241 amrex::ParticleReal const tau4 = (alpha - 1_prt)*tau2;
242
243 // initialize the value of the independent variable
244 amrex::ParticleReal zeval = zin;
245
246 // loop over integration steps
247 for (int j=0; j < nsteps; ++j)
248 {
249 element.map1(tau1,particle,zeval);
250 element.map2(tau2,particle,zeval);
251 element.map1(tau3,particle,zeval);
252 element.map2(tau4,particle,zeval);
253 element.map1(tau3,particle,zeval);
254 element.map2(tau2,particle,zeval);
255 element.map1(tau1,particle,zeval);
256 }
257 }
258
259
282 template <typename T_Real, typename T_Element>
286 amrex::ParticleReal const zin,
287 amrex::ParticleReal const zout,
288 int const nsteps,
289 T_Element const & element
290 )
291 {
292 using namespace amrex::literals; // for _rt and _prt
293
294 // initialize numerical integration parameters
295 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
296 amrex::ParticleReal const w0 = 1.31518632068391121888424973;
297 amrex::ParticleReal const w1 = -1.17767998417887100694641568;
298 amrex::ParticleReal const w2 = 0.23557321335935813368479318;
299 amrex::ParticleReal const w3 = 0.78451361047755726381949763;
300
301 amrex::ParticleReal const tau1 = w3 * dz / 2_prt;
302 amrex::ParticleReal const tau2 = w3 * dz;
303 amrex::ParticleReal const tau3 = (w3 + w2) * dz / 2_prt;
304 amrex::ParticleReal const tau4 = w2 * dz;
305 amrex::ParticleReal const tau5 = (w2 + w1) * dz / 2_prt;
306 amrex::ParticleReal const tau6 = w1 * dz;
307 amrex::ParticleReal const tau7 = (w1 + w0) * dz / 2_prt;
308 amrex::ParticleReal const tau8 = w0 * dz;
309
310 // initialize the value of the independent variable
311 amrex::ParticleReal zeval = zin;
312
313 // loop over integration steps
314 for (int j=0; j < nsteps; ++j)
315 {
316 element.map1(tau1,particle,zeval);
317 element.map2(tau2,particle,zeval);
318 element.map1(tau3,particle,zeval);
319 element.map2(tau4,particle,zeval);
320 element.map1(tau5,particle,zeval);
321 element.map2(tau6,particle,zeval);
322 element.map1(tau7,particle,zeval);
323 element.map2(tau8,particle,zeval);
324 element.map1(tau7,particle,zeval);
325 element.map2(tau6,particle,zeval);
326 element.map1(tau5,particle,zeval);
327 element.map2(tau4,particle,zeval);
328 element.map1(tau3,particle,zeval);
329 element.map2(tau2,particle,zeval);
330 element.map1(tau1,particle,zeval);
331 }
332 }
333
349 template <typename T_Real, typename T_Element>
353 amrex::SmallVector<T_Real, 3, 1> & particle_spin,
354 amrex::ParticleReal const tau,
355 amrex::ParticleReal & zeval,
356 T_Element const & element
357 )
358 {
359 using namespace amrex::literals; // for _rt and _prt
360
361 // initialize numerical integration parameters
362 amrex::ParticleReal const tau1 = tau*0.5_prt;
363 amrex::ParticleReal const tau2 = tau*0.5_prt;
364 amrex::ParticleReal const tau3 = tau;
365
366 // a single second-order step
367 element.map1(tau1,particle,zeval);
368 element.map2(tau2,particle,zeval);
369 element.map3(tau3,particle,particle_spin,zeval);
370 element.map2(tau2,particle,zeval);
371 element.map1(tau1,particle,zeval);
372 }
373
390 template <typename T_Real, typename T_Element>
394 amrex::SmallVector<T_Real, 3, 1> & particle_spin,
395 amrex::ParticleReal const tau,
396 amrex::ParticleReal & zeval,
397 T_Element const & element
398 )
399 {
400 using namespace amrex::literals; // for _rt and _prt
401
402 // initialize numerical integration parameters (Yoshida)
403 constexpr amrex::ParticleReal a = 1.2599210498948732; // C++26 std::pow(2_prt,1_prt/3_prt);
404 constexpr amrex::ParticleReal z0 = 1_prt / (2_prt - a);
405 constexpr amrex::ParticleReal z1 = -a / (2_prt - a);
406 amrex::ParticleReal const tau1 = tau*z0;
407 amrex::ParticleReal const tau2 = tau*z1;
408
409 // a single fourth-order step
410 symp2_integrate_particle_spin_step(particle,particle_spin,tau1,zeval,element);
411 symp2_integrate_particle_spin_step(particle,particle_spin,tau2,zeval,element);
412 symp2_integrate_particle_spin_step(particle,particle_spin,tau1,zeval,element);
413 }
414
415
432 template <typename T_Real, typename T_Element>
436 amrex::SmallVector<T_Real, 3, 1> & particle_spin,
437 amrex::ParticleReal const tau,
438 amrex::ParticleReal & zeval,
439 T_Element const & element
440 )
441 {
442 using namespace amrex::literals; // for _rt and _prt
443
444 // initialize numerical integration parameters (Yoshida)
445 constexpr amrex::ParticleReal a = 1.148698354997035; // C++26 std::pow(2_prt,1_prt/5_prt);
446 constexpr amrex::ParticleReal z0 = 1_prt / (2_prt - a);
447 constexpr amrex::ParticleReal z1 = -a / (2_prt - a);
448 amrex::ParticleReal const tau1 = tau * z0;
449 amrex::ParticleReal const tau2 = tau * z1;
450
451 // a single sixth-order step
452 symp4_integrate_particle_spin_step(particle,particle_spin,tau1,zeval,element);
453 symp4_integrate_particle_spin_step(particle,particle_spin,tau2,zeval,element);
454 symp4_integrate_particle_spin_step(particle,particle_spin,tau1,zeval,element);
455 }
456
457
475 template <typename T_Real, typename T_Element>
479 amrex::SmallVector<T_Real, 3, 1> & particle_spin,
480 amrex::ParticleReal const zin,
481 amrex::ParticleReal const zout,
482 int const nsteps,
483 int int_order,
484 T_Element const & element
485 )
486 {
487 using namespace amrex::literals; // for _rt and _prt
488
489 // initialize numerical integration parameters
490 amrex::ParticleReal const dz = (zout - zin) / static_cast<amrex::ParticleReal>(nsteps);
491
492 // initialize the value of the independent variable
493 amrex::ParticleReal zeval = zin;
494
495 // loop over integration steps
496 for(int j=0; j < nsteps; ++j)
497 {
498 if (int_order == 2) {
499 symp2_integrate_particle_spin_step(particle,particle_spin,dz,zeval,element);
500 } else if (int_order == 4) {
501 symp4_integrate_particle_spin_step(particle,particle_spin,dz,zeval,element);
502 } else if (int_order == 6) {
503 symp6_integrate_particle_spin_step(particle,particle_spin,dz,zeval,element);
504 } else {
505 symp2_integrate_particle_spin_step(particle,particle_spin,dz,zeval,element);
506 }
507 }
508 }
509
510
511} // namespace impactx::integrators
512
513#endif // IMPACTX_INTEGRATORS_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
amrex_particle_real ParticleReal
SmallMatrix< T, N, 1, Order::F, StartIndex > SmallVector
Definition Integrators.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp4_integrate_particle_spin_step(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::SmallVector< T_Real, 3, 1 > &particle_spin, amrex::ParticleReal const tau, amrex::ParticleReal &zeval, T_Element const &element)
Definition Integrators.H:392
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp_integrate_particle_spin(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::SmallVector< T_Real, 3, 1 > &particle_spin, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, int int_order, T_Element const &element)
Definition Integrators.H:477
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp2_integrate_particle_spin_step(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::SmallVector< T_Real, 3, 1 > &particle_spin, amrex::ParticleReal const tau, amrex::ParticleReal &zeval, T_Element const &element)
Definition Integrators.H:351
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp4_integrate(RefPart &refpart, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:128
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp4_integrate_particle(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:225
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp2_integrate(RefPart &refpart, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp2_integrate_split3(RefPart &refpart, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:79
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp6_integrate_particle(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:284
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp2_integrate_particle(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::ParticleReal const zin, amrex::ParticleReal const zout, int const nsteps, T_Element const &element)
Definition Integrators.H:178
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void symp6_integrate_particle_spin_step(amrex::SmallVector< T_Real, 6, 1 > &particle, amrex::SmallVector< T_Real, 3, 1 > &particle_spin, amrex::ParticleReal const tau, amrex::ParticleReal &zeval, T_Element const &element)
Definition Integrators.H:434
Definition ReferenceParticle.H:33