Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions xtrack/monitors/bunch_monitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// ##################################
// Bunch Monitor
//
// Author: Philipp Niedermayer
// Date: 2023-08-14
// Edit: 2024-06-12
// ##################################


#ifndef XTRACK_BEAM_SIZE_MONITOR_H
#define XTRACK_BEAM_SIZE_MONITOR_H

#if !defined( C_LIGHT )
#define C_LIGHT ( 299792458.0 )
#endif /* !defined( C_LIGHT ) */

/*gpufun*/
void BeamSizeMonitor_track_local_particle(BeamSizeMonitorData el, LocalParticle* part0){

// get parameters
int64_t const start_at_turn = BeamSizeMonitorData_get_start_at_turn(el);
int64_t particle_id_start = BeamSizeMonitorData_get_particle_id_start(el);
int64_t particle_id_stop = particle_id_start + BeamSizeMonitorData_get_num_particles(el);
// Should we do explicit casting to float (?)
int64_t const harmonic = BeamSizeMonitorData_get_harmonic(el);
double const frev = BeamSizeMonitorData_get_frev(el);

BeamSizeMonitorRecord record = BeamSizeMonitorData_getp_data(el);

int64_t max_slot = BeamSizeMonitorRecord_len_count(record);

//start_per_particle_block(part0->part)

int64_t particle_id = LocalParticle_get_particle_id(part);
if (particle_id_stop < 0 || (particle_id_start <= particle_id && particle_id < particle_id_stop)){

// zeta is the absolute path length deviation from the reference particle: zeta = (s - beta0*c*t)
// but without limits, i.e. it can exceed the circumference (for coasting beams)
// as the particle falls behind or overtakes the reference particle
double const zeta = LocalParticle_get_zeta(part);
double const at_turn = LocalParticle_get_at_turn(part);
double const beta0 = LocalParticle_get_beta0(part);

// compute sample index
int64_t slot = round( harmonic * ( (at_turn-start_at_turn) - frev * zeta/beta0/C_LIGHT ));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking maybe you could use the circumference line.get_length() instead to simplify the slot calculation.
In principle, the zeta correction is not required if the monitor is only used for bunched beams and h≥1. But I think it's good to keep to properly handle RF gymnastics like de- and re-bunching.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, maybe it could be useful in the future.


if (slot >= 0 && slot < max_slot){

double delta = LocalParticle_get_delta(part);

/*gpuglmem*/ double* count = BeamSizeMonitorRecord_getp1_count(record, slot);
atomicAdd(count, 1);

/*gpuglmem*/ double * zeta_sum = BeamSizeMonitorRecord_getp1_zeta_sum(record, slot);
atomicAdd(zeta_sum, zeta);

/*gpuglmem*/ double * delta_sum = BeamSizeMonitorRecord_getp1_delta_sum(record, slot);
atomicAdd(delta_sum, delta);

/*gpuglmem*/ double * zeta2_sum = BeamSizeMonitorRecord_getp1_zeta2_sum(record, slot);
atomicAdd(zeta2_sum, zeta*zeta);

/*gpuglmem*/ double * delta2_sum = BeamSizeMonitorRecord_getp1_delta2_sum(record, slot);
atomicAdd(delta2_sum, delta*delta);
}
}
//end_per_particle_block
}

#endif

71 changes: 71 additions & 0 deletions xtrack/monitors/bunch_monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// ##################################
// Bunch Monitor
//
// Author: Philipp Niedermayer
// Date: 2023-08-14
// Edit: 2024-06-12
// ##################################


#ifndef XTRACK_BEAM_SIZE_MONITOR_H
#define XTRACK_BEAM_SIZE_MONITOR_H

#if !defined( C_LIGHT )
#define C_LIGHT ( 299792458.0 )
#endif /* !defined( C_LIGHT ) */

/*gpufun*/
void BeamSizeMonitor_track_local_particle(BeamSizeMonitorData el, LocalParticle* part0){

// get parameters
int64_t const start_at_turn = BeamSizeMonitorData_get_start_at_turn(el);
int64_t particle_id_start = BeamSizeMonitorData_get_particle_id_start(el);
int64_t particle_id_stop = particle_id_start + BeamSizeMonitorData_get_num_particles(el);
// Should we do explicit casting to float (?)
int64_t const harmonic = BeamSizeMonitorData_get_harmonic(el);
double const frev = BeamSizeMonitorData_get_frev(el);

BeamSizeMonitorRecord record = BeamSizeMonitorData_getp_data(el);

int64_t max_slot = BeamSizeMonitorRecord_len_count(record);

//start_per_particle_block(part0->part)

int64_t particle_id = LocalParticle_get_particle_id(part);
if (particle_id_stop < 0 || (particle_id_start <= particle_id && particle_id < particle_id_stop)){

// zeta is the absolute path length deviation from the reference particle: zeta = (s - beta0*c*t)
// but without limits, i.e. it can exceed the circumference (for coasting beams)
// as the particle falls behind or overtakes the reference particle
double const zeta = LocalParticle_get_zeta(part);
double const at_turn = LocalParticle_get_at_turn(part);
double const beta0 = LocalParticle_get_beta0(part);

// compute sample index
int64_t slot = round( harmonic * ( (at_turn-start_at_turn) - frev * zeta/beta0/C_LIGHT ));

if (slot >= 0 && slot < max_slot){

double delta = LocalParticle_get_delta(part);

/*gpuglmem*/ double* count = BeamSizeMonitorRecord_getp1_count(record, slot);
atomicAdd(count, 1);

/*gpuglmem*/ double * zeta_sum = BeamSizeMonitorRecord_getp1_zeta_sum(record, slot);
atomicAdd(zeta_sum, zeta);

/*gpuglmem*/ double * delta_sum = BeamSizeMonitorRecord_getp1_delta_sum(record, slot);
atomicAdd(delta_sum, delta);

/*gpuglmem*/ double * zeta2_sum = BeamSizeMonitorRecord_getp1_zeta2_sum(record, slot);
atomicAdd(zeta2_sum, zeta*zeta);

/*gpuglmem*/ double * delta2_sum = BeamSizeMonitorRecord_getp1_delta2_sum(record, slot);
atomicAdd(delta2_sum, delta*delta);
}
}
//end_per_particle_block
}

#endif