@djjansse, the code files of DriftLineRKF.C AvalancheMC.C and AvalancheMicroscopic.C are for the same case, so most codes are same:
TApplication app("app", &argc, argv);
// Make a gas medium.
MediumMagboltz gas;
gas.LoadGasFile("Ar90_CH4_10_1bar.gas");
auto installdir = std::getenv("GARFIELD_INSTALL");
if (!installdir) {
std::cerr << "GARFIELD_INSTALL variable not set.\n";
return 1;
}
const std::string path = installdir;
gas.LoadIonMobility(path + "/share/Garfield/Data/IonMobility_Ar+_Ar.txt");
// Make a component with analytic electric field.
ComponentAnalyticField cmp;
cmp.SetMedium(&gas);
// Wire radius [cm]
const double rWire = 25.e-4;
// Outer radius of the tube [cm]
const double rTube = 0.71;
// Voltages
const double vWire = 1500;
const double vTube = 0.;
// Add the wire in the centre.
cmp.AddWire(0, 0, 2 * rWire, vWire, "s");
// Add the tube.
cmp.AddTube(rTube, vTube, 0);
// Make a sensor.
Sensor sensor;
sensor.AddComponent(&cmp);
sensor.AddElectrode(&cmp, "s");
const double tstep = 2.;
const double tmin = -0.5 * tstep;
const unsigned int nbins = 1000;
sensor.SetTimeWindow(tmin, tstep, nbins);
TCanvas *cDrift=new TCanvas("","",1200,1200);
ViewDrift driftview;
driftview.SetCanvas(cDrift);
TrackHeed track;
track.SetParticle("electron");
track.SetKineticEnergy(1.e11);
track.SetSensor(&sensor);
track.EnablePlotting(&driftview);
const double rTrack = 0.3;
const double x0 = rTrack;
const double y0 = -sqrt(rTube * rTube - rTrack * rTrack);
const unsigned int nTracks = 1;
for DriftLineRKF.C file, the DriftLineRKF class is used to transport electrons and ions, the codes are:
// RKF integration.
DriftLineRKF drift(&sensor);
drift.EnablePlotting(&driftview);
drift.EnableSignalCalculation();
drift.EnableIonTail();
for (unsigned int j = 0; j < nTracks; ++j) {
sensor.ClearSignal();
track.NewTrack(x0, y0, 0, 0, 0, 1, 0);
for (const auto& cluster : track.GetClusters()) {
for (const auto&electrn:cluster.electrons) {
drift.DriftElectron(electrn.x, electrn.y, electrn.z, electrn.t);
double ne,ni;
drift.GetAvalancheSize(ne,ni);
std::cout<<"ne== "<<ne<<"ni== "<<ni<<std::endl;
}
for(const auto&ion:cluster.ions)
{
drift.DriftIon(ion.x,ion.y,ion.z,ion.t);
}
}
cmp.PlotCell(cDrift);
constexpr bool twod = true;
constexpr bool drawaxis = false;
driftview.Plot(twod, drawaxis);
cDrift->Print("drift.png");
}
TCanvas* cS = new TCanvas("cS", "", 1200, 1200);
sensor.PlotSignal("s", cS);
cS->Print("signal.png");
for AvalancheMC.C file, the AvalancheMC class is used to transport electrons and ions, the codes are:
int status;
double xx,yy,zz,tt,ee,dxx,dyy,dzz;
double xx1,yy1,zz1,tt1;
for (unsigned int j = 0; j < nTracks; ++j) {
sensor.ClearSignal();
track.NewTrack(x0, y0, 0, 0, 0, 1, 0);
for (const auto& cluster : track.GetClusters()) {
for(int jj=0;jj<cluster.electrons.size();++jj)
{
xx=cluster.electrons[jj].x;
yy=cluster.electrons[jj].y;
zz=cluster.electrons[jj].z;
tt=cluster.electrons[jj].t;
mc.AvalancheElectron(xx,yy,zz,tt);
std::size_t ne,ni;
mc.GetAvalancheSize(ne,ni);
std::cout<<"ne== "<<ne<<" ||| "<<"ni== "<<ni<<std::endl;
}
for(const auto&ion:cluster.ions)
{
mc.DriftIon(ion.x,ion.y,ion.z,ion.t);
}
}
}
double x1,y1,z1,t1,x2,y2,z2,t2;
std::size_t num_tracks;
num_tracks=mc.GetNumberOfElectronEndpoints();
for(std::size_t i=0;i<num_tracks;i++)
{
mc.GetElectronEndpoint(i,x1,y1,z1,t1,x2,y2,z2,t2,status);
mc.DriftIon(x1,y1,z1,t1);
}
cmp.PlotCell(cDrift);
constexpr bool twod = true;
constexpr bool drawaxis = false;
driftview.Plot(twod, drawaxis);
cDrift->Print("drift.png");
TCanvas* cS = new TCanvas("cS", "", 1200, 1200);
sensor.PlotSignal("s", cS);
cS->Print("signal.png");
for AvalancheMicroscopic.C file, the AvalancheMicroscopic class is used to transport electrons and ions, the codes are:
AvalancheMicroscopic micro;
micro.SetSensor(&sensor);
micro.EnableSignalCalculation();
micro.EnablePlotting(&driftview);
AvalancheMC mc;
mc.SetSensor(&sensor);
mc.EnableSignalCalculation();
mc.EnablePlotting(&driftview);
for (unsigned int j = 0; j < nTracks; ++j) {
sensor.ClearSignal();
track.NewTrack(x0, y0, 0, 0, 0, 1, 0);
for (const auto& cluster : track.GetClusters()) {
for (const auto& electron : cluster.electrons) {
// micro.DriftElectron(electron.x, electron.y, electron.z, electron.t,electron.e);
micro.AvalancheElectron(electron.x, electron.y, electron.z, electron.t,electron.e);
int ne,ni;
micro.GetAvalancheSize(ne,ni);
std::cout<<"ne== "<<ne<<" ||| "<<"ni== "<<ni<<std::endl;
}
for(const auto&ion:cluster.ions)
{
mc.DriftIon(ion.x,ion.y,ion.z,ion.t);
}
}
double x1,y1,z1,t1,e1,x2,y2,z2,t2,e2;
int status;
int num_electrons=micro.GetNumberOfElectronEndpoints();
for(int ii=0;ii<num_electrons;++ii)
{
micro.GetElectronEndpoint(ii,x1,y1,z1,t1,e1,x2,y2,z2,t2,e2,status);
mc.DriftIon(x1,y1,z1,t1);
}
cmp.PlotCell(cDrift);
constexpr bool twod = true;
constexpr bool drawaxis = false;
driftview.Plot(twod, drawaxis);
cDrift->Print("drift.png");
}
TCanvas* cS = new TCanvas("cS", "", 1200, 1200);
sensor.PlotSignal("s", cS);
cS->Print("signal.png");
but the induced electric currents are different, the results have attached.