268{
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 if (fVerboseLevel > 3)
290 G4cout <<
"Calling SampleSecondaries() of G4PenelopeComptonModel" <<
G4endl;
291
293
294
295
297 return;
298
301
303
304 const G4int nmax = 64;
307
313 size_t numberOfOscillators = theTable->size();
314 size_t targetOscillator = 0;
316
317 G4double ek = photonEnergy0/electron_mass_c2;
321
324 G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
325
328
329
330
331 if (photonEnergy0 > 5*MeV)
332 {
333 do{
334 do{
337 else
339
340 TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
343 cosTheta = 1.0 - (1.0-tau)/(ek*tau);
344
345
347 targetOscillator = numberOfOscillators-1;
349 G4bool levelFound =
false;
350 for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
351 {
352 S += (*theTable)[j]->GetOscillatorStrength();
354 {
355 targetOscillator = j;
356 levelFound = true;
357 }
358 }
359
360 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
361 }
while((
epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
362 }
363 else
364 {
365
370 for (size_t i=0;i<numberOfOscillators;i++)
371 {
372 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
373 if (photonEnergy0 > ionEnergy)
374 {
375 G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
376 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
377 oscStren = (*theTable)[i]->GetOscillatorStrength();
378 pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
379 (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
380 if (pzomc > 0)
381 rni = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
382 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
383 else
384 rni = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
385 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
387 }
388 }
389
391 do
392 {
395 else
397 cdt1 = (1.0-tau)/(ek*tau);
398
400 for (size_t i=0;i<numberOfOscillators;i++)
401 {
402 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
403 if (photonEnergy0 > ionEnergy)
404 {
405 aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
406 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
407 oscStren = (*theTable)[i]->GetOscillatorStrength();
408 pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
409 (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
410 if (pzomc > 0)
411 rn[i] = 1.0-0.5*
G4Exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
412 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
413 else
414 rn[i] = 0.5*
G4Exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
415 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
418 }
419 else
421 }
422
423 TST =
S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
425
426 cosTheta = 1.0 - cdt1;
429
430 do
431 {
432 do
433 {
435 targetOscillator = numberOfOscillators-1;
436 G4bool levelFound =
false;
437 for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
438 {
439 if (pac[i]>TST)
440 {
441 targetOscillator = i;
442 levelFound = true;
443 }
444 }
446 hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
447 oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
449 pzomc = (std::sqrt(0.5)-std::sqrt(0.5-
G4Log(2.0*
A)))/
450 (std::sqrt(2.0)*hartreeFunc);
451 else
452 pzomc = (std::sqrt(0.5-
G4Log(2.0-2.0*
A))-std::sqrt(0.5))/
453 (std::sqrt(2.0)*hartreeFunc);
454 } while (pzomc < -1);
455
456
457 G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
458 G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
459 if (AF > 0)
460 fpzmax = 1.0+AF*0.2;
461 else
462 fpzmax = 1.0-AF*0.2;
463 fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
465
466
470 if (pzomc > 0.0)
471 epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
472 else
473 epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
474 }
475
476
477 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
479 G4double dirx = sinTheta * std::cos(phi);
480 G4double diry = sinTheta * std::sin(phi);
482
483
485 photonDirection1.rotateUz(photonDirection0);
487
489
490 if (photonEnergy1 > 0.)
492 else
493 {
496 }
497
498
500 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
501
503 photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
505
506 if (Q2 > 1.0e-12)
507 cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
508 else
509 cosThetaE = 1.0;
510 G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
511
512
513
514 G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
515 G4int Z = (
G4int) (*theTable)[targetOscillator]->GetParentZ();
516
517
520
521
522 if (
Z > 0 && shFlag<30)
523 {
524 shell = fTransitionManager->
Shell(
Z,shFlag-1);
526 }
527
528 G4double ionEnergyInPenelopeDatabase = ionEnergy;
529
530 ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
531
532
533
534 G4double eKineticEnergy = diffEnergy - ionEnergy;
535 G4double localEnergyDeposit = ionEnergy;
538
539 if (eKineticEnergy < 0)
540 {
541
542
543
544
545 localEnergyDeposit = diffEnergy;
546 eKineticEnergy = 0.0;
547 }
548
549
550
551
552 if (fAtomDeexcitation && shell)
553 {
556 {
557 size_t nBefore = fvect->size();
559 size_t nAfter = fvect->size();
560
561 if (nAfter > nBefore)
562 {
563 for (size_t j=nBefore;j<nAfter;j++)
564 {
565 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
566 if (itsEnergy < localEnergyDeposit)
567 {
568 localEnergyDeposit -= itsEnergy;
570 energyInFluorescence += itsEnergy;
571 else if (((*fvect)[j])->GetParticleDefinition() ==
573 energyInAuger += itsEnergy;
574 }
575 else
576 {
577 delete (*fvect)[j];
578 (*fvect)[j] = nullptr;
579 }
580 }
581 }
582
583 }
584 }
585
586
588
589 G4double xEl = sinThetaE * std::cos(phi+pi);
590 G4double yEl = sinThetaE * std::sin(phi+pi);
593 eDirection.rotateUz(photonDirection0);
595 eDirection,eKineticEnergy) ;
596 fvect->push_back(electron);
597
598 if (localEnergyDeposit < 0)
599 {
600 G4Exception(
"G4PenelopeComptonModel::SampleSecondaries()",
601 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
602 localEnergyDeposit=0.;
603 }
605
607 if (electron)
608 electronEnergy = eKineticEnergy;
609 if (fVerboseLevel > 1)
610 {
611 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
612 G4cout <<
"Energy balance from G4PenelopeCompton" <<
G4endl;
613 G4cout <<
"Incoming photon energy: " << photonEnergy0/keV <<
" keV" <<
G4endl;
614 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
615 G4cout <<
"Scattered photon: " << photonEnergy1/keV <<
" keV" <<
G4endl;
616 G4cout <<
"Scattered electron " << electronEnergy/keV <<
" keV" <<
G4endl;
617 if (energyInFluorescence)
618 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
619 if (energyInAuger)
620 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
621 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
622 G4cout <<
"Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
623 localEnergyDeposit+energyInAuger)/keV <<
625 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
626 }
627 if (fVerboseLevel > 0)
628 {
629 G4double energyDiff = std::fabs(photonEnergy1+
630 electronEnergy+energyInFluorescence+
631 localEnergyDeposit+energyInAuger-photonEnergy0);
632 if (energyDiff > 0.05*keV)
633 G4cout <<
"Warning from G4PenelopeCompton: problem with energy conservation: " <<
634 (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
635 " keV (final) vs. " <<
636 photonEnergy0/keV <<
" keV (initial)" <<
G4endl;
637 }
638}
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)