#include #include #include #include #include "Garfield/MediumMagboltz.hh" #include "Garfield/ComponentAnsys123.hh" #include "Garfield/Sensor.hh" #include "Garfield/TrackSrim.hh" #include "Garfield/TrackTrim.hh" #include "Garfield/Plotting.hh" #include "Garfield/DriftLineRKF.hh" #include "Garfield/ViewField.hh" #include "Garfield/ViewSignal.hh" #include "Garfield/ViewFEMesh.hh" #include "Garfield/Random.hh" #include "Garfield/AvalancheMicroscopic.hh" using namespace Garfield; using namespace std; int main(int argc, char *argv[]) { TApplication app("app", &argc, argv); const string path = "inputfile/"; // Set the gas mixture. MediumMagboltz gas; gas.SetTemperature(293.15); gas.SetPressure(760.); gas.SetComposition("Ar", 0.94, "CO2", 0.03, "H2O", 0.03, "O2", 20.9, "N2", 78.1); gas.Initialise(true); gas.LoadGasFile(path + "gas_2atm_10-10000-nE20.gas"); const string ionpath = std::getenv("GARFIELD_INSTALL"); gas.LoadIonMobility(ionpath + "/share/Garfield/Data/IonMobility_Ar+_Ar.txt"); // Load the main field map. ComponentAnsys123 fm; const string fieldpath = "fieldMap/"; fm.Initialise(fieldpath + "ELIST.lis", fieldpath + "NLIST.lis", fieldpath + "MPLIST.lis", fieldpath + "PRNSOL.lis", "micron"); fm.EnableMirrorPeriodicityX(); // fm.EnableMirrorPeriodicityY(); fm.PrintRange(); double x0, y0, z0, x1, y1, z1; fm.GetBoundingBox(x0, y0, z0, x1, y1, z1); cout << " z0= " << z0 << " z1= " << z1 << '\n'; // Associate the gas with the corresponding field map material. fm.SetGas(&gas); fm.PrintMaterials(); // Load the weighting field maps. fm.SetWeightingField(fieldpath + "weight1.lis", "anode"); const double pitch = 0.014; // cm // View field ViewField fieldView; constexpr bool plotField = true; constexpr bool plotWeightingField = true; constexpr bool plotOrdinField = true; if (plotField) { fieldView.SetComponent(&fm); fieldView.SetPlaneXZ(); fieldView.SetArea(-0.5 * pitch, -0.02, 0.5 * pitch, 0.02); if (plotWeightingField) { TCanvas *cf1 = new TCanvas("cf1", " ", 800, 800); cf1->SetLeftMargin(0.16); fieldView.SetCanvas(cf1); // 'v':eletric potential,“e”:eletric field fieldView.PlotContourWeightingField("anode", "e"); } if (plotOrdinField) { TCanvas *cf2 = new TCanvas("cf2", " ", 800, 800); cf2->SetLeftMargin(0.16); fieldView.SetCanvas(cf2); fieldView.PlotContour("e"); } } // Assemble a sensor. Sensor sensor; sensor.AddComponent(&fm); sensor.AddElectrode(&fm, "anode"); // sensor.SetArea(-5 * pitch, -5 * pitch * sqrt(3), z0, 5 * pitch, 5 * pitch * sqrt(3), z1); sensor.ClearSignal(); // Set the time window [ns] for the signal calculation. const double tstep = 0.01; const double tmin = -0.5 * tstep; const unsigned int nTimeBins = 50000; sensor.SetTimeWindow(tmin, tstep, nTimeBins); // RKF integration. DriftLineRKF drift; drift.SetSensor(&sensor); drift.SetMaximumStepSize(5.e-4); // drift.SetGainFluctuationsPolya(0., 20000.); drift.EnableIonTail(); // drift.UseWeightingPotential(true); drift.EnableSignalCalculation(); // Microscopic simulation. AvalancheMicroscopic aval; aval.SetSensor(&sensor); aval.EnableSignalCalculation(); const double x0_cm = 0; const double y0_cm = 0; const double z0_cm = -0.001; const double t0 = 0.; const double e0 = 1; const double dx0 = 0.; const double dy0 = 0; const double dz0 = 1.; // const bool microscopic = true; const bool microscopic = false; if (microscopic) { aval.AvalancheElectron(x0_cm, y0_cm, z0_cm, t0, e0, dx0, dy0, dz0); auto np = aval.GetNumberOfElectronEndpoints(); std::cout << np << " electrons\n"; for (unsigned int i = 0; i < np; ++i) { double x1, y1, z1, t1, e1; double x2, y2, z2, t2, e2; int status = 0; aval.GetElectronEndpoint(i, x1, y1, z1, t1, e1, x2, y2, z2, t2, e2, status); drift.DriftIon(x1, y1, z1, t1); } } else { drift.DriftElectron(x0_cm, y0_cm, z0_cm, 0.); double ne = 0., ni = 0.; drift.GetAvalancheSize(ne, ni); std::cout << ne << " electrons\n"; } ofstream outfile; outfile.open("signal.txt",std::ios::out); outfile << "#Time Total Electrons Ions\n"; for (unsigned int j = 0; j < nTimeBins; ++j) { double t = (j + 0.5) * tstep; outfile << t << " " << sensor.GetSignal("anode", j) << " " << sensor.GetIonSignal("anode", j) << " " << sensor.GetElectronSignal("anode", j) << "\n"; } app.Run(true); }