Hi!
Thanks for your reply. I recalculated the positions within each cluster on the initial path formed by TrackSrim
.Afterwards, I performed AvalancheElectronon
of every electron in the clusters. This is the code I used to simulate the avalanche:
const double rTrack =3.0;
const double projectilex= rTrack;
const double projectiley= sqrt(rTube * rTube - rTrack * rTrack);
const double projectilez= 0.;
const double projectiledx=0.;
const double projectiledy=-1.;
const double projectiledz=0.;
const double projectileT=0.;
const unsigned int nTracks = 1;
for (unsigned int n = 0; n < nTracks; ++n) {
const bool notnewtrack= !tr.NewTrack(projectilex, projectiley, projectilez, projectileT, projectiledx, projectiledy, projectiledz);
if (notnewtrack) {
std::cerr << "Generating clusters failed; skipping this particle's track.\n";
continue;
}
unsigned int netot = 0;
while (true) {
int ne = 0;
double xc, yc, zc, tc, ec, ekin;
const bool done = tr.GetCluster(xc, yc, zc, tc, ne, ec, ekin);
if(done) {
informationofclusters.push_back({xc, yc, zc, tc, ne, ec,ekin});
netot += ne;
}
if (!done) {
std::cout << informationofclusters.size() << " clusters infornation done.\n";
break;
}
}
double MLi=6.9405*1.66053886e-27;
double Mev=1.602176565e-13;
for(int i=0;i<informationofclusters.size()-1;++i){
double speedofprojectile=sqrt(2*informationofclusters[i+1][6]*Mev/MLi)/1.e7;
double distanceofclusters=sqrt(pow(informationofclusters[i+1][0]-informationofclusters[i][0],2) \
+pow(informationofclusters[i+1][1]-informationofclusters[i][1],2) \
+pow(informationofclusters[i+1][2]-informationofclusters[i][2],2)); //Calculate the distance between two clusters
double duation=distanceofclusters/speedofprojectile; //Calculate the transport time of incident ions between two clusters
informationofclusters[i+1][3]=informationofclusters[i][3]+duation; //Adjust the generation time of the i+1th cluster by adding transport time to the i-th cluster time
}
omp_set_num_threads(60);
#pragma omp parallel for
//for(int j=60; j<61; ++j){
for(int j=0; j<informationofclusters.size( ); ++j){ // informationofclusters.size()
double avalancheelectrons=0;
double avalancheions=0;
AvalancheMicroscopic driftelectron;
driftelectron.SetSensor(&sensor);
driftelectron.EnableSignalCalculation();
driftelectron.EnablePlotting(&driftView);
AvalancheMC driftion;
driftion.SetSensor(&sensor);
driftion.SetDistanceSteps(2.e-4);
driftion.EnableSignalCalculation();
AvalancheMC driftprimaryion;
driftprimaryion.SetSensor(&sensor);
driftprimaryion.SetDistanceSteps(2.e-4);
driftprimaryion.EnableSignalCalculation();
for (int k = 0; k <informationofclusters[j][4]; ++k) {
std::cout << k+1<< "/" << informationofclusters[j][4] << " Transport of electron in " \
<< j+1<< "/" << informationofclusters.size() << " cluster begin:\n";
std::cout << "AvalancheElectron begin; ";
//#pragma omp critical
{
driftelectron.AvalancheElectron(informationofclusters[j][0], informationofclusters[j][1], \
informationofclusters[j][2], informationofclusters[j][3], 0.00001, 0., 0., 0.);
}
int avalanchee,avalanchei;
driftelectron.GetAvalancheSize(avalanchee,avalanchei);
std::cout << "numberofavalancheelectron is " <<avalanchee <<" " << "numberofavalancheion is " <<avalanchei <<"\n";
avalancheelectrons=avalancheelectrons+avalanchee;
avalancheions=avalancheions+avalanchei;
std::cout << "AvalancheElectron end\n";
std::cout << k+1<< "/" << informationofclusters[j][4] << " Transport of electron in "\
<< j+1<< "/" << informationofclusters.size() << " cluster is done.\n";
}
avalancheelectrons=avalancheelectrons/informationofclusters[j][4];
avalancheions=avalancheions/informationofclusters[j][4];
printavalancheinclusters(j,informationofclusters[j][0],informationofclusters[j][1],informationofclusters[j][2],\
informationofclusters[j][3],informationofclusters[j][6],avalancheelectrons,avalancheions,name);
std::cout << "Ion tranport in Avalanche begin; ";
int np=0;
np=driftelectron.GetNumberOfElectronEndpoints();
std::cout << "number of Ions in last electron drift line "<< np <<"\n";
for(int m=0; m<np; ++m){
double xestart, yestart, zestart, testart, eestart;
double xeend, yeend, zeend, teend, eeend;
int status;
driftelectron.GetElectronEndpoint(m, xestart, yestart, zestart, testart, eestart, xeend, yeend, zeend, teend, eeend, status);
//#pragma omp critical
{
driftion.SetIonSignalScalingFactor(informationofclusters[j][4]);
driftion.DriftIon(xestart, yestart, zestart, testart);
}
}
std::cout << "Ion tranport in Avalanche end\n";
//#pragma omp critical
{
driftprimaryion.SetIonSignalScalingFactor(informationofclusters[j][4]);
driftprimaryion.DriftIon(informationofclusters[j][0], informationofclusters[j][1], \
informationofclusters[j][2], informationofclusters[j][3]);
}
}
After reading the UserGuide, I also believe that the setting of this value should not have such a huge impact on the results.
Are you sure that the electrons reach such a high value in your simulation?
I’m not sure about that. I just want to set a sufficiently large value. My working voltage is 1100V, anode wire diameter is 30μm, Drifttube diameter 3.5cm.
According to the UserGuide, for electron avalanches, a range of 40-200eV is generally sufficient. However, when I set it to 80eV, the output signal is as follows
SetMaxElectronEnergy(80)
This looks like only a portion of the electrons have undergone avalanche calculations.