306{
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
324
325 if (verboseLevel > 3) {
326 G4cout <<
"G4LowEPComptonModel::SampleSecondaries() E(MeV)= "
329 }
330
331
333 return ;
334
335 G4double e0m = photonEnergy0 / electron_mass_c2 ;
337
338
339
343
344 G4double LowEPCepsilon0 = 1. / (1. + 2. * e0m);
345 G4double LowEPCepsilon0Sq = LowEPCepsilon0 * LowEPCepsilon0;
346 G4double alpha1 = -std::log(LowEPCepsilon0);
347 G4double alpha2 = 0.5 * (1. - LowEPCepsilon0Sq);
348
349 G4double wlPhoton = h_Planck*c_light/photonEnergy0;
350
351
357
358 if (verboseLevel > 3) {
359 G4cout <<
"Started loop to sample gamma energy" <<
G4endl;
360 }
361
362 do
363 {
365 {
367 LowEPCepsilonSq = LowEPCepsilon * LowEPCepsilon;
368 }
369 else
370 {
371 LowEPCepsilonSq = LowEPCepsilon0Sq + (1. - LowEPCepsilon0Sq) *
G4UniformRand();
372 LowEPCepsilon = std::sqrt(LowEPCepsilonSq);
373 }
374
375 oneCosT = (1. - LowEPCepsilon) / ( LowEPCepsilon * e0m);
376 sinT2 = oneCosT * (2. - oneCosT);
377 G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/cm);
378 G4double scatteringFunction = ComputeScatteringFunction(x, Z);
379 gReject = (1. - LowEPCepsilon * sinT2 / (1. + LowEPCepsilonSq)) * scatteringFunction;
380
382
384 G4double sinTheta = std::sqrt(sinT2);
386 G4double dirx = sinTheta * std::cos(phi);
387 G4double diry = sinTheta * std::sin(phi);
389
390
391
392
393
394
395
396
397
398 const G4double vel_c = c_light / (m/s);
399 const G4double momentum_au_to_nat = halfpi* hbar_Planck / Bohr_radius / (kg*m/s);
400 const G4double e_mass_kg = electron_mass_c2 / c_squared / kg ;
401
402 const G4int maxDopplerIterations = 1000;
404 G4double pEIncident = photonEnergy0 ;
409
418
419 if (verboseLevel > 3) {
420 G4cout <<
"Started loop to sample photon energy and electron direction" <<
G4endl;
421 }
422
423 do{
424
425
426
427
428
429
430 do
431 {
432 iteration++;
433
434
435
436
437
438
439
440
443
444
445
447
448
449 G4double ePSI = ePAU * momentum_au_to_nat;
450
451
452 u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)) )/vel_c;
453
454
455
458
459
460
461 G4double eEIncident = electron_mass_c2 / sqrt( 1 - (u_temp*u_temp));
462 G4double systemE = eEIncident + pEIncident;
463
464
465 G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
466 G4double numerator = gamma_temp*electron_mass_c2*(1 - u_temp * std::cos(e_alpha));
467 G4double subdenom1 = u_temp*cosTheta*std::cos(e_alpha);
468 G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
469 G4double denominator = (1.0 - cosTheta) + (gamma_temp*electron_mass_c2*(1 - subdenom1 - subdenom2) / pEIncident);
470 pERecoil = (numerator/denominator);
471 eERecoil = systemE - pERecoil;
472 CE_emission_flag = pEIncident - pERecoil;
473 } while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
474
475
476
477
478
479
480
481
482
483
484
485 G4double a_temp = eERecoil / electron_mass_c2;
486 G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
487
488
489
490 G4double sinAlpha = std::sin(e_alpha);
491 G4double cosAlpha = std::cos(e_alpha);
492 G4double sinBeta = std::sin(e_beta);
493 G4double cosBeta = std::cos(e_beta);
494
495 G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
496 G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
497
498 G4double var_A = pERecoil*u_p_temp*sinTheta;
499 G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
500 G4double var_C = (pERecoil-pEIncident) - ( (pERecoil*pEIncident) / (gamma_p*electron_mass_c2))*(1 - cosTheta);
501
502 G4double var_D1 = gamma*electron_mass_c2*pERecoil;
503 G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
504 G4double var_D3 = ((electron_mass_c2*electron_mass_c2)*(gamma*gamma_p - 1)) - (gamma_p*electron_mass_c2*pERecoil);
505 G4double var_D = var_D1*var_D2 + var_D3;
506
507 G4double var_E1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosAlpha);
508 G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
510
511 G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
512 G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
514
515 G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
516
517
518
519
520 G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
521 G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
523
524 G4double var_Y = 2.0*(((var_A*var_D-var_F*var_C)*(var_F*var_B-var_E*var_A)) - ((var_G*var_G)*var_B*var_C));
525
526 G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
527 G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
532
533
534
535
536
538 G4double g4d_limit = std::pow(10.,-g4d_order);
539
540
541
542 if ((diff < 0.0) && (abs(diff / diff1) < g4d_limit) && (abs(diff / diff2) < g4d_limit) )
543 {
544 diff = 0.0;
545 }
546
547
548
549 G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
550 G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
551
552
553
554
555
556
557 if(X_p >1){X_p=1;} if(X_p<-1){X_p=-1;}
558 if(X_m >1){X_m=1;} if(X_m<-1){X_m=-1;}
559
560
561
563
564
565
567
568 if (sol_select < 0.5)
569 {
570 ThetaE = std::acos(X_p);
571 }
572 if (sol_select > 0.5)
573 {
574 ThetaE = std::acos(X_m);
575 }
576
577
578 cosThetaE = std::cos(ThetaE);
579 sinThetaE = std::sin(ThetaE);
580 G4double Theta = std::acos(cosTheta);
581
582
583 G4double iSinThetaE = std::sqrt(1+std::tan((pi/2.0)-ThetaE)*std::tan((pi/2.0)-ThetaE));
584 G4double iSinTheta = std::sqrt(1+std::tan((pi/2.0)-Theta)*std::tan((pi/2.0)-Theta));
585 G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
586
587 cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
588
589
590
591
592
593 } while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
594
595
596 if (iteration >= maxDopplerIterations)
597 {
598 pERecoil = photonEnergy0 ;
599 bindingE = 0.;
600 dirx=0.0;
601 diry=0.0;
602 dirz=1.0;
603 }
604
605
606
608 photonDirection1.rotateUz(photonDirection0);
610
611 if (pERecoil > 0.)
612 {
614
615
617 G4double eDirX = sinThetaE * std::cos(phi+PhiE);
618 G4double eDirY = sinThetaE * std::sin(phi+PhiE);
620
621 G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
622
624 eDirection.rotateUz(photonDirection0);
626 eDirection,eKineticEnergy) ;
627 fvect->push_back(dp);
628
629 }
630 else
631 {
634 }
635
636
637
638
639 if (verboseLevel > 3) {
640 G4cout <<
"Started atomic de-excitation " << fAtomDeexcitation <<
G4endl;
641 }
642
643 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
646 size_t nbefore = fvect->size();
650 size_t nafter = fvect->size();
651 if(nafter > nbefore) {
652 for (size_t i=nbefore; i<nafter; ++i) {
653
654 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
655 {
656
657 bindingE -= ((*fvect)[i])->GetKineticEnergy();
658 }
659 else
660 {
661
662
663 delete (*fvect)[i];
664 (*fvect)[i]=0;
665 }
666 }
667 }
668 }
669 }
670
671
672 if(bindingE < 0.0)
673 G4Exception(
"G4LowEPComptonModel::SampleSecondaries()",
675
677
678}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
const G4String & GetName() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double BindingEnergy(G4int Z, G4int shellIndex) const
G4int SelectRandomShell(G4int Z) const
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)