Changeset 961 for trunk/source/processes/electromagnetic/utils/src
- Timestamp:
- Apr 6, 2009, 12:21:12 PM (15 years ago)
- Location:
- trunk/source/processes/electromagnetic/utils/src
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/utils/src/G4DummyModel.cc
r819 r961 25 25 // 26 26 // $Id: G4DummyModel.cc,v 1.3 2007/05/22 17:31:58 vnivanch Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- -
trunk/source/processes/electromagnetic/utils/src/G4EmCalculator.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4EmCalculator.cc,v 1. 37 2007/08/16 15:55:42vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4EmCalculator.cc,v 1.46 2009/02/24 09:56:03 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 55 55 // 10 keV to 1 keV (V. Ivanchenko) 56 56 // 15.03.2007 Add ComputeEnergyCutFromRangeCut methods (V.Ivanchenko) 57 // 21.04.2008 Updated computations for ions (V.Ivanchenko) 57 58 // 58 59 // Class Description: … … 126 127 if(couple && UpdateParticle(p, kinEnergy) ) { 127 128 res = manager->GetDEDX(p, kinEnergy, couple); 129 if(isIon) { 130 G4double eth = 2.0*MeV/massRatio; 131 if(kinEnergy > eth) { 132 G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy); 133 G4double x2 = corr->ComputeIonCorrections(p,mat,eth); 134 res += x1 - x2*eth/kinEnergy; 135 /* 136 G4cout << "### GetDEDX: E= " << kinEnergy << " res= " << res 137 << " x1= " << x1 << " x2= " << x2 138 << " del= " << x1 - x2*eth/kinEnergy << G4endl;; 139 */ 140 } 141 } 142 128 143 if(verbose>0) { 129 144 G4cout << "G4EmCalculator::GetDEDX: E(MeV)= " << kinEnergy/MeV … … 406 421 res = currentModel->ComputeDEDXPerVolume( 407 422 mat, baseParticle, escaled, cut) * chargeSquare; 408 if(verbose > 1) 423 if(verbose > 1) { 409 424 G4cout << baseParticle->GetParticleName() 410 425 << " Escaled(MeV)= " << escaled; 426 } 411 427 } else { 412 428 res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut); 413 429 if(verbose > 1) G4cout << " no basePart E(MeV)= " << kinEnergy; 414 430 } 415 if(verbose > 1) 431 if(verbose > 1) { 416 432 G4cout << " DEDX(MeV/mm)= " << res*mm/MeV 417 433 << " DEDX(MeV*cm^2/g)= " 418 434 << res*gram/(MeV*cm2*mat->GetDensity()) 419 435 << G4endl; 420 421 if(isIon) { 422 if(currentModel->HighEnergyLimit() > 100.*MeV) 423 res += corr->HighOrderCorrections(p,mat,kinEnergy); 424 else 425 res *= corr->EffectiveChargeCorrection(p,mat,kinEnergy); 426 if(verbose > 1) 427 G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV 428 << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity()) 429 << G4endl; 430 } 431 432 436 } 437 433 438 // emulate boundary region for different parameterisations 434 439 G4double eth = currentModel->LowEnergyLimit(); … … 447 452 res0 = loweModel->ComputeDEDXPerVolume(mat, p, eth, cut); 448 453 } 449 if(verbose > 1) 454 if(verbose > 1) { 450 455 G4cout << "At boundary energy(MeV)= " << eth/MeV 451 456 << " DEDX(MeV/mm)= " << res1*mm/MeV 452 457 << G4endl; 453 if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio); 454 //G4cout << "eth= " << eth << " escaled= " << escaled 455 // << " res0= " << res0 << " res1= " 456 // << res1 << " q2= " << chargeSquare << G4endl; 458 } 459 /* 460 G4cout << "eth= " << eth << " escaled= " << escaled 461 << " res0= " << res0 << " res1= " 462 << res1 << " q2= " << chargeSquare << G4endl; 463 */ 457 464 res *= (1.0 + (res0/res1 - 1.0)*eth/escaled); 465 466 if(isIon) { 467 G4double ethscaled = eth/massRatio; 468 if(kinEnergy > ethscaled) { 469 G4double x1 = corr->ComputeIonCorrections(p,mat,kinEnergy); 470 G4double x2 = corr->ComputeIonCorrections(p,mat,ethscaled); 471 res += x1 - x2*ethscaled/kinEnergy; 472 } 473 474 if(verbose > 1) { 475 G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV 476 << " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity()) 477 << G4endl; 478 } 479 } 458 480 } 459 481 … … 507 529 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 508 530 509 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4ParticleDefinition* part, 510 const G4Material* mat, G4double cut) 531 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, 532 const G4ParticleDefinition* part, 533 const G4Material* mat, 534 G4double cut) 511 535 { 512 536 G4double dedx = ComputeElectronicDEDX(kinEnergy,part,mat,cut); … … 517 541 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 518 542 519 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, const G4String& part, 520 const G4String& mat, G4double cut) 543 G4double G4EmCalculator::ComputeTotalDEDX(G4double kinEnergy, 544 const G4String& part, 545 const G4String& mat, 546 G4double cut) 521 547 { 522 548 return ComputeTotalDEDX(kinEnergy,FindParticle(part),FindMaterial(mat),cut); … … 729 755 if(currentProcess) currentProcessName = currentProcess->GetProcessName(); 730 756 731 if(p->GetParticleType() == "nucleus" && 732 currentParticleName != "deuteron" && currentParticleName != "triton") { 757 if(p->GetParticleType() == "nucleus" 758 && currentParticleName != "deuteron" 759 && currentParticleName != "triton" 760 && currentParticleName != "alpha+" 761 && currentParticleName != "helium" 762 && currentParticleName != "hydrogen" 763 ) { 733 764 baseParticle = theGenericIon; 734 765 massRatio = baseParticle->GetPDGMass()/p->GetPDGMass(); … … 755 786 if(isIon) { 756 787 chargeSquare = 757 ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy); 758 if(currentProcess) 788 ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy) 789 * corr->EffectiveChargeCorrection(p,currentMaterial,kinEnergy); 790 if(currentProcess) { 759 791 currentProcess->SetDynamicMassCharge(massRatio,chargeSquare); 760 // G4cout << "massR= " << massRatio << " q2= " << chargeSquare << G4endl; 792 //G4cout << "NewP: massR= " << massRatio << " q2= " << chargeSquare << G4endl; 793 } 761 794 } 762 795 return true; -
trunk/source/processes/electromagnetic/utils/src/G4EmCorrections.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4EmCorrections.cc,v 1. 23.2.1 2008/04/22 15:28:13 vnivanchExp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4EmCorrections.cc,v 1.51 2008/12/18 13:01:44 gunter Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 44 44 // 08.05.2007 V.Ivanchenko Use G4IonTable for ion mass instead of NistTable to avoid 45 45 // division by zero 46 // 29.02.2008 V.Ivanchenko use expantions for log and power function 47 // 21.04.2008 Updated computations for ions (V.Ivanchenko) 48 // 20.05.2008 Removed Finite Size correction (V.Ivanchenko) 46 49 // 47 50 // … … 56 59 #include "G4EmCorrections.hh" 57 60 #include "Randomize.hh" 58 #include "G4NistManager.hh"59 61 #include "G4ParticleTable.hh" 60 62 #include "G4IonTable.hh" 61 63 #include "G4VEmModel.hh" 62 64 #include "G4Proton.hh" 65 #include "G4GenericIon.hh" 63 66 #include "G4LPhysicsFreeVector.hh" 67 #include "G4PhysicsLogVector.hh" 68 #include "G4ProductionCutsTable.hh" 69 #include "G4MaterialCutsCouple.hh" 64 70 65 71 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 67 73 G4EmCorrections::G4EmCorrections() 68 74 { 69 Initialise();70 75 particle = 0; 71 76 curParticle= 0; … … 74 79 curVector = 0; 75 80 kinEnergy = 0.0; 76 ionModel = 0; 81 ionLEModel = 0; 82 ionHEModel = 0; 77 83 nIons = 0; 78 84 verbose = 1; 85 ncouples = 0; 79 86 massFactor = 1.0; 87 eth = 2.0*MeV; 88 nbinCorr = 20; 89 eCorrMin = 25.*keV; 90 eCorrMax = 250.*MeV; 80 91 nist = G4NistManager::Instance(); 81 92 ionTable = G4ParticleTable::GetParticleTable()->GetIonTable(); 93 Initialise(); 82 94 } 83 95 … … 93 105 G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p, 94 106 const G4Material* mat, 95 G4double e )107 G4double e, G4double) 96 108 { 97 109 // . Z^3 Barkas effect in the stopping power of matter for charged particles … … 108 120 G4double Bloch = BlochCorrection (p, mat, e); 109 121 G4double Mott = MottCorrection (p, mat, e); 110 G4double FSize = FiniteSizeCorrection (p, mat, e); 111 112 G4double sum = (2.0*(Barkas + Bloch) + FSize + Mott); 122 123 G4double sum = (2.0*(Barkas + Bloch) + Mott); 113 124 114 125 if(verbose > 1) 115 126 G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas 116 << " Bloch= " << Bloch << " Mott= " << Mott << " Fsize= " << FSize127 << " Bloch= " << Bloch << " Mott= " << Mott 117 128 << " Sum= " << sum << G4endl; 118 129 119 130 sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2; 131 return sum; 132 } 133 134 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 135 136 G4double G4EmCorrections::IonBarkasCorrection(const G4ParticleDefinition* p, 137 const G4Material* mat, 138 G4double e) 139 { 140 // . Z^3 Barkas effect in the stopping power of matter for charged particles 141 // J.C Ashley and R.H.Ritchie 142 // Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397 143 // and ICRU49 report 144 // valid for kineticEnergy < 0.5 MeV 145 146 SetupKinematics(p, mat, e); 147 G4double res = 0.0; 148 if(tau > 0.0) 149 res = 2.0*BarkasCorrection(p, mat, e)* 150 material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2; 151 return res; 152 } 153 154 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 155 156 G4double G4EmCorrections::ComputeIonCorrections(const G4ParticleDefinition* p, 157 const G4Material* mat, 158 G4double e) 159 { 160 // . Z^3 Barkas effect in the stopping power of matter for charged particles 161 // J.C Ashley and R.H.Ritchie 162 // Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397 163 // and ICRU49 report 164 // valid for kineticEnergy < 0.5 MeV 165 // Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980 166 SetupKinematics(p, mat, e); 167 if(tau <= 0.0) return 0.0; 168 169 G4double Barkas = BarkasCorrection (p, mat, e); 170 G4double Bloch = BlochCorrection (p, mat, e); 171 G4double Mott = MottCorrection (p, mat, e); 172 173 G4double sum = 2.0*(Barkas*(charge - 1.0)/charge + Bloch) + Mott; 174 175 if(verbose > 1) { 176 G4cout << "EmCorrections: E(MeV)= " << e/MeV << " Barkas= " << Barkas 177 << " Bloch= " << Bloch << " Mott= " << Mott 178 << " Sum= " << sum << G4endl; 179 } 180 sum *= material->GetElectronDensity() * q2 * twopi_mc2_rcl2 /beta2; 181 182 if(verbose > 1) G4cout << " Sum= " << sum << G4endl; 183 return sum; 184 } 185 186 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 187 188 G4double G4EmCorrections::IonHighOrderCorrections(const G4ParticleDefinition* p, 189 const G4MaterialCutsCouple* couple, 190 G4double e) 191 { 192 // . Z^3 Barkas effect in the stopping power of matter for charged particles 193 // J.C Ashley and R.H.Ritchie 194 // Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397 195 // and ICRU49 report 196 // valid for kineticEnergy < 0.5 MeV 197 // Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980 198 199 G4double sum = 0.0; 200 201 if(ionHEModel) { 202 G4int Z = G4int(p->GetPDGCharge()/eplus + 0.5); 203 if(Z >= 100) Z = 99; 204 else if(Z < 1) Z = 1; 205 206 // fill vector 207 if(thcorr[Z].size() == 0) { 208 thcorr[Z].resize(ncouples); 209 G4double ethscaled = eth*p->GetPDGMass()/proton_mass_c2; 210 211 for(size_t i=0; i<ncouples; i++) { 212 (thcorr[Z])[i] = ethscaled*ComputeIonCorrections(p, currmat[i], ethscaled); 213 //G4cout << i << ". ethscaled= " << ethscaled 214 //<< " corr= " << (thcorr[Z])[i]/ethscaled << G4endl; 215 } 216 } 217 G4double rest = (thcorr[Z])[couple->GetIndex()]; 218 219 sum = ComputeIonCorrections(p,couple->GetMaterial(),e) - rest/e; 220 221 if(verbose > 1) G4cout << " Sum= " << sum << " dSum= " << rest/e << G4endl; 222 } 120 223 return sum; 121 224 } … … 226 329 G4int ieta = Index(y, Eta, nEtaK); 227 330 corr = Value2(x, y, TheK[itet], TheK[itet+1], Eta[ieta], Eta[ieta+1], 228 CK[itet][ieta], CK[itet+1][ieta], CK[itet][ieta+1], CK[itet+1][ieta+1]); 331 CK[itet][ieta], CK[itet+1][ieta], 332 CK[itet][ieta+1], CK[itet+1][ieta+1]); 229 333 //G4cout << " x= " <<x<<" y= "<<y<<" tet= " <<TheK[itet] 230 334 //<<" "<< TheK[itet+1]<<" eta= "<< Eta[ieta]<<" "<< Eta[ieta+1] … … 439 543 else { 440 544 G4int iw = Index(W, engBarkas, 47); 441 val = Value(W, engBarkas[iw], engBarkas[iw+1], corBarkas[iw], corBarkas[iw+1]); 545 val = Value(W, engBarkas[iw], engBarkas[iw+1], 546 corBarkas[iw], corBarkas[iw+1]); 442 547 } 443 548 // G4cout << "i= " << i << " b= " << b << " W= " << W … … 479 584 { 480 585 SetupKinematics(p, mat, e); 481 G4double mterm = pi*fine_structure_const*beta*charge; 482 /* 483 G4double mterm = 0.0; 484 if(beta > 0.0) { 485 486 // Estimation of mean square root of the ionisation potential 487 G4double Zeff = 0.0; 488 G4double norm = 0.0; 489 490 for (G4int i = 0; i<numberOfElements; i++) { 491 G4double Z = (*theElementVector)[i]->GetZ(); 492 Zeff += Z*atomDensity[i]; 493 norm += atomDensity[i]; 494 } 495 Zeff *= (2.0/norm); 496 G4double ze1 = std::log(Zeff); 497 G4double eexc= material->GetIonisation()->GetMeanExcitationEnergy()*ze1*ze1/Zeff; 498 499 G4double invbeta = 1.0/beta; 500 G4double invbeta2= invbeta*invbeta; 501 G4double za = charge*fine_structure_const; 502 G4double za2 = za*za; 503 G4double za3 = za2*za; 504 G4double x = za*invbeta; 505 G4double cosx; 506 if(x < COSEB[13]) { 507 G4int i = Index(x,COSEB,14); 508 cosx = Value(x,COSEB[i], COSEB[i+1],COSXI[i],COSXI[i+1]); 509 } else { 510 cosx = COSXI[13]*COSEB[13]/x; 511 } 512 513 mterm = 514 za*beta*(1.725 + pi*cosx*(0.52 - 2.0*std::sqrt(eexc/(2.0*electron_mass_c2*bg2)))); 515 + za2*(3.246 - 0.451*beta2) 516 + za3*(1.522*beta + 0.987*invbeta) 517 + za2*za2*(4.569 - 0.494*beta2 - 2.696*invbeta2) 518 + za3*za2*(1.254*beta + 0.222*invbeta - 1.17*invbeta*invbeta2); 519 } 520 */ 586 G4double mterm = CLHEP::pi*fine_structure_const*beta*charge; 521 587 return mterm; 522 }523 524 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....525 526 G4double G4EmCorrections::FiniteSizeCorrection(const G4ParticleDefinition* p,527 const G4Material* mat,528 G4double e)529 // Finite size corrections are parameterized according to530 // J.D.Jackson Phys. Rev. D59 (1998) 017301531 {532 if(p) return 0.0;533 SetupKinematics(p, mat, e);534 G4double term = 0.0;535 G4double numlim = 0.2;536 537 //Leptons538 if(p->GetLeptonNumber() != 0) {539 G4double x = tmax/(e + mass);540 term = x*x;541 542 // Pions and Kaons543 } else if(p->GetPDGSpin() == 0.0 && q2 < 1.5) {544 G4double xpi = 0.736*GeV;545 G4double x = 2.0*electron_mass_c2*tmax0/(xpi*xpi);546 if(x <= numlim) term = -x*(1.0 - 0.5*x);547 else term = -std::log(1.0 + x);548 549 // Protons and baryons550 } else if(q2 < 1.5) {551 G4double xp = 0.8426*GeV;552 G4double x = 2.0*electron_mass_c2*tmax0/(xp*xp);553 G4double ksi2 = 2.79285*2.79285;554 if(x <= numlim) term = -x*((1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) + 0.5*x);555 else term = -x*(1.0 + 5.0*x/6.0)/((1.0 + x)*(1 + x)) - std::log(1.0 + x);556 G4double b = xp*0.5/mass;557 G4double c = xp*mass/(electron_mass_c2*(mass + e));558 G4double lb = b*b;559 G4double lb2= lb*lb;560 G4double nu = 0.5*c*c;561 G4double x1 = 1.0 + x;562 G4double x2 = x1*x1;563 G4double l1 = 1.0 - lb;564 G4double l2 = l1*l1;565 G4double lx = 1.0 + lb*x;566 G4double ia = lb2*(lx*std::log(lx/x1)/x + l1 -567 0.5*x*l2/(lb*x1) +568 x*(3.0 + 2.0*x)*l2*l1/(6.0*x2*lb2))/(l2*l2);569 G4double ib = x*x*(3.0 + x)/(6.0*x2*x1);570 term += lb*((ksi2 - 1.0)*ia + nu*ksi2*ib);571 // G4cout << "Proton F= " << term << " ia= " << ia << " ib= " << ib << " lb= " << lb<< G4endl;572 573 //ions574 } else {575 G4double xp = 0.8426*GeV/std::pow(mass/proton_mass_c2,-0.33333333);576 G4double x = 2.0*electron_mass_c2*tmax0/(xp*xp);577 if(x <= numlim) term = -x*(1.0 - 0.5*x);578 else term = -std::log(1.0 + x);579 //G4cout << "Ion F= " << term << G4endl;580 }581 582 return term;583 588 } 584 589 … … 629 634 if (er >= ed[0]) nloss = a[0]; 630 635 else { 636 // the table is inverse in energy 631 637 for (G4int i=102; i>=0; i--) 632 638 { … … 657 663 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 658 664 659 G4ionEffectiveCharge* G4EmCorrections::GetIonEffectiveCharge(G4VEmModel* m)660 {661 if(m) ionModel = m;662 return &effCharge;663 }664 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....665 666 G4int G4EmCorrections::GetNumberOfStoppingVectors()667 {668 return nIons;669 }670 671 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....672 673 665 G4double G4EmCorrections::EffectiveChargeCorrection(const G4ParticleDefinition* p, 674 666 const G4Material* mat, … … 676 668 { 677 669 G4double factor = 1.0; 678 if(p->GetPDGCharge() <= 2.5*eplus) return factor; 679 if(verbose > 1) 680 G4cout << "EffectiveChargeCorrection: " << p->GetParticleName() << " in " << mat->GetName() 670 if(p->GetPDGCharge() <= 2.5*eplus || nIons <= 0) return factor; 671 /* 672 if(verbose > 1) { 673 G4cout << "EffectiveChargeCorrection: " << p->GetParticleName() 674 << " in " << mat->GetName() 681 675 << " ekin(MeV)= " << ekin/MeV << G4endl; 676 } 677 */ 682 678 if(p != curParticle || mat != curMaterial) { 683 679 curParticle = p; 684 curMaterial = 0;680 curMaterial = mat; 685 681 curVector = 0; 686 G4int Z = p->GetAtomicNumber(); 687 G4int A = p->GetAtomicMass(); 688 if(verbose > 1) G4cout << "Zion= " << Z << " Aion= " << A << G4endl; 689 massFactor = proton_mass_c2/ionTable->GetIonMass(Z,A); 690 idx = 0; 691 for(; idx<nIons; idx++) { 692 if(Z == Zion[idx] && A == Aion[idx]) { 693 if(materialList[idx] == mat) { 694 curMaterial = mat; 695 curVector = stopData[idx]; 696 break; 697 } else if(materialList[idx] == 0) { 698 if(materialName[idx] == mat->GetName()) 699 curVector = InitialiseMaterial(mat); 700 } 682 currentZ = p->GetAtomicNumber(); 683 if(verbose > 1) { 684 G4cout << "G4EmCorrections::EffectiveChargeCorrection: Zion= " 685 << currentZ << " Aion= " << p->GetPDGMass()/amu_c2 << G4endl; 686 } 687 massFactor = proton_mass_c2/p->GetPDGMass(); 688 idx = -1; 689 G4int dz = 1000; 690 691 for(G4int i=0; i<nIons; i++) { 692 if(materialList[i] == mat) { 693 G4int delz = currentZ - Zion[i]; 694 if(delz < 0) delz = -delz; 695 if(delz < dz) { 696 idx = i; 697 dz = delz; 698 if(0 == delz) break; 699 } 701 700 } 701 } 702 // G4cout << " idx= " << idx << " dz= " << dz << G4endl; 703 if(idx > 0) { 704 if(!ionList[idx]) BuildCorrectionVector(); 705 if(ionList[idx]) curVector = stopData[idx]; 702 706 } 703 707 } … … 705 709 G4bool b; 706 710 factor = curVector->GetValue(ekin*massFactor,b); 707 } 708 if(verbose > 1) G4cout << " factor= " << factor << G4endl; 711 if(verbose > 1) { 712 G4cout << "E= " << ekin << " factor= " << factor << " massfactor= " 713 << massFactor << G4endl; 714 } 715 } 709 716 return factor; 710 717 } … … 714 721 void G4EmCorrections::AddStoppingData(G4int Z, G4int A, 715 722 const G4String& mname, 716 G4PhysicsVector& dVector) 717 { 718 idx = 0; 719 for(; idx<nIons; idx++) { 720 if(Z == Zion[idx] && A == Aion[idx] && mname == materialName[idx]) 721 break; 722 } 723 if(idx == nIons) { 723 G4PhysicsVector* dVector) 724 { 725 G4int i = 0; 726 for(; i<nIons; i++) { 727 if(Z == Zion[i] && A == Aion[i] && mname == materialName[i]) break; 728 } 729 if(i == nIons) { 724 730 Zion.push_back(Z); 725 731 Aion.push_back(A); 726 732 materialName.push_back(mname); 727 733 materialList.push_back(0); 728 stopData.push_back(0); 734 ionList.push_back(0); 735 stopData.push_back(dVector); 729 736 nIons++; 730 } else { 731 if(stopData[idx]) delete stopData[idx]; 732 } 733 size_t nbins = dVector.GetVectorLength(); 734 size_t n = 0; 735 for(; n<nbins; n++) { 736 if(dVector.GetLowEdgeEnergy(n) > 2.0*MeV) break; 737 } 738 if(n < nbins) nbins = n + 1; 739 G4LPhysicsFreeVector* v = 740 new G4LPhysicsFreeVector(nbins, 741 dVector.GetLowEdgeEnergy(0), 742 dVector.GetLowEdgeEnergy(nbins-1)); 737 if(verbose>1) { 738 G4cout << "AddStoppingData Z= " << Z << " A= " << A << " " << mname 739 << " idx= " << i << G4endl; 740 } 741 } 742 } 743 744 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 745 746 void G4EmCorrections::BuildCorrectionVector() 747 { 748 if(!ionLEModel || !ionHEModel) { 749 return; 750 } 751 752 const G4ParticleDefinition* ion = curParticle; 753 G4int Z = Zion[idx]; 754 if(currentZ != Z) { 755 ion = G4ParticleTable::GetParticleTable()->FindIon(Z, Aion[idx], 0, Z); 756 } 757 //G4cout << "BuildCorrectionVector: idx= " << idx << " Z= " << Z 758 // << " curZ= " << currentZ << G4endl; 759 760 // G4double A = nist->GetAtomicMassAmu(Z); 761 G4double A = G4double(ion->GetBaryonNumber()); 762 G4PhysicsVector* v = stopData[idx]; 763 764 const G4ParticleDefinition* p = G4GenericIon::GenericIon(); 765 G4double massRatio = proton_mass_c2/ion->GetPDGMass(); 766 767 if(verbose>1) { 768 G4cout << "BuildCorrectionVector: Stopping for " 769 << curParticle->GetParticleName() << " in " 770 << materialName[idx] << " Ion Z= " << Z << " A= " << A 771 << " massRatio= " << massRatio << G4endl; 772 } 743 773 G4bool b; 744 for(size_t i=0; i<nbins; i++) { 745 G4double e = dVector.GetLowEdgeEnergy(i); 746 G4double dedx = dVector.GetValue(e, b); 747 v->PutValues(i, e, dedx); 748 } 749 // G4cout << *v << G4endl; 750 stopData[idx] = v; 751 } 752 753 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 754 755 G4PhysicsVector* G4EmCorrections::InitialiseMaterial(const G4Material* mat) 756 { 757 G4PhysicsVector* v = 0; 758 const G4Material* m = nist->FindOrBuildMaterial(materialName[idx],false); 759 if(m) { 760 materialList[idx] = m; 761 curMaterial = mat; 762 v = stopData[idx]; 763 size_t nbins = v->GetVectorLength(); 764 const G4ParticleDefinition* p = G4Proton::Proton(); 765 if(verbose>1) G4cout << "G4ionIonisation::InitialiseMaterial Stooping data for " 766 << materialName[idx] << G4endl; 767 G4bool b; 768 for(size_t i=0; i<nbins; i++) { 769 G4double e = v->GetLowEdgeEnergy(i); 770 G4double dedx = v->GetValue(e, b); 771 G4double dedx1= ionModel->ComputeDEDXPerVolume(mat, p, e, e)* 772 effCharge.EffectiveChargeSquareRatio(curParticle,mat,e/massFactor); 773 v->PutValue(i, dedx/dedx1); 774 if(verbose>1) G4cout << " E(meV)= " << e/MeV << " Correction= " << dedx/dedx1 775 << " " << dedx << " " << dedx1 << G4endl; 776 } 777 } 778 return v; 774 775 G4PhysicsLogVector* vv = 776 new G4PhysicsLogVector(eCorrMin,eCorrMax,nbinCorr); 777 vv->SetSpline(true); 778 G4double e, eion, dedx, dedx1; 779 G4double eth0 = v->GetLowEdgeEnergy(0); 780 G4double escal = eth/massRatio; 781 G4double qe = 782 effCharge.EffectiveChargeSquareRatio(ion, curMaterial, escal); 783 G4double dedxt = 784 ionLEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe; 785 G4double dedx1t = 786 ionHEModel->ComputeDEDXPerVolume(curMaterial, p, eth, eth)*qe 787 + ComputeIonCorrections(curParticle, curMaterial, escal); 788 G4double rest = escal*(dedxt - dedx1t); 789 //G4cout << "Escal(MeV)= "<<escal<<" dedxt0= " <<dedxt 790 // << " dedxt1= " << dedx1t << G4endl; 791 792 for(G4int i=0; i<nbinCorr; i++) { 793 e = vv->GetLowEdgeEnergy(i); 794 escal = e/massRatio; 795 eion = escal/A; 796 if(eion <= eth0) { 797 dedx = v->GetValue(eth0, b)*std::sqrt(eion/eth0); 798 } else { 799 dedx = v->GetValue(eion, b); 800 } 801 qe = effCharge.EffectiveChargeSquareRatio(curParticle,curMaterial,escal); 802 if(e <= eth) { 803 dedx1 = ionLEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe; 804 } else { 805 dedx1 = ionHEModel->ComputeDEDXPerVolume(curMaterial, p, e, e)*qe + 806 ComputeIonCorrections(curParticle, curMaterial, escal) + rest/escal; 807 } 808 vv->PutValue(i, dedx/dedx1); 809 if(verbose>1) { 810 G4cout << " E(meV)= " << e/MeV << " Correction= " << dedx/dedx1 811 << " " << dedx << " " << dedx1 812 << " massF= " << massFactor << G4endl; 813 } 814 } 815 delete v; 816 ionList[idx] = ion; 817 stopData[idx] = vv; 818 if(verbose>1) G4cout << "End data set " << G4endl; 819 } 820 821 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 822 823 void G4EmCorrections::InitialiseForNewRun() 824 { 825 G4ProductionCutsTable* tb = G4ProductionCutsTable::GetProductionCutsTable(); 826 ncouples = tb->GetTableSize(); 827 if(currmat.size() != ncouples) { 828 currmat.resize(ncouples); 829 size_t i; 830 for(i=0; i<100; i++) {thcorr[i].clear();} 831 for(i=0; i<ncouples; i++) { 832 currmat[i] = tb->GetMaterialCutsCouple(i)->GetMaterial(); 833 G4String nam = currmat[i]->GetName(); 834 for(G4int j=0; j<nIons; j++) { 835 if(nam == materialName[j]) { materialList[j] = currmat[i]; } 836 } 837 } 838 } 779 839 } 780 840 -
trunk/source/processes/electromagnetic/utils/src/G4EmModelManager.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4EmModelManager.cc,v 1.4 0 2007/11/09 11:35:54vnivanch Exp $27 // GEANT4 tag $Name: $26 // $Id: G4EmModelManager.cc,v 1.46 2008/10/13 14:56:56 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 78 78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 79 79 80 G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& list, G4DataVector& lowE) 80 G4RegionModels::G4RegionModels(G4int nMod, std::vector<G4int>& indx, 81 G4DataVector& lowE, const G4Region* reg) 81 82 { 82 83 nModelsForRegion = nMod; 83 84 theListOfModelIndexes = new G4int [nModelsForRegion]; 84 lowKineticEnergy = new G4double [nModelsForRegion ];85 lowKineticEnergy = new G4double [nModelsForRegion+1]; 85 86 for (G4int i=0; i<nModelsForRegion; i++) { 86 theListOfModelIndexes[i] = list[i];87 theListOfModelIndexes[i] = indx[i]; 87 88 lowKineticEnergy[i] = lowE[i]; 88 89 } 90 lowKineticEnergy[nModelsForRegion] = lowE[nModelsForRegion]; 91 theRegion = reg; 89 92 } 90 93 … … 99 102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 100 103 101 #include "G4LossTableManager.hh"102 104 #include "G4Step.hh" 103 105 #include "G4ParticleDefinition.hh" … … 107 109 #include "G4MaterialCutsCouple.hh" 108 110 #include "G4ProductionCutsTable.hh" 109 #include "G4Region.hh"110 111 #include "G4RegionStore.hh" 111 112 #include "G4Gamma.hh" 112 113 #include "G4Positron.hh" 114 #include "G4UnitsTable.hh" 113 115 114 116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 128 130 regions.clear(); 129 131 orderOfModels.clear(); 130 upperEkin.clear();131 132 maxCutInRange = 12.*cm; 132 133 maxSubCutInRange = 0.7*mm; … … 139 140 G4EmModelManager::~G4EmModelManager() 140 141 { 141 G4int i,j;142 142 Clear(); 143 } 144 145 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 146 147 void G4EmModelManager::Clear() 148 { 143 149 if(1 < verboseLevel) { 144 G4cout << "G4EmModelManager:: delete models "; 145 if(particle) G4cout << " for " << particle->GetParticleName(); 146 G4cout << " nModels=" << nEmModels <<G4endl; 147 } 148 149 for(i = 0; i<nEmModels; i++) { 150 orderOfModels[i] = 1; 151 } 152 for(i = 0; i<nEmModels; i++) { 153 if (orderOfModels[i]) { 154 orderOfModels[i] = 0; 155 for(j = i+1; j<nEmModels; j++) { 156 if(models[i] == models[j]) orderOfModels[j] = 0; 157 } 158 G4String nam = models[i]->GetName(); 159 if(nam != "PAI" && nam != "PAIModel" ) delete models[i]; 160 } 161 } 162 for(i = 0; i<nEmModels; i++) { 163 orderOfModels[i] = 1; 164 } 165 for(i = 0; i<nEmModels; i++) { 166 if (orderOfModels[i]) { 167 orderOfModels[i] = 0; 168 for(j = i+1; j<nEmModels; j++) { 169 if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0; 170 } 171 delete flucModels[i]; 172 } 173 } 174 if(1 < verboseLevel) 175 G4cout << "G4EmModelManager:: models are deleted!" << G4endl; 176 } 177 178 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 179 180 void G4EmModelManager::Clear() 181 { 182 if(1 < verboseLevel) { 183 G4cout << "G4EmModelManager::Clear()"; 184 if(particle) G4cout << " for " << particle->GetParticleName(); 185 G4cout << G4endl; 150 G4cout << "G4EmModelManager::Clear()" << G4endl; 186 151 } 187 152 188 153 theCuts.clear(); 189 154 theSubCuts.clear(); 190 upperEkin.clear();191 155 if(idxOfRegionModels) delete [] idxOfRegionModels; 192 156 if(setOfRegionModels && nRegions) { … … 215 179 orderOfModels.push_back(num); 216 180 p->DefineForRegion(r); 217 if (nEmModels>0) {218 G4int idx = nEmModels;219 do {idx--;} while (idx && num < orderOfModels[idx]);220 if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;221 if (idx < nEmModels) {222 models[nEmModels] = models[idx];223 flucModels[nEmModels] = flucModels[idx];224 regions[nEmModels] = regions[idx];225 orderOfModels[nEmModels] = orderOfModels[idx];226 models[idx] = p;227 flucModels[idx] = fm;228 regions[idx] = r;229 orderOfModels[idx] = num;230 }231 }232 181 nEmModels++; 233 182 } … … 254 203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 255 204 256 G4VEmModel* G4EmModelManager::GetModel(G4int i )205 G4VEmModel* G4EmModelManager::GetModel(G4int i, G4bool ver) 257 206 { 258 207 G4VEmModel* m = 0; 259 if(i >= 0 && i < nEmModels) m = models[i];260 else if(verboseLevel > 0 )208 if(i >= 0 && i < nEmModels) {m = models[i];} 209 else if(verboseLevel > 0 && ver) { 261 210 G4cout << "G4EmModelManager::GetModel WARNING: " 262 211 << "index " << i << " is wrong Nmodels= " 263 << nEmModels << G4endl; 212 << nEmModels; 213 if(particle) G4cout << " for " << particle->GetParticleName(); 214 G4cout<< G4endl; 215 } 264 216 return m; 265 217 } … … 269 221 const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p, 270 222 const G4ParticleDefinition* sp, 271 272 223 G4double theMinSubRange, 224 G4int val) 273 225 { 274 226 verboseLevel = val; … … 293 245 // Identify the list of regions with different set of models 294 246 nRegions = 1; 295 std::vector<const G4Region*> set ;296 set .push_back(world);247 std::vector<const G4Region*> setr; 248 setr.push_back(world); 297 249 G4bool isWorld = false; 298 250 … … 306 258 if (nRegions>1) { 307 259 for (G4int j=1; j<nRegions; j++) { 308 if ( r == set [j] ) newRegion = false;260 if ( r == setr[j] ) newRegion = false; 309 261 } 310 262 } 311 263 if (newRegion) { 312 set .push_back(r);264 setr.push_back(r); 313 265 nRegions++; 314 266 } … … 322 274 idxOfRegionModels[numOfCouples] = 0; 323 275 setOfRegionModels = new G4RegionModels*[nRegions]; 324 upperEkin.resize(nEmModels); 276 277 std::vector<G4int> modelAtRegion(nEmModels); 278 std::vector<G4int> modelOrd(nEmModels); 279 G4DataVector eLow(nEmModels); 280 G4DataVector eHigh(nEmModels); 281 G4int nmax = nEmModels; 325 282 326 283 // Order models for regions 327 284 for (G4int reg=0; reg<nRegions; reg++) { 328 const G4Region* region = set[reg]; 329 285 const G4Region* region = setr[reg]; 330 286 G4int n = 0; 331 332 std::vector<G4int> modelAtRegion;333 G4DataVector eLow;334 G4DataVector eHigh;335 modelAtRegion.clear();336 eLow.clear();337 eHigh.clear();338 287 339 288 if(isWorld || 0 < reg) { … … 346 295 G4double tmin = model->LowEnergyLimit(); 347 296 G4double tmax = model->HighEnergyLimit(); 348 if (n>0) tmin = std::max(tmin, eHigh[n-1]); 297 G4int ord = orderOfModels[ii]; 298 G4bool push = true; 299 G4bool insert = false; 300 G4int idx = n; 349 301 350 302 if(1 < verboseLevel) { … … 355 307 << " tmin(MeV)= " << tmin/MeV 356 308 << "; tmax(MeV)= " << tmax/MeV 357 << "; order= " << ord erOfModels[ii]309 << "; order= " << ord 358 310 << G4endl; 359 311 } 360 361 if (tmin < tmax) { 362 modelAtRegion.push_back(ii); 363 eLow.push_back(tmin); 364 eHigh.push_back(tmax); 365 upperEkin[ii] = tmax; 366 n++; 312 313 if (n == 0) n++; 314 else { 315 tmin = std::min(tmin, eHigh[n-1]); 316 if(tmin >= tmax) push = false; 317 else { 318 319 // high energy model 320 if(tmin == eHigh[n-1] && tmax > eHigh[n-1]) n++; 321 else if (tmax > eHigh[n-1]) { 322 323 // compare order of models 324 for(G4int k = n-1; k>=0; k--) { 325 326 if (ord >= modelOrd[k]) { 327 tmin = std::max(tmin, eHigh[k]); 328 if(k < n-1) n = k + 2; 329 break; 330 } else if (tmin > eLow[k]) { 331 eHigh[k] = tmin; 332 n = k + 2; 333 break; 334 } else if (tmin == eLow[k]) { 335 n = k + 1; 336 break; 337 } 338 } 339 if(tmin < eLow[0]) n = 1; 340 idx = n - 1; 341 342 // low energy model 343 } else { 344 345 tmax = std::max(tmax, eLow[0]); 346 insert = true; 347 push = false; 348 idx = 0; 349 if(tmax <= eLow[0]) tmax = eLow[0]; 350 else { 351 352 for(G4int k=0; k<n; k++) { 353 354 if (ord >= modelOrd[k]) { 355 if(k == 0) { 356 if(tmin < eLow[0]) tmax = eLow[0]; 357 else insert = false; 358 break; 359 } else { 360 insert = false; 361 break; 362 } 363 } else if(tmax < eHigh[k]) { 364 idx = k; 365 if(k > 0) tmin = eLow[k]; 366 eLow[k] = tmax; 367 break; 368 } else if(tmax == eHigh[k]) { 369 insert = false; 370 push = true; 371 idx = k; 372 if(k > 0) tmin = eLow[k]; 373 else tmin = std::min(tmin,eLow[0]); 374 break; 375 } else { 376 modelAtRegion[k] = ii; 377 modelOrd[k] = ord; 378 if(k == 0) eLow[idx] = std::min(tmin,eLow[0]); 379 } 380 } 381 } 382 if(insert && idx < n) n++; 383 else insert = false; 384 } 385 } 386 } 387 if(n > nmax) { 388 nmax = n; 389 modelAtRegion.resize(nmax); 390 modelOrd.resize(nmax); 391 eLow.resize(nmax); 392 eHigh.resize(nmax); 393 } 394 if(insert) { 395 for(G4int k=n-2; k>=idx; k--) { 396 modelAtRegion[k+1] = modelAtRegion[k]; 397 modelOrd[k+1] = modelOrd[k]; 398 eLow[k+1] = eLow[k]; 399 eHigh[k+1] = eHigh[k]; 400 } 401 } 402 if (push || insert) { 403 modelAtRegion[idx] = ii; 404 modelOrd[idx] = ord; 405 eLow[idx] = tmin; 406 eHigh[idx] = tmax; 367 407 } 368 408 } … … 374 414 eLow.push_back(0.0); 375 415 eHigh.push_back(DBL_MAX); 376 upperEkin.push_back(DBL_MAX);377 416 } 378 417 eLow[0] = 0.0; 418 if(n >= nmax) eLow.resize(nmax+1); 419 eLow[n] = eHigh[n-1]; 379 420 380 421 if(1 < verboseLevel) { … … 382 423 if (region) G4cout << region->GetName(); 383 424 G4cout << "> Elow(MeV)= "; 384 for(G4int ii=0; ii< n; ii++) {G4cout << eLow[ii]/MeV << " ";}425 for(G4int ii=0; ii<=n; ii++) {G4cout << eLow[ii]/MeV << " ";} 385 426 G4cout << G4endl; 386 427 } 387 G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow );428 G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow, region); 388 429 setOfRegionModels[reg] = rm; 389 430 } … … 399 440 400 441 G4int reg = nRegions; 401 do {reg--;} while (reg>0 && pcuts != (set [reg]->GetProductionCuts()));442 do {reg--;} while (reg>0 && pcuts != (setr[reg]->GetProductionCuts())); 402 443 idxOfRegionModels[i] = reg; 403 444 … … 474 515 { 475 516 476 // vectors to provide continues dE/dx477 G4DataVector factor;478 G4DataVector dedxLow;479 G4DataVector dedxHigh;480 481 517 G4double e; 482 518 … … 491 527 G4cout << "G4EmModelManager::FillDEDXVector() for " 492 528 << couple->GetMaterial()->GetName() 493 << " Ecut(MeV)= " << cut494 << " Esubcut(MeV)= " << subcut529 << " cut(MeV)= " << cut 530 << " subcut(MeV)= " << subcut 495 531 << " Type " << tType 496 532 << " for " << particle->GetParticleName() … … 501 537 const G4RegionModels* regModels = setOfRegionModels[reg]; 502 538 G4int nmod = regModels->NumberOfModels(); 503 factor.resize(nmod); 504 dedxLow.resize(nmod); 505 dedxHigh.resize(nmod); 539 540 // vectors to provide continues dE/dx 541 G4DataVector factor(nmod); 542 G4DataVector eLow(nmod+1); 543 G4DataVector dedxLow(nmod); 544 G4DataVector dedxHigh(nmod); 506 545 507 546 if(1 < verboseLevel) { … … 512 551 } 513 552 514 515 553 // calculate factors to provide continuity of energy loss 554 555 516 556 factor[0] = 1.0; 517 557 G4int j; … … 519 559 G4int totBinsLoss = aVector->GetVectorLength(); 520 560 521 dedxLow[0] = 0.0; 522 523 e = upperEkin[regModels->ModelIndex(0)]; 561 dedxLow[0] = 0.0; 562 eLow[0] = 0.0; 563 564 e = regModels->LowEdgeEnergy(1); 565 eLow[1] = e; 524 566 G4VEmModel* model = models[regModels->ModelIndex(0)]; 525 567 dedxHigh[0] = 0.0; 526 568 if(model && cut > subcut) { 527 569 dedxHigh[0] = model->ComputeDEDX(couple,particle,e,cut); 528 if(subcut > 0.0) 570 if(subcut > 0.0) { 529 571 dedxHigh[0] -= model->ComputeDEDX(couple,particle,e,subcut); 572 } 530 573 } 531 574 if(nmod > 1) { 532 575 for(j=1; j<nmod; j++) { 533 576 534 e = upperEkin[regModels->ModelIndex(j-1)]; 577 e = regModels->LowEdgeEnergy(j); 578 eLow[j] = e; 535 579 G4int idx = regModels->ModelIndex(j); 536 580 537 581 dedxLow[j] = models[idx]->ComputeDEDX(couple,particle,e,cut); 538 if(subcut > 0.0) 582 if(subcut > 0.0) { 539 583 dedxLow[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut); 584 } 540 585 if(subcut == cut) dedxLow[j] = 0.0; 541 586 542 e = upperEkin[idx]; 587 e = regModels->LowEdgeEnergy(j+1); 588 eLow[j+1] = e; 543 589 dedxHigh[j] = models[idx]->ComputeDEDX(couple,particle,e,cut); 544 if(subcut > 0.0) 590 if(subcut > 0.0) { 545 591 dedxHigh[j] -= models[idx]->ComputeDEDX(couple,particle,e,subcut); 592 } 546 593 if(subcut == cut) dedxHigh[j] = 0.0; 547 594 } 595 if(1 < verboseLevel) { 596 G4cout << " model #0" 597 << " dedx(" << eLow[0] << ")= " << dedxLow[0] 598 << " dedx(" << eLow[1] << ")= " << dedxHigh[0] 599 << G4endl; 600 } 548 601 549 602 for(j=1; j<nmod; j++) { 550 if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0); 551 else factor[j] = 0.0; 603 if(dedxLow[j] > 0.0) { 604 factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0)*eLow[j]; 605 } else factor[j] = 0.0; 606 if(1 < verboseLevel) { 607 G4cout << " model #" << j 608 << " dedx(" << eLow[j] << ")= " << dedxLow[j] 609 << " dedx(" << eLow[j+1] << ")= " << dedxHigh[j] 610 << " factor= " << factor[j]/eLow[j] 611 << G4endl; 612 } 552 613 } 553 614 … … 565 626 // Choose a model of energy losses 566 627 G4int k = 0; 567 if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {628 if (nmod > 1 && e > eLow[1]) { 568 629 do { 569 630 k++; 570 fac *= (1.0 + factor[k] *upperEkin[regModels->ModelIndex(k-1)]/e);571 } while (k <nmod-1 && e > upperEkin[regModels->ModelIndex(k)]);631 fac *= (1.0 + factor[k]/e); 632 } while (k+1 < nmod && e > eLow[k+1]); 572 633 } 573 634 … … 602 663 G4EmTableType tType) 603 664 { 604 // vectors to provide continues cross section605 G4DataVector factor;606 G4DataVector sigmaLow;607 G4DataVector sigmaHigh;608 609 665 G4double e; 610 666 … … 630 686 const G4RegionModels* regModels = setOfRegionModels[reg]; 631 687 G4int nmod = regModels->NumberOfModels(); 632 factor.resize(nmod); 633 sigmaLow.resize(nmod); 634 sigmaHigh.resize(nmod); 688 689 // vectors to provide continues dE/dx 690 G4DataVector factor(nmod); 691 G4DataVector eLow(nmod+1); 692 G4DataVector sigmaLow(nmod); 693 G4DataVector sigmaHigh(nmod); 635 694 636 695 if(2 < verboseLevel) { … … 644 703 G4int totBinsLambda = aVector->GetVectorLength(); 645 704 646 sigmaLow[0] = 0.0; 647 648 e = upperEkin[regModels->ModelIndex(0)]; 705 sigmaLow[0] = 0.0; 706 eLow[0] = 0.0; 707 708 e = regModels->LowEdgeEnergy(1); 709 eLow[1] = e; 649 710 G4VEmModel* model = models[regModels->ModelIndex(0)]; 650 711 sigmaHigh[0] = 0.0; … … 668 729 for(j=1; j<nmod; j++) { 669 730 670 e = upperEkin[regModels->ModelIndex(j-1)]; 671 sigmaLow[j] = 672 models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax); 673 e = upperEkin[regModels->ModelIndex(j)]; 674 sigmaHigh[j] = 675 models[regModels->ModelIndex(j)]->CrossSection(couple,particle,e,cut,tmax); 731 e = regModels->LowEdgeEnergy(j); 732 eLow[j] = e; 733 G4int idx = regModels->ModelIndex(j); 734 735 sigmaLow[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax); 736 e = regModels->LowEdgeEnergy(j+1); 737 eLow[j+1] = e; 738 sigmaHigh[j] = models[idx]->CrossSection(couple,particle,e,cut,tmax); 739 } 740 if(1 < verboseLevel) { 741 G4cout << " model #0" 742 << " sigma(" << eLow[0] << ")= " << sigmaLow[0] 743 << " sigma(" << eLow[1] << ")= " << sigmaHigh[0] 744 << G4endl; 745 } 746 for(j=1; j<nmod; j++) { 747 if(sigmaLow[j] > 0.0) { 748 factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0)*eLow[j]; 749 } else factor[j] = 0.0; 676 750 if(1 < verboseLevel) { 677 G4cout << " model #" << j << " eUp= " << e 678 << " sigmaUp= " << sigmaHigh[j] 679 << " sigmaDown= " << sigmaLow[j] 751 G4cout << " model #" << j 752 << " sigma(" << eLow[j] << ")= " << sigmaLow[j] 753 << " sigma(" << eLow[j+1] << ")= " << sigmaHigh[j] 754 << " factor= " << factor[j]/eLow[j] 680 755 << G4endl; 681 756 } 682 }683 for(j=1; j<nmod; j++) {684 if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);685 else factor[j] = 0.0;686 757 } 687 758 } … … 695 766 G4int k = 0; 696 767 G4double fac = 1.0; 697 if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {768 if (nmod > 1 && e > eLow[1]) { 698 769 do { 699 770 k++; 700 fac *= (1.0 + factor[k] *upperEkin[regModels->ModelIndex(k-1)]/e);701 } while ( k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );771 fac *= (1.0 + factor[k]/e); 772 } while ( k+1 < nmod && e > eLow[k+1] ); 702 773 } 703 774 … … 721 792 722 793 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 794 795 void G4EmModelManager::DumpModelList(G4int verb) 796 { 797 if(verb == 0) return; 798 for(G4int i=0; i<nRegions; i++) { 799 G4RegionModels* r = setOfRegionModels[i]; 800 const G4Region* reg = r->Region(); 801 if(verb > 1 || nRegions > 1) { 802 } 803 G4int n = r->NumberOfModels(); 804 if(verb > 1 || n > 0) { 805 G4cout << " ===== EM models for the G4Region " << reg->GetName() 806 << " ======" << G4endl;; 807 for(G4int j=0; j<n; j++) { 808 const G4VEmModel* m = models[r->ModelIndex(j)]; 809 G4cout << std::setw(20); 810 G4cout << m->GetName() << " : Emin= " 811 << std::setw(10) << G4BestUnit(r->LowEdgeEnergy(j),"Energy") 812 << " Emax= " 813 << G4BestUnit(r->LowEdgeEnergy(j+1),"Energy") 814 << G4endl; 815 } 816 } 817 } 818 } 819 820 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... -
trunk/source/processes/electromagnetic/utils/src/G4EmMultiModel.cc
r819 r961 25 25 // 26 26 // $Id: G4EmMultiModel.cc,v 1.6 2007/05/22 17:31:58 vnivanch Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- -
trunk/source/processes/electromagnetic/utils/src/G4EmProcessOptions.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4EmProcessOptions.cc,v 1.2 2 2007/11/07 18:38:49vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4EmProcessOptions.cc,v 1.26 2009/02/18 14:43:27 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 59 59 #include "G4VMultipleScattering.hh" 60 60 #include "G4Region.hh" 61 #include "G4RegionStore.hh" 61 62 62 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 392 393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 393 394 394 void G4EmProcessOptions::ActivateDeexcitation(G4bool val, const G4Region* r) 395 { 396 const std::vector<G4VEnergyLossProcess*>& v = 397 theManager->GetEnergyLossProcessVector(); 398 std::vector<G4VEnergyLossProcess*>::const_iterator itr; 399 for(itr = v.begin(); itr != v.end(); itr++) { 400 G4VEnergyLossProcess* p = *itr; 401 if(p) p->ActivateDeexcitation(val,r); 402 } 403 const std::vector<G4VEmProcess*>& w = 404 theManager->GetEmProcessVector(); 405 std::vector<G4VEmProcess*>::const_iterator itp; 406 for(itp = w.begin(); itp != w.end(); itp++) { 407 G4VEmProcess* q = *itp; 408 if(q) q->ActivateDeexcitation(val,r); 395 void G4EmProcessOptions::ActivateDeexcitation(const G4String& pname, 396 G4bool val, 397 const G4String& reg) 398 { 399 G4RegionStore* regionStore = G4RegionStore::GetInstance(); 400 const G4Region* r = 0; 401 if(reg == "" || reg == "World") { 402 r = regionStore->GetRegion("DefaultRegionForTheWorld", false); 403 } else { 404 r = regionStore->GetRegion(reg, false); 405 } 406 if(!r) { 407 G4cout << "G4EmProcessOptions::ActivateDeexcitation ERROR: G4Region <" 408 << reg << "> not found, the command ignored" << G4endl; 409 return; 410 } 411 412 const std::vector<G4VEnergyLossProcess*>& v = 413 theManager->GetEnergyLossProcessVector(); 414 std::vector<G4VEnergyLossProcess*>::const_iterator itr; 415 for(itr = v.begin(); itr != v.end(); itr++) { 416 G4VEnergyLossProcess* p = *itr; 417 if(p) { 418 if(pname == p->GetProcessName()) p->ActivateDeexcitation(val,r); 419 } 420 } 421 const std::vector<G4VEmProcess*>& w = 422 theManager->GetEmProcessVector(); 423 std::vector<G4VEmProcess*>::const_iterator itp; 424 for(itp = w.begin(); itp != w.end(); itp++) { 425 G4VEmProcess* q = *itp; 426 if(q) { 427 if(pname == q->GetProcessName()) q->ActivateDeexcitation(val,r); 428 } 409 429 } 410 430 } … … 477 497 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 478 498 499 void G4EmProcessOptions::SetPolarAngleLimit(G4double val) 500 { 501 const std::vector<G4VMultipleScattering*>& u = 502 theManager->GetMultipleScatteringVector(); 503 std::vector<G4VMultipleScattering*>::const_iterator itm; 504 for(itm = u.begin(); itm != u.end(); itm++) { 505 if(*itm) (*itm)->SetPolarAngleLimit(val); 506 } 507 const std::vector<G4VEmProcess*>& w = 508 theManager->GetEmProcessVector(); 509 std::vector<G4VEmProcess*>::const_iterator itp; 510 for(itp = w.begin(); itp != w.end(); itp++) { 511 G4VEmProcess* q = *itp; 512 if(q) q->SetPolarAngleLimit(val); 513 } 514 } 515 516 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 517 479 518 void G4EmProcessOptions::SetLPMFlag(G4bool val) 480 519 { … … 484 523 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 485 524 525 void G4EmProcessOptions::SetSplineFlag(G4bool val) 526 { 527 theManager->SetSplineFlag(val); 528 } 529 530 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 531 486 532 void G4EmProcessOptions::SetLinearLossLimit(G4double val) 487 533 { -
trunk/source/processes/electromagnetic/utils/src/G4EnergyLossMessenger.cc
r819 r961 25 25 // 26 26 // 27 // $Id: G4EnergyLossMessenger.cc,v 1. 29 2007/06/11 14:56:51vnivanch Exp $28 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $27 // $Id: G4EnergyLossMessenger.cc,v 1.37 2009/02/18 14:43:27 vnivanch Exp $ 28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 // ------------------------------------------------------------------- … … 49 49 // 16-03-07 modify /process/eLoss/minsubsec command (V.Ivanchenko) 50 50 // 18-05-07 add /process/msc directory and commands (V.Ivanchenko) 51 // 11-03-08 add /process/em directory and commands (V.Ivanchenko) 51 52 // 52 53 // ------------------------------------------------------------------- … … 84 85 mscDirectory = new G4UIdirectory("/process/msc/"); 85 86 mscDirectory->SetGuidance("Commands for EM scattering processes."); 87 emDirectory = new G4UIdirectory("/process/em/"); 88 emDirectory->SetGuidance("General commands for EM processes."); 86 89 87 90 RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this); … … 146 149 147 150 IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this); 148 IntegCmd->SetGuidance("Switch true/false the integra tion of cross section over step.");151 IntegCmd->SetGuidance("Switch true/false the integral option"); 149 152 IntegCmd->SetParameterName("integ",true); 150 153 IntegCmd->SetDefaultValue(true); … … 152 155 153 156 rangeCmd = new G4UIcmdWithABool("/process/eLoss/CSDARange",this); 154 rangeCmd->SetGuidance("Switch true/false the precise range calculation.");157 rangeCmd->SetGuidance("Switch true/false the CSDA range calculation"); 155 158 rangeCmd->SetParameterName("range",true); 156 159 rangeCmd->SetDefaultValue(true); … … 158 161 159 162 lpmCmd = new G4UIcmdWithABool("/process/eLoss/LPM",this); 160 lpmCmd->SetGuidance(" Switch true/false the LPM effect calculation.");163 lpmCmd->SetGuidance("The flag of the LPM effect calculation"); 161 164 lpmCmd->SetParameterName("lpm",true); 162 165 lpmCmd->SetDefaultValue(true); 163 166 lpmCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 164 167 168 splCmd = new G4UIcmdWithABool("/process/em/spline",this); 169 splCmd->SetGuidance("The flag of usage spline for Physics Vectors"); 170 splCmd->SetParameterName("spl",true); 171 splCmd->SetDefaultValue(false); 172 splCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 173 174 aplCmd = new G4UIcmdWithABool("/process/em/applyCuts",this); 175 aplCmd->SetGuidance("The flag to Apply Cuts for gamma processes"); 176 aplCmd->SetParameterName("apl",true); 177 aplCmd->SetDefaultValue(false); 178 aplCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 179 180 deexCmd = new G4UIcommand("/process/em/deexcitation",this); 181 deexCmd->SetGuidance("Set deexcitation flag per process and G4Region."); 182 deexCmd->SetGuidance(" procName : process name"); 183 deexCmd->SetGuidance(" flag : flag"); 184 deexCmd->SetGuidance(" regName : G4Region name"); 185 186 G4UIparameter* pName = new G4UIparameter("pName",'s',false); 187 deexCmd->SetParameter(pName); 188 189 G4UIparameter* flag = new G4UIparameter("flag",'s',false); 190 deexCmd->SetParameter(flag); 191 192 G4UIparameter* regName = new G4UIparameter("regName",'s',false); 193 deexCmd->SetParameter(regName); 194 165 195 dedxCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsDEDX",this); 166 dedxCmd->SetGuidance("Set number of bins for DEDX tables .");196 dedxCmd->SetGuidance("Set number of bins for DEDX tables"); 167 197 dedxCmd->SetParameterName("binsDEDX",true); 168 198 dedxCmd->SetDefaultValue(120); … … 170 200 171 201 lamCmd = new G4UIcmdWithAnInteger("/process/eLoss/binsLambda",this); 172 lamCmd->SetGuidance("Set number of bins for Lambda tables .");202 lamCmd->SetGuidance("Set number of bins for Lambda tables"); 173 203 lamCmd->SetParameterName("binsL",true); 174 204 lamCmd->SetDefaultValue(120); … … 176 206 177 207 verCmd = new G4UIcmdWithAnInteger("/process/eLoss/verbose",this); 178 verCmd->SetGuidance("Set verbose level for EM physics .");208 verCmd->SetGuidance("Set verbose level for EM physics"); 179 209 verCmd->SetParameterName("verb",true); 180 210 verCmd->SetDefaultValue(1); 181 211 verCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 182 212 213 ver1Cmd = new G4UIcmdWithAnInteger("/process/em/verbose",this); 214 ver1Cmd->SetGuidance("Set verbose level for EM physics"); 215 ver1Cmd->SetParameterName("verb1",true); 216 ver1Cmd->SetDefaultValue(1); 217 ver1Cmd->AvailableForStates(G4State_PreInit,G4State_Idle); 218 183 219 lllCmd = new G4UIcmdWithADouble("/process/eLoss/linLossLimit",this); 184 lllCmd->SetGuidance("Set linearLossLimit parameter .");220 lllCmd->SetGuidance("Set linearLossLimit parameter"); 185 221 lllCmd->SetParameterName("linlim",true); 186 222 lllCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 187 223 188 labCmd = new G4UIcmdWithADouble("/process/eLoss/ lambdaFactor",this);189 labCmd->SetGuidance("Set lambdaFactor parameter .");224 labCmd = new G4UIcmdWithADouble("/process/eLoss/LambdaFactor",this); 225 labCmd->SetGuidance("Set lambdaFactor parameter for integral option"); 190 226 labCmd->SetParameterName("Fl",true); 191 227 labCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 192 228 193 229 mscCmd = new G4UIcmdWithAString("/process/msc/StepLimit",this); 194 mscCmd->SetGuidance("Set msc step limitation type .");230 mscCmd->SetGuidance("Set msc step limitation type"); 195 231 mscCmd->SetParameterName("StepLim",true); 196 232 mscCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 197 233 198 234 latCmd = new G4UIcmdWithABool("/process/msc/LateralDisplacement",this); 199 latCmd->SetGuidance("S witch true/false sampling of latra dislacent.");235 latCmd->SetGuidance("Set flag of sampling of lateral displacement"); 200 236 latCmd->SetParameterName("lat",true); 201 237 latCmd->SetDefaultValue(true); … … 203 239 204 240 frCmd = new G4UIcmdWithADouble("/process/msc/RangeFactor",this); 205 frCmd->SetGuidance("Set RangeFactor parameter for msc process .");241 frCmd->SetGuidance("Set RangeFactor parameter for msc processes"); 206 242 frCmd->SetParameterName("Fr",true); 207 243 frCmd->SetRange("Fr>0"); … … 210 246 211 247 fgCmd = new G4UIcmdWithADouble("/process/msc/GeomFactor",this); 212 fgCmd->SetGuidance("Set GeomFactor parameter for msc process .");248 fgCmd->SetGuidance("Set GeomFactor parameter for msc processes"); 213 249 fgCmd->SetParameterName("Fg",true); 214 250 fgCmd->SetRange("Fg>0"); … … 217 253 218 254 skinCmd = new G4UIcmdWithADouble("/process/msc/Skin",this); 219 skinCmd->SetGuidance("Set skin parameter for m ultiple scattering.");255 skinCmd->SetGuidance("Set skin parameter for msc processes"); 220 256 skinCmd->SetParameterName("skin",true); 221 257 skinCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 222 258 259 angCmd = new G4UIcmdWithADoubleAndUnit("/process/msc/ThetaLimit",this); 260 angCmd->SetGuidance("Set the limit on the polar angle"); 261 angCmd->SetParameterName("theta",true); 262 angCmd->SetUnitCategory("Angle"); 263 angCmd->AvailableForStates(G4State_PreInit,G4State_Idle); 223 264 } 224 265 … … 233 274 delete MinSubSecCmd; 234 275 delete StepFuncCmd; 276 delete deexCmd; 235 277 delete eLossDirectory; 236 278 delete mscDirectory; 279 delete emDirectory; 237 280 delete MinEnCmd; 238 281 delete MaxEnCmd; … … 240 283 delete rangeCmd; 241 284 delete lpmCmd; 285 delete splCmd; 286 delete aplCmd; 242 287 delete latCmd; 243 288 delete verCmd; 289 delete ver1Cmd; 244 290 delete mscCmd; 245 291 delete dedxCmd; … … 250 296 delete labCmd; 251 297 delete skinCmd; 298 delete angCmd; 252 299 } 253 300 … … 289 336 } 290 337 338 if (command == deexCmd) { 339 G4String s1 (""), s2(""), s3(""); 340 G4bool b = false; 341 std::istringstream is(newValue); 342 is >> s1 >> s2 >> s3; 343 if(s2 == "true") b = true; 344 opt->ActivateDeexcitation(s1,b,s3); 345 } 346 291 347 if (command == mscCmd) { 292 348 if(newValue == "Minimal") … … 317 373 } 318 374 319 if (command == IntegCmd) 375 if (command == IntegCmd) { 320 376 opt->SetIntegral(IntegCmd->GetNewBoolValue(newValue)); 321 377 } 322 378 if (command == rangeCmd) { 323 379 opt->SetBuildCSDARange(rangeCmd->GetNewBoolValue(newValue)); … … 330 386 } 331 387 388 if (command == splCmd) { 389 opt->SetSplineFlag(splCmd->GetNewBoolValue(newValue)); 390 G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified"); 391 } 392 393 if (command == aplCmd) { 394 opt->SetApplyCuts(aplCmd->GetNewBoolValue(newValue)); 395 } 396 332 397 if (command == latCmd) { 333 398 opt->SetMscLateralDisplacement(latCmd->GetNewBoolValue(newValue)); … … 335 400 } 336 401 337 if (command == verCmd) 402 if (command == verCmd) { 338 403 opt->SetVerbose(verCmd->GetNewIntValue(newValue)); 339 340 if (command == lllCmd) 404 } 405 if (command == ver1Cmd) { 406 opt->SetVerbose(ver1Cmd->GetNewIntValue(newValue)); 407 } 408 if (command == lllCmd) { 341 409 opt->SetLinearLossLimit(lllCmd->GetNewDoubleValue(newValue)); 342 343 if (command == labCmd) 410 } 411 if (command == labCmd) { 344 412 opt->SetLambdaFactor(labCmd->GetNewDoubleValue(newValue)); 345 413 } 346 414 if (command == skinCmd) { 347 415 opt->SetSkin(skinCmd->GetNewDoubleValue(newValue)); … … 364 432 G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified"); 365 433 } 434 if (command == angCmd) { 435 opt->SetPolarAngleLimit(angCmd->GetNewDoubleValue(newValue)); 436 G4UImanager::GetUIpointer()->ApplyCommand("/run/physicsModified"); 437 } 366 438 } 367 439 -
trunk/source/processes/electromagnetic/utils/src/G4EnergyLossTables.cc
r819 r961 25 25 // 26 26 // 27 // $Id: G4EnergyLossTables.cc,v 1.3 3 2006/06/29 19:55:09 gunterExp $28 // GEANT4 tag $Name: $27 // $Id: G4EnergyLossTables.cc,v 1.34 2008/07/08 10:57:22 vnivanch Exp $ 28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 // ------------------------------------------------------------------- … … 998 998 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 999 999 1000 void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, const G4String& q) 1001 { 1002 G4String s = "G4EnergyLossTables:: " + q + " table not found for " 1003 + aParticle->GetParticleName() + "!"; 1004 G4Exception(s); 1005 exit(1); 1006 } 1007 1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 1000 void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle, 1001 const G4String& q) 1002 { 1003 G4String s = " " + q + " table not found for " 1004 + aParticle->GetParticleName() + " !"; 1005 G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01", 1006 FatalException, s); 1007 } 1008 1009 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... -
trunk/source/processes/electromagnetic/utils/src/G4LossTableBuilder.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4LossTableBuilder.cc,v 1.2 4 2007/02/16 11:59:35vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4LossTableBuilder.cc,v 1.28 2009/02/18 16:24:47 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 64 64 65 65 G4LossTableBuilder::G4LossTableBuilder() 66 {} 66 { 67 splineFlag = true; 68 } 67 69 68 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 73 75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 74 76 75 void G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable, 76 const std::vector<G4PhysicsTable*>& list) 77 void 78 G4LossTableBuilder::BuildDEDXTable(G4PhysicsTable* dedxTable, 79 const std::vector<G4PhysicsTable*>& list) 77 80 { 78 81 size_t n_processes = list.size(); … … 91 94 92 95 pv = new G4PhysicsLogVector(elow, ehigh, nbins); 96 pv->SetSpline(splineFlag); 93 97 for (size_t j=0; j<nbins; j++) { 94 98 G4double dedx = 0.0; … … 128 132 G4double dedx1 = pv->GetValue(elow, b); 129 133 134 //G4cout << "nbins= " << nbins << " dedx1= " << dedx1 << G4endl; 135 136 // protection for specific cases dedx=0 130 137 if(dedx1 == 0.0) { 131 for (size_t k=1; k<nbins ; k++) {138 for (size_t k=1; k<nbins-1; k++) { 132 139 bin0++; 133 140 elow = pv->GetLowEdgeEnergy(k); … … 138 145 } 139 146 147 //G4cout << "nbins= " << nbins << " elow= " << elow << " ehigh= " << ehigh << G4endl; 148 // initialisation of a new vector 140 149 G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins); 141 150 // dedx is exect zero 151 if(nbins <= 2) { 152 v->PutValue(0,1000.); 153 v->PutValue(1,2000.); 154 G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v); 155 return; 156 } 157 v->SetSpline(splineFlag); 158 159 // assumed dedx proportional to beta 142 160 G4double range = 2.*elow/dedx1; 143 //G4double range = elow/dedx1;144 161 v->PutValue(0,range); 145 162 G4double energy1 = elow; … … 148 165 149 166 G4double energy2 = pv->GetLowEdgeEnergy(j+bin0); 150 G4double dedx2 = pv->GetValue(energy2, b);151 167 G4double de = (energy2 - energy1) * del; 152 G4double energy = energy1 - de*0.5; 153 154 G4bool yes = true; 155 //G4bool yes = false; 156 if(dedx1 < DBL_MIN || dedx2 < DBL_MIN) yes = false; 157 158 G4double fac, f; 159 160 if(yes) fac = std::log(dedx2/dedx1)/std::log(energy2/energy1); 161 else fac = (dedx2 - dedx1)/(energy2 - energy1); 162 168 G4double energy = energy2 + de*0.5; 163 169 for (size_t k=0; k<n; k++) { 164 energy += de;165 if(yes) f = dedx1*std::exp(fac*std::log(energy/energy1));166 else f = dedx1 + fac*(energy - energy1);167 if(f > DBL_MIN) range += de/f; 168 } 170 energy -= de; 171 dedx1 = pv->GetValue(energy, b); 172 if(dedx1 > 0.0) range += de/dedx1; 173 } 174 169 175 // G4cout << "Range i= " <<i << " j= " << j << G4endl; 170 176 v->PutValue(j,range); 171 177 energy1 = energy2; 172 dedx1 = dedx2;173 178 } 174 179 G4PhysicsTableHelper::SetPhysicsVector(rangeTable, i, v); … … 197 202 G4double rlow = pv->GetValue(elow, b); 198 203 G4double rhigh = pv->GetValue(ehigh, b); 199 200 rhigh *= std::exp(std::log(rhigh/rlow)/((G4double)(nbins-1)));201 202 204 203 205 G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(nbins,rlow,rhigh); 206 v->SetSpline(splineFlag); 207 204 208 for (size_t j=0; j<nbins; j++) { 205 209 G4double e = pv->GetLowEdgeEnergy(j); … … 207 211 v->PutValues(j,r,e); 208 212 } 213 v->PutValues(nbins,rhigh+rlow,ehigh); 209 214 210 215 G4PhysicsTableHelper::SetPhysicsVector(invRangeTable, i, v); -
trunk/source/processes/electromagnetic/utils/src/G4LossTableManager.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4LossTableManager.cc,v 1. 84 2007/06/14 07:28:48 vnivanchExp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4LossTableManager.cc,v 1.95 2008/11/13 18:23:39 schaelic Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 70 70 // 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko) 71 71 // 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko) 72 // 21-02-08 Add G4EmSaturation (V.Ivanchenko) 72 73 // 73 74 // Class Description: … … 91 92 #include "G4PhysicsTableHelper.hh" 92 93 #include "G4EmCorrections.hh" 94 #include "G4EmSaturation.hh" 93 95 #include "G4EmTableType.hh" 94 96 #include "G4LossTableBuilder.hh" … … 116 118 size_t msc = msc_vector.size(); 117 119 for (size_t j=0; j<msc; j++) { 118 if( msc_vector[j] ) delete msc_vector[j];120 if( msc_vector[j] ) delete msc_vector[j]; 119 121 } 120 122 size_t emp = emp_vector.size(); 121 123 for (size_t k=0; k<emp; k++) { 122 if(emp_vector[k] ) delete emp_vector[k]; 124 if( emp_vector[k] ) delete emp_vector[k]; 125 } 126 size_t mod = mod_vector.size(); 127 for (size_t a=0; a<mod; a++) { 128 if( mod_vector[a] ) delete mod_vector[a]; 129 } 130 size_t fmod = fmod_vector.size(); 131 for (size_t b=0; b<fmod; b++) { 132 if( fmod_vector[b] ) delete fmod_vector[b]; 123 133 } 124 134 Clear(); … … 126 136 delete tableBuilder; 127 137 delete emCorrections; 138 delete emSaturation; 128 139 } 129 140 … … 152 163 tableBuilder = new G4LossTableBuilder(); 153 164 emCorrections= new G4EmCorrections(); 165 emSaturation = new G4EmSaturation(); 154 166 integral = true; 155 167 integralActive = false; … … 160 172 stepFunctionActive = false; 161 173 flagLPM = true; 174 splineFlag = true; 162 175 bremsTh = DBL_MAX; 163 176 verbose = 1; 177 tableBuilder->SetSplineFlag(splineFlag); 164 178 } 165 179 … … 226 240 { 227 241 msc_vector.push_back(p); 228 if(verbose > 1) 242 if(verbose > 1) { 229 243 G4cout << "G4LossTableManager::Register G4VMultipleScattering : " 230 244 << p->GetProcessName() << G4endl; 245 } 231 246 } 232 247 … … 246 261 { 247 262 emp_vector.push_back(p); 248 if(verbose > 1) 263 if(verbose > 1) { 249 264 G4cout << "G4LossTableManager::Register G4VEmProcess : " 250 265 << p->GetProcessName() << G4endl; 266 } 251 267 } 252 268 … … 258 274 for (size_t i=0; i<emp; i++) { 259 275 if(emp_vector[i] == p) emp_vector[i] = 0; 276 } 277 } 278 279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 280 281 void G4LossTableManager::Register(G4VEmModel* p) 282 { 283 mod_vector.push_back(p); 284 if(verbose > 1) { 285 G4cout << "G4LossTableManager::Register G4VEmModel : " 286 << p->GetName() << G4endl; 287 } 288 } 289 290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 291 292 void G4LossTableManager::DeRegister(G4VEmModel* p) 293 { 294 size_t n = mod_vector.size(); 295 for (size_t i=0; i<n; i++) { 296 if(mod_vector[i] == p) mod_vector[i] = 0; 297 } 298 } 299 300 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 301 302 void G4LossTableManager::Register(G4VEmFluctuationModel* p) 303 { 304 fmod_vector.push_back(p); 305 if(verbose > 1) { 306 G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : " 307 << p->GetName() << G4endl; 308 } 309 } 310 311 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 312 313 void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p) 314 { 315 size_t n = fmod_vector.size(); 316 for (size_t i=0; i<n; i++) { 317 if(fmod_vector[i] == p) fmod_vector[i] = 0; 260 318 } 261 319 } … … 364 422 const G4ParticleDefinition* aParticle) 365 423 { 366 G4String s = "G4LossTableManager:: dE/dx table not found for " 367 + aParticle->GetParticleName() + "!"; 368 G4Exception(s); 369 exit(1); 424 G4String s = " dE/dx table not found for " 425 + aParticle->GetParticleName() + " !"; 426 G4Exception("G4LossTableManager::ParticleHaveNoLoss", "EM01", 427 FatalException, s); 428 370 429 } 371 430 … … 476 535 p = loss_vector[i]; 477 536 if (p && aParticle == part_vector[i] && !tables_are_built[i]) { 478 if (p->IsIonisationProcess() && isActive[i] || !em || (em && !isActive[iem]) ) { 537 if ((p->IsIonisationProcess() && isActive[i]) || 538 !em || (em && !isActive[iem]) ) { 479 539 em = p; 480 540 iem= i; … … 509 569 dedx = em->IonisationTable(); 510 570 if (1 < n_dedx) { 511 em->SetDEDXTable(dedx, fI onisation);571 em->SetDEDXTable(dedx, fIsIonisation); 512 572 dedx = 0; 513 573 dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx); … … 560 620 G4PhysicsTable* dedxSub = em->IonisationTableForSubsec(); 561 621 if (1 < listSub.size()) { 562 em->SetDEDXTable(dedxSub, f SubIonisation);622 em->SetDEDXTable(dedxSub, fIsSubIonisation); 563 623 dedxSub = 0; 564 624 dedxSub = G4PhysicsTableHelper::PreparePhysicsTable(dedxSub); … … 829 889 } 830 890 891 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 892 893 void G4LossTableManager::SetSplineFlag(G4bool val) 894 { 895 splineFlag = val; 896 tableBuilder->SetSplineFlag(splineFlag); 897 } 898 899 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 900 901 G4bool G4LossTableManager::SplineFlag() const 902 { 903 return splineFlag; 904 } 905 831 906 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 832 907 … … 843 918 } 844 919 920 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 921 922 G4EmCorrections* G4LossTableManager::EmCorrections() 923 { 924 return emCorrections; 925 } 926 927 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 928 929 G4EmSaturation* G4LossTableManager::EmSaturation() 930 { 931 return emSaturation; 932 } 933 845 934 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... -
trunk/source/processes/electromagnetic/utils/src/G4VEmFluctuationModel.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4VEmFluctuationModel.cc,v 1. 2 2006/06/29 19:55:15 gunterExp $27 // GEANT4 tag $Name: $26 // $Id: G4VEmFluctuationModel.cc,v 1.4 2009/02/19 11:25:50 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 49 49 50 50 #include "G4VEmFluctuationModel.hh" 51 51 #include "G4LossTableManager.hh" 52 52 53 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 56 56 G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam) 57 57 : name(nam) 58 { 59 G4LossTableManager::Instance()->Register(this); 60 } 61 62 G4VEmFluctuationModel::~G4VEmFluctuationModel() 63 { 64 G4LossTableManager::Instance()->DeRegister(this); 65 } 66 67 void G4VEmFluctuationModel::InitialiseMe(const G4ParticleDefinition*) 58 68 {} 59 69 60 G4VEmFluctuationModel::~G4VEmFluctuationModel() 70 void G4VEmFluctuationModel::SetParticleAndCharge(const G4ParticleDefinition*, 71 G4double) 61 72 {} 62 73 -
trunk/source/processes/electromagnetic/utils/src/G4VEmModel.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4VEmModel.cc,v 1. 8 2007/09/25 10:19:07vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4VEmModel.cc,v 1.25 2009/02/19 09:57:36 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 41 41 // 25.10.2005 Set default highLimit=100.TeV (V.Ivanchenko) 42 42 // 06.02.2006 add method ComputeMeanFreePath() (mma) 43 // 16.02.2009 Move implementations of virtual methods to source (VI) 43 44 // 44 45 // … … 51 52 52 53 #include "G4VEmModel.hh" 54 #include "G4LossTableManager.hh" 55 #include "G4ProductionCutsTable.hh" 53 56 54 57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... … … 56 59 57 60 G4VEmModel::G4VEmModel(const G4String& nam): 58 lowLimit(0.1*keV), highLimit(100.0*TeV), fluc(0), name(nam), pParticleChange(0) 59 {} 61 fluc(0), name(nam), lowLimit(0.1*keV), highLimit(100.0*TeV), 62 polarAngleLimit(0.0),secondaryThreshold(DBL_MAX),theLPMflag(false), 63 pParticleChange(0),nuclearStopping(false), 64 currentCouple(0),currentElement(0), 65 nsec(5),flagDeexcitation(false) 66 { 67 xsec.resize(nsec); 68 nSelectors = 0; 69 G4LossTableManager::Instance()->Register(this); 70 } 60 71 61 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 62 73 63 74 G4VEmModel::~G4VEmModel() 64 {} 75 { 76 G4LossTableManager::Instance()->DeRegister(this); 77 G4int n = elmSelectors.size(); 78 if(n > 0) { 79 for(G4int i=0; i<n; i++) { 80 delete elmSelectors[i]; 81 } 82 } 83 } 84 85 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 86 87 void G4VEmModel::InitialiseElementSelectors(const G4ParticleDefinition* p, 88 const G4DataVector& cuts) 89 { 90 // initialise before run 91 flagDeexcitation = false; 92 93 G4int nbins = G4int(std::log10(highLimit/lowLimit) + 0.5); 94 if(nbins < 3) nbins = 3; 95 G4bool spline = G4LossTableManager::Instance()->SplineFlag(); 96 97 G4ProductionCutsTable* theCoupleTable= 98 G4ProductionCutsTable::GetProductionCutsTable(); 99 G4int numOfCouples = theCoupleTable->GetTableSize(); 100 101 // prepare vector 102 if(numOfCouples > nSelectors) { 103 elmSelectors.resize(numOfCouples); 104 nSelectors = numOfCouples; 105 } 106 107 // initialise vector 108 for(G4int i=0; i<numOfCouples; i++) { 109 const G4MaterialCutsCouple* couple = 110 theCoupleTable->GetMaterialCutsCouple(i); 111 const G4Material* material = couple->GetMaterial(); 112 G4int idx = couple->GetIndex(); 113 114 // selector already exist check if should be deleted 115 G4bool create = true; 116 if(elmSelectors[i]) { 117 if(material == elmSelectors[i]->GetMaterial()) create = false; 118 else delete elmSelectors[i]; 119 } 120 if(create) { 121 elmSelectors[i] = new G4EmElementSelector(this,material,nbins, 122 lowLimit,highLimit,spline); 123 } 124 elmSelectors[i]->Initialise(p, cuts[idx]); 125 //elmSelectors[i]->Dump(p); 126 } 127 } 128 129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 130 131 G4double G4VEmModel::ComputeDEDXPerVolume(const G4Material*, 132 const G4ParticleDefinition*, 133 G4double,G4double) 134 { 135 return 0.0; 136 } 65 137 66 138 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... … … 68 140 G4double G4VEmModel::CrossSectionPerVolume(const G4Material* material, 69 141 const G4ParticleDefinition* p, 70 G4double ekin, 71 G4double emin, 72 G4double emax) 73 { 142 G4double ekin, 143 G4double emin, 144 G4double emax) 145 { 146 SetupForMaterial(p, material, ekin); 74 147 G4double cross = 0.0; 75 148 const G4ElementVector* theElementVector = material->GetElementVector(); 76 149 const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume(); 77 size_t nelm = material->GetNumberOfElements(); 78 for (size_t i=0; i<nelm; i++) { 79 const G4Element* elm = (*theElementVector)[i]; 150 G4int nelm = material->GetNumberOfElements(); 151 if(nelm > nsec) { 152 xsec.resize(nelm); 153 nsec = nelm; 154 } 155 for (G4int i=0; i<nelm; i++) { 80 156 cross += theAtomNumDensityVector[i]* 81 ComputeCrossSectionPerAtom(p, ekin,elm->GetZ(),elm->GetN(),emin,emax);157 ComputeCrossSectionPerAtom(p,(*theElementVector)[i],ekin,emin,emax); 82 158 xsec[i] = cross; 83 159 } … … 87 163 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 88 164 89 G4double G4VEmModel::ComputeMeanFreePath(const G4ParticleDefinition* p, 90 G4double ekin, 91 const G4Material* material, 92 G4double emin, 93 G4double emax) 94 { 95 G4double mfp = DBL_MAX; 96 G4double cross = CrossSectionPerVolume(material,p,ekin,emin,emax); 97 if (cross > DBL_MIN) mfp = 1./cross; 98 return mfp; 99 } 100 101 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 102 103 165 G4double G4VEmModel::ComputeCrossSectionPerAtom(const G4ParticleDefinition*, 166 G4double, G4double, G4double, 167 G4double, G4double) 168 { 169 return 0.0; 170 } 171 172 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 173 174 G4double G4VEmModel::MinEnergyCut(const G4ParticleDefinition*, 175 const G4MaterialCutsCouple*) 176 { 177 return 0.0; 178 } 179 180 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 181 182 G4double G4VEmModel::GetChargeSquareRatio(const G4ParticleDefinition* p, 183 const G4Material*, G4double) 184 { 185 G4double q = p->GetPDGCharge()/CLHEP::eplus; 186 return q*q; 187 } 188 189 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 190 191 G4double G4VEmModel::GetParticleCharge(const G4ParticleDefinition* p, 192 const G4Material*, G4double) 193 { 194 return p->GetPDGCharge(); 195 } 196 197 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 198 199 void G4VEmModel::CorrectionsAlongStep(const G4MaterialCutsCouple*, 200 const G4DynamicParticle*, 201 G4double&,G4double&,G4double) 202 {} 203 204 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 205 206 void G4VEmModel::SampleDeexcitationAlongStep(const G4Material*, 207 const G4Track&, 208 G4double& ) 209 {} 210 211 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 212 213 G4double G4VEmModel::MaxSecondaryEnergy(const G4ParticleDefinition*, 214 G4double kineticEnergy) 215 { 216 return kineticEnergy; 217 } 218 219 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 220 221 void G4VEmModel::SampleScattering(const G4DynamicParticle*, G4double) 222 {} 223 224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 225 226 G4double G4VEmModel::ComputeTruePathLengthLimit(const G4Track&, 227 G4PhysicsTable*, 228 G4double) 229 { 230 return DBL_MAX; 231 } 232 233 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 234 235 G4double G4VEmModel::ComputeGeomPathLength(G4double truePathLength) 236 { 237 return truePathLength; 238 } 239 240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 241 242 G4double G4VEmModel::ComputeTrueStepLength(G4double geomPathLength) 243 { 244 return geomPathLength; 245 } 246 247 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 248 249 void G4VEmModel::DefineForRegion(const G4Region*) 250 {} 251 252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 253 254 void G4VEmModel::SetupForMaterial(const G4ParticleDefinition*, 255 const G4Material*, G4double) 256 {} 257 258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... -
trunk/source/processes/electromagnetic/utils/src/G4VEmProcess.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4VEmProcess.cc,v 1. 48 2007/10/29 08:38:58vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4VEmProcess.cc,v 1.62 2009/02/19 09:57:36 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 82 82 83 83 G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type): 84 G4VDiscreteProcess(name, type), 85 selectedModel(0), 84 G4VDiscreteProcess(name, type), 85 secondaryParticle(0), 86 buildLambdaTable(true), 86 87 theLambdaTable(0), 87 88 theEnergyOfCrossSectionMax(0), 88 89 theCrossSectionMax(0), 89 particle(0),90 secondaryParticle(0),91 nLambdaBins(90),92 lambdaFactor(0.8),93 currentCouple(0),94 90 integral(false), 95 buildLambdaTable(true),96 91 applyCuts(false), 97 92 startFromNull(true), 98 nRegions(0) 93 useDeexcitation(false), 94 nDERegions(0), 95 idxDERegions(0), 96 currentModel(0), 97 particle(0), 98 currentCouple(0) 99 99 { 100 100 SetVerboseLevel(1); 101 102 // Size of tables assuming spline 101 103 minKinEnergy = 0.1*keV; 102 maxKinEnergy = 100.0*GeV; 104 maxKinEnergy = 100.0*TeV; 105 nLambdaBins = 84; 106 107 // default lambda factor 108 lambdaFactor = 0.8; 109 110 // default limit on polar angle 111 polarAngleLimit = 0.0; 112 113 // particle types 103 114 theGamma = G4Gamma::Gamma(); 104 115 theElectron = G4Electron::Electron(); … … 126 137 delete modelManager; 127 138 (G4LossTableManager::Instance())->DeRegister(this); 139 } 140 141 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 142 143 void G4VEmProcess::Clear() 144 { 145 delete [] theEnergyOfCrossSectionMax; 146 delete [] theCrossSectionMax; 147 delete [] idxDERegions; 148 theEnergyOfCrossSectionMax = 0; 149 theCrossSectionMax = 0; 150 idxDERegions = 0; 151 currentCouple = 0; 152 preStepLambda = 0.0; 153 mfpKinEnergy = DBL_MAX; 154 deRegions.clear(); 155 nDERegions = 0; 128 156 } 129 157 … … 153 181 theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable); 154 182 } 155 } 156 157 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 158 159 void G4VEmProcess::Clear() 160 { 161 if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax; 162 if(theCrossSectionMax) delete [] theCrossSectionMax; 163 theEnergyOfCrossSectionMax = 0; 164 theCrossSectionMax = 0; 165 currentCouple = 0; 166 preStepLambda = 0.0; 167 mfpKinEnergy = DBL_MAX; 183 // Sub Cutoff and Deexcitation 184 if (nDERegions>0) { 185 186 const G4ProductionCutsTable* theCoupleTable= 187 G4ProductionCutsTable::GetProductionCutsTable(); 188 size_t numOfCouples = theCoupleTable->GetTableSize(); 189 190 idxDERegions = new G4bool[numOfCouples]; 191 192 for (size_t j=0; j<numOfCouples; j++) { 193 194 const G4MaterialCutsCouple* couple = 195 theCoupleTable->GetMaterialCutsCouple(j); 196 const G4ProductionCuts* pcuts = couple->GetProductionCuts(); 197 G4bool reg = false; 198 for(G4int i=0; i<nDERegions; i++) { 199 if(deRegions[i]) { 200 if(pcuts == deRegions[i]->GetProductionCuts()) reg = true; 201 } 202 } 203 idxDERegions[j] = reg; 204 } 205 } 206 if (1 < verboseLevel && nDERegions>0) { 207 G4cout << " Deexcitation is activated for regions: " << G4endl; 208 for (G4int i=0; i<nDERegions; i++) { 209 const G4Region* r = deRegions[i]; 210 G4cout << " " << r->GetName() << G4endl; 211 } 212 } 168 213 } 169 214 … … 228 273 G4cout << *theLambdaTable << G4endl; 229 274 } 275 } 276 } 277 278 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 279 280 void G4VEmProcess::PrintInfoDefinition() 281 { 282 if(verboseLevel > 0) { 283 G4cout << G4endl << GetProcessName() << ": for " 284 << particle->GetParticleName(); 285 if(integral) G4cout << ", integral: 1 "; 286 if(applyCuts) G4cout << ", applyCuts: 1 "; 287 G4cout << " SubType= " << GetProcessSubType() << G4endl; 288 if(buildLambdaTable) { 289 G4cout << " Lambda tables from " 290 << G4BestUnit(minKinEnergy,"Energy") 291 << " to " 292 << G4BestUnit(maxKinEnergy,"Energy") 293 << " in " << nLambdaBins << " bins, spline: " 294 << (G4LossTableManager::Instance())->SplineFlag() 295 << G4endl; 296 } 297 PrintInfo(); 298 modelManager->DumpModelList(verboseLevel); 299 } 300 301 if(verboseLevel > 2 && buildLambdaTable) { 302 G4cout << " LambdaTable address= " << theLambdaTable << G4endl; 303 if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl; 230 304 } 231 305 } … … 295 369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 296 370 297 G4double G4VEmProcess::GetMeanFreePath(const G4Track& track,298 G4double,299 G4ForceCondition* condition)300 {301 *condition = NotForced;302 return G4VEmProcess::MeanFreePath(track);303 }304 305 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....306 307 371 G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track, 308 372 const G4Step&) … … 333 397 } 334 398 335 G4VEmModel* currentModel = SelectModel(finalT); 336 399 SelectModel(finalT); 400 if(useDeexcitation) { 401 currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]); 402 } 337 403 /* 338 404 if(0 < verboseLevel) { … … 373 439 374 440 } else if (p == thePositron) { 375 if (e < (*theCutsPositron)[currentMaterialIndex]) { 441 if (electron_mass_c2 < (*theCutsGamma)[currentMaterialIndex] && 442 e < (*theCutsPositron)[currentMaterialIndex]) { 376 443 good = false; 377 444 e += 2.0*electron_mass_c2; … … 394 461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 395 462 396 void G4VEmProcess::PrintInfoDefinition()397 {398 if(verboseLevel > 0) {399 G4cout << G4endl << GetProcessName() << ": " ;400 PrintInfo();401 if(integral) {402 G4cout << " Integral mode is used "<< G4endl;403 }404 }405 406 if (!buildLambdaTable) return;407 408 if(verboseLevel > 0) {409 G4cout << " tables are built for "410 << particle->GetParticleName()411 << G4endl412 << " Lambda tables from "413 << G4BestUnit(minKinEnergy,"Energy")414 << " to "415 << G4BestUnit(maxKinEnergy,"Energy")416 << " in " << nLambdaBins << " bins."417 << G4endl;418 }419 420 if(verboseLevel > 1) {421 G4cout << "Tables are built for " << particle->GetParticleName()422 << G4endl;423 424 if(verboseLevel > 2) {425 G4cout << "LambdaTable address= " << theLambdaTable << G4endl;426 if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;427 }428 }429 }430 431 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....432 433 G4double G4VEmProcess::MicroscopicCrossSection(G4double kineticEnergy,434 const G4MaterialCutsCouple* couple)435 {436 // Cross section per atom is calculated437 DefineMaterial(couple);438 G4double cross = 0.0;439 G4bool b;440 if(theLambdaTable) {441 cross = (((*theLambdaTable)[currentMaterialIndex])->442 GetValue(kineticEnergy, b));443 444 cross /= currentMaterial->GetTotNbOfAtomsPerVolume();445 } else {446 G4VEmModel* model = SelectModel(kineticEnergy);447 cross =448 model->CrossSectionPerVolume(currentMaterial,particle,kineticEnergy);449 }450 451 return cross;452 }453 454 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....455 456 463 G4bool G4VEmProcess::StorePhysicsTable(const G4ParticleDefinition* part, 457 464 const G4String& directory, … … 508 515 << G4endl; 509 516 } 517 if((G4LossTableManager::Instance())->SplineFlag()) { 518 size_t n = theLambdaTable->length(); 519 for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);} 520 } 510 521 } else { 511 522 if (1 < verboseLevel) { … … 517 528 518 529 return yes; 530 } 531 532 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 533 534 void G4VEmProcess::ActivateDeexcitation(G4bool val, const G4Region* r) 535 { 536 G4RegionStore* regionStore = G4RegionStore::GetInstance(); 537 const G4Region* reg = r; 538 if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);} 539 540 // the region is in the list 541 if (nDERegions) { 542 for (G4int i=0; i<nDERegions; i++) { 543 if (reg == deRegions[i]) { 544 if(!val) deRegions[i] = 0; 545 return; 546 } 547 } 548 } 549 550 // new region 551 if(val) { 552 useDeexcitation = true; 553 deRegions.push_back(reg); 554 nDERegions++; 555 } else { 556 useDeexcitation = false; 557 } 558 } 559 560 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 561 562 G4double G4VEmProcess::CrossSectionPerVolume(G4double kineticEnergy, 563 const G4MaterialCutsCouple* couple) 564 { 565 // Cross section per atom is calculated 566 DefineMaterial(couple); 567 G4double cross = 0.0; 568 G4bool b; 569 if(theLambdaTable) { 570 cross = (((*theLambdaTable)[currentMaterialIndex])-> 571 GetValue(kineticEnergy, b)); 572 } else { 573 SelectModel(kineticEnergy); 574 cross = currentModel->CrossSectionPerVolume(currentMaterial, 575 particle,kineticEnergy); 576 } 577 578 return cross; 579 } 580 581 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 582 583 G4double G4VEmProcess::GetMeanFreePath(const G4Track& track, 584 G4double, 585 G4ForceCondition* condition) 586 { 587 *condition = NotForced; 588 return G4VEmProcess::MeanFreePath(track); 519 589 } 520 590 … … 568 638 G4PhysicsVector* v = 569 639 new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nLambdaBins); 640 v->SetSpline((G4LossTableManager::Instance())->SplineFlag()); 570 641 return v; 571 642 } -
trunk/source/processes/electromagnetic/utils/src/G4VEnergyLoss.cc
r819 r961 26 26 // 27 27 // $Id: G4VEnergyLoss.cc,v 1.46 2006/06/29 19:55:21 gunter Exp $ 28 // GEANT4 tag $Name: $28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 -
trunk/source/processes/electromagnetic/utils/src/G4VEnergyLossProcess.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4VEnergyLossProcess.cc,v 1.1 23 2008/01/11 19:55:29vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4VEnergyLossProcess.cc,v 1.146 2009/02/19 11:25:50 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 146 146 147 147 G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, 148 G4ProcessType type): G4VContinuousDiscreteProcess(name, type), 148 G4ProcessType type): 149 G4VContinuousDiscreteProcess(name, type), 150 secondaryParticle(0), 149 151 nSCoffRegions(0), 152 nDERegions(0), 150 153 idxSCoffRegions(0), 154 idxDERegions(0), 151 155 nProcesses(0), 152 156 theDEDXTable(0), … … 165 169 theEnergyOfCrossSectionMax(0), 166 170 theCrossSectionMax(0), 167 particle(0),168 171 baseParticle(0), 169 secondaryParticle(0),170 currentCouple(0),171 nBins(120),172 nBinsCSDA(70),173 nWarnings(0),174 linLossLimit(0.05),175 172 minSubRange(0.1), 176 lambdaFactor(0.8),177 mfpKinEnergy(0.0),178 173 lossFluctuationFlag(true), 179 174 rndmStepFlag(false), 180 175 tablesAreBuilt(false), 181 176 integral(true), 177 isIon(false), 182 178 isIonisation(true), 183 useSubCutoff(false) 179 useSubCutoff(false), 180 useDeexcitation(false), 181 particle(0), 182 currentCouple(0), 183 nWarnings(0), 184 mfpKinEnergy(0.0) 184 185 { 185 186 SetVerboseLevel(1); 186 187 187 // Size of tables188 // low energy limit 188 189 lowestKinEnergy = 1.*eV; 190 191 // Size of tables assuming spline 189 192 minKinEnergy = 0.1*keV; 190 193 maxKinEnergy = 100.0*TeV; 194 nBins = 84; 191 195 maxKinEnergyCSDA = 1.0*GeV; 196 nBinsCSDA = 35; 197 198 // default linear loss limit for spline 199 linLossLimit = 0.01; 192 200 193 201 // default dRoverRange and finalRange 194 202 SetStepFunction(0.2, 1.0*mm); 195 203 196 theElectron = G4Electron::Electron(); 197 thePositron = G4Positron::Positron(); 204 // default lambda factor 205 lambdaFactor = 0.8; 206 207 // particle types 208 theElectron = G4Electron::Electron(); 209 thePositron = G4Positron::Positron(); 210 theGenericIon = 0; 198 211 199 212 // run time objects … … 208 221 fluctModel = 0; 209 222 210 scoffRegions.clear();211 scProcesses.clear();212 223 scTracks.reserve(5); 213 224 secParticles.reserve(5); … … 215 226 // Data for stragling of ranges from ICRU'37 report 216 227 const G4int nrbins = 7; 217 vstrag = new G4PhysicsLogVector(keV, GeV, nrbins); 228 vstrag = new G4PhysicsLogVector(keV, GeV, nrbins-1); 229 vstrag->SetSpline(true); 218 230 G4double s[nrbins] = {-0.2, -0.85, -1.3, -1.578, -1.76, -1.85, -1.9}; 219 231 for(G4int i=0; i<nrbins; i++) {vstrag->PutValue(i, s[i]);} … … 228 240 << G4endl; 229 241 delete vstrag; 230 Clea r();242 Clean(); 231 243 232 244 if ( !baseParticle ) { … … 282 294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 283 295 284 void G4VEnergyLossProcess::Clea r()285 { 286 if(1 < verboseLevel) 296 void G4VEnergyLossProcess::Clean() 297 { 298 if(1 < verboseLevel) { 287 299 G4cout << "G4VEnergyLossProcess::Clear() for " << GetProcessName() 288 289 300 << G4endl; 301 } 290 302 delete [] theDEDXAtMaxEnergy; 291 303 delete [] theRangeAtMaxEnergy; … … 293 305 delete [] theCrossSectionMax; 294 306 delete [] idxSCoffRegions; 307 delete [] idxDERegions; 295 308 296 309 theDEDXAtMaxEnergy = 0; … … 300 313 tablesAreBuilt = false; 301 314 302 scTracks.clear();315 //scTracks.clear(); 303 316 scProcesses.clear(); 304 } 305 306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 307 308 void G4VEnergyLossProcess::PreparePhysicsTable( 309 const G4ParticleDefinition& part) 310 { 311 312 // Are particle defined? 313 if( !particle ) { 314 if(part.GetParticleType() == "nucleus" && 315 part.GetParticleSubType() == "generic") 316 particle = G4GenericIon::GenericIon(); 317 else particle = ∂ 318 } 319 317 nProcesses = 0; 318 } 319 320 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 321 322 G4double G4VEnergyLossProcess::MinPrimaryEnergy(const G4ParticleDefinition*, 323 const G4Material*, 324 G4double cut) 325 { 326 return cut; 327 } 328 329 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 330 331 void 332 G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part) 333 { 320 334 if(1 < verboseLevel) { 321 335 G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for " 322 336 << GetProcessName() 323 337 << " for " << part.GetParticleName() 324 << " local: " << particle->GetParticleName()325 338 << G4endl; 326 339 } 327 328 G4LossTableManager* lManager = G4LossTableManager::Instance();329 330 if(&part != particle) {331 if(part.GetParticleType() == "nucleus") lManager->RegisterIon(&part, this);332 else lManager->RegisterExtraParticle(&part, this);333 return;334 }335 336 Clear();337 340 338 341 currentCouple = 0; … … 341 344 fRange = DBL_MAX; 342 345 preStepKinEnergy = 0.0; 346 chargeSqRatio = 1.0; 347 massRatio = 1.0; 348 reduceFactor = 1.0; 349 350 G4LossTableManager* lManager = G4LossTableManager::Instance(); 351 352 // Are particle defined? 353 if( !particle ) { 354 particle = ∂ 355 if(part.GetParticleType() == "nucleus") { 356 if(!theGenericIon) theGenericIon = G4GenericIon::GenericIon(); 357 if(particle == theGenericIon) { isIon = true; } 358 else if(part.GetPDGCharge() > eplus) { 359 isIon = true; 360 361 // generic ions created on-fly 362 if(part.GetPDGCharge() > 2.5*eplus) { 363 particle = theGenericIon; 364 } 365 } 366 } 367 } 368 369 if( particle != &part) { 370 if(part.GetParticleType() == "nucleus") { 371 isIon = true; 372 lManager->RegisterIon(&part, this); 373 } else { 374 lManager->RegisterExtraParticle(&part, this); 375 } 376 return; 377 } 378 379 Clean(); 343 380 344 381 // Base particle and set of models can be defined here … … 372 409 G4double initialCharge = particle->GetPDGCharge(); 373 410 G4double initialMass = particle->GetPDGMass(); 374 chargeSquare = initialCharge*initialCharge/(eplus*eplus);375 chargeSqRatio = 1.0;376 massRatio = 1.0;377 reduceFactor = 1.0;378 411 379 412 if (baseParticle) { … … 387 420 minSubRange, verboseLevel); 388 421 389 // Sub Cutoff Regime 390 scProcesses.clear(); 391 nProcesses = 0; 392 393 if (nSCoffRegions>0) { 422 // Sub Cutoff and Deexcitation 423 if (nSCoffRegions>0 || nDERegions>0) { 394 424 theSubCuts = modelManager->SubCutoff(); 395 425 … … 397 427 G4ProductionCutsTable::GetProductionCutsTable(); 398 428 size_t numOfCouples = theCoupleTable->GetTableSize(); 399 idxSCoffRegions = new G4int[numOfCouples]; 429 430 if(nSCoffRegions>0) idxSCoffRegions = new G4bool[numOfCouples]; 431 if(nDERegions>0) idxDERegions = new G4bool[numOfCouples]; 400 432 401 433 for (size_t j=0; j<numOfCouples; j++) { … … 404 436 theCoupleTable->GetMaterialCutsCouple(j); 405 437 const G4ProductionCuts* pcuts = couple->GetProductionCuts(); 406 G4int reg = 0; 407 for(G4int i=0; i<nSCoffRegions; i++) { 408 if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = 1; 409 } 410 idxSCoffRegions[j] = reg; 438 439 if(nSCoffRegions>0) { 440 G4bool reg = false; 441 for(G4int i=0; i<nSCoffRegions; i++) { 442 if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = true; 443 } 444 idxSCoffRegions[j] = reg; 445 } 446 if(nDERegions>0) { 447 G4bool reg = false; 448 for(G4int i=0; i<nDERegions; i++) { 449 if( pcuts == deRegions[i]->GetProductionCuts()) reg = true; 450 } 451 idxDERegions[j] = reg; 452 } 411 453 } 412 454 } … … 416 458 if (1 < verboseLevel) { 417 459 G4cout << "G4VEnergyLossProcess::Initialise() is done " 460 << " for local " << particle->GetParticleName() 461 << " isIon= " << isIon 418 462 << " chargeSqRatio= " << chargeSqRatio 419 463 << " massRatio= " << massRatio … … 426 470 } 427 471 } 472 if (nDERegions) { 473 G4cout << " Deexcitation is ON for regions: " << G4endl; 474 for (G4int i=0; i<nDERegions; i++) { 475 const G4Region* r = deRegions[i]; 476 G4cout << " " << r->GetName() << G4endl; 477 } 478 } 428 479 } 429 480 } … … 442 493 } 443 494 444 if(!tablesAreBuilt && &part == particle) 445 G4LossTableManager::Instance()->BuildPhysicsTable(particle, this); 446 447 if(0 < verboseLevel && (&part == particle) && !baseParticle) { 448 PrintInfoDefinition(); 449 safetyHelper->InitialiseHelper(); 495 if(&part == particle) { 496 if(!tablesAreBuilt) { 497 G4LossTableManager::Instance()->BuildPhysicsTable(particle, this); 498 } 499 if(!baseParticle) { 500 if(0 < verboseLevel) PrintInfoDefinition(); 501 502 // needs to be done only once 503 safetyHelper->InitialiseHelper(); 504 } 450 505 } 451 506 … … 456 511 if(isIonisation) G4cout << " isIonisation flag = 1"; 457 512 G4cout << G4endl; 458 }459 }460 461 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....462 463 void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)464 {465 G4RegionStore* regionStore = G4RegionStore::GetInstance();466 if(val) {467 useSubCutoff = true;468 if (!r) r = regionStore->GetRegion("DefaultRegionForTheWorld", false);469 if (nSCoffRegions) {470 for (G4int i=0; i<nSCoffRegions; i++) {471 if (r == scoffRegions[i]) return;472 }473 }474 scoffRegions.push_back(r);475 nSCoffRegions++;476 } else {477 useSubCutoff = false;478 513 } 479 514 } … … 528 563 for(size_t i=0; i<numOfCouples; i++) { 529 564 530 if(1 < verboseLevel) 565 if(1 < verboseLevel) { 531 566 G4cout << "G4VEnergyLossProcess::BuildDEDXVector flag= " 532 567 << table->GetFlag(i) << G4endl; 533 568 } 534 569 if (table->GetFlag(i)) { 535 570 … … 538 573 theCoupleTable->GetMaterialCutsCouple(i); 539 574 G4PhysicsVector* aVector = new G4PhysicsLogVector(emin, emax, bin); 575 aVector->SetSpline((G4LossTableManager::Instance())->SplineFlag()); 576 540 577 modelManager->FillDEDXVector(aVector, couple, tType); 541 578 … … 580 617 << G4endl; 581 618 } 582 if(!table) return table;619 if(!table) {return table;} 583 620 584 621 // Access to materials … … 615 652 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 616 653 617 G4double G4VEnergyLossProcess::GetContinuousStepLimit( 618 const G4Track&, 619 G4double, G4double, G4double&) 620 { 621 return DBL_MAX; 654 void G4VEnergyLossProcess::PrintInfoDefinition() 655 { 656 if(0 < verboseLevel) { 657 G4cout << G4endl << GetProcessName() << ": for " 658 << particle->GetParticleName() 659 << " SubType= " << GetProcessSubType() 660 << G4endl 661 << " dE/dx and range tables from " 662 << G4BestUnit(minKinEnergy,"Energy") 663 << " to " << G4BestUnit(maxKinEnergy,"Energy") 664 << " in " << nBins << " bins" << G4endl 665 << " Lambda tables from threshold to " 666 << G4BestUnit(maxKinEnergy,"Energy") 667 << " in " << nBins << " bins, spline: " 668 << (G4LossTableManager::Instance())->SplineFlag() 669 << G4endl; 670 if(theRangeTableForLoss && isIonisation) { 671 G4cout << " finalRange(mm)= " << finalRange/mm 672 << ", dRoverRange= " << dRoverRange 673 << ", integral: " << integral 674 << ", fluct: " << lossFluctuationFlag 675 << ", linLossLimit= " << linLossLimit 676 << G4endl; 677 } 678 PrintInfo(); 679 modelManager->DumpModelList(verboseLevel); 680 if(theCSDARangeTable && isIonisation) { 681 G4cout << " CSDA range table up" 682 << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy") 683 << " in " << nBinsCSDA << " bins" << G4endl; 684 } 685 if(nSCoffRegions>0 && isIonisation) { 686 G4cout << " Subcutoff sampling in " << nSCoffRegions 687 << " regions" << G4endl; 688 } 689 if(2 < verboseLevel) { 690 G4cout << " DEDXTable address= " << theDEDXTable << G4endl; 691 if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl; 692 G4cout << "non restricted DEDXTable address= " 693 << theDEDXunRestrictedTable << G4endl; 694 if(theDEDXunRestrictedTable && isIonisation) { 695 G4cout << (*theDEDXunRestrictedTable) << G4endl; 696 } 697 if(theDEDXSubTable && isIonisation) { 698 G4cout << (*theDEDXSubTable) << G4endl; 699 } 700 G4cout << " CSDARangeTable address= " << theCSDARangeTable 701 << G4endl; 702 if(theCSDARangeTable && isIonisation) { 703 G4cout << (*theCSDARangeTable) << G4endl; 704 } 705 G4cout << " RangeTableForLoss address= " << theRangeTableForLoss 706 << G4endl; 707 if(theRangeTableForLoss && isIonisation) { 708 G4cout << (*theRangeTableForLoss) << G4endl; 709 } 710 G4cout << " InverseRangeTable address= " << theInverseRangeTable 711 << G4endl; 712 if(theInverseRangeTable && isIonisation) { 713 G4cout << (*theInverseRangeTable) << G4endl; 714 } 715 G4cout << " LambdaTable address= " << theLambdaTable << G4endl; 716 if(theLambdaTable && isIonisation) { 717 G4cout << (*theLambdaTable) << G4endl; 718 } 719 G4cout << " SubLambdaTable address= " << theSubLambdaTable << G4endl; 720 if(theSubLambdaTable && isIonisation) { 721 G4cout << (*theSubLambdaTable) << G4endl; 722 } 723 } 724 } 725 } 726 727 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 728 729 void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r) 730 { 731 G4RegionStore* regionStore = G4RegionStore::GetInstance(); 732 const G4Region* reg = r; 733 if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);} 734 735 // the region is in the list 736 if (nSCoffRegions) { 737 for (G4int i=0; i<nSCoffRegions; i++) { 738 if (reg == scoffRegions[i]) { 739 if(!val) deRegions[i] = 0; 740 return; 741 } 742 } 743 } 744 745 // new region 746 if(val) { 747 useSubCutoff = true; 748 scoffRegions.push_back(reg); 749 nSCoffRegions++; 750 } else { 751 useSubCutoff = false; 752 } 753 } 754 755 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 756 757 void G4VEnergyLossProcess::ActivateDeexcitation(G4bool val, const G4Region* r) 758 { 759 G4RegionStore* regionStore = G4RegionStore::GetInstance(); 760 const G4Region* reg = r; 761 if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);} 762 763 // the region is in the list 764 if (nDERegions) { 765 for (G4int i=0; i<nDERegions; i++) { 766 if (reg == deRegions[i]) { 767 if(!val) deRegions[i] = 0; 768 return; 769 } 770 } 771 } 772 773 // new region 774 if(val) { 775 useDeexcitation = true; 776 deRegions.push_back(reg); 777 nDERegions++; 778 } else { 779 useDeexcitation = false; 780 } 622 781 } 623 782 … … 641 800 if(x > finalRange && y < currentMinStep) { 642 801 x = y + finalRange*(1.0 - dRoverRange)*(2.0 - finalRange/fRange); 643 } else if (rndmStepFlag) x = SampleRange();644 // 645 // 646 // <<" safety= " << safety<< " limit= " << x <<G4endl;647 } 648 // 802 } else if (rndmStepFlag) {x = SampleRange();} 803 //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy 804 // <<" range= "<<fRange <<" cMinSt="<<currentMinStep 805 // << " limit= " << x <<G4endl; 806 } 807 //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy 649 808 // <<" stepLimit= "<<x<<G4endl; 650 809 return x; 651 }652 653 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....654 655 G4double G4VEnergyLossProcess::GetMeanFreePath(656 const G4Track& track,657 G4double,658 G4ForceCondition* condition)659 660 {661 *condition = NotForced;662 return MeanFreePath(track);663 810 } 664 811 … … 673 820 *condition = NotForced; 674 821 G4double x = DBL_MAX; 822 823 // initialisation of material, mass, charge, model at the beginning of the step 824 DefineMaterial(track.GetMaterialCutsCouple()); 825 826 const G4ParticleDefinition* currPart = track.GetDefinition(); 827 if(theGenericIon == particle) { 828 massRatio = proton_mass_c2/currPart->GetPDGMass(); 829 } 830 preStepKinEnergy = track.GetKineticEnergy(); 831 preStepScaledEnergy = preStepKinEnergy*massRatio; 832 SelectModel(preStepScaledEnergy); 833 834 if(isIon) { 835 chargeSqRatio = 836 currentModel->GetChargeSquareRatio(currPart,currentMaterial,preStepKinEnergy); 837 reduceFactor = 1.0/(chargeSqRatio*massRatio); 838 } 839 //G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl; 840 // initialisation for sampling of the interaction length 675 841 if(previousStepSize <= DBL_MIN) theNumberOfInteractionLengthLeft = -1.0; 676 InitialiseStep(track); 677 842 if(theNumberOfInteractionLengthLeft < 0.0) mfpKinEnergy = DBL_MAX; 843 844 // compute mean free path 678 845 if(preStepScaledEnergy < mfpKinEnergy) { 679 846 if (integral) ComputeLambdaForScaledEnergy(preStepScaledEnergy); … … 686 853 if (theNumberOfInteractionLengthLeft < 0.0) { 687 854 // beggining of tracking (or just after DoIt of this process) 855 //G4cout<<"G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength Reset"<<G4endl; 688 856 ResetNumberOfInteractionLengthLeft(); 689 857 } else if(currentInteractionLength < DBL_MAX) { … … 702 870 G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength "; 703 871 G4cout << "[ " << GetProcessName() << "]" << G4endl; 704 G4cout << " for " << particle->GetParticleName()872 G4cout << " for " << currPart->GetParticleName() 705 873 << " in Material " << currentMaterial->GetName() 706 874 << " Ekin(MeV)= " << preStepKinEnergy/MeV … … 710 878 } 711 879 #endif 712 713 880 // zero cross section case 714 881 } else { … … 738 905 if(length <= DBL_MIN) return &fParticleChange; 739 906 G4double eloss = 0.0; 740 741 /* 907 G4double esecdep = 0.0; 908 909 /* 742 910 if(-1 < verboseLevel) { 743 911 const G4ParticleDefinition* d = track.GetDefinition(); … … 755 923 */ 756 924 925 const G4DynamicParticle* dynParticle = track.GetDynamicParticle(); 926 757 927 // stopping 758 928 if (length >= fRange) { 929 eloss = preStepKinEnergy; 930 if (useDeexcitation) { 931 if(idxDERegions[currentMaterialIndex]) { 932 currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss); 933 if(eloss < 0.0) eloss = 0.0; 934 } 935 } 759 936 fParticleChange.SetProposedKineticEnergy(0.0); 760 fParticleChange.ProposeLocalEnergyDeposit( preStepKinEnergy);937 fParticleChange.ProposeLocalEnergyDeposit(eloss); 761 938 return &fParticleChange; 762 939 } … … 772 949 GetScaledRangeForScaledEnergy(preStepScaledEnergy) - length/reduceFactor; 773 950 eloss = preStepKinEnergy - ScaledKinEnergyForLoss(x)/massRatio; 951 774 952 /* 775 953 if(-1 < verboseLevel) … … 781 959 << " eloss0(MeV)= " 782 960 << GetDEDXForScaledEnergy(preStepScaledEnergy)*length/MeV 961 << " lim(MeV)= " << preStepKinEnergy*linLossLimit/MeV 783 962 << G4endl; 784 963 */ 785 964 } 786 965 787 const G4DynamicParticle* dynParticle = track.GetDynamicParticle(); 788 G4VEmModel* currentModel = SelectModel(preStepScaledEnergy); 789 /* 966 /* 790 967 G4double eloss0 = eloss; 791 968 if(-1 < verboseLevel ) { … … 801 978 G4double cut = (*theCuts)[currentMaterialIndex]; 802 979 G4double esec = 0.0; 803 G4double esecdep = 0.0;804 980 805 981 // SubCutOff … … 807 983 if(idxSCoffRegions[currentMaterialIndex]) { 808 984 809 G4 double currentMinSafety = 0.0;985 G4bool yes = false; 810 986 G4StepPoint* prePoint = step.GetPreStepPoint(); 811 G4StepPoint* postPoint = step.GetPostStepPoint(); 812 G4double preSafety = prePoint->GetSafety(); 813 G4double postSafety = preSafety - length; 814 G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1); 815 816 // recompute safety 817 if(prePoint->GetStepStatus() != fGeomBoundary && 818 postPoint->GetStepStatus() != fGeomBoundary) { 819 820 /* 821 // G4bool yes = (track.GetTrackID() == 5512); 822 G4bool yes = false; 823 if(yes) 824 G4cout << "G4VEnergyLoss: presafety= " << preSafety 825 << " rcut= " << rcut << " length= " << length 826 << " dir " << track.GetMomentumDirection() 827 << G4endl; 828 */ 829 830 if(preSafety < rcut) 987 988 // Check boundary 989 if(prePoint->GetStepStatus() == fGeomBoundary) yes = true; 990 991 // Check PrePoint 992 else { 993 G4double preSafety = prePoint->GetSafety(); 994 G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1); 995 996 // recompute presafety 997 if(preSafety < rcut) { 831 998 preSafety = safetyHelper->ComputeSafety(prePoint->GetPosition()); 832 833 //if(yes) { 834 // G4cout << "G4VEnergyLoss: newsafety= " << preSafety << G4endl; 835 // if(preSafety==0.0 && track.GetTrackID() == 5512 ) exit(1); 836 //} 837 if(postSafety < rcut) 838 postSafety = safetyHelper->ComputeSafety(postPoint->GetPosition()); 839 /* 840 if(-1 < verboseLevel) 841 G4cout << "Subcutoff: presafety(mm)= " << preSafety/mm 842 << " postsafety(mm)= " << postSafety/mm 843 << " rcut(mm)= " << rcut/mm 844 << G4endl; 845 */ 846 currentMinSafety = std::min(preSafety,postSafety); 847 } 848 999 } 1000 1001 if(preSafety < rcut) yes = true; 1002 1003 // Check PostPoint 1004 else { 1005 G4double postSafety = preSafety - length; 1006 if(postSafety < rcut) { 1007 postSafety = 1008 safetyHelper->ComputeSafety(step.GetPostStepPoint()->GetPosition()); 1009 if(postSafety < rcut) yes = true; 1010 } 1011 } 1012 } 1013 849 1014 // Decide to start subcut sampling 850 if( currentMinSafety < rcut) {1015 if(yes) { 851 1016 852 1017 cut = (*theSubCuts)[currentMaterialIndex]; … … 856 1021 currentModel,currentMaterialIndex, 857 1022 esecdep); 1023 // add bremsstrahlung sampling 858 1024 /* 859 1025 if(nProcesses > 0) { … … 876 1042 esec += e; 877 1043 pParticleChange->AddSecondary(t); 878 // mom -= t->GetMomentum();879 1044 } 880 // fParticleChange.SetProposedMomentum(mom);881 1045 } 882 1046 } … … 885 1049 886 1050 // Corrections, which cannot be tabulated 887 CorrectionsAlongStep(currentCouple, dynParticle, eloss, length); 1051 currentModel->CorrectionsAlongStep(currentCouple, dynParticle, 1052 eloss, esecdep, length); 888 1053 889 1054 // Sample fluctuations … … 895 1060 G4double tmax = 896 1061 std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),cut); 1062 G4double emean = eloss; 897 1063 eloss = fluc->SampleFluctuations(currentMaterial,dynParticle, 898 tmax,length,e loss);899 /* 1064 tmax,length,emean); 1065 /* 900 1066 if(-1 < verboseLevel) 901 1067 G4cout << "After fluct: eloss(MeV)= " << eloss/MeV 902 1068 << " fluc= " << (eloss-eloss0)/MeV 903 << " currentChargeSquare= " << chargeSquare1069 << " ChargeSqRatio= " << chargeSqRatio 904 1070 << " massRatio= " << massRatio 905 1071 << " tmax= " << tmax … … 911 1077 eloss += esecdep; 912 1078 if(eloss < 0.0) eloss = 0.0; 1079 1080 // deexcitation 1081 else if (useDeexcitation) { 1082 if(idxDERegions[currentMaterialIndex]) { 1083 currentModel->SampleDeexcitationAlongStep(currentMaterial, track, eloss); 1084 if(eloss < 0.0) eloss = 0.0; 1085 } 1086 } 913 1087 914 1088 // Energy balanse … … 917 1091 eloss = preStepKinEnergy - esec; 918 1092 finalT = 0.0; 1093 } else if(isIon) { 1094 fParticleChange.SetProposedCharge( 1095 currentModel->GetParticleCharge(track.GetDefinition(),currentMaterial,finalT)); 919 1096 } 920 1097 … … 922 1099 fParticleChange.ProposeLocalEnergyDeposit(eloss); 923 1100 924 /* 1101 /* 925 1102 if(-1 < verboseLevel) { 926 1103 G4cout << "Final value eloss(MeV)= " << eloss/MeV … … 931 1108 << G4endl; 932 1109 } 933 */ 1110 */ 934 1111 935 1112 return &fParticleChange; … … 943 1120 G4VEmModel* model, 944 1121 G4int idx, 945 G4double& extraEdep)1122 G4double& /*extraEdep*/) 946 1123 { 947 1124 // Fast check weather subcutoff can work … … 952 1129 const G4Track* track = step.GetTrack(); 953 1130 const G4DynamicParticle* dp = track->GetDynamicParticle(); 1131 G4double e = dp->GetKineticEnergy()*massRatio; 954 1132 G4bool b; 955 G4double cross = 956 chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(dp->GetKineticEnergy(),b)); 1133 G4double cross = chargeSqRatio*(((*theSubLambdaTable)[idx])->GetValue(e,b)); 957 1134 G4double length = step.GetStepLength(); 958 1135 959 1136 // negligible probability to get any interaction 960 1137 if(length*cross < perMillion) return; 961 /* 1138 /* 962 1139 if(-1 < verboseLevel) 963 1140 G4cout << "<<< Subcutoff for " << GetProcessName() … … 970 1147 // Sample subcutoff secondaries 971 1148 G4StepPoint* preStepPoint = step.GetPreStepPoint(); 1149 G4StepPoint* postStepPoint = step.GetPostStepPoint(); 972 1150 G4ThreeVector prepoint = preStepPoint->GetPosition(); 973 G4ThreeVector dr = step.GetPostStepPoint()->GetPosition() - prepoint;1151 G4ThreeVector dr = postStepPoint->GetPosition() - prepoint; 974 1152 G4double pretime = preStepPoint->GetGlobalTime(); 975 // G4double dt = length/preStepPoint->GetVelocity(); 1153 G4double dt = postStepPoint->GetGlobalTime() - pretime; 1154 //G4double dt = length/preStepPoint->GetVelocity(); 976 1155 G4double fragment = 0.0; 977 1156 … … 992 1171 993 1172 G4bool addSec = true; 1173 /* 994 1174 // do not track very low-energy delta-electrons 995 1175 if(theSecondaryRangeTable && (*it)->GetDefinition() == theElectron) { … … 1004 1184 } 1005 1185 } 1186 */ 1006 1187 if(addSec) { 1007 //G4Track* t = new G4Track((*it), pretime + fragment*dt, r);1008 G4Track* t = new G4Track((*it), pretime, r);1188 G4Track* t = new G4Track((*it), pretime + fragment*dt, r); 1189 //G4Track* t = new G4Track((*it), pretime, r); 1009 1190 t->SetTouchableHandle(track->GetTouchableHandle()); 1010 1191 tracks.push_back(t); 1011 1192 1012 /* 1013 1014 G4cout << "New track " << p->GetDefinition()->GetParticleName()1015 << " e(keV)= " << p->GetKineticEnergy()/keV1016 1017 1193 /* 1194 if(-1 < verboseLevel) 1195 G4cout << "New track " << t->GetDefinition()->GetParticleName() 1196 << " e(keV)= " << t->GetKineticEnergy()/keV 1197 << " fragment= " << fragment 1198 << G4endl; 1018 1199 */ 1019 1200 } … … 1059 1240 } 1060 1241 1061 G4VEmModel* currentModel = SelectModel(postStepScaledEnergy); 1242 SelectModel(postStepScaledEnergy); 1243 if(useDeexcitation) { 1244 currentModel->SetDeexcitationFlag(idxDERegions[currentMaterialIndex]); 1245 } 1246 1062 1247 const G4DynamicParticle* dynParticle = track.GetDynamicParticle(); 1063 1248 G4double tcut = (*theCuts)[currentMaterialIndex]; … … 1094 1279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1095 1280 1096 void G4VEnergyLossProcess::PrintInfoDefinition() 1097 { 1098 if(0 < verboseLevel) { 1099 G4cout << G4endl << GetProcessName() << ": tables are built for " 1100 << particle->GetParticleName() 1101 << G4endl 1102 << " dE/dx and range tables from " 1103 << G4BestUnit(minKinEnergy,"Energy") 1104 << " to " << G4BestUnit(maxKinEnergy,"Energy") 1105 << " in " << nBins << " bins." << G4endl 1106 << " Lambda tables from threshold to " 1107 << G4BestUnit(maxKinEnergy,"Energy") 1108 << " in " << nBins << " bins." 1281 G4bool G4VEnergyLossProcess::StorePhysicsTable( 1282 const G4ParticleDefinition* part, const G4String& directory, 1283 G4bool ascii) 1284 { 1285 G4bool res = true; 1286 if ( baseParticle || part != particle ) return res; 1287 1288 if(!StoreTable(part,theDEDXTable,ascii,directory,"DEDX")) 1289 {res = false;} 1290 1291 if(!StoreTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr")) 1292 {res = false;} 1293 1294 if(!StoreTable(part,theDEDXSubTable,ascii,directory,"SubDEDX")) 1295 {res = false;} 1296 1297 if(!StoreTable(part,theIonisationTable,ascii,directory,"Ionisation")) 1298 {res = false;} 1299 1300 if(!StoreTable(part,theIonisationSubTable,ascii,directory,"SubIonisation")) 1301 {res = false;} 1302 1303 if(isIonisation && 1304 !StoreTable(part,theCSDARangeTable,ascii,directory,"CSDARange")) 1305 {res = false;} 1306 1307 if(isIonisation && 1308 !StoreTable(part,theRangeTableForLoss,ascii,directory,"Range")) 1309 {res = false;} 1310 1311 if(isIonisation && 1312 !StoreTable(part,theInverseRangeTable,ascii,directory,"InverseRange")) 1313 {res = false;} 1314 1315 if(!StoreTable(part,theLambdaTable,ascii,directory,"Lambda")) 1316 {res = false;} 1317 1318 if(!StoreTable(part,theSubLambdaTable,ascii,directory,"SubLambda")) 1319 {res = false;} 1320 1321 if ( res ) { 1322 if(0 < verboseLevel) { 1323 G4cout << "Physics tables are stored for " << particle->GetParticleName() 1324 << " and process " << GetProcessName() 1325 << " in the directory <" << directory 1326 << "> " << G4endl; 1327 } 1328 } else { 1329 G4cout << "Fail to store Physics Tables for " 1330 << particle->GetParticleName() 1331 << " and process " << GetProcessName() 1332 << " in the directory <" << directory 1333 << "> " << G4endl; 1334 } 1335 return res; 1336 } 1337 1338 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 1339 1340 G4bool G4VEnergyLossProcess::RetrievePhysicsTable( 1341 const G4ParticleDefinition* part, const G4String& directory, 1342 G4bool ascii) 1343 { 1344 G4bool res = true; 1345 const G4String particleName = part->GetParticleName(); 1346 1347 if(1 < verboseLevel) { 1348 G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for " 1349 << particleName << " and process " << GetProcessName() 1350 << "; tables_are_built= " << tablesAreBuilt 1109 1351 << G4endl; 1110 PrintInfo(); 1111 if(theRangeTableForLoss && isIonisation) 1112 G4cout << " Step function: finalRange(mm)= " << finalRange/mm 1113 << ", dRoverRange= " << dRoverRange 1114 << ", integral: " << integral 1115 << ", fluct: " << lossFluctuationFlag 1116 << G4endl; 1117 1118 if(theCSDARangeTable && isIonisation) 1119 G4cout << " CSDA range table up" 1120 << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy") 1121 << " in " << nBinsCSDA << " bins." << G4endl; 1122 1123 if(nSCoffRegions>0) 1124 G4cout << " Subcutoff sampling in " << nSCoffRegions 1125 << " regions" << G4endl; 1126 1127 if(2 < verboseLevel) { 1128 G4cout << "DEDXTable address= " << theDEDXTable << G4endl; 1129 if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl; 1130 G4cout << "non restricted DEDXTable address= " 1131 << theDEDXunRestrictedTable << G4endl; 1132 if(theDEDXunRestrictedTable && isIonisation) 1133 G4cout << (*theDEDXunRestrictedTable) << G4endl; 1134 if(theDEDXSubTable && isIonisation) G4cout << (*theDEDXSubTable) 1135 << G4endl; 1136 G4cout << "CSDARangeTable address= " << theCSDARangeTable 1352 } 1353 if(particle == part) { 1354 1355 // G4bool yes = true; 1356 if ( !baseParticle ) { 1357 1358 G4bool fpi = true; 1359 if(!RetrieveTable(part,theDEDXTable,ascii,directory,"DEDX",fpi)) 1360 {fpi = false;} 1361 1362 if(!RetrieveTable(part,theIonisationTable,ascii,directory,"Ionisation",false)) 1363 {fpi = false;} 1364 1365 if(!RetrieveTable(part,theRangeTableForLoss,ascii,directory,"Range",fpi)) 1366 {res = false;} 1367 1368 if(!RetrieveTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr",false)) 1369 {res = false;} 1370 1371 if(!RetrieveTable(part,theCSDARangeTable,ascii,directory,"CSDARange",false)) 1372 {res = false;} 1373 1374 if(!RetrieveTable(part,theInverseRangeTable,ascii,directory,"InverseRange",fpi)) 1375 {res = false;} 1376 1377 if(!RetrieveTable(part,theLambdaTable,ascii,directory,"Lambda",true)) 1378 {res = false;} 1379 1380 G4bool yes = false; 1381 if(nSCoffRegions > 0) {yes = true;} 1382 1383 if(!RetrieveTable(part,theDEDXSubTable,ascii,directory,"SubDEDX",yes)) 1384 {res = false;} 1385 1386 if(!RetrieveTable(part,theSubLambdaTable,ascii,directory,"SubLambda",yes)) 1387 {res = false;} 1388 1389 if(!fpi) yes = false; 1390 if(!RetrieveTable(part,theIonisationSubTable,ascii,directory,"SubIonisation",yes)) 1391 {res = false;} 1392 } 1393 } 1394 1395 return res; 1396 } 1397 1398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 1399 1400 G4bool G4VEnergyLossProcess::StoreTable(const G4ParticleDefinition* part, 1401 G4PhysicsTable* aTable, G4bool ascii, 1402 const G4String& directory, 1403 const G4String& tname) 1404 { 1405 G4bool res = true; 1406 if ( aTable ) { 1407 const G4String name = GetPhysicsTableFileName(part,directory,tname,ascii); 1408 if( !aTable->StorePhysicsTable(name,ascii)) res = false; 1409 } 1410 return res; 1411 } 1412 1413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 1414 1415 G4bool G4VEnergyLossProcess::RetrieveTable(const G4ParticleDefinition* part, 1416 G4PhysicsTable* aTable, G4bool ascii, 1417 const G4String& directory, 1418 const G4String& tname, 1419 G4bool mandatory) 1420 { 1421 G4bool res = true; 1422 G4String filename = GetPhysicsTableFileName(part,directory,tname,ascii); 1423 G4bool yes = aTable->ExistPhysicsTable(filename); 1424 if(yes) { 1425 yes = G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii); 1426 if((G4LossTableManager::Instance())->SplineFlag()) { 1427 size_t n = aTable->length(); 1428 for(size_t i=0; i<n; i++) {(*aTable)[i]->SetSpline(true);} 1429 } 1430 } 1431 if(yes) { 1432 if (0 < verboseLevel) { 1433 G4cout << tname << " table for " << part->GetParticleName() 1434 << " is Retrieved from <" << filename << ">" 1137 1435 << G4endl; 1138 if(theCSDARangeTable && isIonisation) G4cout << (*theCSDARangeTable) 1139 << G4endl; 1140 G4cout << "RangeTableForLoss address= " << theRangeTableForLoss 1436 } 1437 } else { 1438 if(mandatory) res = false; 1439 if(mandatory || 1 < verboseLevel) { 1440 G4cout << tname << " table for " << part->GetParticleName() 1441 << " from file <" 1442 << filename << "> is not Retrieved" 1141 1443 << G4endl; 1142 if(theRangeTableForLoss && isIonisation) 1143 G4cout << (*theRangeTableForLoss) << G4endl; 1144 G4cout << "InverseRangeTable address= " << theInverseRangeTable 1145 << G4endl; 1146 if(theInverseRangeTable && isIonisation) 1147 G4cout << (*theInverseRangeTable) << G4endl; 1148 G4cout << "LambdaTable address= " << theLambdaTable << G4endl; 1149 if(theLambdaTable && isIonisation) G4cout << (*theLambdaTable) << G4endl; 1150 G4cout << "SubLambdaTable address= " << theSubLambdaTable << G4endl; 1151 if(theSubLambdaTable && isIonisation) G4cout << (*theSubLambdaTable) 1152 << G4endl; 1444 } 1445 } 1446 return res; 1447 } 1448 1449 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1450 1451 G4double G4VEnergyLossProcess::GetDEDXDispersion( 1452 const G4MaterialCutsCouple *couple, 1453 const G4DynamicParticle* dp, 1454 G4double length) 1455 { 1456 DefineMaterial(couple); 1457 G4double ekin = dp->GetKineticEnergy(); 1458 SelectModel(ekin*massRatio); 1459 G4double tmax = currentModel->MaxSecondaryKinEnergy(dp); 1460 tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]); 1461 G4double d = 0.0; 1462 G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations(); 1463 if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length); 1464 return d; 1465 } 1466 1467 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1468 1469 G4double G4VEnergyLossProcess::CrossSectionPerVolume( 1470 G4double kineticEnergy, const G4MaterialCutsCouple* couple) 1471 { 1472 // Cross section per volume is calculated 1473 DefineMaterial(couple); 1474 G4double cross = 0.0; 1475 G4bool b; 1476 if(theLambdaTable) { 1477 cross = 1478 ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b); 1479 } else { 1480 SelectModel(kineticEnergy); 1481 cross = 1482 currentModel->CrossSectionPerVolume(currentMaterial, 1483 particle, kineticEnergy, 1484 (*theCuts)[currentMaterialIndex]); 1485 } 1486 1487 return cross; 1488 } 1489 1490 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1491 1492 G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track) 1493 { 1494 DefineMaterial(track.GetMaterialCutsCouple()); 1495 preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio); 1496 G4double x = DBL_MAX; 1497 if(DBL_MIN < preStepLambda) x = 1.0/preStepLambda; 1498 return x; 1499 } 1500 1501 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1502 1503 G4double G4VEnergyLossProcess::ContinuousStepLimit(const G4Track& track, 1504 G4double x, G4double y, 1505 G4double& z) 1506 { 1507 G4GPILSelection sel; 1508 return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel); 1509 } 1510 1511 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1512 1513 G4double G4VEnergyLossProcess::GetMeanFreePath( 1514 const G4Track& track, 1515 G4double, 1516 G4ForceCondition* condition) 1517 1518 { 1519 *condition = NotForced; 1520 return MeanFreePath(track); 1521 } 1522 1523 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1524 1525 G4double G4VEnergyLossProcess::GetContinuousStepLimit( 1526 const G4Track&, 1527 G4double, G4double, G4double&) 1528 { 1529 return DBL_MAX; 1530 } 1531 1532 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1533 1534 G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector( 1535 const G4MaterialCutsCouple* couple, G4double cut) 1536 { 1537 // G4double cut = (*theCuts)[couple->GetIndex()]; 1538 // G4int nbins = nLambdaBins; 1539 G4double tmin = 1540 std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut), 1541 minKinEnergy); 1542 if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy; 1543 G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins); 1544 v->SetSpline((G4LossTableManager::Instance())->SplineFlag()); 1545 1546 return v; 1547 } 1548 1549 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1550 1551 void G4VEnergyLossProcess::AddCollaborativeProcess( 1552 G4VEnergyLossProcess* p) 1553 { 1554 G4bool add = true; 1555 if(p->GetProcessName() != "eBrem") add = false; 1556 if(add && nProcesses > 0) { 1557 for(G4int i=0; i<nProcesses; i++) { 1558 if(p == scProcesses[i]) { 1559 add = false; 1560 break; 1561 } 1562 } 1563 } 1564 if(add) { 1565 scProcesses.push_back(p); 1566 nProcesses++; 1567 if (1 < verboseLevel) { 1568 G4cout << "### The process " << p->GetProcessName() 1569 << " is added to the list of collaborative processes of " 1570 << GetProcessName() << G4endl; 1153 1571 } 1154 1572 } … … 1182 1600 } else if(fSubRestricted == tType) { 1183 1601 theDEDXSubTable = p; 1184 } else if(fI onisation == tType && theIonisationTable != p) {1602 } else if(fIsIonisation == tType && theIonisationTable != p) { 1185 1603 if(theIonisationTable) theIonisationTable->clearAndDestroy(); 1186 1604 theIonisationTable = p; 1187 } else if(f SubIonisation == tType && theIonisationSubTable != p) {1605 } else if(fIsSubIonisation == tType && theIonisationSubTable != p) { 1188 1606 if(theIonisationSubTable) theIonisationSubTable->clearAndDestroy(); 1189 1607 theIonisationSubTable = p; … … 1319 1737 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 1320 1738 1321 G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(1322 const G4MaterialCutsCouple* couple, G4double cut)1323 {1324 // G4double cut = (*theCuts)[couple->GetIndex()];1325 // G4int nbins = nLambdaBins;1326 G4double tmin =1327 std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),1328 minKinEnergy);1329 if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;1330 G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nBins);1331 return v;1332 }1333 1334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1335 1336 G4double G4VEnergyLossProcess::MicroscopicCrossSection(1337 G4double kineticEnergy, const G4MaterialCutsCouple* couple)1338 {1339 // Cross section per atom is calculated1340 DefineMaterial(couple);1341 G4double cross = 0.0;1342 G4bool b;1343 if(theLambdaTable)1344 cross =1345 ((*theLambdaTable)[currentMaterialIndex])->GetValue(kineticEnergy, b)/1346 currentMaterial->GetTotNbOfAtomsPerVolume();1347 1348 return cross;1349 }1350 1351 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1352 1353 G4bool G4VEnergyLossProcess::StorePhysicsTable(1354 const G4ParticleDefinition* part, const G4String& directory,1355 G4bool ascii)1356 {1357 G4bool res = true;1358 if ( baseParticle || part != particle ) return res;1359 1360 if ( theDEDXTable ) {1361 const G4String name = GetPhysicsTableFileName(part,directory,"DEDX",ascii);1362 if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;1363 }1364 1365 if ( theDEDXunRestrictedTable ) {1366 const G4String name =1367 GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);1368 if( !theDEDXTable->StorePhysicsTable(name,ascii)) res = false;1369 }1370 1371 if ( theDEDXSubTable ) {1372 const G4String name =1373 GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);1374 if( !theDEDXSubTable->StorePhysicsTable(name,ascii)) res = false;1375 }1376 1377 if ( theIonisationTable ) {1378 const G4String name =1379 GetPhysicsTableFileName(part,directory,"Ionisation",ascii);1380 if( !theIonisationTable->StorePhysicsTable(name,ascii)) res = false;1381 }1382 1383 if ( theIonisationSubTable ) {1384 const G4String name =1385 GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);1386 if( !theIonisationSubTable->StorePhysicsTable(name,ascii)) res = false;1387 }1388 1389 if ( theCSDARangeTable && isIonisation ) {1390 const G4String name =1391 GetPhysicsTableFileName(part,directory,"CSDARange",ascii);1392 if( !theCSDARangeTable->StorePhysicsTable(name,ascii)) res = false;1393 }1394 1395 if ( theRangeTableForLoss && isIonisation ) {1396 const G4String name =1397 GetPhysicsTableFileName(part,directory,"Range",ascii);1398 if( !theRangeTableForLoss->StorePhysicsTable(name,ascii)) res = false;1399 }1400 1401 if ( theInverseRangeTable && isIonisation ) {1402 const G4String name =1403 GetPhysicsTableFileName(part,directory,"InverseRange",ascii);1404 if( !theInverseRangeTable->StorePhysicsTable(name,ascii)) res = false;1405 }1406 1407 if ( theLambdaTable && isIonisation) {1408 const G4String name =1409 GetPhysicsTableFileName(part,directory,"Lambda",ascii);1410 if( !theLambdaTable->StorePhysicsTable(name,ascii)) res = false;1411 }1412 1413 if ( theSubLambdaTable && isIonisation) {1414 const G4String name =1415 GetPhysicsTableFileName(part,directory,"SubLambda",ascii);1416 if( !theSubLambdaTable->StorePhysicsTable(name,ascii)) res = false;1417 }1418 if ( res ) {1419 if(0 < verboseLevel) {1420 G4cout << "Physics tables are stored for " << particle->GetParticleName()1421 << " and process " << GetProcessName()1422 << " in the directory <" << directory1423 << "> " << G4endl;1424 }1425 } else {1426 G4cout << "Fail to store Physics Tables for "1427 << particle->GetParticleName()1428 << " and process " << GetProcessName()1429 << " in the directory <" << directory1430 << "> " << G4endl;1431 }1432 return res;1433 }1434 1435 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....1436 1437 G4bool G4VEnergyLossProcess::RetrievePhysicsTable(1438 const G4ParticleDefinition* part, const G4String& directory,1439 G4bool ascii)1440 {1441 G4bool res = true;1442 const G4String particleName = part->GetParticleName();1443 1444 if(1 < verboseLevel) {1445 G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "1446 << particleName << " and process " << GetProcessName()1447 << "; tables_are_built= " << tablesAreBuilt1448 << G4endl;1449 }1450 if(particle == part) {1451 1452 G4bool yes = true;1453 G4bool fpi = true;1454 if ( !baseParticle ) {1455 G4String filename;1456 1457 filename = GetPhysicsTableFileName(part,directory,"DEDX",ascii);1458 yes = theDEDXTable->ExistPhysicsTable(filename);1459 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1460 theDEDXTable,filename,ascii);1461 if(yes) {1462 if (0 < verboseLevel) {1463 G4cout << "DEDX table for " << particleName1464 << " is Retrieved from <"1465 << filename << ">"1466 << G4endl;1467 }1468 } else {1469 fpi = false;1470 if (1 < verboseLevel) {1471 G4cout << "DEDX table for " << particleName << " from file <"1472 << filename << "> is not Retrieved"1473 << G4endl;1474 }1475 }1476 1477 filename = GetPhysicsTableFileName(part,directory,"Range",ascii);1478 yes = theRangeTableForLoss->ExistPhysicsTable(filename);1479 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1480 theRangeTableForLoss,filename,ascii);1481 if(yes) {1482 if (0 < verboseLevel) {1483 G4cout << "Range table for loss for " << particleName1484 << " is Retrieved from <"1485 << filename << ">"1486 << G4endl;1487 }1488 } else {1489 if(fpi) {1490 res = false;1491 G4cout << "Range table for loss for " << particleName1492 << " from file <"1493 << filename << "> is not Retrieved"1494 << G4endl;1495 }1496 }1497 1498 filename = GetPhysicsTableFileName(part,directory,"DEDXnr",ascii);1499 yes = theDEDXunRestrictedTable->ExistPhysicsTable(filename);1500 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1501 theDEDXunRestrictedTable,filename,ascii);1502 if(yes) {1503 if (0 < verboseLevel) {1504 G4cout << "Non-restricted DEDX table for " << particleName1505 << " is Retrieved from <"1506 << filename << ">"1507 << G4endl;1508 }1509 } else {1510 if (1 < verboseLevel) {1511 G4cout << "Non-restricted DEDX table for " << particleName1512 << " from file <"1513 << filename << "> is not Retrieved"1514 << G4endl;1515 }1516 }1517 1518 filename = GetPhysicsTableFileName(part,directory,"CSDARange",ascii);1519 yes = theCSDARangeTable->ExistPhysicsTable(filename);1520 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1521 theCSDARangeTable,filename,ascii);1522 if(yes) {1523 if (0 < verboseLevel) {1524 G4cout << "CSDA Range table for " << particleName1525 << " is Retrieved from <"1526 << filename << ">"1527 << G4endl;1528 }1529 } else {1530 G4cout << "CSDA Range table for loss for " << particleName1531 << " does not exist"1532 << G4endl;1533 }1534 1535 filename = GetPhysicsTableFileName(part,directory,"InverseRange",ascii);1536 yes = theInverseRangeTable->ExistPhysicsTable(filename);1537 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1538 theInverseRangeTable,filename,ascii);1539 if(yes) {1540 if (0 < verboseLevel) {1541 G4cout << "InverseRange table for " << particleName1542 << " is Retrieved from <"1543 << filename << ">"1544 << G4endl;1545 }1546 } else {1547 if(fpi) {1548 res = false;1549 G4cout << "InverseRange table for " << particleName1550 << " from file <"1551 << filename << "> is not Retrieved"1552 << G4endl;1553 1554 }1555 }1556 1557 filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);1558 yes = theLambdaTable->ExistPhysicsTable(filename);1559 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1560 theLambdaTable,filename,ascii);1561 if(yes) {1562 if (0 < verboseLevel) {1563 G4cout << "Lambda table for " << particleName1564 << " is Retrieved from <"1565 << filename << ">"1566 << G4endl;1567 }1568 } else {1569 if(fpi) {1570 res = false;1571 G4cout << "Lambda table for " << particleName << " from file <"1572 << filename << "> is not Retrieved"1573 << G4endl;1574 }1575 }1576 1577 filename = GetPhysicsTableFileName(part,directory,"SubDEDX",ascii);1578 yes = theDEDXSubTable->ExistPhysicsTable(filename);1579 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1580 theDEDXSubTable,filename,ascii);1581 if(yes) {1582 if (0 < verboseLevel) {1583 G4cout << "SubDEDX table for " << particleName1584 << " is Retrieved from <"1585 << filename << ">"1586 << G4endl;1587 }1588 } else {1589 if(nSCoffRegions) {1590 res=false;1591 G4cout << "SubDEDX table for " << particleName << " from file <"1592 << filename << "> is not Retrieved"1593 << G4endl;1594 }1595 }1596 1597 filename = GetPhysicsTableFileName(part,directory,"SubLambda",ascii);1598 yes = theSubLambdaTable->ExistPhysicsTable(filename);1599 if(yes) yes = G4PhysicsTableHelper::RetrievePhysicsTable(1600 theSubLambdaTable,filename,ascii);1601 if(yes) {1602 if (0 < verboseLevel) {1603 G4cout << "SubLambda table for " << particleName1604 << " is Retrieved from <"1605 << filename << ">"1606 << G4endl;1607 }1608 } else {1609 if(nSCoffRegions) {1610 res=false;1611 G4cout << "SubLambda table for " << particleName << " from file <"1612 << filename << "> is not Retrieved"1613 << G4endl;1614 }1615 }1616 1617 filename = GetPhysicsTableFileName(part,directory,"Ionisation",ascii);1618 yes = theIonisationTable->ExistPhysicsTable(filename);1619 if(yes) {1620 theIonisationTable =1621 G4PhysicsTableHelper::PreparePhysicsTable(theIonisationTable);1622 1623 yes = G4PhysicsTableHelper::RetrievePhysicsTable(1624 theIonisationTable,filename,ascii);1625 }1626 if(yes) {1627 if (0 < verboseLevel) {1628 G4cout << "Ionisation table for " << particleName1629 << " is Retrieved from <"1630 << filename << ">"1631 << G4endl;1632 }1633 }1634 1635 filename = GetPhysicsTableFileName(part,directory,"SubIonisation",ascii);1636 yes = theIonisationSubTable->ExistPhysicsTable(filename);1637 if(yes) {1638 theIonisationSubTable =1639 G4PhysicsTableHelper::PreparePhysicsTable(theIonisationSubTable);1640 yes = G4PhysicsTableHelper::RetrievePhysicsTable(1641 theIonisationSubTable,filename,ascii);1642 }1643 if(yes) {1644 if (0 < verboseLevel) {1645 G4cout << "SubIonisation table for " << particleName1646 << " is Retrieved from <"1647 << filename << ">"1648 << G4endl;1649 }1650 }1651 }1652 }1653 1654 return res;1655 }1656 1657 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1658 1659 void G4VEnergyLossProcess::AddCollaborativeProcess(1660 G4VEnergyLossProcess* p)1661 {1662 G4bool add = true;1663 if(nProcesses > 0) {1664 for(G4int i=0; i<nProcesses; i++) {1665 if(p == scProcesses[i]) {1666 add = false;1667 break;1668 }1669 }1670 }1671 if(add) {1672 scProcesses.push_back(p);1673 nProcesses++;1674 if (0 < verboseLevel)1675 G4cout << "### The process " << p->GetProcessName()1676 << " is added to the list of collaborative processes of "1677 << GetProcessName() << G4endl;1678 }1679 }1680 1681 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1682 1683 G4double G4VEnergyLossProcess::GetDEDXDispersion(1684 const G4MaterialCutsCouple *couple,1685 const G4DynamicParticle* dp,1686 G4double length)1687 {1688 DefineMaterial(couple);1689 G4double ekin = dp->GetKineticEnergy();1690 G4VEmModel* currentModel = SelectModel(ekin*massRatio);1691 G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);1692 tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);1693 G4double d = 0.0;1694 G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();1695 if(fm) d = fm->Dispersion(currentMaterial,dp,tmax,length);1696 return d;1697 }1698 1699 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1700 1701 void G4VEnergyLossProcess::ActivateDeexcitation(G4bool, const G4Region*)1702 {}1703 1704 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....1705 -
trunk/source/processes/electromagnetic/utils/src/G4VMultipleScattering.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4VMultipleScattering.cc,v 1. 47 2007/11/09 11:35:54vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4VMultipleScattering.cc,v 1.60 2008/11/20 20:32:40 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 55 55 // 12-04-07 Add verbosity at destruction (V.Ivanchenko) 56 56 // 27-10-07 Virtual functions moved to source (V.Ivanchenko) 57 // 11-03-08 Set skin value does not effect step limit type (V.Ivanchenko) 57 58 // 58 59 // Class Description: … … 85 86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 86 87 87 G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType type): 88 G4VContinuousDiscreteProcess(name, type), 88 G4VMultipleScattering::G4VMultipleScattering(const G4String& name, 89 G4ProcessType type): 90 G4VContinuousDiscreteProcess(name, type), 91 buildLambdaTable(true), 89 92 theLambdaTable(0), 90 93 firstParticle(0), 91 currentParticle(0),92 currentCouple(0),93 nBins(120),94 94 stepLimit(fUseSafety), 95 skin( 0.0),95 skin(3.0), 96 96 facrange(0.02), 97 97 facgeom(2.5), 98 98 latDisplasment(true), 99 buildLambdaTable(true) 100 { 99 currentParticle(0), 100 currentCouple(0) 101 { 102 SetVerboseLevel(1); 103 SetProcessSubType(fMultipleScattering); 104 105 // Size of tables assuming spline 101 106 minKinEnergy = 0.1*keV; 102 107 maxKinEnergy = 100.0*TeV; 103 SetVerboseLevel(1); 108 nBins = 84; 109 110 // default limit on polar angle 111 polarAngleLimit = 0.0; 104 112 105 113 pParticleChange = &fParticleChange; … … 114 122 G4VMultipleScattering::~G4VMultipleScattering() 115 123 { 116 if(1 < verboseLevel) 124 if(1 < verboseLevel) { 117 125 G4cout << "G4VMultipleScattering destruct " << GetProcessName() 118 126 << G4endl; 127 } 119 128 delete modelManager; 120 129 if (theLambdaTable) { … … 131 140 G4String num = part.GetParticleName(); 132 141 if(1 < verboseLevel) { 133 // G4cout << "========================================================" << G4endl;134 142 G4cout << "### G4VMultipleScattering::BuildPhysicsTable() for " 135 143 << GetProcessName() … … 148 156 if (theLambdaTable->GetFlag(i)) { 149 157 // create physics vector and fill it 150 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i); 158 const G4MaterialCutsCouple* couple = 159 theCoupleTable->GetMaterialCutsCouple(i); 151 160 G4PhysicsVector* aVector = PhysicsVector(couple); 152 161 modelManager->FillLambdaVector(aVector, couple, false); … … 162 171 } 163 172 if(verboseLevel>0 && ( num == "e-" || num == "mu+" || 164 num == "proton" || num == "pi-" || num == "GenericIon")) { 173 num == "proton" || num == "pi-" || 174 num == "GenericIon")) { 165 175 PrintInfoDefinition(); 166 176 if(2 < verboseLevel && theLambdaTable) G4cout << *theLambdaTable << G4endl; … … 182 192 currentCouple = 0; 183 193 if(part.GetParticleType() == "nucleus" && 184 part.GetParticleSubType() == "generic") 185 firstParticle = G4GenericIon::GenericIon(); 186 else firstParticle = ∂ 194 part.GetParticleSubType() == "generic") { 195 firstParticle = G4GenericIon::GenericIon(); 196 } else { 197 firstParticle = ∂ 198 } 199 187 200 currentParticle = ∂ 188 201 } 189 202 190 203 if(1 < verboseLevel) { 191 // G4cout << "========================================================" << G4endl;192 204 G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for " 193 205 << GetProcessName() … … 217 229 { 218 230 if (0 < verboseLevel) { 219 G4cout << G4endl << GetProcessName() << ": Model variant of multiple scattering " 220 << "for " << firstParticle->GetParticleName() 231 G4cout << G4endl << GetProcessName() 232 << ": for " << firstParticle->GetParticleName() 233 << " SubType= " << GetProcessSubType() 221 234 << G4endl; 222 235 if (theLambdaTable) { … … 225 238 << " to " 226 239 << G4BestUnit(MaxKinEnergy(),"Energy") 227 << " in " << nBins << " bins." 240 << " in " << nBins << " bins, spline: " 241 << (G4LossTableManager::Instance())->SplineFlag() 228 242 << G4endl; 229 243 } 230 G4cout << " LateralDisplacementFlag= " << latDisplasment231 << " Skin= " << skin << G4endl;232 244 PrintInfo(); 245 modelManager->DumpModelList(verboseLevel); 233 246 if (2 < verboseLevel) { 234 247 G4cout << "LambdaTable address= " << theLambdaTable << G4endl; … … 242 255 G4double G4VMultipleScattering::AlongStepGetPhysicalInteractionLength( 243 256 const G4Track& track, 244 G4double previousStepSize,257 G4double, 245 258 G4double currentMinimalStep, 246 259 G4double& currentSafety, … … 249 262 // get Step limit proposed by the process 250 263 valueGPILSelectionMSC = NotCandidateForSelection; 251 G4double steplength = GetMscContinuousStepLimit(track,previousStepSize, 252 currentMinimalStep,currentSafety); 264 G4double steplength = GetMscContinuousStepLimit(track, 265 track.GetKineticEnergy(), 266 currentMinimalStep, 267 currentSafety); 253 268 // G4cout << "StepLimit= " << steplength << G4endl; 254 269 // set return value for G4GPILSelection … … 315 330 if( couple->IsUsed() ) nbins = nBins; 316 331 G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins); 332 v->SetSpline((G4LossTableManager::Instance())->SplineFlag()); 317 333 return v; 318 334 } … … 372 388 << G4endl; 373 389 } 390 if((G4LossTableManager::Instance())->SplineFlag()) { 391 size_t n = theLambdaTable->length(); 392 for(size_t i=0; i<n; i++) {(* theLambdaTable)[i]->SetSpline(true);} 393 } 374 394 } else { 375 395 if (1 < verboseLevel) { -
trunk/source/processes/electromagnetic/utils/src/G4ionEffectiveCharge.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4ionEffectiveCharge.cc,v 1. 17.2.1 2008/04/22 15:28:13 vnivanchExp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4ionEffectiveCharge.cc,v 1.24 2008/12/18 13:01:46 gunter Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 54 54 #include "G4ionEffectiveCharge.hh" 55 55 #include "G4UnitsTable.hh" 56 #include "G4ParticleDefinition.hh"57 56 #include "G4Material.hh" 57 #include "G4NistManager.hh" 58 58 59 59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 62 62 { 63 63 chargeCorrection = 1.0; 64 energyHighLimit = 10.0*MeV;64 energyHighLimit = 20.0*MeV; 65 65 energyLowLimit = 1.0*keV; 66 66 energyBohr = 25.*keV; 67 67 massFactor = amu_c2/(proton_mass_c2*keV); 68 minCharge = 0.1; 68 minCharge = 1.0; 69 lastPart = 0; 70 lastMat = 0; 71 lastKinEnergy = 0.0; 72 effCharge = eplus; 73 nist = G4NistManager::Instance(); 69 74 } 70 75 … … 78 83 G4double G4ionEffectiveCharge::EffectiveCharge(const G4ParticleDefinition* p, 79 84 const G4Material* material, 80 85 G4double kineticEnergy) 81 86 { 87 if(p == lastPart && material == lastMat && kineticEnergy == lastKinEnergy) 88 return effCharge; 89 90 lastPart = p; 91 lastMat = material; 92 lastKinEnergy = kineticEnergy; 93 82 94 G4double mass = p->GetPDGMass(); 83 95 G4double charge = p->GetPDGCharge(); … … 85 97 86 98 chargeCorrection = 1.0; 99 effCharge = charge; 87 100 88 101 // The aproximation of ion effective charge from: … … 94 107 if( reducedEnergy > Zi*energyHighLimit || Zi < 1.5 || !material) return charge; 95 108 96 static G4double c[6] = {0.2865, 0.1266, -0.001429,97 0.02402,-0.01135, 0.001475} ;98 99 109 G4double z = material->GetIonisation()->GetZeffective(); 100 reducedEnergy = std::max(reducedEnergy,energyLowLimit); 101 G4double q; 110 // reducedEnergy = std::max(reducedEnergy,energyLowLimit); 102 111 103 112 // Helium ion case 104 113 if( Zi < 2.5 ) { 114 115 static G4double c[6] = {0.2865, 0.1266, -0.001429, 116 0.02402,-0.01135, 0.001475} ; 105 117 106 118 G4double Q = std::max(0.0,std::log(reducedEnergy*massFactor)); … … 120 132 if(tq2 < 0.2) tt *= (1.0 - tq2 + 0.5*tq2*tq2); 121 133 else tt *= std::exp(-tq2); 122 q = (1.0 + tt) * std::sqrt(ex); 134 135 effCharge = charge*(1.0 + tt) * std::sqrt(ex); 123 136 124 137 // Heavy ion case 125 138 } else { 126 139 127 G4double z23 = std::pow(z, 0.666666); 128 G4double zi13 = std::pow(Zi, 0.333333); 140 G4double y; 141 // = nist->GetZ13(z); 142 //G4double z23 = y*y; 143 G4double zi13 = nist->GetZ13(Zi); 129 144 G4double zi23 = zi13*zi13; 130 G4double e = std::max(reducedEnergy,energyBohr/z23); 145 // G4double e = std::max(reducedEnergy,energyBohr/z23); 146 //G4double e = reducedEnergy; 131 147 132 148 // v1 is ion velocity in vF unit 133 149 G4double eF = material->GetIonisation()->GetFermiEnergy(); 134 G4double v1sq = e/eF;150 G4double v1sq = reducedEnergy/eF; 135 151 G4double vFsq = eF/energyBohr; 136 G4double vF = std::sqrt(vFsq); 137 138 G4double y ; 152 G4double vF = std::sqrt(eF/energyBohr); 139 153 140 154 // Faster than Fermi velocity … … 147 161 } 148 162 163 G4double q; 149 164 G4double y3 = std::pow(y, 0.3) ; 150 // G4cout << "y= " << y << " y3= " << y3 << " v1= " << v1 << " vF= " << vF <<G4endl;165 // G4cout<<"y= "<<y<<" y3= "<<y3<<" v1= "<<v1<<" vF= "<<vF<<G4endl; 151 166 q = 1.0 - std::exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ; 152 153 // q = 1.0 - std::exp(-0.95*std::sqrt(reducedEnergy/energyBohr)/zi23); 167 168 //y *= 0.77; 169 //y *= (0.75 + 0.52/Zi); 170 171 //if( y < 0.2 ) q = y*(1.0 - 0.5*y); 172 //else q = 1.0 - std::exp(-y); 154 173 155 174 G4double qmin = minCharge/Zi; 156 157 175 if(q < qmin) q = qmin; 176 177 effCharge = q*charge; 178 179 /* 180 G4double x1 = 1.0*effCharge*(1.0 - 0.132*std::log(y))/(y*std::sqrt(z)); 181 G4double x2 = 0.1*effCharge*effCharge*energyBohr/reducedEnergy; 182 183 chargeCorrection = 1.0 + x1 - x2; 184 185 G4cout << "x1= "<<x1<<" x2= "<< x2<<" corr= "<<chargeCorrection<<G4endl; 186 */ 158 187 159 188 G4double tq = 7.6 - std::log(reducedEnergy/keV); … … 170 199 171 200 G4double lambda = 10.0 * vF / (zi13 * (6.0 + q)); 172 if(q < 0.2) lambda *= (1.0 - 0.666666 *q - q*q/9.0);201 if(q < 0.2) lambda *= (1.0 - 0.66666667*q - q*q/9.0); 173 202 else lambda *= std::pow(1.0-q, 0.666666); 174 203 … … 180 209 181 210 chargeCorrection = sq * (1.0 + xx); 211 182 212 } 183 213 // G4cout << "G4ionEffectiveCharge: charge= " << charge << " q= " << q 184 214 // << " chargeCor= " << chargeCorrection 185 215 // << " e(MeV)= " << kineticEnergy/MeV << G4endl; 186 return q*charge;216 return effCharge; 187 217 } 188 218
Note: See TracChangeset
for help on using the changeset viewer.