19#ifndef OPAL_PartBunch_HPP
20#define OPAL_PartBunch_HPP
40#include "PoissonSolvers/P3MSolver.h"
46template <
typename T =
double,
unsigned Dim = 3>
50template <
typename T =
double,
unsigned Dim = 3>
53template <
typename T =
double,
unsigned Dim = 3>
55 ConditionalType<Dim == 3, ippl::FFTOpenPoissonSolver<VField_t<T, Dim>,
Field_t<Dim>>>;
57template <
typename T =
double,
unsigned Dim = 3>
61template <
class PLayout,
typename T,
unsigned Dim = 3>
219 for (
unsigned int i = 0; i <
Dim; i++) {
263 <<
"Could not set total charge in PartBunch::setCharge based on this->getTotalNum"
372 for (
unsigned int i = 0; i <
Dim; i++)
373 grid[i] = domain[i].length();
391 bool fromAnalyticDensity =
false;
392 bool res =
orb.binaryRepartition(this->
R, fl, fromAnalyticDensity);
395 std::cout <<
"Could not repartition!" <<
std::endl;
405 double threshold = 1.0;
406 double equalPart = (double)totalP /
ippl::Comm->size();
407 double dev = std::abs((
double)this->
getLocalNum() - equalPart) / totalP;
408 if (dev > threshold) {
411 MPI_Allgather(&local, 1, MPI_INT, res.data(), 1, MPI_INT,
ippl::Comm->getCommunicator());
413 for (
unsigned int i = 0; i < res.size(); i++) {
462 layout.updateLayout(fl, mesh);
486 const int dimIdx = (
dcBeam_m ? 2 : 3);
499 for (
int i = 0; i < dimIdx; i++) {
501 if (length < 1
e-10) {
514 for (
int i = 0; i < dimIdx; ++i) {
542 std::vector<size_t> tmpbinemitted;
552 if (haveEnergyBins) {
555 for (
unsigned int i = 0; i < localNum; i++) {
556 if (this->
Bin(i) < 0) {
560 }
else if (haveEnergyBins) {
561 tmpbinemitted[this->
Bin(i)]++;
575 std::unique_ptr<size_t[]> tmpbinemitted;
584 tmpbinemitted[i] = 0;
586 for (
unsigned int i = 0; i < localNum; i++) {
587 if (this->
Bin(i) < 0) {
591 tmpbinemitted[this->
Bin(i)]++;
595 for (
size_t i = 0; i < localNum; i++) {
596 if ((this->
Bin(i) < 0)) {
614 ippl::Comm->reduce(newTotalNum, newTotalNum, 1, std::plus<size_t>());
619 return totalNum - newTotalNum;
657 for (
unsigned int i = 0; i <
Dim; i++)
658 nr_m[i] = domain[i].length();
660 for (
int i = 0; i < 3; i++)
661 hr_m[i] = (ur[i] - ll[i]) /
nr_m[i];
678 void swap(
unsigned int i,
unsigned int j) {
682 std::swap(this->
R(i), this->
R(j));
683 std::swap(this->
P(i), this->
P(j));
684 std::swap(this->
Q(i), this->
Q(j));
685 std::swap(this->
M(i), this->
M(j));
686 std::swap(this->
Phi(i), this->
Phi(j));
708 std::cout <<
"Rank " <<
ippl::Comm->rank() <<
" has "
710 <<
" percent of the total particles " <<
std::endl;
716 bool hasToReset =
false;
722 if (use_dt_per_particle)
741 std::size_t localnum = 0;
744 for (
unsigned long k = 0; k < this->
getLocalNum(); ++k)
745 if (std::abs(this->
R(k)(0) - meanR(0)) > x(0)
746 || std::abs(this->
R(k)(1) - meanR(1)) > x(1)
747 || std::abs(this->
R(k)(2) - meanR(2)) > x(2)) {
753 size_t npOutside = std::accumulate(
755 std::plus<size_t>());
770 unsigned int nBins, std::vector<double>& lineDensity, std::pair<double, double>& meshInfo) {
780 double length = rmax(2) - rmin(2);
781 double zmin = rmin(2) -
dh_m * length, zmax = rmax(2) +
dh_m * length;
782 double hz = (zmax - zmin) / (nBins - 2);
783 double perMeter = 1.0 / hz;
786 lineDensity.resize(nBins, 0.0);
787 std::fill(lineDensity.begin(), lineDensity.end(), 0.0);
790 for (
unsigned int i = 0; i < lN; ++i) {
791 const double z = this->
R(i)(2) - 0.5 * hz;
792 unsigned int idx = (z - zmin) / hz;
793 double tau = (z - zmin) / hz - idx;
802 meshInfo.first = zmin;
803 meshInfo.second = hz;
875 os << std::scientific;
877 os <<
"* ************** B U N C H "
878 "********************************************************* \n";
911 "********************************************************************************** "
923 auto view =
P.getView();
928 "Particle Energy", view.extent(0),
929 KOKKOS_LAMBDA(
const int i,
double& valL) {
930 double myVal =
dot(view(i), view(i)).apply();
933 Kokkos::Sum<double>(Energy));
936 double gEnergy = 0.0;
938 MPI_Reduce(&Energy, &gEnergy, 1, MPI_DOUBLE, MPI_SUM, 0,
ippl::Comm->getCommunicator());
942 csvout.
setf(std::ios::scientific, std::ios::floatfield);
944 csvout << iteration <<
" " << gEnergy <<
endl;
974 unsigned int Total_particles = 0;
975 unsigned int local_particles = this->
getLocalNum();
978 &local_particles, &Total_particles, 1, MPI_UNSIGNED, MPI_SUM, 0,
981 double rel_error = std::fabs((
Q_m - Q_grid) /
Q_m);
982 m <<
"Rel. error in charge conservation = " << rel_error <<
endl;
985 if (Total_particles != totalP || rel_error > 1
e-10) {
986 std::cout <<
"Total particles in the sim. " << totalP <<
" "
987 <<
"after update: " << Total_particles <<
std::endl;
988 std::cout <<
"Total particles not matched in iteration: " << iteration <<
std::endl;
989 std::cout <<
"Q grid: " << Q_grid <<
"Q particles: " <<
Q_m <<
std::endl;
990 std::cout <<
"Rel. error in charge conservation: " << rel_error <<
std::endl;
1058 &local_particles, &total_particles, 1, MPI_UNSIGNED_LONG, MPI_SUM, 0,
1093 return (
pbin_m !=
nullptr);
1167 for (
unsigned int i = 0; i <
Dim; ++i) {
1168 min[2 * i] = rmin[i];
1169 min[2 * i + 1] = -rmax[i];
1174 for (
unsigned int i = 0; i <
Dim; ++i) {
1175 rmin[i] =
min[2 * i];
1176 rmax[i] = -
min[2 * i + 1];
1182 if (localNum == 0) {
1183 double maxValue = 1e8;
1191 for (
size_t i = 1; i < localNum; ++i) {
1192 for (
unsigned short d = 0; d < 3u; ++d) {
1193 if (rmin(d) > this->
R(i)(d))
1194 rmin(d) = this->
R(i)(d);
1195 else if (rmax(d) < this->
R(i)(d))
1196 rmax(d) = this->
R(i)(d);
1205 std::pair<Vector_t<T, Dim>,
double> sphere;
1206 sphere.first = 0.5 * (rmin + rmax);
1207 sphere.second = std::sqrt(
dot(rmax - sphere.first, rmax - sphere.first));
1216 std::pair<Vector_t<T, Dim>,
double> sphere;
1217 sphere.first = 0.5 * (rmin + rmax);
1218 sphere.second = std::sqrt(
dot(rmax - sphere.first, rmax - sphere.first));
1224 bounds(this->P,
min,
max);
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
ConditionalType< Dim==3, ippl::P3MSolver< VField_t< T, Dim >, Field_t< Dim > > > P3MSolver_t
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
VariantFromConditionalTypes< FFTSolver_t< T, Dim >, P3MSolver_t< T, Dim >, OpenSolver_t< T, Dim > > Solver_t
ConditionalType< Dim==2||Dim==3, ippl::FFTPeriodicPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > FFTSolver_t
ConditionalType< Dim==3, ippl::FFTOpenPoissonSolver< VField_t< T, Dim >, Field_t< Dim > > > OpenSolver_t
Inform & endl(Inform &inf)
Inform & level1(Inform &inf)
constexpr double e
The value of.
constexpr double c
The velocity of light in m/s.
Implementations for FFT constructor/destructor and transforms.
KOKKOS_INLINE_FUNCTION Vector< T, Dim > max(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
std::unique_ptr< Inform > Warn
void gather(Attrib1 &attrib, Field &f, const Attrib2 &pp, const bool addToAttribute=false)
Non-class interface for gathering field data into a particle attribute.
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
void scatter(const Attrib1 &attrib, Field &f, const Attrib2 &pp)
Non-class interface for scattering particle attribute data onto a field.
std::conditional_t< B, T, void > ConditionalType
typename ConstructVariant< std::variant< Types... >, std::variant<>, IsEnabled >::type VariantFromConditionalTypes
int getSteptoLastInj() const
long long localTrackStep_m
step in a TRACK command
std::array< bool, Dim > isParallel_m
ParticleAttrib< int > bunchNum
void updateDomainLength(Vector_t< int, 3 > &grid)
void gatherLoadBalanceStatistics()
void initializeORB(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
Vector_t< T, Dim > get_hr() const
ParticleAttrib< double > Phi
double getMassPerParticle() const
void setBeamFrequency(double v)
void setMass(double mass)
Vector_t< T, Dim > get_prms() const
void getLocalBounds(Vector_t< T, Dim > &rmin, Vector_t< T, Dim > &rmax) const
double centroid_m[2 *Dim]
holds the centroid of the beam
void updateFields(const Vector_t< T, Dim > &, const Vector_t< T, Dim > &origin)
Vector_t< double, Dim > rmin_m
Solver_t< T, Dim > solver_m
ParticleLayout< double, 3 > & getLayout()
size_t getNumberOfEmissionSteps()
void repartition(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
void setBinCharge(int bin, double q)
Set the charge of one bin to the value of q and all other to zero.
std::unique_ptr< Inform > pmsg_m
const Mesh_t< Dim > & getMesh() const
UnitState_t stateOfLastBoundP_m
Vector_t< T, Dim > globalMeanR_m
Initialize the translation vector and rotation quaternion here.
double t_m
holds the actual time of the integration
const PartData * reference
relative enlargement of the mesh
void setChargeZeroPart(double q)
Vector_t< T, Dim > get_99_99Percentile() const
std::pair< Vector_t< double, 3 >, Vector_t< double, 3 > > VectorPair_t
ParticleAttrib< Vector_t< T, Dim > > Ef
size_t calcNumPartsOutside(Vector_t< T, Dim > x)
returns the number of particles outside of a box defined by x
Vector_t< T, Dim > get_normalizedEps_99Percentile() const
size_t boundp_destroyT()
This is only temporary in order to get the collimator and pepperpot working.
PartBunch & operator=(const PartBunch &)=delete
void setLocalTrackStep(long long n)
step in a TRACK command
PartBins * pbin_m
The structure for particle binning.
int getLastEmittedEnergyBin()
size_t getLoadBalance(int p) const
void setPType(const std::string &type)
void calcBeamParameters()
Vector_t< T, Dim > get_maxExtent() const
Vector_t< T, Dim > get_pmean() const
int stepsPerTurn_m
steps per turn for OPAL-cycl
ParticleAttrib< int > Bin
double spos_m
the position along design trajectory
double getQ() const
Access to reference data.
void swap(unsigned int i, unsigned int j)
std::pair< Vector_t< T, Dim >, double > getLocalBoundingSphere()
ParticleAttrib< double > M
bool resetPartBinID2(const double eta)
reset Bin[] for each particle according to the method given in paper PAST-AB(064402) by G.
void setBinCharge(int bin)
Set the charge of all other the ones in bin to zero.
void resetInterpolationCache(bool clearCache=false)
void resetQ(double q)
Set reference data.
Vector_t< double, Dim > rmax_m
void setPBins(PartBins *pbin)
std::pair< Vector_t< T, Dim >, double > getBoundingSphere()
void switchToUnitlessPositions(bool use_dt_per_particle=false)
double getCharge() const
get the total charge per simulation particle
double getInitialBeta() const
void get_PBounds(Vector_t< T, Dim > &min, Vector_t< T, Dim > &max) const
Vector_t< T, Dim > get_rrms() const
std::unique_ptr< size_t[]> binemitted_m
Vector_t< T, Dim > get_halo() const
Vector_t< T, Dim > get_origin() const
short numBunch_m
current bunch number
Vector_t< T, Dim > RefPartR_m
Reference particle structures.
double tEmission_m
if larger than 0, emitt particles for tEmission_m [s]
short getNumBunch() const
double getRho(int x, int y, int z)
void calcBeamParametersInitial()
double getGamma(int i) const
Vector_t< T, Dim > get_68Percentile() const
bool balance(unsigned int totalP)
void setTEmission(double t)
void setLocalBinCount(size_t num, int bin)
ParticleAttrib< double > dt
double get_meanKineticEnergy()
int getNumberOfEnergyBins()
double dt_m
6x6 matrix of the moments of the beam
long long getLocalTrackStep() const
void gatherStatistics(unsigned int totalP)
void get_bounds(Vector_t< T, Dim > &rmin, Vector_t< T, Dim > &rmax) const
void set_sPos(double s)
get the spos of the primary beam
double calculateAngle(double x, double y)
long long globalTrackStep_m
if multiple TRACK commands
size_t getLocalNum() const
double dh_m
Mesh enlargement.
std::vector< size_t > bunchTotalNum_m
number of particles per bunch
void setZ(int i, double zcoo)
double calcMeanPhi()
calculate average angle of longitudinal direction of bins
int SteptoLastInj_m
this parameter records the current steps since last bunch injection it helps to inject new bunches co...
Vector_t< T, Dim > get_99Percentile() const
Vector_t< T, Dim > get_normalizedEps_99_99Percentile() const
void calcLineDensity(unsigned int nBins, std::vector< double > &lineDensity, std::pair< double, double > &meshInfo)
\method calcLineDensity()
Vector_t< T, Dim > get_rmean() const
double getChargePerParticle() const
get the macro particle charge
ParticleAttrib< Vector_t< T, Dim > > P
Vector_t< T, Dim > getGlobalMeanR()
void setSteptoLastInj(int n)
ParticleAttrib< Vector_t< T, Dim > > Eftmp
void setStepsPerTurn(int n)
Vector_t< T, Dim > get_pmean_Distribution() const
Vector_t< T, Dim > get_emit() const
ippl::BConds< Field< T, Dim >, Dim > bc_type
const PartData * getReference() const
Vector_t< T, Dim > get_95Percentile() const
VectorPair_t getEExtrema()
std::unique_ptr< std::ofstream > f_stream
void setEnergyBins(int numberOfEnergyBins)
Vector_t< T, Dim > get_centroid() const
void setGlobalTrackStep(long long n)
step in multiple TRACK commands
PartBunch(PLayout &pl, Vector_t< double, Dim > hr, Vector_t< double, Dim > rmin, Vector_t< double, Dim > rmax, std::array< bool, Dim > decomp, double Qtot)
Vector_t< double, Dim > hr_m
mesh size [m]
long long getGlobalTrackStep() const
void scatterCIC(unsigned int totalP, int iteration)
void initialize(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
ParticleAttrib< Vector_t< T, Dim > > E
double getInitialGamma() const
std::vector< size_t > bunchLocalNum_m
void updateLayout(FieldLayout_t< Dim > &fl, Mesh_t< Dim > &mesh)
Inform & print(Inform &os)
double getBeta(int i) const
FieldLayout_t< Dim > & getFieldLayout()
Vector_t< T, Dim > get_normalizedEps_95Percentile() const
void switchOffUnitlessPositions(bool use_dt_per_particle=false)
double couplingConstant_m
void setMassZeroPart(double mass)
Vector_t< T, Dim > get_normalizedEps_68Percentile() const
double getCouplingConstant() const
size_t getTotalNum() const
void calcGammas()
Compute the gammas of all bins.
void set_meshEnlargement(double dh)
void computeSelfFields(int b)
/brief used for self fields with binned distribution
double getEmissionDeltaT()
Vector_t< T, Dim > RefPartP_m
Vector_t< T, Dim > get_rprms() const
void setCouplingConstant(double c)
void setGlobalMeanR(Vector_t< T, Dim > globalMeanR)
bool getFieldSolverType() const
Return the fieldsolver type if we have a fieldsolver.
void dumpData(int iteration)
void setNumBunch(short n)
int getStepsPerTurn() const
ParticleAttrib< double > Q
double getBinGamma(int bin)
Get gamma of one bin.
Vector_t< T, Dim > get_norm_emit() const
std::unique_ptr< size_t[]> globalPartPerNode_m
ParticleAttrib< Vector_t< T, Dim > > Bf
size_t emitParticles(double eZ)
Emit particles in the given bin i.e.
CoordinateSystemTrafo toLabTrafo_m
std::unique_ptr< double[]> bingamma_m
holds the gamma of the bin
int getLastemittedBin()
the last emitted bin is always smaller or equal getNbins
double getBeta() const
The relativistic beta per particle.
double getGamma() const
The relativistic gamma per particle.
double getP() const
The constant reference momentum per particle.
KOKKOS_INLINE_FUNCTION double getM() const
The constant mass per particle.
double getE() const
The constant reference Energy per particle.
KOKKOS_INLINE_FUNCTION double getQ() const
The constant charge per particle.
void updateLayout(Layout_t &, int nghost=1)
void setParticleBC(const bc_container_type &bcs)
void addAttribute(detail::ParticleAttribBase< MemorySpace > &pa)
detail::size_type size_type
particle_position_type R
view of particle positions
std::ios_base::fmtflags FmtFlags_t
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)