273{
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295 if (verboseLevel > 3)
296 G4cout <<
"Calling SampleSecondaries() of G4PenelopeComptonModel" <<
G4endl;
297
299
300
301
303 return;
304
307
309
310 const G4int nmax = 64;
313
319 size_t numberOfOscillators = theTable->size();
320 size_t targetOscillator = 0;
322
323 G4double ek = photonEnergy0/electron_mass_c2;
327
330 G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
331
334
335
336
337 if (photonEnergy0 > 5*MeV)
338 {
339 do{
340 do{
343 else
345
346 TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
349 cosTheta = 1.0 - (1.0-tau)/(ek*tau);
350
351
353 targetOscillator = numberOfOscillators-1;
355 G4bool levelFound =
false;
356 for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
357 {
358 S += (*theTable)[j]->GetOscillatorStrength();
360 {
361 targetOscillator = j;
362 levelFound = true;
363 }
364 }
365
366 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
367 }
while((
epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
368 }
369 else
370 {
371
376 for (size_t i=0;i<numberOfOscillators;i++)
377 {
378 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
379 if (photonEnergy0 > ionEnergy)
380 {
381 G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
382 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
383 oscStren = (*theTable)[i]->GetOscillatorStrength();
384 pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
385 (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
386 if (pzomc > 0)
387 rni = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
388 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
389 else
390 rni = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
391 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
393 }
394 }
395
397 do
398 {
401 else
403 cdt1 = (1.0-tau)/(ek*tau);
404
406 for (size_t i=0;i<numberOfOscillators;i++)
407 {
408 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
409 if (photonEnergy0 > ionEnergy)
410 {
411 aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
412 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
413 oscStren = (*theTable)[i]->GetOscillatorStrength();
414 pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
415 (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
416 if (pzomc > 0)
417 rn[i] = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
418 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
419 else
420 rn[i] = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
421 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
424 }
425 else
427 }
428
429 TST =
S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
431
432 cosTheta = 1.0 - cdt1;
435
436 do
437 {
438 do
439 {
441 targetOscillator = numberOfOscillators-1;
442 G4bool levelFound =
false;
443 for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
444 {
445 if (pac[i]>TST)
446 {
447 targetOscillator = i;
448 levelFound = true;
449 }
450 }
452 hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
453 oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
454 if (A < 0.5)
455 pzomc = (std::sqrt(0.5)-std::sqrt(0.5-
G4Log(2.0*A)))/
456 (std::sqrt(2.0)*hartreeFunc);
457 else
458 pzomc = (std::sqrt(0.5-
G4Log(2.0-2.0*A))-std::sqrt(0.5))/
459 (std::sqrt(2.0)*hartreeFunc);
460 } while (pzomc < -1);
461
462
463 G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
464 G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
465 if (AF > 0)
466 fpzmax = 1.0+AF*0.2;
467 else
468 fpzmax = 1.0-AF*0.2;
469 fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
471
472
476 if (pzomc > 0.0)
477 epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
478 else
479 epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
480 }
481
482
483 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
485 G4double dirx = sinTheta * std::cos(phi);
486 G4double diry = sinTheta * std::sin(phi);
488
489
491 photonDirection1.rotateUz(photonDirection0);
493
495
496 if (photonEnergy1 > 0.)
498 else
499 {
502 }
503
504
506 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
507
509 photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
511
512 if (Q2 > 1.0e-12)
513 cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
514 else
515 cosThetaE = 1.0;
516 G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
517
518
519
520 G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
521 G4int Z = (
G4int) (*theTable)[targetOscillator]->GetParentZ();
522
523
526
527
528 if (Z > 0 && shFlag<30)
529 {
530 shell = fTransitionManager->
Shell(Z,shFlag-1);
532 }
533
534 G4double ionEnergyInPenelopeDatabase = ionEnergy;
535
536 ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
537
538
539
540 G4double eKineticEnergy = diffEnergy - ionEnergy;
541 G4double localEnergyDeposit = ionEnergy;
544
545 if (eKineticEnergy < 0)
546 {
547
548
549
550
551 localEnergyDeposit = diffEnergy;
552 eKineticEnergy = 0.0;
553 }
554
555
556
557
558 if (fAtomDeexcitation && shell)
559 {
562 {
563 size_t nBefore = fvect->size();
565 size_t nAfter = fvect->size();
566
567 if (nAfter > nBefore)
568 {
569 for (size_t j=nBefore;j<nAfter;j++)
570 {
571 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
572 if (itsEnergy < localEnergyDeposit)
573 {
574 localEnergyDeposit -= itsEnergy;
576 energyInFluorescence += itsEnergy;
577 else if (((*fvect)[j])->GetParticleDefinition() ==
579 energyInAuger += itsEnergy;
580 }
581 else
582 {
583 delete (*fvect)[j];
584 (*fvect)[j] = nullptr;
585 }
586 }
587 }
588
589 }
590 }
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
662
663 G4double xEl = sinThetaE * std::cos(phi+pi);
664 G4double yEl = sinThetaE * std::sin(phi+pi);
667 eDirection.rotateUz(photonDirection0);
669 eDirection,eKineticEnergy) ;
670 fvect->push_back(electron);
671
672
673 if (localEnergyDeposit < 0)
674 {
675 G4Exception(
"G4PenelopeComptonModel::SampleSecondaries()",
676 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
677 localEnergyDeposit=0.;
678 }
680
682 if (electron)
683 electronEnergy = eKineticEnergy;
684 if (verboseLevel > 1)
685 {
686 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
687 G4cout <<
"Energy balance from G4PenelopeCompton" <<
G4endl;
688 G4cout <<
"Incoming photon energy: " << photonEnergy0/keV <<
" keV" <<
G4endl;
689 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
690 G4cout <<
"Scattered photon: " << photonEnergy1/keV <<
" keV" <<
G4endl;
691 G4cout <<
"Scattered electron " << electronEnergy/keV <<
" keV" <<
G4endl;
692 if (energyInFluorescence)
693 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
694 if (energyInAuger)
695 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
696 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
697 G4cout <<
"Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
698 localEnergyDeposit+energyInAuger)/keV <<
700 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
701 }
702 if (verboseLevel > 0)
703 {
704 G4double energyDiff = std::fabs(photonEnergy1+
705 electronEnergy+energyInFluorescence+
706 localEnergyDeposit+energyInAuger-photonEnergy0);
707 if (energyDiff > 0.05*keV)
708 G4cout <<
"Warning from G4PenelopeCompton: problem with energy conservation: " <<
709 (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
710 " keV (final) vs. " <<
711 photonEnergy0/keV <<
" keV (initial)" <<
G4endl;
712 }
713}
double epsilon(double density, double temperature)
double A(double temperature)
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(G4double Px, G4double Py, G4double Pz)
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)