270{
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 if (fVerboseLevel > 3)
292 G4cout <<
"Calling SampleSecondaries() of G4PenelopeComptonModel" <<
G4endl;
293
295
296
297
299 return;
300
302 const G4Material* material = couple->
GetMaterial();
303
305
306 const G4int nmax = 64;
309
315 size_t numberOfOscillators = theTable->size();
316 size_t targetOscillator = 0;
318
319 G4double ek = photonEnergy0/electron_mass_c2;
323
325
326
327
328 static G4double taumax = std::nexttoward(1.0,0.0);
329 if (fVerboseLevel > 3)
330 G4cout <<
"G4PenelopeComptonModel: maximum value of tau: 1 - " << 1.-taumax <<
G4endl;
331
333 G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
334
337
338
339
340 if (photonEnergy0 > 5*MeV)
341 {
342 do{
343 do{
346 else
348
349 TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
351 if (tau > taumax) tau = taumax;
353 cosTheta = 1.0 - (1.0-tau)/(ek*tau);
354
355
357 targetOscillator = numberOfOscillators-1;
359 G4bool levelFound =
false;
360 for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
361 {
362 S += (*theTable)[j]->GetOscillatorStrength();
364 {
365 targetOscillator = j;
366 levelFound = true;
367 }
368 }
369
370 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
371 }
while((
epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
372 }
373 else
374 {
375
380 for (size_t i=0;i<numberOfOscillators;i++)
381 {
382 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
383 if (photonEnergy0 > ionEnergy)
384 {
385 G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
386 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
387 oscStren = (*theTable)[i]->GetOscillatorStrength();
388 pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
389 (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
390 if (pzomc > 0)
391 rni = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
392 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
393 else
394 rni = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
395 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
397 }
398 }
399
401 do
402 {
405 else
407 if (tau > taumax) tau = taumax;
408 cdt1 = (1.0-tau)/(ek*tau);
409
411 for (size_t i=0;i<numberOfOscillators;i++)
412 {
413 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
414 if (photonEnergy0 > ionEnergy)
415 {
416 aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
417 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
418 oscStren = (*theTable)[i]->GetOscillatorStrength();
419 pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
420 (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
421 if (pzomc > 0)
422 rn[i] = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
423 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
424 else
425 rn[i] = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
426 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
429 }
430 else
432 }
433
434 TST =
S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
436
437 cosTheta = 1.0 - cdt1;
440
441 do
442 {
443 do
444 {
446 targetOscillator = numberOfOscillators-1;
447 G4bool levelFound =
false;
448 for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
449 {
450 if (pac[i]>TST)
451 {
452 targetOscillator = i;
453 levelFound = true;
454 }
455 }
457 hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
458 oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
460 pzomc = (std::sqrt(0.5)-std::sqrt(0.5-
G4Log(2.0*
A)))/
461 (std::sqrt(2.0)*hartreeFunc);
462 else
463 pzomc = (std::sqrt(0.5-
G4Log(2.0-2.0*
A))-std::sqrt(0.5))/
464 (std::sqrt(2.0)*hartreeFunc);
465 } while (pzomc < -1);
466
467
468 G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
469 G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
470 if (AF > 0)
471 fpzmax = 1.0+AF*0.2;
472 else
473 fpzmax = 1.0-AF*0.2;
474 fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
476
477
481 if (pzomc > 0.0)
482 epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
483 else
484 epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
485 }
486
487
488 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
490 G4double dirx = sinTheta * std::cos(phi);
491 G4double diry = sinTheta * std::sin(phi);
493
494
496 photonDirection1.rotateUz(photonDirection0);
498
500
501 if (photonEnergy1 > 0.)
503 else
504 {
507 }
508
509
511 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
512
514 photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
516
517 if (Q2 > 1.0e-12)
518 cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
519 else
520 cosThetaE = 1.0;
521 G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
522
523
524
525 G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
526 G4int Z = (
G4int) (*theTable)[targetOscillator]->GetParentZ();
527
528
530 const G4AtomicShell*
shell = 0;
531
532
533 if (Z > 0 && shFlag<30)
534 {
535 shell = fTransitionManager->Shell(Z,shFlag-1);
537 }
538
539 G4double ionEnergyInPenelopeDatabase = ionEnergy;
540
541 ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
542
543
544
545 G4double eKineticEnergy = diffEnergy - ionEnergy;
546 G4double localEnergyDeposit = ionEnergy;
549
550 if (eKineticEnergy < 0)
551 {
552
553
554
555
556 localEnergyDeposit = diffEnergy;
557 eKineticEnergy = 0.0;
558 }
559
560
561
562
563 if (fAtomDeexcitation && shell)
564 {
566 if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
567 {
568 size_t nBefore = fvect->size();
569 fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
570 size_t nAfter = fvect->size();
571
572 if (nAfter > nBefore)
573 {
574 for (size_t j=nBefore;j<nAfter;j++)
575 {
576 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
577 if (itsEnergy < localEnergyDeposit)
578 {
579 localEnergyDeposit -= itsEnergy;
581 energyInFluorescence += itsEnergy;
582 else if (((*fvect)[j])->GetParticleDefinition() ==
584 energyInAuger += itsEnergy;
585 }
586 else
587 {
588 delete (*fvect)[j];
589 (*fvect)[j] = nullptr;
590 }
591 }
592 }
593
594 }
595 }
596
597
599
600 G4double xEl = sinThetaE * std::cos(phi+pi);
601 G4double yEl = sinThetaE * std::sin(phi+pi);
604 eDirection.rotateUz(photonDirection0);
606 eDirection,eKineticEnergy) ;
607 fvect->push_back(electron);
608
609 if (localEnergyDeposit < 0)
610 {
611 G4Exception(
"G4PenelopeComptonModel::SampleSecondaries()",
612 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
613 localEnergyDeposit=0.;
614 }
616
618 if (electron)
619 electronEnergy = eKineticEnergy;
620 if (fVerboseLevel > 1)
621 {
622 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
623 G4cout <<
"Energy balance from G4PenelopeCompton" <<
G4endl;
624 G4cout <<
"Incoming photon energy: " << photonEnergy0/keV <<
" keV" <<
G4endl;
625 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
626 G4cout <<
"Scattered photon: " << photonEnergy1/keV <<
" keV" <<
G4endl;
627 G4cout <<
"Scattered electron " << electronEnergy/keV <<
" keV" <<
G4endl;
628 if (energyInFluorescence)
629 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
630 if (energyInAuger)
631 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
632 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
633 G4cout <<
"Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
634 localEnergyDeposit+energyInAuger)/keV <<
636 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
637 }
638 if (fVerboseLevel > 0)
639 {
640 G4double energyDiff = std::fabs(photonEnergy1+
641 electronEnergy+energyInFluorescence+
642 localEnergyDeposit+energyInAuger-photonEnergy0);
643 if (energyDiff > 0.05*keV)
644 G4cout <<
"Warning from G4PenelopeCompton: problem with energy conservation: " <<
645 (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
646 " keV (final) vs. " <<
647 photonEnergy0/keV <<
" keV (initial)" <<
G4endl;
648 }
649}
G4double epsilon(G4double density, G4double temperature)
G4double S(G4double temp)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4ThreeVector G4ParticleMomentum
CLHEP::Hep3Vector G4ThreeVector
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Electron * Electron()
static G4Gamma * Definition()
const G4Material * GetMaterial() const
G4double bindingEnergy(G4int A, G4int Z)