source: trunk/source/processes/electromagnetic/utils/src/G4VEmProcess.cc@ 1275

Last change on this file since 1275 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

File size: 22.5 KB
Line 
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// $Id: G4VEmProcess.cc,v 1.79 2009/11/10 20:30:55 vnivanch Exp $
27// GEANT4 tag $Name: geant4-09-03 $
28//
29// -------------------------------------------------------------------
30//
31// GEANT4 Class file
32//
33//
34// File name: G4VEmProcess
35//
36// Author: Vladimir Ivanchenko on base of Laszlo Urban code
37//
38// Creation date: 01.10.2003
39//
40// Modifications:
41// 30-06-04 make it to be pure discrete process (V.Ivanchenko)
42// 30-09-08 optimise integral option (V.Ivanchenko)
43// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko)
44// 11-03-05 Shift verbose level by 1, add applyCuts and killPrimary flags (VI)
45// 14-03-05 Update logic PostStepDoIt (V.Ivanchenko)
46// 08-04-05 Major optimisation of internal interfaces (V.Ivanchenko)
47// 18-04-05 Use G4ParticleChangeForGamma (V.Ivanchenko)
48// 25-07-05 Add protection: integral mode only for charged particles (VI)
49// 04-09-05 default lambdaFactor 0.8 (V.Ivanchenko)
50// 11-01-06 add A to parameters of ComputeCrossSectionPerAtom (VI)
51// 12-09-06 add SetModel() (mma)
52// 12-04-07 remove double call to Clear model manager (V.Ivanchenko)
53// 27-10-07 Virtual functions moved to source (V.Ivanchenko)
54// 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko)
55//
56// Class Description:
57//
58
59// -------------------------------------------------------------------
60//
61//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
62//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
63
64#include "G4VEmProcess.hh"
65#include "G4LossTableManager.hh"
66#include "G4Step.hh"
67#include "G4ParticleDefinition.hh"
68#include "G4VEmModel.hh"
69#include "G4DataVector.hh"
70#include "G4PhysicsTable.hh"
71#include "G4PhysicsVector.hh"
72#include "G4PhysicsLogVector.hh"
73#include "G4VParticleChange.hh"
74#include "G4ProductionCutsTable.hh"
75#include "G4Region.hh"
76#include "G4RegionStore.hh"
77#include "G4Gamma.hh"
78#include "G4Electron.hh"
79#include "G4Positron.hh"
80#include "G4PhysicsTableHelper.hh"
81#include "G4EmConfigurator.hh"
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
84
85G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
86 G4VDiscreteProcess(name, type),
87 secondaryParticle(0),
88 buildLambdaTable(true),
89 theLambdaTable(0),
90 theEnergyOfCrossSectionMax(0),
91 theCrossSectionMax(0),
92 integral(false),
93 applyCuts(false),
94 startFromNull(true),
95 useDeexcitation(false),
96 nDERegions(0),
97 idxDERegions(0),
98 currentModel(0),
99 particle(0),
100 currentCouple(0)
101{
102 SetVerboseLevel(1);
103
104 // Size of tables assuming spline
105 minKinEnergy = 0.1*keV;
106 maxKinEnergy = 10.0*TeV;
107 nLambdaBins = 77;
108
109 // default lambda factor
110 lambdaFactor = 0.8;
111
112 // default limit on polar angle
113 polarAngleLimit = 0.0;
114
115 // particle types
116 theGamma = G4Gamma::Gamma();
117 theElectron = G4Electron::Electron();
118 thePositron = G4Positron::Positron();
119
120 pParticleChange = &fParticleChange;
121 secParticles.reserve(5);
122
123 modelManager = new G4EmModelManager();
124 (G4LossTableManager::Instance())->Register(this);
125}
126
127//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
128
129G4VEmProcess::~G4VEmProcess()
130{
131 if(1 < verboseLevel)
132 G4cout << "G4VEmProcess destruct " << GetProcessName()
133 << G4endl;
134 Clear();
135 if(theLambdaTable) {
136 theLambdaTable->clearAndDestroy();
137 delete theLambdaTable;
138 }
139 delete modelManager;
140 (G4LossTableManager::Instance())->DeRegister(this);
141}
142
143//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
144
145void G4VEmProcess::Clear()
146{
147 delete [] theEnergyOfCrossSectionMax;
148 delete [] theCrossSectionMax;
149 delete [] idxDERegions;
150 theEnergyOfCrossSectionMax = 0;
151 theCrossSectionMax = 0;
152 idxDERegions = 0;
153 currentCouple = 0;
154 preStepLambda = 0.0;
155 mfpKinEnergy = DBL_MAX;
156 deRegions.clear();
157 nDERegions = 0;
158}
159
160//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
161
162void G4VEmProcess::AddEmModel(G4int order, G4VEmModel* p,
163 const G4Region* region)
164{
165 G4VEmFluctuationModel* fm = 0;
166 modelManager->AddEmModel(order, p, fm, region);
167 if(p) p->SetParticleChange(pParticleChange);
168}
169
170//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
171
172void G4VEmProcess::SetModel(G4VEmModel* p, G4int index)
173{
174 G4int n = emModels.size();
175 if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
176 emModels[index] = p;
177}
178
179//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
180
181G4VEmModel* G4VEmProcess::Model(G4int index)
182{
183 G4VEmModel* p = 0;
184 if(index >= 0 && index < G4int(emModels.size())) { p = emModels[index]; }
185 return p;
186}
187
188//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
189
190void G4VEmProcess::UpdateEmModel(const G4String& nam,
191 G4double emin, G4double emax)
192{
193 modelManager->UpdateEmModel(nam, emin, emax);
194}
195
196//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
197
198G4VEmModel* G4VEmProcess::GetModelByIndex(G4int idx, G4bool ver)
199{
200 return modelManager->GetModel(idx, ver);
201}
202
203//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
204
205void G4VEmProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
206{
207 if(!particle) particle = &part;
208 if(1 < verboseLevel) {
209 G4cout << "G4VEmProcess::PreparePhysicsTable() for "
210 << GetProcessName()
211 << " and particle " << part.GetParticleName()
212 << " local particle " << particle->GetParticleName()
213 << G4endl;
214 }
215
216 (G4LossTableManager::Instance())->EmConfigurator()->AddModels();
217
218 if(particle == &part) {
219 Clear();
220 InitialiseProcess(particle);
221
222 // initialisation of models
223 G4int nmod = modelManager->NumberOfModels();
224 for(G4int i=0; i<nmod; ++i) {
225 G4VEmModel* mod = modelManager->GetModel(i);
226 mod->SetPolarAngleLimit(polarAngleLimit);
227 if(mod->HighEnergyLimit() > maxKinEnergy) {
228 mod->SetHighEnergyLimit(maxKinEnergy);
229 }
230 }
231
232 theCuts = modelManager->Initialise(particle,secondaryParticle,2.,verboseLevel);
233 const G4ProductionCutsTable* theCoupleTable=
234 G4ProductionCutsTable::GetProductionCutsTable();
235 theCutsGamma = theCoupleTable->GetEnergyCutsVector(idxG4GammaCut);
236 theCutsElectron = theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut);
237 theCutsPositron = theCoupleTable->GetEnergyCutsVector(idxG4PositronCut);
238
239 // prepare tables
240 if(buildLambdaTable){
241 theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
242 }
243 }
244 // Sub Cutoff and Deexcitation
245 if (nDERegions>0) {
246
247 const G4ProductionCutsTable* theCoupleTable=
248 G4ProductionCutsTable::GetProductionCutsTable();
249 size_t numOfCouples = theCoupleTable->GetTableSize();
250
251 idxDERegions = new G4bool[numOfCouples];
252
253 for (size_t j=0; j<numOfCouples; ++j) {
254
255 const G4MaterialCutsCouple* couple =
256 theCoupleTable->GetMaterialCutsCouple(j);
257 const G4ProductionCuts* pcuts = couple->GetProductionCuts();
258 G4bool reg = false;
259 for(G4int i=0; i<nDERegions; ++i) {
260 if(deRegions[i]) {
261 if(pcuts == deRegions[i]->GetProductionCuts()) reg = true;
262 }
263 }
264 idxDERegions[j] = reg;
265 }
266 }
267 if (1 < verboseLevel && nDERegions>0) {
268 G4cout << " Deexcitation is activated for regions: " << G4endl;
269 for (G4int i=0; i<nDERegions; ++i) {
270 const G4Region* r = deRegions[i];
271 G4cout << " " << r->GetName() << G4endl;
272 }
273 }
274}
275
276//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
277
278void G4VEmProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
279{
280 G4String partname = part.GetParticleName();
281 if(1 < verboseLevel) {
282 G4cout << "G4VEmProcess::BuildPhysicsTable() for "
283 << GetProcessName()
284 << " and particle " << partname
285 << " buildLambdaTable= " << buildLambdaTable
286 << G4endl;
287 }
288
289 if(buildLambdaTable) {
290 BuildLambdaTable();
291 FindLambdaMax();
292 }
293
294 // reduce printout for nuclear stopping
295 G4bool gproc = true;
296 if(GetProcessName() == "nuclearStopping" &&
297 partname != "GenericIon" && partname != "alpha") { gproc = false; }
298
299 if(gproc && 0 < verboseLevel) { PrintInfoDefinition(); }
300
301 if(1 < verboseLevel) {
302 G4cout << "G4VEmProcess::BuildPhysicsTable() done for "
303 << GetProcessName()
304 << " and particle " << partname
305 << G4endl;
306 }
307}
308
309//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
310
311void G4VEmProcess::BuildLambdaTable()
312{
313 if(1 < verboseLevel) {
314 G4cout << "G4EmProcess::BuildLambdaTable() for process "
315 << GetProcessName() << " and particle "
316 << particle->GetParticleName()
317 << G4endl;
318 }
319
320 // Access to materials
321 const G4ProductionCutsTable* theCoupleTable=
322 G4ProductionCutsTable::GetProductionCutsTable();
323 size_t numOfCouples = theCoupleTable->GetTableSize();
324
325 G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
326
327 G4PhysicsLogVector* aVector = 0;
328 G4PhysicsLogVector* bVector = 0;
329
330 for(size_t i=0; i<numOfCouples; ++i) {
331
332 if (theLambdaTable->GetFlag(i)) {
333
334 // create physics vector and fill it
335 const G4MaterialCutsCouple* couple =
336 theCoupleTable->GetMaterialCutsCouple(i);
337 if(!bVector) {
338 aVector =
339 static_cast<G4PhysicsLogVector*>(LambdaPhysicsVector(couple));
340 bVector = aVector;
341 } else {
342 aVector = new G4PhysicsLogVector(*bVector);
343 }
344 // G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
345 aVector->SetSpline(splineFlag);
346 modelManager->FillLambdaVector(aVector, couple, startFromNull);
347 if(splineFlag) aVector->FillSecondDerivatives();
348 G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
349 }
350 }
351
352 if(1 < verboseLevel) {
353 G4cout << "Lambda table is built for "
354 << particle->GetParticleName()
355 << G4endl;
356 if(2 < verboseLevel) {
357 G4cout << *theLambdaTable << G4endl;
358 }
359 }
360}
361
362//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
363
364void G4VEmProcess::PrintInfoDefinition()
365{
366 if(verboseLevel > 0) {
367 G4cout << G4endl << GetProcessName() << ": for "
368 << particle->GetParticleName();
369 if(integral) G4cout << ", integral: 1 ";
370 if(applyCuts) G4cout << ", applyCuts: 1 ";
371 G4cout << " SubType= " << GetProcessSubType() << G4endl;
372 if(buildLambdaTable) {
373 G4cout << " Lambda tables from "
374 << G4BestUnit(minKinEnergy,"Energy")
375 << " to "
376 << G4BestUnit(maxKinEnergy,"Energy")
377 << " in " << nLambdaBins << " bins, spline: "
378 << (G4LossTableManager::Instance())->SplineFlag()
379 << G4endl;
380 }
381 PrintInfo();
382 modelManager->DumpModelList(verboseLevel);
383 }
384
385 if(verboseLevel > 2 && buildLambdaTable) {
386 G4cout << " LambdaTable address= " << theLambdaTable << G4endl;
387 if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
388 }
389}
390
391//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
392
393G4double G4VEmProcess::PostStepGetPhysicalInteractionLength(
394 const G4Track& track,
395 G4double previousStepSize,
396 G4ForceCondition* condition)
397{
398 // condition is set to "Not Forced"
399 *condition = NotForced;
400 G4double x = DBL_MAX;
401 if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0;
402 InitialiseStep(track);
403 if(!currentModel->IsActive(preStepKinEnergy)) return x;
404
405 if(preStepKinEnergy < mfpKinEnergy) {
406 if (integral) ComputeIntegralLambda(preStepKinEnergy);
407 else preStepLambda = GetCurrentLambda(preStepKinEnergy);
408 if(preStepLambda <= DBL_MIN) mfpKinEnergy = 0.0;
409 }
410
411 // non-zero cross section
412 if(preStepLambda > DBL_MIN) {
413 if (theNumberOfInteractionLengthLeft < 0.0) {
414 // beggining of tracking (or just after DoIt of this process)
415 ResetNumberOfInteractionLengthLeft();
416 } else if(currentInteractionLength < DBL_MAX) {
417 // subtract NumberOfInteractionLengthLeft
418 SubtractNumberOfInteractionLengthLeft(previousStepSize);
419 if(theNumberOfInteractionLengthLeft < 0.)
420 theNumberOfInteractionLengthLeft = perMillion;
421 }
422
423 // get mean free path and step limit
424 currentInteractionLength = 1.0/preStepLambda;
425 x = theNumberOfInteractionLengthLeft * currentInteractionLength;
426#ifdef G4VERBOSE
427 if (verboseLevel>2){
428 G4cout << "G4VEmProcess::PostStepGetPhysicalInteractionLength ";
429 G4cout << "[ " << GetProcessName() << "]" << G4endl;
430 G4cout << " for " << particle->GetParticleName()
431 << " in Material " << currentMaterial->GetName()
432 << " Ekin(MeV)= " << preStepKinEnergy/MeV
433 <<G4endl;
434 G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]"
435 << "InteractionLength= " << x/cm <<"[cm] " <<G4endl;
436 }
437#endif
438
439 // zero cross section case
440 } else {
441 if(theNumberOfInteractionLengthLeft > DBL_MIN &&
442 currentInteractionLength < DBL_MAX) {
443
444 // subtract NumberOfInteractionLengthLeft
445 SubtractNumberOfInteractionLengthLeft(previousStepSize);
446 if(theNumberOfInteractionLengthLeft < 0.)
447 theNumberOfInteractionLengthLeft = perMillion;
448 }
449 currentInteractionLength = DBL_MAX;
450 }
451 return x;
452}
453
454//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
455
456G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
457 const G4Step&)
458{
459 fParticleChange.InitializeForPostStep(track);
460
461 // Do not make anything if particle is stopped, the annihilation then
462 // should be performed by the AtRestDoIt!
463 if (track.GetTrackStatus() == fStopButAlive) return &fParticleChange;
464
465 G4double finalT = track.GetKineticEnergy();
466
467 // Integral approach
468 if (integral) {
469 G4double lx = GetLambda(finalT, currentCouple);
470 if(preStepLambda<lx && 1 < verboseLevel) {
471 G4cout << "WARING: for " << particle->GetParticleName()
472 << " and " << GetProcessName()
473 << " E(MeV)= " << finalT/MeV
474 << " preLambda= " << preStepLambda << " < " << lx << " (postLambda) "
475 << G4endl;
476 }
477
478 if(preStepLambda*G4UniformRand() > lx) {
479 ClearNumberOfInteractionLengthLeft();
480 return &fParticleChange;
481 }
482 }
483
484 SelectModel(finalT, currentCoupleIndex);
485 if(!currentModel->IsActive(finalT)) return &fParticleChange;
486 if(useDeexcitation) {
487 currentModel->SetDeexcitationFlag(idxDERegions[currentCoupleIndex]);
488 }
489 /*
490 if(0 < verboseLevel) {
491 G4cout << "G4VEmProcess::PostStepDoIt: Sample secondary; E= "
492 << finalT/MeV
493 << " MeV; model= (" << currentModel->LowEnergyLimit()
494 << ", " << currentModel->HighEnergyLimit() << ")"
495 << G4endl;
496 }
497 */
498
499
500 // sample secondaries
501 secParticles.clear();
502 currentModel->SampleSecondaries(&secParticles,
503 currentCouple,
504 track.GetDynamicParticle(),
505 (*theCuts)[currentCoupleIndex]);
506
507 // save secondaries
508 G4int num = secParticles.size();
509 if(num > 0) {
510
511 fParticleChange.SetNumberOfSecondaries(num);
512 G4double edep = fParticleChange.GetLocalEnergyDeposit();
513
514 for (G4int i=0; i<num; ++i) {
515 G4DynamicParticle* dp = secParticles[i];
516 const G4ParticleDefinition* p = dp->GetDefinition();
517 G4double e = dp->GetKineticEnergy();
518 G4bool good = true;
519 if(applyCuts) {
520 if (p == theGamma) {
521 if (e < (*theCutsGamma)[currentCoupleIndex]) good = false;
522
523 } else if (p == theElectron) {
524 if (e < (*theCutsElectron)[currentCoupleIndex]) good = false;
525
526 } else if (p == thePositron) {
527 if (electron_mass_c2 < (*theCutsGamma)[currentCoupleIndex] &&
528 e < (*theCutsPositron)[currentCoupleIndex]) {
529 good = false;
530 e += 2.0*electron_mass_c2;
531 }
532 }
533 if(!good) {
534 delete dp;
535 edep += e;
536 }
537 }
538 if (good) fParticleChange.AddSecondary(dp);
539 }
540 fParticleChange.ProposeLocalEnergyDeposit(edep);
541 }
542
543 ClearNumberOfInteractionLengthLeft();
544 return &fParticleChange;
545}
546
547//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
548
549G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part,
550 const G4String& directory,
551 G4bool ascii)
552{
553 G4bool yes = true;
554
555 if ( theLambdaTable && part == particle) {
556 const G4String name =
557 GetPhysicsTableFileName(part,directory,"Lambda",ascii);
558 yes = theLambdaTable->StorePhysicsTable(name,ascii);
559
560 if ( yes ) {
561 G4cout << "Physics tables are stored for " << particle->GetParticleName()
562 << " and process " << GetProcessName()
563 << " in the directory <" << directory
564 << "> " << G4endl;
565 } else {
566 G4cout << "Fail to store Physics Tables for "
567 << particle->GetParticleName()
568 << " and process " << GetProcessName()
569 << " in the directory <" << directory
570 << "> " << G4endl;
571 }
572 }
573 return yes;
574}
575
576//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
577
578G4bool G4VEmProcess::RetrievePhysicsTable(const G4ParticleDefinition* part,
579 const G4String& directory,
580 G4bool ascii)
581{
582 if(1 < verboseLevel) {
583 G4cout << "G4VEmProcess::RetrievePhysicsTable() for "
584 << part->GetParticleName() << " and process "
585 << GetProcessName() << G4endl;
586 }
587 G4bool yes = true;
588
589 if(!buildLambdaTable || particle != part) return yes;
590
591 const G4String particleName = part->GetParticleName();
592 G4String filename;
593
594 filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
595 yes = G4PhysicsTableHelper::RetrievePhysicsTable(theLambdaTable,
596 filename,ascii);
597 if ( yes ) {
598 if (0 < verboseLevel) {
599 G4cout << "Lambda table for " << particleName
600 << " is Retrieved from <"
601 << filename << ">"
602 << G4endl;
603 }
604 if((G4LossTableManager::Instance())->SplineFlag()) {
605 size_t n = theLambdaTable->length();
606 for(size_t i=0; i<n; ++i) {
607 if((* theLambdaTable)[i]) {
608 (* theLambdaTable)[i]->SetSpline(true);
609 }
610 }
611 }
612 } else {
613 if (1 < verboseLevel) {
614 G4cout << "Lambda table for " << particleName << " in file <"
615 << filename << "> is not exist"
616 << G4endl;
617 }
618 }
619
620 return yes;
621}
622
623//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
624
625void G4VEmProcess::ActivateDeexcitation(G4bool val, const G4Region* r)
626{
627 G4RegionStore* regionStore = G4RegionStore::GetInstance();
628 const G4Region* reg = r;
629 if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
630
631 // the region is in the list
632 if (nDERegions) {
633 for (G4int i=0; i<nDERegions; ++i) {
634 if (reg == deRegions[i]) {
635 if(!val) deRegions[i] = 0;
636 return;
637 }
638 }
639 }
640
641 // new region
642 if(val) {
643 useDeexcitation = true;
644 deRegions.push_back(reg);
645 nDERegions++;
646 } else {
647 useDeexcitation = false;
648 }
649}
650
651//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
652
653G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy,
654 const G4MaterialCutsCouple* couple)
655{
656 // Cross section per atom is calculated
657 DefineMaterial(couple);
658 G4double cross = 0.0;
659 if(theLambdaTable) {
660 cross = (((*theLambdaTable)[currentCoupleIndex])->Value(kineticEnergy));
661 } else {
662 SelectModel(kineticEnergy, currentCoupleIndex);
663 cross = currentModel->CrossSectionPerVolume(currentMaterial,
664 particle,kineticEnergy);
665 }
666
667 return cross;
668}
669
670//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
671
672G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,
673 G4double,
674 G4ForceCondition* condition)
675{
676 *condition = NotForced;
677 return G4VEmProcess::MeanFreePath(track);
678}
679
680//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
681
682void G4VEmProcess::FindLambdaMax()
683{
684 if(1 < verboseLevel) {
685 G4cout << "### G4VEmProcess::FindLambdaMax: "
686 << particle->GetParticleName()
687 << " and process " << GetProcessName() << G4endl;
688 }
689 size_t n = theLambdaTable->length();
690 G4PhysicsVector* pv = (*theLambdaTable)[0];
691 G4double e, s, emax, smax;
692 theEnergyOfCrossSectionMax = new G4double [n];
693 theCrossSectionMax = new G4double [n];
694
695 for (size_t i=0; i<n; ++i) {
696 pv = (*theLambdaTable)[i];
697 emax = DBL_MAX;
698 smax = 0.0;
699 if(pv) {
700 size_t nb = pv->GetVectorLength();
701 emax = DBL_MAX;
702 smax = 0.0;
703 if(nb > 0) {
704 for (size_t j=0; j<nb; ++j) {
705 e = pv->Energy(j);
706 s = (*pv)(j);
707 if(s > smax) {
708 smax = s;
709 emax = e;
710 }
711 }
712 }
713 }
714 theEnergyOfCrossSectionMax[i] = emax;
715 theCrossSectionMax[i] = smax;
716 if(2 < verboseLevel) {
717 G4cout << "For " << particle->GetParticleName()
718 << " Max CS at i= " << i << " emax(MeV)= " << emax/MeV
719 << " lambda= " << smax << G4endl;
720 }
721 }
722}
723
724//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
725
726G4PhysicsVector* G4VEmProcess::LambdaPhysicsVector(const G4MaterialCutsCouple*)
727{
728 G4PhysicsVector* v =
729 new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins);
730 v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
731 return v;
732}
733
734//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
Note: See TracBrowser for help on using the repository browser.