299{
300
301
302
303
304
305
306 if (verboseLevel > 3)
307 G4cout <<
"Calling SampleSecondaries() of G4LivermorePolarizedComptonModel" <<
G4endl;
308
310
311
312
314 return ;
315
316
318
319
320
321
322
324
325
326
327
328 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
329 {
330 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
331 }
332 else
333 {
335 {
336 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
337 }
338 }
339
340
341
342 G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
343
344
345
349
350
351
353
354 G4double epsilon0Local = 1./(1. + 2*E0_m);
355 G4double epsilon0Sq = epsilon0Local*epsilon0Local;
357 G4double alpha2 = 0.5*(1.- epsilon0Sq);
358
359 G4double wlGamma = h_Planck*c_light/gammaEnergy0;
362
363 do {
365 {
368 }
369 else
370 {
372 epsilon = std::sqrt(epsilonSq);
373 }
374
376 sinThetaSqr = onecost*(2.-onecost);
377
378
379 if (sinThetaSqr > 1.)
380 {
382 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
383 << "sin(theta)**2 = "
384 << sinThetaSqr
385 << "; set to 1"
387 sinThetaSqr = 1.;
388 }
389 if (sinThetaSqr < 0.)
390 {
392 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
393 << "sin(theta)**2 = "
394 << sinThetaSqr
395 << "; set to 0"
397 sinThetaSqr = 0.;
398 }
399
400
401 G4double x = std::sqrt(onecost/2.) / (wlGamma/cm);;
403 greject = (1. -
epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
404
406
407
408
409
410
411
413
414
415
416
417
419
420
421
422 if (cosTheta > 1.)
423 {
425 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
426 << "cosTheta = "
427 << cosTheta
428 << "; set to 1"
430 cosTheta = 1.;
431 }
432 if (cosTheta < -1.)
433 {
435 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
436 << "cosTheta = "
437 << cosTheta
438 << "; set to -1"
440 cosTheta = -1.;
441 }
442
443
444
445 G4double sinTheta = std::sqrt (sinThetaSqr);
446
447
448 if (sinTheta > 1.)
449 {
451 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
452 << "sinTheta = "
453 << sinTheta
454 << "; set to 1"
456 sinTheta = 1.;
457 }
458 if (sinTheta < -1.)
459 {
461 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
462 << "sinTheta = "
463 << sinTheta
464 << "; set to -1"
466 sinTheta = -1.;
467 }
468
469
470
471 G4double dirx = sinTheta*std::cos(phi);
472 G4double diry = sinTheta*std::sin(phi);
474
475
476
477
478
479
480
481
482
483
484
485 static G4int maxDopplerIterations = 1000;
491
493
494 if (verboseLevel > 3) {
496 }
497
498 do
499 {
500 iteration++;
501
504
505 if (verboseLevel > 3) {
506 G4cout <<
"Shell ID= " << shellIdx
507 <<
" Ebind(keV)= " << bindingE/keV <<
G4endl;
508 }
509 eMax = gammaEnergy0 - bindingE;
510
511
513
514 if (verboseLevel > 3) {
516 }
517
518 G4double pDoppler = pSample * fine_structure_const;
519 G4double pDoppler2 = pDoppler * pDoppler;
520 G4double var2 = 1. + onecost * E0_m;
521 G4double var3 = var2*var2 - pDoppler2;
522 G4double var4 = var2 - pDoppler2 * cosTheta;
523 G4double var = var4*var4 - var3 + pDoppler2 * var3;
524 if (var > 0.)
525 {
527 G4double scale = gammaEnergy0 / var3;
528
529 if (
G4UniformRand() < 0.5) photonE = (var4 - varSqrt) * scale;
530 else photonE = (var4 + varSqrt) * scale;
531 }
532 else
533 {
534 photonE = -1.;
535 }
536 } while ( iteration <= maxDopplerIterations &&
537 (photonE < 0. || photonE > eMax || photonE < eMax*
G4UniformRand()) );
538
539
540
541
542
543 if (iteration >= maxDopplerIterations)
544 {
545 photonE = photonEoriginal;
546 bindingE = 0.;
547 }
548
549 gammaEnergy1 = photonE;
550
551
552
553
554
555
556
557
558
559
560
561
563 sinThetaSqr,
564 phi,
565 cosTheta);
566
567
569 gammaDirection1 = tmpDirection1;
570
571
572
573 SystemOfRefChange(gammaDirection0,gammaDirection1,
574 gammaPolarization0,gammaPolarization1);
575
576 if (gammaEnergy1 > 0.)
577 {
581 }
582 else
583 {
584 gammaEnergy1 = 0.;
587 }
588
589
590
591
592
593 G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 -bindingE;
594
595
596
597 if(ElecKineEnergy < 0.0) {
599 return;
600 }
601
602
603
604 G4double ElecMomentum = std::sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
605
606 G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
607 gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
608
610 fvect->push_back(dp);
611
612
613
614
615 if (verboseLevel > 3) {
616 G4cout <<
"Started atomic de-excitation " << fAtomDeexcitation <<
G4endl;
617 }
618
619 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
622 size_t nbefore = fvect->size();
626 size_t nafter = fvect->size();
627 if(nafter > nbefore) {
628 for (size_t i=nbefore; i<nafter; ++i) {
629
630 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
631 {
632
633 bindingE -= ((*fvect)[i])->GetKineticEnergy();
634 }
635 else
636 {
637
638
639 delete (*fvect)[i];
640 (*fvect)[i]=0;
641 }
642 }
643 }
644 }
645 }
646
647 if(bindingE < 0.0)
648 G4Exception(
"G4LivermoreComptonModel::SampleSecondaries()",
650
652
653}
double epsilon(double density, double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
double howOrthogonal(const Hep3Vector &v) const
virtual G4double FindValue(G4double x, G4int componentId=0) const
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
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)