1414#include " particles/CovarianceMatrix.H"
1515#include " particles/ImpactXParticleContainer.H"
1616#include " particles/distribution/All.H"
17+ #include " particles/distribution/SpinvMF.H"
1718#include " particles/SplitEqually.H"
1819
1920#include < ablastr/constant.H>
@@ -295,7 +296,8 @@ namespace impactx
295296 ImpactX::add_particles (
296297 amrex::ParticleReal bunch_charge,
297298 distribution::KnownDistributions distr,
298- amrex::Long npart
299+ amrex::Long npart,
300+ std::optional<distribution::SpinvMF> spin_distr
299301 )
300302 {
301303 BL_PROFILE (" ImpactX::add_particles" );
@@ -337,13 +339,21 @@ namespace impactx
337339 // alloc data for particle attributes
338340 amrex::Gpu::DeviceVector<amrex::ParticleReal> x, y, t;
339341 amrex::Gpu::DeviceVector<amrex::ParticleReal> px, py, pt;
342+ amrex::Gpu::DeviceVector<amrex::ParticleReal> sx, sy, sz;
340343 x.resize (npart_this_proc);
341344 y.resize (npart_this_proc);
342345 t.resize (npart_this_proc);
343346 px.resize (npart_this_proc);
344347 py.resize (npart_this_proc);
345348 pt.resize (npart_this_proc);
346349
350+ bool const has_spin = spin_distr.has_value ();
351+ if (has_spin) {
352+ sx.resize (npart_this_proc);
353+ sy.resize (npart_this_proc);
354+ sz.resize (npart_this_proc);
355+ }
356+
347357 std::visit ([&](auto && distribution){
348358 // initialize distributions
349359 distribution.initialize (bunch_charge, ref);
@@ -354,6 +364,9 @@ namespace impactx
354364 amrex::ParticleReal * const AMREX_RESTRICT px_ptr = px.data ();
355365 amrex::ParticleReal * const AMREX_RESTRICT py_ptr = py.data ();
356366 amrex::ParticleReal * const AMREX_RESTRICT pt_ptr = pt.data ();
367+ amrex::ParticleReal * const AMREX_RESTRICT sx_ptr = sx.data ();
368+ amrex::ParticleReal * const AMREX_RESTRICT sy_ptr = sy.data ();
369+ amrex::ParticleReal * const AMREX_RESTRICT sz_ptr = sz.data ();
357370
358371 using Distribution = std::decay_t <decltype (distribution)>;
359372
@@ -373,6 +386,7 @@ namespace impactx
373386 npart_this_thread = thread_chunk.size ;
374387#endif
375388
389+ // phase space init
376390 initialization::InitSingleParticleData<Distribution> const init_single_particle_data (
377391 distribution,
378392 x_ptr + my_offset,
@@ -384,6 +398,20 @@ namespace impactx
384398 );
385399
386400 amrex::ParallelForRNG (npart_this_thread, init_single_particle_data);
401+
402+ // spin init
403+ if (has_spin) {
404+ auto spinv = spin_distr.value ();
405+ amrex::ParallelForRNG (npart_this_thread,
406+ [=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const & engine) noexcept {
407+ spinv (
408+ sx_ptr[i + my_offset],
409+ sy_ptr[i + my_offset],
410+ sz_ptr[i + my_offset],
411+ engine
412+ );
413+ });
414+ }
387415 }
388416
389417 // finalize distributions and deallocate temporary device global memory
@@ -548,15 +576,28 @@ namespace impactx
548576 std::string unit_type; // System of units
549577 pp_dist.get (" units" , unit_type);
550578
579+ // phase space distribution
551580 distribution::KnownDistributions dist = initialization::read_distribution (pp_dist);
552581 std::string distribution;
553582 pp_dist.get (" distribution" , distribution);
554583
584+ // spin distribution
585+ amrex::ParticleReal polarization_x = 0 .0_prt,
586+ polarization_y = 0 .0_prt,
587+ polarization_z = 0 .0_prt;
588+ pp_dist.queryWithParser (" polarization_x" , polarization_x);
589+ pp_dist.queryWithParser (" polarization_y" , polarization_y);
590+ pp_dist.queryWithParser (" polarization_z" , polarization_z);
591+ // TODO: check magnitude of x,y,z is in range [0:1]
592+ // TODO: calculate kappa from mag(x,y,z)
593+ amrex::ParticleReal kappa = 1.0 ; // FIXME: root finding
594+ distribution::SpinvMF spin_dist (polarization_x, polarization_y, polarization_z, kappa);
595+
555596 amrex::Long npart = 0 ; // Number of simulation particles
556597 if (distribution != " empty" )
557598 {
558599 pp_dist.getWithParser (" npart" , npart);
559- add_particles (bunch_charge, dist, npart);
600+ add_particles (bunch_charge, dist, npart, spin_dist );
560601 }
561602
562603 // print information on the initialized beam
0 commit comments