- Timestamp:
- Apr 6, 2009, 12:21:12 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/muons/src/G4MuBremsstrahlungModel.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4MuBremsstrahlungModel.cc,v 1. 24 2007/11/08 11:48:28vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4MuBremsstrahlungModel.cc,v 1.33 2009/02/20 14:48:16 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 46 46 // 13-02-03 Add name (V.Ivanchenko) 47 47 // 10-02-04 Add lowestKinEnergy (V.Ivanchenko) 48 // 08-04-05 Major optimisation of internal interfaces (V.Ivan tchenko)49 // 03-08-05 Angular correlations according to PRM (V.Ivan tchenko)48 // 08-04-05 Major optimisation of internal interfaces (V.Ivanchenko) 49 // 03-08-05 Angular correlations according to PRM (V.Ivanchenko) 50 50 // 13-02-06 add ComputeCrossSectionPerAtom (mma) 51 51 // 21-03-06 Fix problem of initialisation in case when cuts are not defined (VI) 52 52 // 07-11-07 Improve sampling of final state (A.Bogdanov) 53 // 28-02-08 Use precomputed Z^1/3 and Log(A) (V.Ivanchenko) 53 54 // 54 55 … … 74 75 75 76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 76 77 // static members78 //79 G4double G4MuBremsstrahlungModel::zdat[]={1., 4., 13., 29., 92.};80 G4double G4MuBremsstrahlungModel::adat[]={1.01, 9.01, 26.98, 63.55, 238.03};81 G4double G4MuBremsstrahlungModel::tdat[]={1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8,82 1.e9, 1.e10};83 84 77 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 85 78 … … 90 83 : G4VEmModel(nam), 91 84 particle(0), 85 sqrte(sqrt(exp(1.))), 86 bh(202.4), 87 bh1(446.), 88 btf(183.), 89 btf1(1429.), 90 fParticleChange(0), 92 91 lowestKinEnergy(1.0*GeV), 93 minThreshold(1.0*keV), 94 nzdat(5), 95 ntdat(8), 96 NBIN(1000), 97 cutFixed(0.98*keV), 98 ignoreCut(false), 99 samplingTablesAreFilled(false) 92 minThreshold(1.0*keV) 100 93 { 101 94 theGamma = G4Gamma::Gamma(); 95 nist = G4NistManager::Instance(); 102 96 if(p) SetParticle(p); 103 97 } … … 125 119 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 126 120 127 void G4MuBremsstrahlungModel::SetParticle(const G4ParticleDefinition* p)128 {129 if(!particle) {130 particle = p;131 mass = particle->GetPDGMass();132 }133 }134 135 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......136 137 121 void G4MuBremsstrahlungModel::Initialise(const G4ParticleDefinition* p, 138 122 const G4DataVector& cuts) … … 142 126 highKinEnergy = HighEnergyLimit(); 143 127 128 // partial cross section is computed for fixed energy 144 129 G4double fixedEnergy = 0.5*highKinEnergy; 145 130 … … 148 133 if(theCoupleTable) { 149 134 G4int numOfCouples = theCoupleTable->GetTableSize(); 150 135 136 // clear old data 151 137 G4int nn = partialSumSigma.size(); 152 138 G4int nc = cuts.size(); 153 139 if(nn > 0) { 154 140 for (G4int ii=0; ii<nn; ii++){ 155 G4DataVector* a =partialSumSigma[ii];141 G4DataVector* a = partialSumSigma[ii]; 156 142 if ( a ) delete a; 157 143 } 158 144 partialSumSigma.clear(); 159 145 } 146 // fill new data 160 147 if (numOfCouples>0) { 161 148 for (G4int i=0; i<numOfCouples; i++) { 162 149 G4double cute = DBL_MAX; 150 151 // protection for usage with extrapolator 163 152 if(i < nc) cute = cuts[i]; 164 if(cute < cutFixed || ignoreCut) cute = cutFixed; 153 165 154 const G4MaterialCutsCouple* couple = 166 155 theCoupleTable->GetMaterialCutsCouple(i); … … 171 160 } 172 161 } 173 if(!samplingTablesAreFilled) MakeSamplingTables(); 174 if(pParticleChange) 175 fParticleChange = 176 reinterpret_cast<G4ParticleChangeForLoss*>(pParticleChange); 177 else 178 fParticleChange = new G4ParticleChangeForLoss(); 162 163 // define pointer to G4ParticleChange 164 if(!fParticleChange) { 165 if(pParticleChange) 166 fParticleChange = 167 reinterpret_cast<G4ParticleChangeForLoss*>(pParticleChange); 168 else 169 fParticleChange = new G4ParticleChangeForLoss(); 170 } 179 171 } 180 172 … … 188 180 { 189 181 G4double dedx = 0.0; 190 if (kineticEnergy <= lowestKinEnergy || ignoreCut) return dedx;182 if (kineticEnergy <= lowestKinEnergy) return dedx; 191 183 192 184 G4double tmax = kineticEnergy; 193 G4double cut = min(cutEnergy,tmax);194 if(cut < cutFixed) cut = cutFixed;185 G4double cut = std::min(cutEnergy,tmax); 186 if(cut < minThreshold) cut = minThreshold; 195 187 196 188 const G4ElementVector* theElementVector = material->GetElementVector(); 197 189 const G4double* theAtomicNumDensityVector = 198 190 material->GetAtomicNumDensityVector(); 199 191 200 192 // loop for elements in the material 201 193 for (size_t i=0; i<material->GetNumberOfElements(); i++) { 202 194 203 G4double Z = (*theElementVector)[i]->GetZ(); 204 G4double A = (*theElementVector)[i]->GetA()/(g/mole) ; 205 206 G4double loss = ComputMuBremLoss(Z, A, kineticEnergy, cut); 195 G4double loss = 196 ComputMuBremLoss((*theElementVector)[i]->GetZ(), kineticEnergy, cut); 207 197 208 198 dedx += loss*theAtomicNumDensityVector[i]; 209 199 } 200 // G4cout << "BR e= " << kineticEnergy << " dedx= " << dedx << G4endl; 210 201 if(dedx < 0.) dedx = 0.; 211 202 return dedx; … … 214 205 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 215 206 216 G4double G4MuBremsstrahlungModel::ComputMuBremLoss(G4double Z, G4double A,207 G4double G4MuBremsstrahlungModel::ComputMuBremLoss(G4double Z, 217 208 G4double tkin, G4double cut) 218 209 { … … 239 230 { 240 231 G4double ep = (aa + xgi[i]*hhh)*totalEnergy; 241 loss += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, A,ep);232 loss += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, ep); 242 233 } 243 234 aa += hhh; … … 254 245 G4double tkin, 255 246 G4double Z, 256 G4double A,257 247 G4double cut) 258 248 { … … 272 262 G4double bbb = log(vmax); 273 263 G4int kkk = (G4int)((bbb-aaa)/ak1)+k2 ; 274 G4double hhh = (bbb-aaa)/ float(kkk);264 G4double hhh = (bbb-aaa)/G4double(kkk); 275 265 276 266 G4double aa = aaa; … … 281 271 { 282 272 G4double ep = exp(aa + xgi[i]*hhh)*totalEnergy; 283 cross += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, A,ep);273 cross += ep*wgi[i]*ComputeDMicroscopicCrossSection(tkin, Z, ep); 284 274 } 285 275 aa += hhh; … … 287 277 288 278 cross *=hhh; 279 280 //G4cout << "BR e= " << tkin<< " cross= " << cross/barn << G4endl; 289 281 290 282 return cross; … … 296 288 G4double tkin, 297 289 G4double Z, 298 G4double A,299 290 G4double gammaEnergy) 300 291 // differential cross section 301 292 { 302 static const G4double sqrte=sqrt(exp(1.)) ;303 static const G4double bh=202.4,bh1=446.,btf=183.,btf1=1429. ;304 static const G4double rmass=mass/electron_mass_c2 ;305 static const G4double cc=classic_electr_radius/rmass ;306 static const G4double coeff= 16.*fine_structure_const*cc*cc/3. ;307 308 293 G4double dxsection = 0.; 309 294 … … 315 300 G4double rab0=delta*sqrte ; 316 301 317 G4double z13 = exp(-log(Z)/3.) ; 318 G4double dn = 1.54*exp(0.27*log(A)) ; 302 G4int iz = G4int(Z); 303 if(iz < 1) iz = 1; 304 305 G4double z13 = 1.0/nist->GetZ13(iz); 306 G4double dn = 1.54*nist->GetA27(iz); 319 307 320 308 G4double b,b1,dnstar ; 321 309 322 if( Z<1.5)310 if(1 == iz) 323 311 { 324 b =bh;325 b1 =bh1;326 dnstar =dn;312 b = bh; 313 b1 = bh1; 314 dnstar = dn; 327 315 } 328 316 else 329 317 { 330 b =btf;331 b1 =btf1;332 dnstar = exp((1.-1./Z)*log(dn));318 b = btf; 319 b1 = btf1; 320 dnstar = dn/std::pow(dn, 1./Z); 333 321 } 334 322 … … 359 347 const G4ParticleDefinition*, 360 348 G4double kineticEnergy, 361 G4double Z, G4double A,349 G4double Z, G4double, 362 350 G4double cutEnergy, 363 G4double) 364 { 365 G4double cut = min(cutEnergy, kineticEnergy); 366 if(cut < cutFixed || ignoreCut) cut = cutFixed; 367 G4double cross = 368 ComputeMicroscopicCrossSection (kineticEnergy, Z, A/(g/mole), cut); 369 return cross; 370 } 371 372 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 373 374 G4double G4MuBremsstrahlungModel::CrossSectionPerVolume( 375 const G4Material* material, 376 const G4ParticleDefinition*, 377 G4double kineticEnergy, 378 G4double cutEnergy, 379 G4double maxEnergy) 351 G4double maxEnergy) 380 352 { 381 353 G4double cross = 0.0; 382 if (cutEnergy >= maxEnergy || kineticEnergy <= lowestKinEnergy) return cross; 383 384 G4double tmax = min(maxEnergy, kineticEnergy); 385 G4double cut = min(cutEnergy, tmax); 386 if(cut < cutFixed || ignoreCut) cut = cutFixed; 387 388 const G4ElementVector* theElementVector = material->GetElementVector(); 389 const G4double* theAtomNumDensityVector = 390 material->GetAtomicNumDensityVector(); 391 392 for (size_t i=0; i<material->GetNumberOfElements(); i++) { 393 394 G4double Z = (*theElementVector)[i]->GetZ(); 395 G4double A = (*theElementVector)[i]->GetA()/(g/mole); 396 397 G4double cr = ComputeMicroscopicCrossSection(kineticEnergy, Z, A, cut); 398 399 if(tmax < kineticEnergy) { 400 cr -= ComputeMicroscopicCrossSection(kineticEnergy, Z, A, tmax); 401 } 402 cross += theAtomNumDensityVector[i] * cr; 403 } 404 354 if (kineticEnergy <= lowestKinEnergy) return cross; 355 G4double tmax = std::min(maxEnergy, kineticEnergy); 356 G4double cut = std::min(cutEnergy, kineticEnergy); 357 if(cut < minThreshold) cut = minThreshold; 358 if (cut >= tmax) return cross; 359 360 cross = ComputeMicroscopicCrossSection (kineticEnergy, Z, cut); 361 if(tmax < kineticEnergy) { 362 cross -= ComputeMicroscopicCrossSection(kineticEnergy, Z, tmax); 363 } 405 364 return cross; 406 365 } … … 410 369 G4DataVector* G4MuBremsstrahlungModel::ComputePartialSumSigma( 411 370 const G4Material* material, 412 G4double kineticEnergy, 413 G4double cut) 414 415 // Build the table of cross section per element. The table is built for MATERIAL 416 // This table is used by DoIt to select randomly an element in the material. 371 G4double kineticEnergy, 372 G4double cut) 373 374 // Build the table of cross section per element. 375 // The table is built for material 376 // This table is used to select randomly an element in the material. 417 377 { 418 378 G4int nElements = material->GetNumberOfElements(); 419 379 const G4ElementVector* theElementVector = material->GetElementVector(); 420 380 const G4double* theAtomNumDensityVector = 421 381 material->GetAtomicNumDensityVector(); 422 382 423 383 G4DataVector* dv = new G4DataVector(); … … 426 386 427 387 for (G4int i=0; i<nElements; i++ ) { 428 429 G4double Z = (*theElementVector)[i]->GetZ();430 G4double A = (*theElementVector)[i]->GetA()/(g/mole) ;431 388 cross += theAtomNumDensityVector[i] 432 * ComputeMicroscopicCrossSection(kineticEnergy, Z, A, cut); 389 * ComputeMicroscopicCrossSection(kineticEnergy, 390 (*theElementVector)[i]->GetZ(), cut); 433 391 dv->push_back(cross); 434 392 } … … 438 396 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 439 397 440 void G4MuBremsstrahlungModel::MakeSamplingTables() 441 { 442 443 G4double AtomicNumber,AtomicWeight,KineticEnergy, 444 TotalEnergy,Maxep; 445 446 for (G4int iz=0; iz<nzdat; iz++) 447 { 448 AtomicNumber = zdat[iz]; 449 AtomicWeight = adat[iz]*g/mole ; 450 451 for (G4int it=0; it<ntdat; it++) 452 { 453 KineticEnergy = tdat[it]; 454 TotalEnergy = KineticEnergy + mass; 455 Maxep = KineticEnergy ; 456 457 G4double CrossSection = 0.0 ; 458 459 // calculate the differential cross section 460 // numerical integration in 461 // log ............... 462 G4double c = log(Maxep/cutFixed) ; 463 G4double ymin = -5. ; 464 G4double ymax = 0. ; 465 G4double dy = (ymax-ymin)/NBIN ; 466 467 G4double y = ymin - 0.5*dy ; 468 G4double yy = ymin - dy ; 469 G4double x = exp(y); 470 G4double fac = exp(dy); 471 G4double dx = exp(yy)*(fac - 1.0); 472 473 for (G4int i=0 ; i<NBIN; i++) 474 { 475 y += dy ; 476 x *= fac; 477 dx*= fac; 478 G4double ep = cutFixed*exp(c*x) ; 479 480 CrossSection += ep*dx*ComputeDMicroscopicCrossSection( 481 KineticEnergy,AtomicNumber, 482 AtomicWeight,ep) ; 483 ya[i]=y ; 484 proba[iz][it][i] = CrossSection ; 485 486 } 487 488 proba[iz][it][NBIN] = CrossSection ; 489 ya[NBIN] = 0. ; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 490 491 if(CrossSection > 0.) 492 { 493 for(G4int ib=0; ib<=NBIN; ib++) 494 { 495 proba[iz][it][ib] /= CrossSection ; 496 } 497 } 498 } 499 } 500 samplingTablesAreFilled = true; 501 } 502 503 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 504 505 void G4MuBremsstrahlungModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp, 506 const G4MaterialCutsCouple* couple, 507 const G4DynamicParticle* dp, 508 G4double minEnergy, 509 G4double maxEnergy) 398 void G4MuBremsstrahlungModel::SampleSecondaries( 399 std::vector<G4DynamicParticle*>* vdp, 400 const G4MaterialCutsCouple* couple, 401 const G4DynamicParticle* dp, 402 G4double minEnergy, 403 G4double maxEnergy) 510 404 { 511 405 G4double kineticEnergy = dp->GetKineticEnergy(); 512 406 // check against insufficient energy 513 G4double tmax = min(kineticEnergy, maxEnergy);514 G4double tmin = min(kineticEnergy, minEnergy);515 if(tmin < cutFixed || ignoreCut) tmin = cutFixed;407 G4double tmax = std::min(kineticEnergy, maxEnergy); 408 G4double tmin = std::min(kineticEnergy, minEnergy); 409 if(tmin < minThreshold) tmin = minThreshold; 516 410 if(tmin >= tmax) return; 517 411 518 // ===== the begining of a new code ======519 412 // ===== sampling of energy transfer ====== 520 413 … … 523 416 // select randomly one element constituing the material 524 417 const G4Element* anElement = SelectRandomAtom(couple); 418 G4double Z = anElement->GetZ(); 525 419 526 420 G4double totalEnergy = kineticEnergy + mass; 527 421 G4double totalMomentum = sqrt(kineticEnergy*(kineticEnergy + 2.0*mass)); 528 422 529 G4double AtomicNumber = anElement->GetZ(); 530 G4double AtomicWeight = anElement->GetA()/(g/mole); 531 532 G4double func1 = tmin*ComputeDMicroscopicCrossSection( 533 kineticEnergy,AtomicNumber, 534 AtomicWeight,tmin); 423 G4double func1 = tmin* 424 ComputeDMicroscopicCrossSection(kineticEnergy,Z,tmin); 535 425 536 426 G4double lnepksi, epksi; 537 427 G4double func2; 538 G4double ksi2;539 428 540 429 do { 541 430 lnepksi = log(tmin) + G4UniformRand()*log(kineticEnergy/tmin); 542 431 epksi = exp(lnepksi); 543 func2 = epksi*ComputeDMicroscopicCrossSection( 544 kineticEnergy,AtomicNumber, 545 AtomicWeight,epksi); 546 ksi2 = G4UniformRand(); 547 548 } while(func2/func1 < ksi2); 549 550 // ===== the end of a new code ===== 551 552 // create G4DynamicParticle object for the Gamma 432 func2 = epksi*ComputeDMicroscopicCrossSection(kineticEnergy,Z,epksi); 433 434 } while(func2 < func1*G4UniformRand()); 435 553 436 G4double gEnergy = epksi; 554 437 555 // sample angle 438 // ===== sample angle ===== 439 556 440 G4double gam = totalEnergy/mass; 557 G4double rmax = gam* min(1.0, totalEnergy/gEnergy - 1.0);558 rmax *=rmax;559 G4double x = G4UniformRand()*rmax /(1.0 + rmax);441 G4double rmax = gam*std::min(1.0, totalEnergy/gEnergy - 1.0); 442 G4double rmax2= rmax*rmax; 443 G4double x = G4UniformRand()*rmax2/(1.0 + rmax2); 560 444 561 445 G4double theta = sqrt(x/(1.0 - x))/gam; … … 577 461 578 462 // save secondary 579 G4DynamicParticle* aGamma = new G4DynamicParticle(theGamma,gDirection,gEnergy); 463 G4DynamicParticle* aGamma = 464 new G4DynamicParticle(theGamma,gDirection,gEnergy); 580 465 vdp->push_back(aGamma); 581 466 }
Note: See TracChangeset
for help on using the changeset viewer.