00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include "G4hRDEnergyLoss.hh"
00067 #include "G4PhysicalConstants.hh"
00068 #include "G4SystemOfUnits.hh"
00069 #include "G4EnergyLossTables.hh"
00070 #include "G4Poisson.hh"
00071 #include "G4ProductionCutsTable.hh"
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 G4int G4hRDEnergyLoss::NumberOfProcesses = 1 ;
00088
00089 G4int G4hRDEnergyLoss::CounterOfProcess = 0 ;
00090 G4PhysicsTable** G4hRDEnergyLoss::RecorderOfProcess =
00091 new G4PhysicsTable*[100] ;
00092
00093 G4int G4hRDEnergyLoss::CounterOfpProcess = 0 ;
00094 G4PhysicsTable** G4hRDEnergyLoss::RecorderOfpProcess =
00095 new G4PhysicsTable*[100] ;
00096
00097 G4int G4hRDEnergyLoss::CounterOfpbarProcess = 0 ;
00098 G4PhysicsTable** G4hRDEnergyLoss::RecorderOfpbarProcess =
00099 new G4PhysicsTable*[100] ;
00100
00101 G4PhysicsTable* G4hRDEnergyLoss::theDEDXpTable = 0 ;
00102 G4PhysicsTable* G4hRDEnergyLoss::theDEDXpbarTable = 0 ;
00103 G4PhysicsTable* G4hRDEnergyLoss::theRangepTable = 0 ;
00104 G4PhysicsTable* G4hRDEnergyLoss::theRangepbarTable = 0 ;
00105 G4PhysicsTable* G4hRDEnergyLoss::theInverseRangepTable = 0 ;
00106 G4PhysicsTable* G4hRDEnergyLoss::theInverseRangepbarTable = 0 ;
00107 G4PhysicsTable* G4hRDEnergyLoss::theLabTimepTable = 0 ;
00108 G4PhysicsTable* G4hRDEnergyLoss::theLabTimepbarTable = 0 ;
00109 G4PhysicsTable* G4hRDEnergyLoss::theProperTimepTable = 0 ;
00110 G4PhysicsTable* G4hRDEnergyLoss::theProperTimepbarTable = 0 ;
00111
00112 G4PhysicsTable* G4hRDEnergyLoss::thepRangeCoeffATable = 0 ;
00113 G4PhysicsTable* G4hRDEnergyLoss::thepRangeCoeffBTable = 0 ;
00114 G4PhysicsTable* G4hRDEnergyLoss::thepRangeCoeffCTable = 0 ;
00115 G4PhysicsTable* G4hRDEnergyLoss::thepbarRangeCoeffATable = 0 ;
00116 G4PhysicsTable* G4hRDEnergyLoss::thepbarRangeCoeffBTable = 0 ;
00117 G4PhysicsTable* G4hRDEnergyLoss::thepbarRangeCoeffCTable = 0 ;
00118
00119 G4PhysicsTable* G4hRDEnergyLoss::theDEDXTable = 0 ;
00120 G4PhysicsTable* G4hRDEnergyLoss::theRangeTable = 0 ;
00121 G4PhysicsTable* G4hRDEnergyLoss::theInverseRangeTable = 0 ;
00122 G4PhysicsTable* G4hRDEnergyLoss::theLabTimeTable = 0 ;
00123 G4PhysicsTable* G4hRDEnergyLoss::theProperTimeTable = 0 ;
00124
00125 G4PhysicsTable* G4hRDEnergyLoss::theRangeCoeffATable = 0 ;
00126 G4PhysicsTable* G4hRDEnergyLoss::theRangeCoeffBTable = 0 ;
00127 G4PhysicsTable* G4hRDEnergyLoss::theRangeCoeffCTable = 0 ;
00128
00129
00130
00131
00132 G4double G4hRDEnergyLoss::ParticleMass;
00133 G4double G4hRDEnergyLoss::ptableElectronCutInRange = 0.0*mm ;
00134 G4double G4hRDEnergyLoss::pbartableElectronCutInRange = 0.0*mm ;
00135
00136 G4double G4hRDEnergyLoss::Mass,
00137 G4hRDEnergyLoss::taulow,
00138 G4hRDEnergyLoss::tauhigh,
00139 G4hRDEnergyLoss::ltaulow,
00140 G4hRDEnergyLoss::ltauhigh;
00141
00142 G4double G4hRDEnergyLoss::dRoverRange = 0.20 ;
00143 G4double G4hRDEnergyLoss::finalRange = 200.*micrometer ;
00144
00145 G4double G4hRDEnergyLoss::c1lim = dRoverRange ;
00146 G4double G4hRDEnergyLoss::c2lim = 2.*(1.-dRoverRange)*finalRange ;
00147 G4double G4hRDEnergyLoss::c3lim = -(1.-dRoverRange)*finalRange*finalRange;
00148
00149 G4double G4hRDEnergyLoss::Charge ;
00150
00151 G4bool G4hRDEnergyLoss::rndmStepFlag = false ;
00152 G4bool G4hRDEnergyLoss::EnlossFlucFlag = true ;
00153
00154 G4double G4hRDEnergyLoss::LowestKineticEnergy = 10.*eV;
00155 G4double G4hRDEnergyLoss::HighestKineticEnergy= 100.*GeV;
00156 G4int G4hRDEnergyLoss::TotBin = 360;
00157 G4double G4hRDEnergyLoss::RTable,G4hRDEnergyLoss::LOGRTable;
00158
00159
00160
00161
00162
00163 G4hRDEnergyLoss::G4hRDEnergyLoss(const G4String& processName)
00164 : G4VContinuousDiscreteProcess (processName),
00165 MaxExcitationNumber (1.e6),
00166 probLimFluct (0.01),
00167 nmaxDirectFluct (100),
00168 nmaxCont1(4),
00169 nmaxCont2(16),
00170 theLossTable(0),
00171 linLossLimit(0.05),
00172 MinKineticEnergy(0.0)
00173 {;}
00174
00175
00176
00177 G4hRDEnergyLoss::~G4hRDEnergyLoss()
00178 {
00179 if(theLossTable) {
00180 theLossTable->clearAndDestroy();
00181 delete theLossTable;
00182 }
00183 }
00184
00185
00186
00187 G4int G4hRDEnergyLoss::GetNumberOfProcesses()
00188 {
00189 return NumberOfProcesses;
00190 }
00191
00192
00193
00194 void G4hRDEnergyLoss::SetNumberOfProcesses(G4int number)
00195 {
00196 NumberOfProcesses=number;
00197 }
00198
00199
00200
00201 void G4hRDEnergyLoss::PlusNumberOfProcesses()
00202 {
00203 NumberOfProcesses++;
00204 }
00205
00206
00207
00208 void G4hRDEnergyLoss::MinusNumberOfProcesses()
00209 {
00210 NumberOfProcesses--;
00211 }
00212
00213
00214
00215 void G4hRDEnergyLoss::SetdRoverRange(G4double value)
00216 {
00217 dRoverRange = value;
00218 }
00219
00220
00221
00222 void G4hRDEnergyLoss::SetRndmStep (G4bool value)
00223 {
00224 rndmStepFlag = value;
00225 }
00226
00227
00228
00229 void G4hRDEnergyLoss::SetEnlossFluc (G4bool value)
00230 {
00231 EnlossFlucFlag = value;
00232 }
00233
00234
00235
00236 void G4hRDEnergyLoss::SetStepFunction (G4double c1, G4double c2)
00237 {
00238 dRoverRange = c1;
00239 finalRange = c2;
00240 c1lim=dRoverRange;
00241 c2lim=2.*(1-dRoverRange)*finalRange;
00242 c3lim=-(1.-dRoverRange)*finalRange*finalRange;
00243 }
00244
00245
00246
00247 void G4hRDEnergyLoss::BuildDEDXTable(
00248 const G4ParticleDefinition& aParticleType)
00249 {
00250
00251
00252 const G4ProductionCutsTable* theCoupleTable=
00253 G4ProductionCutsTable::GetProductionCutsTable();
00254 size_t numOfCouples = theCoupleTable->GetTableSize();
00255
00256
00257 Charge = aParticleType.GetPDGCharge()/eplus;
00258 ParticleMass = aParticleType.GetPDGMass() ;
00259
00260 if (Charge>0.) {theDEDXTable= theDEDXpTable;}
00261 else {theDEDXTable= theDEDXpbarTable;}
00262
00263 if( ((Charge>0.) && (theDEDXTable==0)) ||
00264 ((Charge<0.) && (theDEDXTable==0))
00265 )
00266 {
00267
00268
00269
00270 if( Charge >0.)
00271 {
00272 RecorderOfProcess=RecorderOfpProcess;
00273 CounterOfProcess=CounterOfpProcess;
00274
00275 if(CounterOfProcess == NumberOfProcesses)
00276 {
00277 if(theDEDXpTable)
00278 { theDEDXpTable->clearAndDestroy();
00279 delete theDEDXpTable; }
00280 theDEDXpTable = new G4PhysicsTable(numOfCouples);
00281 theDEDXTable = theDEDXpTable;
00282 }
00283 }
00284 else
00285 {
00286 RecorderOfProcess=RecorderOfpbarProcess;
00287 CounterOfProcess=CounterOfpbarProcess;
00288
00289 if(CounterOfProcess == NumberOfProcesses)
00290 {
00291 if(theDEDXpbarTable)
00292 { theDEDXpbarTable->clearAndDestroy();
00293 delete theDEDXpbarTable; }
00294 theDEDXpbarTable = new G4PhysicsTable(numOfCouples);
00295 theDEDXTable = theDEDXpbarTable;
00296 }
00297 }
00298
00299 if(CounterOfProcess == NumberOfProcesses)
00300 {
00301
00302 G4double LowEdgeEnergy , Value ;
00303 G4bool isOutRange ;
00304 G4PhysicsTable* pointer ;
00305
00306 for (size_t J=0; J<numOfCouples; J++)
00307 {
00308
00309 G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
00310 LowestKineticEnergy, HighestKineticEnergy, TotBin);
00311
00312
00313 for (G4int i=0; i<TotBin; i++)
00314 {
00315 LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
00316 Value = 0. ;
00317
00318
00319 for (G4int process=0; process < NumberOfProcesses; process++)
00320 {
00321 pointer= RecorderOfProcess[process];
00322 Value += (*pointer)[J]->
00323 GetValue(LowEdgeEnergy,isOutRange) ;
00324 }
00325
00326 aVector->PutValue(i,Value) ;
00327 }
00328
00329 theDEDXTable->insert(aVector) ;
00330 }
00331
00332
00333 if( Charge >0.)
00334 CounterOfpProcess=0 ;
00335 else
00336 CounterOfpbarProcess=0 ;
00337
00338
00339 BuildRangeTable( aParticleType);
00340
00341
00342 BuildTimeTables( aParticleType) ;
00343
00344
00345 BuildRangeCoeffATable( aParticleType);
00346 BuildRangeCoeffBTable( aParticleType);
00347 BuildRangeCoeffCTable( aParticleType);
00348
00349
00350
00351 BuildInverseRangeTable(aParticleType);
00352 }
00353 }
00354
00355
00356 G4EnergyLossTables::Register(&aParticleType,
00357 (Charge>0)?
00358 theDEDXpTable: theDEDXpbarTable,
00359 (Charge>0)?
00360 theRangepTable: theRangepbarTable,
00361 (Charge>0)?
00362 theInverseRangepTable: theInverseRangepbarTable,
00363 (Charge>0)?
00364 theLabTimepTable: theLabTimepbarTable,
00365 (Charge>0)?
00366 theProperTimepTable: theProperTimepbarTable,
00367 LowestKineticEnergy, HighestKineticEnergy,
00368 proton_mass_c2/aParticleType.GetPDGMass(),
00369 TotBin);
00370
00371 }
00372
00373
00374
00375 void G4hRDEnergyLoss::BuildRangeTable(
00376 const G4ParticleDefinition& aParticleType)
00377
00378 {
00379 Mass = aParticleType.GetPDGMass();
00380
00381 const G4ProductionCutsTable* theCoupleTable=
00382 G4ProductionCutsTable::GetProductionCutsTable();
00383 size_t numOfCouples = theCoupleTable->GetTableSize();
00384
00385 if( Charge >0.)
00386 {
00387 if(theRangepTable)
00388 { theRangepTable->clearAndDestroy();
00389 delete theRangepTable; }
00390 theRangepTable = new G4PhysicsTable(numOfCouples);
00391 theRangeTable = theRangepTable ;
00392 }
00393 else
00394 {
00395 if(theRangepbarTable)
00396 { theRangepbarTable->clearAndDestroy();
00397 delete theRangepbarTable; }
00398 theRangepbarTable = new G4PhysicsTable(numOfCouples);
00399 theRangeTable = theRangepbarTable ;
00400 }
00401
00402
00403
00404 for (size_t J=0; J<numOfCouples; J++)
00405 {
00406 G4PhysicsLogVector* aVector;
00407 aVector = new G4PhysicsLogVector(LowestKineticEnergy,
00408 HighestKineticEnergy,TotBin);
00409
00410 BuildRangeVector(J, aVector);
00411 theRangeTable->insert(aVector);
00412 }
00413 }
00414
00415
00416
00417 void G4hRDEnergyLoss::BuildTimeTables(
00418 const G4ParticleDefinition& aParticleType)
00419 {
00420
00421 const G4ProductionCutsTable* theCoupleTable=
00422 G4ProductionCutsTable::GetProductionCutsTable();
00423 size_t numOfCouples = theCoupleTable->GetTableSize();
00424
00425 if(&aParticleType == G4Proton::Proton())
00426 {
00427 if(theLabTimepTable)
00428 { theLabTimepTable->clearAndDestroy();
00429 delete theLabTimepTable; }
00430 theLabTimepTable = new G4PhysicsTable(numOfCouples);
00431 theLabTimeTable = theLabTimepTable ;
00432
00433 if(theProperTimepTable)
00434 { theProperTimepTable->clearAndDestroy();
00435 delete theProperTimepTable; }
00436 theProperTimepTable = new G4PhysicsTable(numOfCouples);
00437 theProperTimeTable = theProperTimepTable ;
00438 }
00439
00440 if(&aParticleType == G4AntiProton::AntiProton())
00441 {
00442 if(theLabTimepbarTable)
00443 { theLabTimepbarTable->clearAndDestroy();
00444 delete theLabTimepbarTable; }
00445 theLabTimepbarTable = new G4PhysicsTable(numOfCouples);
00446 theLabTimeTable = theLabTimepbarTable ;
00447
00448 if(theProperTimepbarTable)
00449 { theProperTimepbarTable->clearAndDestroy();
00450 delete theProperTimepbarTable; }
00451 theProperTimepbarTable = new G4PhysicsTable(numOfCouples);
00452 theProperTimeTable = theProperTimepbarTable ;
00453 }
00454
00455 for (size_t J=0; J<numOfCouples; J++)
00456 {
00457 G4PhysicsLogVector* aVector;
00458 G4PhysicsLogVector* bVector;
00459
00460 aVector = new G4PhysicsLogVector(LowestKineticEnergy,
00461 HighestKineticEnergy,TotBin);
00462
00463 BuildLabTimeVector(J, aVector);
00464 theLabTimeTable->insert(aVector);
00465
00466 bVector = new G4PhysicsLogVector(LowestKineticEnergy,
00467 HighestKineticEnergy,TotBin);
00468
00469 BuildProperTimeVector(J, bVector);
00470 theProperTimeTable->insert(bVector);
00471 }
00472 }
00473
00474
00475
00476 void G4hRDEnergyLoss::BuildRangeVector(G4int materialIndex,
00477 G4PhysicsLogVector* rangeVector)
00478
00479 {
00480 G4bool isOut;
00481 G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
00482 G4double energy1 = rangeVector->GetLowEdgeEnergy(0);
00483 G4double dedx = physicsVector->GetValue(energy1,isOut);
00484 G4double range = 0.5*energy1/dedx;
00485 rangeVector->PutValue(0,range);
00486 G4int n = 100;
00487 G4double del = 1.0/(G4double)n ;
00488
00489 for (G4int j=1; j<TotBin; j++) {
00490
00491 G4double energy2 = rangeVector->GetLowEdgeEnergy(j);
00492 G4double de = (energy2 - energy1) * del ;
00493 G4double dedx1 = dedx ;
00494
00495 for (G4int i=1; i<n; i++) {
00496 G4double energy = energy1 + i*de ;
00497 G4double dedx2 = physicsVector->GetValue(energy,isOut);
00498 range += 0.5*de*(1.0/dedx1 + 1.0/dedx2);
00499 dedx1 = dedx2;
00500 }
00501 rangeVector->PutValue(j,range);
00502 dedx = dedx1 ;
00503 energy1 = energy2 ;
00504 }
00505 }
00506
00507
00508
00509 void G4hRDEnergyLoss::BuildLabTimeVector(G4int materialIndex,
00510 G4PhysicsLogVector* timeVector)
00511
00512 {
00513
00514 G4int nbin=100;
00515 G4bool isOut;
00516 G4double tlim=5.*keV,parlowen=0.4,ppar=0.5-parlowen ;
00517
00518 G4double losslim,clim,taulim,timelim,
00519 LowEdgeEnergy,tau,Value ;
00520
00521 G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
00522
00523
00524 losslim = physicsVector->GetValue(tlim,isOut);
00525 taulim=tlim/ParticleMass ;
00526 clim=std::sqrt(ParticleMass*tlim/2.)/(c_light*losslim*ppar) ;
00527
00528
00529
00530 G4int i=-1;
00531 G4double oldValue = 0. ;
00532 G4double tauold ;
00533 do
00534 {
00535 i += 1 ;
00536 LowEdgeEnergy = timeVector->GetLowEdgeEnergy(i);
00537 tau = LowEdgeEnergy/ParticleMass ;
00538 if ( tau <= taulim )
00539 {
00540 Value = clim*std::exp(ppar*std::log(tau/taulim)) ;
00541 }
00542 else
00543 {
00544 timelim=clim ;
00545 ltaulow = std::log(taulim);
00546 ltauhigh = std::log(tau);
00547 Value = timelim+LabTimeIntLog(physicsVector,nbin);
00548 }
00549 timeVector->PutValue(i,Value);
00550 oldValue = Value ;
00551 tauold = tau ;
00552 } while (tau<=taulim) ;
00553
00554 i += 1 ;
00555 for (G4int j=i; j<TotBin; j++)
00556 {
00557 LowEdgeEnergy = timeVector->GetLowEdgeEnergy(j);
00558 tau = LowEdgeEnergy/ParticleMass ;
00559 ltaulow = std::log(tauold);
00560 ltauhigh = std::log(tau);
00561 Value = oldValue+LabTimeIntLog(physicsVector,nbin);
00562 timeVector->PutValue(j,Value);
00563 oldValue = Value ;
00564 tauold = tau ;
00565 }
00566 }
00567
00568
00569
00570 void G4hRDEnergyLoss::BuildProperTimeVector(G4int materialIndex,
00571 G4PhysicsLogVector* timeVector)
00572
00573 {
00574 G4int nbin=100;
00575 G4bool isOut;
00576 G4double tlim=5.*keV,parlowen=0.4,ppar=0.5-parlowen ;
00577
00578 G4double losslim,clim,taulim,timelim,
00579 LowEdgeEnergy,tau,Value ;
00580
00581 G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
00582
00583
00584 losslim = physicsVector->GetValue(tlim,isOut);
00585 taulim=tlim/ParticleMass ;
00586 clim=std::sqrt(ParticleMass*tlim/2.)/(c_light*losslim*ppar) ;
00587
00588
00589
00590 G4int i=-1;
00591 G4double oldValue = 0. ;
00592 G4double tauold ;
00593 do
00594 {
00595 i += 1 ;
00596 LowEdgeEnergy = timeVector->GetLowEdgeEnergy(i);
00597 tau = LowEdgeEnergy/ParticleMass ;
00598 if ( tau <= taulim )
00599 {
00600 Value = clim*std::exp(ppar*std::log(tau/taulim)) ;
00601 }
00602 else
00603 {
00604 timelim=clim ;
00605 ltaulow = std::log(taulim);
00606 ltauhigh = std::log(tau);
00607 Value = timelim+ProperTimeIntLog(physicsVector,nbin);
00608 }
00609 timeVector->PutValue(i,Value);
00610 oldValue = Value ;
00611 tauold = tau ;
00612 } while (tau<=taulim) ;
00613
00614 i += 1 ;
00615 for (G4int j=i; j<TotBin; j++)
00616 {
00617 LowEdgeEnergy = timeVector->GetLowEdgeEnergy(j);
00618 tau = LowEdgeEnergy/ParticleMass ;
00619 ltaulow = std::log(tauold);
00620 ltauhigh = std::log(tau);
00621 Value = oldValue+ProperTimeIntLog(physicsVector,nbin);
00622 timeVector->PutValue(j,Value);
00623 oldValue = Value ;
00624 tauold = tau ;
00625 }
00626 }
00627
00628
00629
00630 G4double G4hRDEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
00631 G4int nbin)
00632
00633 {
00634 G4double dtau,Value,taui,ti,lossi,ci;
00635 G4bool isOut;
00636 dtau = (tauhigh-taulow)/nbin;
00637 Value = 0.;
00638
00639 for (G4int i=0; i<=nbin; i++)
00640 {
00641 taui = taulow + dtau*i ;
00642 ti = Mass*taui;
00643 lossi = physicsVector->GetValue(ti,isOut);
00644 if(i==0)
00645 ci=0.5;
00646 else
00647 {
00648 if(i<nbin)
00649 ci=1.;
00650 else
00651 ci=0.5;
00652 }
00653 Value += ci/lossi;
00654 }
00655 Value *= Mass*dtau;
00656 return Value;
00657 }
00658
00659
00660
00661 G4double G4hRDEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
00662 G4int nbin)
00663
00664 {
00665 G4double ltt,dltau,Value,ui,taui,ti,lossi,ci;
00666 G4bool isOut;
00667 ltt = ltauhigh-ltaulow;
00668 dltau = ltt/nbin;
00669 Value = 0.;
00670
00671 for (G4int i=0; i<=nbin; i++)
00672 {
00673 ui = ltaulow+dltau*i;
00674 taui = std::exp(ui);
00675 ti = Mass*taui;
00676 lossi = physicsVector->GetValue(ti,isOut);
00677 if(i==0)
00678 ci=0.5;
00679 else
00680 {
00681 if(i<nbin)
00682 ci=1.;
00683 else
00684 ci=0.5;
00685 }
00686 Value += ci*taui/lossi;
00687 }
00688 Value *= Mass*dltau;
00689 return Value;
00690 }
00691
00692
00693
00694 G4double G4hRDEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
00695 G4int nbin)
00696
00697 {
00698 G4double ltt,dltau,Value,ui,taui,ti,lossi,ci;
00699 G4bool isOut;
00700 ltt = ltauhigh-ltaulow;
00701 dltau = ltt/nbin;
00702 Value = 0.;
00703
00704 for (G4int i=0; i<=nbin; i++)
00705 {
00706 ui = ltaulow+dltau*i;
00707 taui = std::exp(ui);
00708 ti = ParticleMass*taui;
00709 lossi = physicsVector->GetValue(ti,isOut);
00710 if(i==0)
00711 ci=0.5;
00712 else
00713 {
00714 if(i<nbin)
00715 ci=1.;
00716 else
00717 ci=0.5;
00718 }
00719 Value += ci*taui*(ti+ParticleMass)/(std::sqrt(ti*(ti+2.*ParticleMass))*lossi);
00720 }
00721 Value *= ParticleMass*dltau/c_light;
00722 return Value;
00723 }
00724
00725
00726
00727 G4double G4hRDEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
00728 G4int nbin)
00729
00730 {
00731 G4double ltt,dltau,Value,ui,taui,ti,lossi,ci;
00732 G4bool isOut;
00733 ltt = ltauhigh-ltaulow;
00734 dltau = ltt/nbin;
00735 Value = 0.;
00736
00737 for (G4int i=0; i<=nbin; i++)
00738 {
00739 ui = ltaulow+dltau*i;
00740 taui = std::exp(ui);
00741 ti = ParticleMass*taui;
00742 lossi = physicsVector->GetValue(ti,isOut);
00743 if(i==0)
00744 ci=0.5;
00745 else
00746 {
00747 if(i<nbin)
00748 ci=1.;
00749 else
00750 ci=0.5;
00751 }
00752 Value += ci*taui*ParticleMass/(std::sqrt(ti*(ti+2.*ParticleMass))*lossi);
00753 }
00754 Value *= ParticleMass*dltau/c_light;
00755 return Value;
00756 }
00757
00758
00759
00760 void G4hRDEnergyLoss::BuildRangeCoeffATable(
00761 const G4ParticleDefinition& )
00762
00763
00764 {
00765
00766 G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
00767
00768 if(Charge>0.)
00769 {
00770 if(thepRangeCoeffATable)
00771 { thepRangeCoeffATable->clearAndDestroy();
00772 delete thepRangeCoeffATable; }
00773 thepRangeCoeffATable = new G4PhysicsTable(numOfCouples);
00774 theRangeCoeffATable = thepRangeCoeffATable ;
00775 theRangeTable = theRangepTable ;
00776 }
00777 else
00778 {
00779 if(thepbarRangeCoeffATable)
00780 { thepbarRangeCoeffATable->clearAndDestroy();
00781 delete thepbarRangeCoeffATable; }
00782 thepbarRangeCoeffATable = new G4PhysicsTable(numOfCouples);
00783 theRangeCoeffATable = thepbarRangeCoeffATable ;
00784 theRangeTable = theRangepbarTable ;
00785 }
00786
00787 G4double R2 = RTable*RTable ;
00788 G4double R1 = RTable+1.;
00789 G4double w = R1*(RTable-1.)*(RTable-1.);
00790 G4double w1 = RTable/w , w2 = -RTable*R1/w , w3 = R2/w ;
00791 G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
00792 G4bool isOut;
00793
00794
00795 for (G4int J=0; J<numOfCouples; J++)
00796 {
00797 G4int binmax=TotBin ;
00798 G4PhysicsLinearVector* aVector =
00799 new G4PhysicsLinearVector(0.,binmax, TotBin);
00800 Ti = LowestKineticEnergy ;
00801 if (Ti < DBL_MIN) Ti = 1.e-8;
00802 G4PhysicsVector* rangeVector= (*theRangeTable)[J];
00803
00804 for ( G4int i=0; i<TotBin; i++)
00805 {
00806 Ri = rangeVector->GetValue(Ti,isOut) ;
00807 if (Ti < DBL_MIN) Ti = 1.e-8;
00808 if ( i==0 )
00809 Rim = 0. ;
00810 else
00811 {
00812
00813
00814
00815 if (RTable != 0.)
00816 {
00817 Tim = Ti/RTable ;
00818 }
00819 else
00820 {
00821 Tim = 0.;
00822 }
00823 Rim = rangeVector->GetValue(Tim,isOut);
00824 }
00825 if ( i==(TotBin-1))
00826 Rip = Ri ;
00827 else
00828 {
00829 Tip = Ti*RTable ;
00830 Rip = rangeVector->GetValue(Tip,isOut);
00831 }
00832 Value = (w1*Rip + w2*Ri + w3*Rim)/(Ti*Ti) ;
00833
00834 aVector->PutValue(i,Value);
00835 Ti = RTable*Ti ;
00836 }
00837
00838 theRangeCoeffATable->insert(aVector);
00839 }
00840 }
00841
00842
00843
00844 void G4hRDEnergyLoss::BuildRangeCoeffBTable(
00845 const G4ParticleDefinition& )
00846
00847
00848 {
00849
00850 G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
00851
00852 if(Charge>0.)
00853 {
00854 if(thepRangeCoeffBTable)
00855 { thepRangeCoeffBTable->clearAndDestroy();
00856 delete thepRangeCoeffBTable; }
00857 thepRangeCoeffBTable = new G4PhysicsTable(numOfCouples);
00858 theRangeCoeffBTable = thepRangeCoeffBTable ;
00859 theRangeTable = theRangepTable ;
00860 }
00861 else
00862 {
00863 if(thepbarRangeCoeffBTable)
00864 { thepbarRangeCoeffBTable->clearAndDestroy();
00865 delete thepbarRangeCoeffBTable; }
00866 thepbarRangeCoeffBTable = new G4PhysicsTable(numOfCouples);
00867 theRangeCoeffBTable = thepbarRangeCoeffBTable ;
00868 theRangeTable = theRangepbarTable ;
00869 }
00870
00871 G4double R2 = RTable*RTable ;
00872 G4double R1 = RTable+1.;
00873 G4double w = R1*(RTable-1.)*(RTable-1.);
00874 if (w < DBL_MIN) w = DBL_MIN;
00875 G4double w1 = -R1/w , w2 = R1*(R2+1.)/w , w3 = -R2*R1/w ;
00876 G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
00877 G4bool isOut;
00878
00879
00880 for (G4int J=0; J<numOfCouples; J++)
00881 {
00882 G4int binmax=TotBin ;
00883 G4PhysicsLinearVector* aVector =
00884 new G4PhysicsLinearVector(0.,binmax, TotBin);
00885 Ti = LowestKineticEnergy ;
00886 if (Ti < DBL_MIN) Ti = 1.e-8;
00887 G4PhysicsVector* rangeVector= (*theRangeTable)[J];
00888
00889 for ( G4int i=0; i<TotBin; i++)
00890 {
00891 Ri = rangeVector->GetValue(Ti,isOut) ;
00892 if (Ti < DBL_MIN) Ti = 1.e-8;
00893 if ( i==0 )
00894 Rim = 0. ;
00895 else
00896 {
00897 if (RTable < DBL_MIN) RTable = DBL_MIN;
00898 Tim = Ti/RTable ;
00899 Rim = rangeVector->GetValue(Tim,isOut);
00900 }
00901 if ( i==(TotBin-1))
00902 Rip = Ri ;
00903 else
00904 {
00905 Tip = Ti*RTable ;
00906 Rip = rangeVector->GetValue(Tip,isOut);
00907 }
00908 if (Ti < DBL_MIN) Ti = DBL_MIN;
00909 Value = (w1*Rip + w2*Ri + w3*Rim)/Ti;
00910
00911 aVector->PutValue(i,Value);
00912 Ti = RTable*Ti ;
00913 }
00914 theRangeCoeffBTable->insert(aVector);
00915 }
00916 }
00917
00918
00919
00920 void G4hRDEnergyLoss::BuildRangeCoeffCTable(
00921 const G4ParticleDefinition& )
00922
00923
00924 {
00925
00926 G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
00927
00928 if(Charge>0.)
00929 {
00930 if(thepRangeCoeffCTable)
00931 { thepRangeCoeffCTable->clearAndDestroy();
00932 delete thepRangeCoeffCTable; }
00933 thepRangeCoeffCTable = new G4PhysicsTable(numOfCouples);
00934 theRangeCoeffCTable = thepRangeCoeffCTable ;
00935 theRangeTable = theRangepTable ;
00936 }
00937 else
00938 {
00939 if(thepbarRangeCoeffCTable)
00940 { thepbarRangeCoeffCTable->clearAndDestroy();
00941 delete thepbarRangeCoeffCTable; }
00942 thepbarRangeCoeffCTable = new G4PhysicsTable(numOfCouples);
00943 theRangeCoeffCTable = thepbarRangeCoeffCTable ;
00944 theRangeTable = theRangepbarTable ;
00945 }
00946
00947 G4double R2 = RTable*RTable ;
00948 G4double R1 = RTable+1.;
00949 G4double w = R1*(RTable-1.)*(RTable-1.);
00950 G4double w1 = 1./w , w2 = -RTable*R1/w , w3 = RTable*R2/w ;
00951 G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
00952 G4bool isOut;
00953
00954
00955 for (G4int J=0; J<numOfCouples; J++)
00956 {
00957 G4int binmax=TotBin ;
00958 G4PhysicsLinearVector* aVector =
00959 new G4PhysicsLinearVector(0.,binmax, TotBin);
00960 Ti = LowestKineticEnergy ;
00961 G4PhysicsVector* rangeVector= (*theRangeTable)[J];
00962
00963 for ( G4int i=0; i<TotBin; i++)
00964 {
00965 Ri = rangeVector->GetValue(Ti,isOut) ;
00966 if ( i==0 )
00967 Rim = 0. ;
00968 else
00969 {
00970 Tim = Ti/RTable ;
00971 Rim = rangeVector->GetValue(Tim,isOut);
00972 }
00973 if ( i==(TotBin-1))
00974 Rip = Ri ;
00975 else
00976 {
00977 Tip = Ti*RTable ;
00978 Rip = rangeVector->GetValue(Tip,isOut);
00979 }
00980 Value = w1*Rip + w2*Ri + w3*Rim ;
00981
00982 aVector->PutValue(i,Value);
00983 Ti = RTable*Ti ;
00984 }
00985 theRangeCoeffCTable->insert(aVector);
00986 }
00987 }
00988
00989
00990
00991 void G4hRDEnergyLoss::BuildInverseRangeTable(
00992 const G4ParticleDefinition& aParticleType)
00993
00994 {
00995 G4bool b;
00996
00997 const G4ProductionCutsTable* theCoupleTable=
00998 G4ProductionCutsTable::GetProductionCutsTable();
00999 size_t numOfCouples = theCoupleTable->GetTableSize();
01000
01001 if(&aParticleType == G4Proton::Proton())
01002 {
01003 if(theInverseRangepTable)
01004 { theInverseRangepTable->clearAndDestroy();
01005 delete theInverseRangepTable; }
01006 theInverseRangepTable = new G4PhysicsTable(numOfCouples);
01007 theInverseRangeTable = theInverseRangepTable ;
01008 theRangeTable = theRangepTable ;
01009 theDEDXTable = theDEDXpTable ;
01010 theRangeCoeffATable = thepRangeCoeffATable ;
01011 theRangeCoeffBTable = thepRangeCoeffBTable ;
01012 theRangeCoeffCTable = thepRangeCoeffCTable ;
01013 }
01014
01015 if(&aParticleType == G4AntiProton::AntiProton())
01016 {
01017 if(theInverseRangepbarTable)
01018 { theInverseRangepbarTable->clearAndDestroy();
01019 delete theInverseRangepbarTable; }
01020 theInverseRangepbarTable = new G4PhysicsTable(numOfCouples);
01021 theInverseRangeTable = theInverseRangepbarTable ;
01022 theRangeTable = theRangepbarTable ;
01023 theDEDXTable = theDEDXpbarTable ;
01024 theRangeCoeffATable = thepbarRangeCoeffATable ;
01025 theRangeCoeffBTable = thepbarRangeCoeffBTable ;
01026 theRangeCoeffCTable = thepbarRangeCoeffCTable ;
01027 }
01028
01029
01030 for (size_t i=0; i<numOfCouples; i++)
01031 {
01032
01033 G4PhysicsVector* pv = (*theRangeTable)[i];
01034 size_t nbins = pv->GetVectorLength();
01035 G4double elow = pv->GetLowEdgeEnergy(0);
01036 G4double ehigh = pv->GetLowEdgeEnergy(nbins-1);
01037 G4double rlow = pv->GetValue(elow, b);
01038 G4double rhigh = pv->GetValue(ehigh, b);
01039
01040 if (rlow <DBL_MIN) rlow = 1.e-8;
01041 if (rhigh > 1.e16) rhigh = 1.e16;
01042 if (rhigh < 1.e-8) rhigh =1.e-8;
01043 G4double tmpTrick = rhigh/rlow;
01044
01045
01046
01047
01048 if (tmpTrick <= 0. || tmpTrick < DBL_MIN) tmpTrick = 1.e-8;
01049 if (tmpTrick > 1.e16) tmpTrick = 1.e16;
01050
01051 rhigh *= std::exp(std::log(tmpTrick)/((G4double)(nbins-1)));
01052
01053 G4PhysicsLogVector* v = new G4PhysicsLogVector(rlow, rhigh, nbins);
01054
01055 v->PutValue(0,elow);
01056 G4double energy1 = elow;
01057 G4double range1 = rlow;
01058 G4double energy2 = elow;
01059 G4double range2 = rlow;
01060 size_t ilow = 0;
01061 size_t ihigh;
01062
01063 for (size_t j=1; j<nbins; j++) {
01064
01065 G4double range = v->GetLowEdgeEnergy(j);
01066
01067 for (ihigh=ilow+1; ihigh<nbins; ihigh++) {
01068 energy2 = pv->GetLowEdgeEnergy(ihigh);
01069 range2 = pv->GetValue(energy2, b);
01070 if(range2 >= range || ihigh == nbins-1) {
01071 ilow = ihigh - 1;
01072 energy1 = pv->GetLowEdgeEnergy(ilow);
01073 range1 = pv->GetValue(energy1, b);
01074 break;
01075 }
01076 }
01077
01078 G4double e = std::log(energy1) + std::log(energy2/energy1)*std::log(range/range1)/std::log(range2/range1);
01079
01080 v->PutValue(j,std::exp(e));
01081 }
01082 theInverseRangeTable->insert(v);
01083
01084 }
01085 }
01086
01087
01088
01089 void G4hRDEnergyLoss::InvertRangeVector(G4int materialIndex,
01090 G4PhysicsLogVector* aVector)
01091
01092 {
01093 G4double LowEdgeRange,A,B,C,discr,KineticEnergy ;
01094 G4double Tbin = LowestKineticEnergy/RTable ;
01095 G4double rangebin = 0.0 ;
01096 G4int binnumber = -1 ;
01097 G4bool isOut ;
01098
01099
01100
01101 for( G4int i=0; i<TotBin; i++)
01102 {
01103 LowEdgeRange = aVector->GetLowEdgeEnergy(i) ;
01104
01105 if( rangebin < LowEdgeRange )
01106 {
01107 do
01108 {
01109 binnumber += 1 ;
01110 Tbin *= RTable ;
01111 rangebin = (*theRangeTable)(materialIndex)->GetValue(Tbin,isOut) ;
01112 }
01113 while ((rangebin < LowEdgeRange) && (binnumber < TotBin )) ;
01114 }
01115
01116 if(binnumber == 0)
01117 KineticEnergy = LowestKineticEnergy ;
01118 else if(binnumber == TotBin-1)
01119 KineticEnergy = HighestKineticEnergy ;
01120 else
01121 {
01122 A = (*(*theRangeCoeffATable)(materialIndex))(binnumber-1) ;
01123 B = (*(*theRangeCoeffBTable)(materialIndex))(binnumber-1) ;
01124 C = (*(*theRangeCoeffCTable)(materialIndex))(binnumber-1) ;
01125 if(A==0.)
01126 KineticEnergy = (LowEdgeRange -C )/B ;
01127 else
01128 {
01129 discr = B*B - 4.*A*(C-LowEdgeRange);
01130 discr = discr>0. ? std::sqrt(discr) : 0.;
01131 KineticEnergy = 0.5*(discr-B)/A ;
01132 }
01133 }
01134
01135 aVector->PutValue(i,KineticEnergy) ;
01136 }
01137 }
01138
01139
01140
01141 G4bool G4hRDEnergyLoss::CutsWhereModified()
01142 {
01143 G4bool wasModified = false;
01144 const G4ProductionCutsTable* theCoupleTable=
01145 G4ProductionCutsTable::GetProductionCutsTable();
01146 size_t numOfCouples = theCoupleTable->GetTableSize();
01147
01148 for (size_t j=0; j<numOfCouples; j++){
01149 if (theCoupleTable->GetMaterialCutsCouple(j)->IsRecalcNeeded()) {
01150 wasModified = true;
01151 break;
01152 }
01153 }
01154 return wasModified;
01155 }
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180