269{
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290 if (fVerboseLevel > 3)
291 G4cout <<
"Calling SampleSecondaries() of G4PenelopeComptonModel" <<
G4endl;
292
294
295
296
298 return;
299
302
304
305 const G4int nmax = 64;
308
314 size_t numberOfOscillators = theTable->size();
315 size_t targetOscillator = 0;
317
318 G4double ek = photonEnergy0/electron_mass_c2;
322
324
325
326
327 static G4double taumax = std::nexttoward(1.0,0.0);
328 if (fVerboseLevel > 3)
329 G4cout <<
"G4PenelopeComptonModel: maximum value of tau: 1 - " << 1.-taumax <<
G4endl;
330
332 G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
333
336
337
338
339 if (photonEnergy0 > 5*MeV)
340 {
341 do{
342 do{
345 else
347
348 TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
350 if (tau > taumax) tau = taumax;
352 cosTheta = 1.0 - (1.0-tau)/(ek*tau);
353
354
356 targetOscillator = numberOfOscillators-1;
358 G4bool levelFound =
false;
359 for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
360 {
361 S += (*theTable)[j]->GetOscillatorStrength();
363 {
364 targetOscillator = j;
365 levelFound = true;
366 }
367 }
368
369 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
370 }
while((
epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
371 }
372 else
373 {
374
379 for (size_t i=0;i<numberOfOscillators;i++)
380 {
381 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
382 if (photonEnergy0 > ionEnergy)
383 {
384 G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
385 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
386 oscStren = (*theTable)[i]->GetOscillatorStrength();
387 pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
388 (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
389 if (pzomc > 0)
390 rni = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
391 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
392 else
393 rni = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
394 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
396 }
397 }
398
400 do
401 {
404 else
406 if (tau > taumax) tau = taumax;
407 cdt1 = (1.0-tau)/(ek*tau);
408
410 for (size_t i=0;i<numberOfOscillators;i++)
411 {
412 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
413 if (photonEnergy0 > ionEnergy)
414 {
415 aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
416 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
417 oscStren = (*theTable)[i]->GetOscillatorStrength();
418 pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
419 (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
420 if (pzomc > 0)
421 rn[i] = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
422 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
423 else
424 rn[i] = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
425 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
428 }
429 else
431 }
432
433 TST =
S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
435
436 cosTheta = 1.0 - cdt1;
439
440 do
441 {
442 do
443 {
445 targetOscillator = numberOfOscillators-1;
446 G4bool levelFound =
false;
447 for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
448 {
449 if (pac[i]>TST)
450 {
451 targetOscillator = i;
452 levelFound = true;
453 }
454 }
456 hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
457 oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
459 pzomc = (std::sqrt(0.5)-std::sqrt(0.5-
G4Log(2.0*
A)))/
460 (std::sqrt(2.0)*hartreeFunc);
461 else
462 pzomc = (std::sqrt(0.5-
G4Log(2.0-2.0*
A))-std::sqrt(0.5))/
463 (std::sqrt(2.0)*hartreeFunc);
464 } while (pzomc < -1);
465
466
467 G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
468 G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
469 if (AF > 0)
470 fpzmax = 1.0+AF*0.2;
471 else
472 fpzmax = 1.0-AF*0.2;
473 fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
475
476
480 if (pzomc > 0.0)
481 epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
482 else
483 epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
484 }
485
486
487 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
489 G4double dirx = sinTheta * std::cos(phi);
490 G4double diry = sinTheta * std::sin(phi);
492
493
495 photonDirection1.rotateUz(photonDirection0);
497
499
500 if (photonEnergy1 > 0.)
502 else
503 {
506 }
507
508
510 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
511
513 photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
515
516 if (Q2 > 1.0e-12)
517 cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
518 else
519 cosThetaE = 1.0;
520 G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
521
522
523
524 G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
525 G4int Z = (
G4int) (*theTable)[targetOscillator]->GetParentZ();
526
527
530
531
532 if (Z > 0 && shFlag<30)
533 {
534 shell = fTransitionManager->
Shell(Z,shFlag-1);
536 }
537
538 G4double ionEnergyInPenelopeDatabase = ionEnergy;
539
540 ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
541
542
543
544 G4double eKineticEnergy = diffEnergy - ionEnergy;
545 G4double localEnergyDeposit = ionEnergy;
548
549 if (eKineticEnergy < 0)
550 {
551
552
553
554
555 localEnergyDeposit = diffEnergy;
556 eKineticEnergy = 0.0;
557 }
558
559
560
561
562 if (fAtomDeexcitation && shell)
563 {
566 {
567 size_t nBefore = fvect->size();
569 size_t nAfter = fvect->size();
570
571 if (nAfter > nBefore)
572 {
573 for (size_t j=nBefore;j<nAfter;j++)
574 {
575 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
576 if (itsEnergy < localEnergyDeposit)
577 {
578 localEnergyDeposit -= itsEnergy;
580 energyInFluorescence += itsEnergy;
581 else if (((*fvect)[j])->GetParticleDefinition() ==
583 energyInAuger += itsEnergy;
584 }
585 else
586 {
587 delete (*fvect)[j];
588 (*fvect)[j] = nullptr;
589 }
590 }
591 }
592
593 }
594 }
595
596
598
599 G4double xEl = sinThetaE * std::cos(phi+pi);
600 G4double yEl = sinThetaE * std::sin(phi+pi);
603 eDirection.rotateUz(photonDirection0);
605 eDirection,eKineticEnergy) ;
606 fvect->push_back(electron);
607
608 if (localEnergyDeposit < 0)
609 {
610 G4Exception(
"G4PenelopeComptonModel::SampleSecondaries()",
611 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
612 localEnergyDeposit=0.;
613 }
615
617 if (electron)
618 electronEnergy = eKineticEnergy;
619 if (fVerboseLevel > 1)
620 {
621 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
622 G4cout <<
"Energy balance from G4PenelopeCompton" <<
G4endl;
623 G4cout <<
"Incoming photon energy: " << photonEnergy0/keV <<
" keV" <<
G4endl;
624 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
625 G4cout <<
"Scattered photon: " << photonEnergy1/keV <<
" keV" <<
G4endl;
626 G4cout <<
"Scattered electron " << electronEnergy/keV <<
" keV" <<
G4endl;
627 if (energyInFluorescence)
628 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
629 if (energyInAuger)
630 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
631 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
632 G4cout <<
"Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
633 localEnergyDeposit+energyInAuger)/keV <<
635 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
636 }
637 if (fVerboseLevel > 0)
638 {
639 G4double energyDiff = std::fabs(photonEnergy1+
640 electronEnergy+energyInFluorescence+
641 localEnergyDeposit+energyInAuger-photonEnergy0);
642 if (energyDiff > 0.05*keV)
643 G4cout <<
"Warning from G4PenelopeCompton: problem with energy conservation: " <<
644 (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
645 " keV (final) vs. " <<
646 photonEnergy0/keV <<
" keV (initial)" <<
G4endl;
647 }
648}
G4double epsilon(G4double density, G4double temperature)
G4double S(G4double temp)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4double BindingEnergy() const
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Electron * Electron()
static G4Gamma * Definition()
const G4Material * GetMaterial() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4double GetTotalZ(const G4Material *)
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)