CbmRoot
Loading...
Searching...
No Matches
CbmRadDamage.cxx
Go to the documentation of this file.
1/* Copyright (C) 2011-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer], Florian Uhlig */
4
9#include "CbmRadDamage.h"
10
11#include <Logger.h> // for LOG
12
13#include <TMath.h> // for Exp, Qe, K
14#include <TMathBase.h> // for Abs
15#include <TString.h> // for TString, operator+, operator<<
16
17#include <stdlib.h> // for getenv
18
19
20// ===== Constructor ==================================================
22 : niel_neutron()
23 , niel_proton()
24 , niel_pion()
25 , niel_electron()
26 , fIAlpha(4.e-17)
27 , fEGap0(1.166)
28 , fEGapAlpha(4.73e-4)
29 , fEGapBeta(636.)
30 , fNeff0(9.0e11)
31 , fNeffC(2.5e-14)
32 , fNeffGc(1.5e-2)
33 , fEpsilon(1.04e-12)
34{
35 Init();
36}
37// ========================================================================
38
39
40// ===== Destructor ===================================================
42// ========================================================================
43
44
45// ===== Get leakage current ==========================================
46Double_t CbmRadDamage::GetLeakageCurrent(Double_t fluence, Double_t volume, Double_t temperature)
47{
48
49 // --- Boltzmann constant in ev/K
50 Double_t kB = TMath::K() / TMath::Qe();
51
52 // --- Leakage current at room temperature (293 K)
53 Double_t i20 = fIAlpha * fluence * volume;
54
55 // --- Gap energy at given temperature
56 Double_t eGap = fEGap0 - fEGapAlpha * temperature * temperature / (temperature + fEGapBeta);
57
58 // --- Leakage current at given temperature
59 Double_t exponent = -1. * eGap / 2. / kB * (1. / temperature - 1. / 293.);
60 Double_t iLeak = i20 * temperature * temperature / 85849. * TMath::Exp(exponent);
61
62 return iLeak;
63}
64// ========================================================================
65
66
67// ===== Get NIEL factor ==============================================
68Double_t CbmRadDamage::GetNiel(Int_t type, Double_t energy)
69{
70
71 // Convert energy to MeV like in table
72 energy = energy * 1000.;
73
74 std::map<Double_t, Double_t>* table = nullptr;
75 Int_t atype = TMath::Abs(type);
76
77 // Select table according to particle type
78 switch (atype) {
79 case 2112: table = &niel_neutron; break; // neutrons
80 case 2212: table = &niel_proton; break; // protons
81 case 211: table = &niel_pion; break; // pions
82 case 11: table = &niel_electron; break; // electrons
83 default: table = nullptr;
84 }
85
86 // Return zero for unknown particles
87 if (!table) return 0.;
88
89 // First table entry above selected energy
90 std::map<Double_t, Double_t>::iterator it = table->upper_bound(energy);
91
92 // Return zero if below lower limit
93 if (it == table->begin()) {
94 //LOG(warn) << "-I- Below table limit: " << atype << " " << energy;
95 return 0.;
96 }
97
98 // Return asymptotic value if above upper limit
99 if (it == table->end()) {
100 //LOG(warn) << "-I- Above table limit: " << atype << " " << energy;
101 switch (atype) {
102 case 2112: return 0.44; break;
103 case 2212: return 0.50; break;
104 case 211: return 0.38; break;
105 case 11: return 0.08; break;
106 default: return 0.00; break;
107 }
108 }
109
110 // Interpolate within table values
111 Double_t e2 = (*it).first;
112 Double_t v2 = (*it).second;
113 it--;
114 Double_t e1 = (*it).first;
115 Double_t v1 = (*it).second;
116
117 Double_t v = v1 + (v2 - v1) * (energy - e1) / (e2 - e1);
118
119 return v;
120}
121// ========================================================================
122
123
124// ===== Get full depletion voltage ===================================
125Double_t CbmRadDamage::GetVfd(Double_t fluence, Double_t d)
126{
127
128 // --- Calculate effective doping concentration at given fluence
129 Double_t corr1 = 0.7 * fNeff0 * (1. - TMath::Exp(-1. * fNeffC * fluence));
130 Double_t corr2 = fNeffGc * fluence;
131 Double_t nEff = fNeff0 - corr1 - corr2;
132
133 // --- Calculate full depletion voltage from doping concentration
134 Double_t vfd = TMath::Qe() * nEff * d * d / 2. / fEpsilon;
135
136 return vfd;
137}
138// ========================================================================
139
140
141// ===== Private method Init ==========================================
143{
144
145 // --- Read NIEL tables
146 ReadData("niel_neutrons.dat", niel_neutron);
147 ReadData("niel_protons.dat", niel_proton);
148 ReadData("niel_pions.dat", niel_pion);
149 ReadData("niel_electrons.dat", niel_electron);
150
151
152 // --- Proportionality constant of leakage current and fluence
153 // --- for Silicon at room temperature
154 // --- Numerical value provided by S. Chatterji
155 fIAlpha = 4.e-17; // [A/cm]
156
157
158 // --- Constants for temperature dependence of leakage current
159 // --- Values are for Silicon
160 // --- Numerical values provided by S. Chatterji
161 fEGap0 = 1.166; // Gap energy [eV] at T = 0K
162 fEGapAlpha = 4.73e-4; // [ev/K]
163 fEGapBeta = 636.; // [K]
164
165
166 // --- Constants for effective doping concentration
167 // --- Values are for Silicon
168 // --- Numerical values provided by S. Chatterji
169 fNeff0 = 9.0e11; // Doping concentration without irradiation [cm^-3];
170 fNeffC = 2.5e-14; // [cm^2]
171 fNeffGc = 1.5e-2; // [1/cm]
172
173
174 // --- Permittivivity of Silicon
175 fEpsilon = 1.04e-12; // [F/cm]
176}
177// ========================================================================
178
179
180// ===== Private method ReadData ======================================
181void CbmRadDamage::ReadData(const char* file, std::map<Double_t, Double_t>& table)
182{
183
184 TString wrkdir = getenv("VMCWORKDIR");
185 TString fileName = wrkdir + "/input/" + TString(file);
186 LOG(info) << "Reading " << fileName;
187
188 std::ifstream* data = new std::ifstream(fileName.Data());
189 if (!data->is_open()) { LOG(fatal) << "Error when reading from file!"; }
190
191 Double_t e = 0.;
192 Double_t v = 0.;
193 Int_t nEntries = 0;
194
195 *data >> e >> v;
196 while (!data->eof()) {
197 table[e] = v;
198 nEntries++;
199 *data >> e >> v;
200 }
201
202 data->close();
203 delete data;
204
205 std::map<Double_t, Double_t>::iterator it1 = table.begin();
206 std::map<Double_t, Double_t>::iterator it2 = table.end();
207 it2--;
208
209 LOG(info) << nEntries << " values read; energy range " << (*it1).first << " to " << (*it2).first << " MeV; map size "
210 << table.size();
211}
212// ========================================================================
213
214
ClassImp(CbmConverterManager)
fscal v[fmask::Size]
Definition KfSimdPseudo.h:4
Tool class to calculate the non-ionising radiation damage.
std::map< Double_t, Double_t > niel_electron
Double_t fNeff0
Double_t fEpsilon
Double_t fEGapBeta
Double_t GetVfd(Double_t fluence, Double_t d)
Double_t fEGapAlpha
Double_t fIAlpha
std::map< Double_t, Double_t > niel_neutron
Double_t fNeffGc
std::map< Double_t, Double_t > niel_proton
Double_t GetNiel(Int_t type, Double_t energy)
void ReadData(const char *file, std::map< Double_t, Double_t > &map)
virtual ~CbmRadDamage()
std::map< Double_t, Double_t > niel_pion
Double_t GetLeakageCurrent(Double_t fluence, Double_t volume, Double_t temperatur)
Double_t fEGap0
Double_t fNeffC