Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VLEPTSModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26#include "G4VLEPTSModel.hh"
27
29
30//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
31G4VLEPTSModel::G4VLEPTSModel(const G4String& modelName) : G4VEmModel(modelName),isInitialised(false)
32{
34
36
37 verboseLevel = 0;
38}
39
40
41//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
43{
44
48 }
49}
50
51
52//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
54{
55 theLowestEnergyLimit = 0.5*CLHEP::eV;
56 theHighestEnergyLimit = 1.0*CLHEP::MeV;
57 //t theHighestEnergyLimit = 15.0*CLHEP::MeV;
60 theNumbBinTable = 100;
61
62}
63
64
65
66//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69 G4double kineticEnergy )
70{
71 G4double MeanFreePath;
72
73 if( verboseLevel >= 3 ) G4cout << aMaterial->GetIndex() << " G4VLEPTSModel::GetMeanFreePath " << kineticEnergy << " > " << theHighestEnergyLimit << " < " << theLowestEnergyLimit << G4endl;
74 if (kineticEnergy > theHighestEnergyLimit || kineticEnergy < theLowestEnergyLimit)
75 MeanFreePath = DBL_MAX;
76 else
77 MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->Value(kineticEnergy);
78
79 return MeanFreePath;
80}
81
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
85{
86 //CHECK IF PATH VARIABLE IS DEFINED
87 const char* path = G4FindDataDir("G4LEDATA");
88 if( !path ) {
89 G4Exception("G4VLEPTSModel",
90 "",
92 "variable G4LEDATA not defined");
93 }
94
95 // Build microscopic cross section table and mean free path table
96
97 G4String aParticleName = aParticleType.GetParticleName();
98
102 }
103
105
106 //LOOP TO MATERIALS IN GEOMETRY
107 const G4MaterialTable * materialTable = G4Material::GetMaterialTable() ;
108 std::vector<G4Material*>::const_iterator matite;
109 for( matite = materialTable->begin(); matite != materialTable->end(); matite++ ) {
110 const G4Material * aMaterial = (*matite);
111 G4String mateName = aMaterial->GetName();
112
113 //READ PARAMETERS FOR THIS MATERIAL
114 std::string dirName = std::string(path) + "/lepts/";
115 std::string fnParam = dirName + mateName + "." + aParticleName + ".param.dat";
116 std::string baseName = std::string(path) + "/lepts/" + mateName + "." + aParticleName;
117 G4bool bData = ReadParam( fnParam, aMaterial );
118 if( !bData ) continue; // MATERIAL NOT EXISTING, DO NOT READ OTHER FILES
119
120 //READ INTEGRAL CROSS SECTION FOR THIS MATERIAL
121 std::string fnIXS = baseName + ".IXS.dat";
122
123 std::map< G4int, std::vector<G4double> > integralXS = ReadIXS(fnIXS, aMaterial);
124 if( verboseLevel >= 2 ) G4cout << GetName() << " : " << theXSType << " " << mateName << " INTEGRALXS " << integralXS.size() << G4endl;
125
126 if( integralXS.size() == 0 ) {
127 G4cerr << " Integral cross sections will be set to 0. for material " << mateName << G4endl;
129 ptrVector->PutValue(0, DBL_MAX);
130 ptrVector->PutValue(1, DBL_MAX);
131
132 std::size_t matIdx = aMaterial->GetIndex();
133 theMeanFreePathTable->insertAt( matIdx , ptrVector ) ;
134
135 } else {
136
137 if( verboseLevel >= 2 ) {
138 std::map< G4int, std::vector<G4double> >::const_iterator itei;
139 for( itei = integralXS.begin(); itei != integralXS.end(); itei++ ){
140 G4cout << GetName() << " : " << (*itei).first << " INTEGRALXS NDATA " << (*itei).second.size() << G4endl;
141 }
142 }
143
144 BuildMeanFreePathTable( aMaterial, integralXS );
145
146 std::string fnDXS = baseName + ".DXS.dat";
147 std::string fnRMT = baseName + ".RMT.dat";
148 std::string fnEloss = baseName + ".Eloss.dat";
149 std::string fnEloss2 = baseName + ".Eloss2.dat";
150
151 theDiffXS[aMaterial] = new G4LEPTSDiffXS(fnDXS);
152 if( !theDiffXS[aMaterial]->IsFileFound() ) {
153 G4Exception("G4VLEPTSModel::BuildPhysicsTable",
154 "",
156 (G4String("File not found :" + fnDXS).c_str()));
157 }
158
159 theRMTDistr[aMaterial] = new G4LEPTSDistribution();
160 theRMTDistr[aMaterial]->ReadFile(fnRMT);
161
162 theElostDistr[aMaterial] = new G4LEPTSElossDistr(fnEloss);
163 if( !theElostDistr[aMaterial]->IsFileFound() ) {
164 G4Exception("G4VLEPTSModel::BuildPhysicsTable",
165 "",
167 (G4String("File not found :" + fnEloss).c_str()));
168 }
169 }
170
171 }
172
173}
174
175void G4VLEPTSModel::BuildMeanFreePathTable( const G4Material* aMaterial, std::map< G4int, std::vector<G4double> >& integralXS )
176{
177 G4double LowEdgeEnergy, fValue;
178
179 //BUILD MEAN FREE PATH TABLE FROM INTEGRAL CROSS SECTION
180 std::size_t matIdx = aMaterial->GetIndex();
182
183 for (G4int ii=0; ii < theNumbBinTable; ++ii) {
184 LowEdgeEnergy = ptrVector->Energy(ii);
185 if( verboseLevel >= 2 ) G4cout << GetName() << " " << ii << " Energy " << LowEdgeEnergy << " > " << theLowestEnergyLimit << " < " << theHighestEnergyLimit << G4endl;
186 //- fValue = ComputeMFP(LowEdgeEnergy, material, aParticleName);
187 fValue = 0.;
188 if( LowEdgeEnergy >= theLowestEnergyLimit &&
189 LowEdgeEnergy <= theHighestEnergyLimit) {
190 G4double NbOfMoleculesPerVolume = aMaterial->GetDensity()/theMolecularMass[aMaterial]*CLHEP::Avogadro;
191
192 G4double SIGMA = 0. ;
193 //- for ( std::size_t elm=0 ; elm < aMaterial->GetNumberOfElements() ; elm++ ) {
194 G4double crossSection = 0.;
195
196 G4double eVEnergy = LowEdgeEnergy/CLHEP::eV;
197
198 //- if( verboseLevel >= 2 ) G4cout << " eVEnergy " << eVEnergy << " LowEdgeE " << LowEdgeEnergy << " " << integralXS[theXSType][1] << G4endl;
199
200 if(eVEnergy < integralXS[0][1] ) {
201 crossSection = 0.;
202 } else {
203 G4int Bin = 0; // locate bin
204 G4double aa, bb;
205 for( G4int jj=1; jj<theNXSdat[aMaterial]; jj++) { // Extrapolate for E > Emax !!!
206 if( verboseLevel >= 3 ) G4cout << " GET BIN " << jj << " "<< eVEnergy << " > " << integralXS[0][jj] << G4endl;
207 if( eVEnergy > integralXS[0][jj]) {
208 Bin = jj;
209 } else {
210 break;
211 }
212 }
213 aa = integralXS[0][Bin];
214 bb = integralXS[0][Bin+1];
215 crossSection = (integralXS[theXSType][Bin] + (integralXS[theXSType][Bin+1]-integralXS[theXSType][Bin])/(bb-aa)*(eVEnergy-aa) ) * 1.e-16*CLHEP::cm2;
216
217 if( verboseLevel >= 3 ) G4cout << " crossSection " << crossSection << " " <<integralXS[theXSType][Bin] << " + " << (integralXS[theXSType][Bin+1]-integralXS[theXSType][Bin]) << " / " << (bb-aa) << " *" << (eVEnergy-aa) << " * " << 1.e-16*CLHEP::cm2 << G4endl;;
218
219 // SIGMA += NbOfAtomsPerVolume[elm] * crossSection;
220 SIGMA = NbOfMoleculesPerVolume * crossSection;
221 if( verboseLevel >= 2 ) G4cout << GetName() << " ADDING SIGMA " << SIGMA << " NAtoms " << NbOfMoleculesPerVolume
222 << " Bin " << Bin << " TOTAL " << aa << " " << bb
223 << " XS " << integralXS[theXSType][Bin] << " " << integralXS[theXSType][Bin+1] << G4endl;
224 }
225
226 //-}
227
228 fValue = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
229 }
230
231 ptrVector->PutValue(ii, fValue);
232 if( verboseLevel >= 2 ) G4cout << GetName() << " BUILDXS " << ii << " : " << LowEdgeEnergy << " = " << fValue << G4endl;
233 }
234
235 theMeanFreePathTable->insertAt( matIdx , ptrVector ) ;
236}
237
238
239//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
241{
242 G4double x;
243
244 if( e < 10001) {
245 x = theDiffXS[aMaterial]->SampleAngleMT(e, el);
246 }
247 else {
248 G4double Ei = e; //incidente
249 G4double Ed = e -el; //dispersado
250
251 G4double Pi = std::sqrt( std::pow( (Ei/27.2/137),2) +2*Ei/27.2); //incidente
252 G4double Pd = std::sqrt( std::pow( (Ed/27.2/137),2) +2*Ed/27.2); //dispersado
253
254 G4double Kmin = Pi - Pd;
255 G4double Kmax = Pi + Pd;
256
257 G4double KR = theRMTDistr[aMaterial]->Sample(Kmin, Kmax); //sorteo mom. transf.
258
259 G4double co = (Pi*Pi + Pd*Pd - KR*KR) / (2*Pi*Pd); //cos ang. disp.
260 if( co > 1. ) co = 1.;
261 x = std::acos(co); //*360/twopi; //ang. dispers.
262 }
263 return(x);
264}
265
266//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
268
269 G4double x = SampleAngle(aMaterial, e, el);
270
271 G4double cosTeta = std::cos(x); //*twopi/360.0);
272 G4double sinTeta = std::sqrt(1.0-cosTeta*cosTeta);
273 G4double Phi = CLHEP::twopi * G4UniformRand() ;
274 G4double dirx = sinTeta*std::cos(Phi) , diry = sinTeta*std::sin(Phi) , dirz = cosTeta ;
275
276 G4ThreeVector P1Dir(dirx, diry, dirz);
277#ifdef DEBUG_LEPTS
278 if( verboseLevel >= 2 ) G4cout << " G4VLEPTSModel::SampleNewDirection " <<P1Dir << G4endl;
279#endif
280 P1Dir.rotateUz(P0Dir);
281#ifdef DEBUG_LEPTS
282 if( verboseLevel >= 2 ) G4cout << " G4VLEPTSModel::SampleNewDirection rotated " <<P1Dir << " " << P0Dir << G4endl;
283#endif
284
285 return(P1Dir);
286}
287
288
289//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
291{
292 G4double cosTeta = std::cos(x); //*twopi/360.0);
293 G4double sinTeta = std::sqrt(1.0-cosTeta*cosTeta);
294 G4double Phi = CLHEP::twopi * G4UniformRand() ;
295 G4double dirx = sinTeta*std::cos(Phi) , diry = sinTeta*std::sin(Phi) , dirz = cosTeta ;
296
297 G4ThreeVector P1Dir( dirx,diry,dirz );
298 P1Dir.rotateUz(P0Dir);
299
300 return(P1Dir);
301}
302
303
304//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
306{
307 G4double el;
308 el = theElostDistr[aMaterial]->Sample(eMin/CLHEP::eV, eMax/CLHEP::eV)*CLHEP::eV;
309
310#ifdef DEBUG_LEPTS
311 if( verboseLevel >= 2 ) G4cout << aMaterial->GetName() <<"SampleEnergyLoss/eV " << el/CLHEP::eV << " eMax/eV " << eMax/CLHEP::eV << " "
312 << " " << GetName() << G4endl;
313#endif
314 return el;
315}
316
317
318//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
320{
321 std::ifstream fin(fnParam);
322 if (!fin.is_open()) {
323 G4Exception("G4VLEPTSModel::ReadParam",
324 "",
326 (G4String("File not found: ")+ fnParam).c_str());
327 return false;
328 }
329
330 G4double IonisPot, IonisPotInt;
331
332 fin >> IonisPot >> IonisPotInt;
333 if( verboseLevel >= 1 ) G4cout << "Read param (" << fnParam << ")\t IonisPot: " << IonisPot
334 << " IonisPotInt: " << IonisPotInt << G4endl;
335
336 theIonisPot[aMaterial] = IonisPot * CLHEP::eV;
337 theIonisPotInt[aMaterial] = IonisPotInt * CLHEP::eV;
338
339 G4double MolecularMass = 0;
340 G4int nelem = (G4int)aMaterial->GetNumberOfElements();
341 const G4int* atomsV = aMaterial->GetAtomsVector();
342 for( G4int ii = 0; ii < nelem; ++ii ) {
343 MolecularMass += aMaterial->GetElement(ii)->GetA()*atomsV[ii]/CLHEP::g;
344 // G4cout << " MMASS1 " << mmass/CLHEP::g << " " << aMaterial->GetElement(ii)->GetName() << " " << aMaterial->GetElement(ii)->GetA()/CLHEP::g << G4endl;
345 }
346 // G4cout << " MMASS " << MolecularMass << " " << MolecularMass*CLHEP::g << " ME " << mmass << " " << mmass/CLHEP::g << G4endl;
347 theMolecularMass[aMaterial] = MolecularMass* CLHEP::g/CLHEP::mole;
348 // theMolecularMass[aMaterial] = aMaterial->GetMassOfMolecule()*CLHEP::Avogadro; // Material mixtures do not calculate molecular mass
349
350 if( verboseLevel >= 1) G4cout << " IonisPot: " << IonisPot/CLHEP::eV << " eV "
351 << " IonisPotInt: " << IonisPotInt/CLHEP::eV << " eV"
352 << " MolecularMass " << MolecularMass/(CLHEP::g/CLHEP::mole) << " g/mole" << G4endl;
353
354 return true;
355}
356
357//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
358std::map< G4int, std::vector<G4double> > G4VLEPTSModel::ReadIXS(G4String fnIXS, const G4Material* aMaterial )
359{
360 std::map< G4int, std::vector<G4double> > integralXS; // process type - energy
361 //G4cout << "fnIXS (" << fnIXS << ")" << G4endl;
362
363 std::ifstream fin(fnIXS);
364 if (!fin.is_open()) {
365 G4Exception("G4VLEPTSModel::ReadIXS",
366 "",
368 (G4String("File not found: ")+ fnIXS).c_str());
369 return integralXS;
370 }
371
372 G4int nXSdat, nXSsub;
373 fin >> nXSdat >> nXSsub;
374 if( verboseLevel >= 1 ) G4cout << "Read IXS (" << fnIXS << ")\t nXSdat: " << nXSdat
375 << " nXSsub: " << nXSsub << G4endl;
376 theNXSdat[aMaterial] = nXSdat;
377 theNXSsub[aMaterial] = nXSsub;
378
379 G4double xsdat;
380 for (G4int ip=0; ip<=nXSsub; ip++) {
381 integralXS[ip].push_back(0.);
382 }
383 for (G4int ie=1; ie<=nXSdat; ie++) {
384 for (G4int ip=0; ip<=nXSsub; ip++) {
385 fin >> xsdat;
386 integralXS[ip].push_back(xsdat);
387 if( verboseLevel >= 3 ) G4cout << GetName() << " FILL IXS " << ip << " " << ie << " = " << integralXS[ip][ie] << " " << xsdat << G4endl;
388 // xsdat 1e-16*cm2
389 }
390 }
391 fin.close();
392
393 return integralXS;
394}
395
const char * G4FindDataDir(const char *)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::vector< G4Material * > G4MaterialTable
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
G4double GetA() const
Definition: G4Element.hh:139
G4double GetDensity() const
Definition: G4Material.hh:175
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:684
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:197
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
const G4int * GetAtomsVector() const
Definition: G4Material.hh:193
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:677
const G4String & GetName() const
Definition: G4Material.hh:172
size_t GetIndex() const
Definition: G4Material.hh:255
const G4String & GetParticleName() const
void clearAndDestroy()
void insertAt(std::size_t, G4PhysicsVector *)
void PutValue(const std::size_t index, const G4double value)
G4double Energy(const std::size_t index) const
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:746
virtual G4double Value(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
Definition: G4VEmModel.cc:349
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:753
const G4String & GetName() const
Definition: G4VEmModel.hh:816
G4bool ReadParam(G4String fileName, const G4Material *aMaterial)
std::map< const G4Material *, G4LEPTSDiffXS * > theDiffXS
G4ThreeVector SampleNewDirection(const G4Material *aMaterial, G4ThreeVector Dir, G4double e, G4double el)
G4double SampleEnergyLoss(const G4Material *aMaterial, G4double eMin, G4double eMax)
std::map< const G4Material *, G4double > theMolecularMass
G4double GetMeanFreePath(const G4Material *mate, const G4ParticleDefinition *aParticle, G4double kineticEnergy)
std::map< const G4Material *, G4int > theNXSsub
G4VLEPTSModel(const G4String &processName)
std::map< const G4Material *, G4LEPTSElossDistr * > theElostDistr
std::map< const G4Material *, G4double > theIonisPotInt
G4int theNumbBinTable
std::map< const G4Material *, G4double > theIonisPot
G4PhysicsTable * theMeanFreePathTable
G4double theHighestEnergyLimit
void BuildPhysicsTable(const G4ParticleDefinition &aParticleType)
virtual std::map< G4int, std::vector< G4double > > ReadIXS(G4String fileName, const G4Material *aMaterial)
G4double theLowestEnergyLimit
std::map< const G4Material *, G4LEPTSDistribution * > theRMTDistr
void BuildMeanFreePathTable(const G4Material *aMaterial, std::map< G4int, std::vector< G4double > > &integralXS)
std::map< const G4Material *, G4int > theNXSdat
G4double SampleAngle(const G4Material *aMaterial, G4double e, G4double el)
#define DBL_MIN
Definition: templates.hh:54
#define DBL_MAX
Definition: templates.hh:62