1 #include "G4HadReentrentException.hh" 2 #include "G4ProcessManager.hh" 3 #include "G4ParticleTable.hh" 11 using namespace CLHEP;
14 : G4VDiscreteProcess(processName), theHelper(aHelper) {}
23 const G4Element* anElement,
32 G4Material* aMaterial = aTrack.GetMaterial();
33 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
36 G4int nElements = aMaterial->GetNumberOfElements();
38 const G4double* theAtomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
39 G4double aTemp = aMaterial->GetTemperature();
41 for (G4int
i = 0;
i < nElements; ++
i) {
43 sigma += theAtomicNumDensityVector[
i] * xSection;
45 G4double
res = DBL_MAX;
54 const G4TouchableHandle& thisTouchable(aTrack.GetTouchableHandle());
57 aParticleChange.Initialize(aTrack);
58 const G4DynamicParticle* IncidentRhadron = aTrack.GetDynamicParticle();
60 const G4ThreeVector& aPosition = aTrack.GetPosition();
62 const G4int theIncidentPDG = IncidentRhadron->GetDefinition()->GetPDGEncoding();
63 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
64 std::vector<G4ParticleDefinition*> theParticleDefinitions;
65 G4bool IncidentSurvives =
false;
66 G4bool TargetSurvives =
false;
67 G4Nucleus targetNucleus(aTrack.GetMaterial());
68 G4ParticleDefinition* outgoingRhadron =
nullptr;
69 G4ParticleDefinition* outgoingCloud =
nullptr;
70 G4ParticleDefinition* outgoingTarget =
nullptr;
72 G4ThreeVector p_0 = IncidentRhadron->GetMomentum();
73 G4double e_kin_0 = IncidentRhadron->GetKineticEnergy();
76 G4DynamicParticle* cloudParticle =
new G4DynamicParticle();
83 cloudParticle->SetDefinition(CustomIncident->
GetCloud());
85 if (cloudParticle->GetDefinition() ==
nullptr) {
86 G4cout <<
"FullModelHadronicProcess::PostStepDoIt Definition of particle cloud not available!!" << G4endl;
93 double scale = cloudParticle->GetDefinition()->GetPDGMass() / IncidentRhadron->GetDefinition()->GetPDGMass();
95 G4LorentzVector cloudMomentum(IncidentRhadron->GetMomentum() *
scale, cloudParticle->GetDefinition()->GetPDGMass());
96 G4LorentzVector gluinoMomentum(IncidentRhadron->GetMomentum() * (1. -
scale),
100 G4LorentzVector FullRhadron4Momentum = IncidentRhadron->Get4Momentum();
101 const G4LorentzVector& Cloud4Momentum = cloudMomentum;
103 cloudParticle->Set4Momentum(cloudMomentum);
105 G4DynamicParticle* OrgPart = cloudParticle;
117 double E_0 = IncidentRhadron->GetKineticEnergy();
118 G4double ek = OrgPart->GetKineticEnergy();
119 G4double amas = OrgPart->GetDefinition()->GetPDGMass();
120 G4ThreeVector
dir = (OrgPart->GetMomentum()).
unit();
121 G4double tkin = targetNucleus.Cinema(ek);
125 tkin = targetNucleus.EvaporationEffects(ek);
128 if (ek + gluinoMomentum.e() - gluinoMomentum.m() <= 0.1 *
MeV || ek <= 0.) {
130 G4cout <<
"Kinetic energy is sick" << G4endl;
131 G4cout <<
"Full R-hadron: " << (ek + gluinoMomentum.e() - gluinoMomentum.m()) /
MeV <<
" MeV" << G4endl;
132 G4cout <<
"Quark system: " << ek /
MeV <<
" MeV" << G4endl;
133 aParticleChange.ProposeTrackStatus(fStopButAlive);
134 return &aParticleChange;
136 OrgPart->SetKineticEnergy(ek);
138 OrgPart->SetMomentum(dir * p);
141 G4ParticleDefinition* aTarget;
143 G4bool force2to2 =
false;
145 while (rp.size() != 2 && force2to2) {
148 G4int NumberOfSecondaries = rp.size();
152 G4LorentzVector Target4Momentum(0., 0., 0., aTarget->GetPDGMass());
154 G4LorentzVector psum_full = FullRhadron4Momentum + Target4Momentum;
155 G4LorentzVector psum_cloud = Cloud4Momentum + Target4Momentum;
156 G4ThreeVector trafo_full_cms = (-1) * psum_full.boostVector();
157 G4ThreeVector trafo_cloud_cms = (-1) * psum_cloud.boostVector();
161 for (ReactionProduct::iterator it = rp.begin(); it != rp.end(); ++it) {
162 G4ParticleDefinition* tempDef = theParticleTable->FindParticle(*it);
164 if (tempDef == aTarget)
165 TargetSurvives =
true;
168 if (tempCust !=
nullptr) {
169 outgoingRhadron = tempDef;
171 outgoingCloud = tempCust->
GetCloud();
172 if (outgoingCloud ==
nullptr) {
173 G4cout <<
"FullModelHadronicProcess::PostStepDoIt Definition of outgoing particle cloud not available!" 182 if (tempDef == G4Proton::Proton() || tempDef == G4Neutron::Neutron())
183 outgoingTarget = tempDef;
184 if (tempCust ==
nullptr && rp.size() == 2)
185 outgoingTarget = tempDef;
186 if (tempDef->GetPDGEncoding() == theIncidentPDG) {
187 IncidentSurvives =
true;
189 theParticleDefinitions.push_back(tempDef);
193 if (outgoingTarget ==
nullptr)
194 outgoingTarget = theParticleTable->FindParticle(rp[1]);
208 if (IncidentSurvives)
209 NumberOfSecondaries--;
210 aParticleChange.SetNumberOfSecondaries(NumberOfSecondaries);
217 const G4HadProjectile* originalIncident =
new G4HadProjectile(*OrgPart);
220 G4HadProjectile* org2 =
new G4HadProjectile(*OrgPart);
221 G4LorentzRotation trans = org2->GetTrafoToLab();
226 G4DynamicParticle* originalTarget =
new G4DynamicParticle;
227 originalTarget->SetDefinition(aTarget);
229 G4ReactionProduct targetParticle(aTarget);
231 G4ReactionProduct currentParticle(const_cast<G4ParticleDefinition*>(originalIncident->GetDefinition()));
232 currentParticle.SetMomentum(originalIncident->Get4Momentum().vect());
233 currentParticle.SetKineticEnergy(originalIncident->GetKineticEnergy());
242 G4ReactionProduct modifiedOriginal = currentParticle;
244 currentParticle.SetSide(1);
245 targetParticle.SetSide(-1);
246 G4bool incidentHasChanged =
false;
247 if (!IncidentSurvives)
248 incidentHasChanged =
true;
249 G4bool targetHasChanged =
false;
251 targetHasChanged =
true;
252 G4bool quasiElastic =
false;
255 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> vec;
262 for (G4int
i = 0;
i != NumberOfSecondaries;
i++) {
263 if (theParticleDefinitions[
i] != aTarget && theParticleDefinitions[
i] != originalIncident->GetDefinition() &&
264 theParticleDefinitions[
i] != outgoingRhadron && theParticleDefinitions[
i] != outgoingTarget) {
265 G4ReactionProduct*
pa =
new G4ReactionProduct;
266 pa->SetDefinition(theParticleDefinitions[
i]);
267 (G4UniformRand() < 0.5) ? pa->SetSide(-1) : pa->SetSide(1);
268 vec.SetElement(vecLen++, pa);
272 if (incidentHasChanged)
273 currentParticle.SetDefinitionAndUpdateE(outgoingCloud);
274 if (incidentHasChanged)
275 modifiedOriginal.SetDefinition(
277 if (targetHasChanged)
278 targetParticle.SetDefinitionAndUpdateE(outgoingTarget);
301 G4String cPname = currentParticle.GetDefinition()->GetParticleName();
328 aParticleChange.SetNumberOfSecondaries(vecLen + NumberOfSecondaries);
330 G4LorentzVector cloud_p4_new;
342 cloud_p4_new.setVectM(currentParticle.GetMomentum(), currentParticle.GetMass());
343 cloud_p4_new *= trans;
345 G4LorentzVector cloud_p4_old_full = Cloud4Momentum;
346 cloud_p4_old_full.boost(trafo_full_cms);
347 G4LorentzVector cloud_p4_old_cloud = Cloud4Momentum;
348 cloud_p4_old_cloud.boost(trafo_cloud_cms);
349 G4LorentzVector cloud_p4_full = cloud_p4_new;
350 cloud_p4_full.boost(trafo_full_cms);
351 G4LorentzVector cloud_p4_cloud = cloud_p4_new;
352 cloud_p4_cloud.boost(trafo_cloud_cms);
354 G4LorentzVector p_g_cms = gluinoMomentum;
355 p_g_cms.boost(trafo_full_cms);
357 double e = cloud_p4_new.e() + gluinoMomentum.e();
359 e += outgoingRhadron->GetPDGMass();
360 G4LorentzVector p4_new(cloud_p4_new.v() + gluinoMomentum.v(),
e);
364 G4ThreeVector p_new = p4_new.vect();
366 aParticleChange.ProposeLocalEnergyDeposit((p4_new - cloud_p4_new - gluinoMomentum).
m());
368 if (incidentHasChanged) {
369 G4DynamicParticle* p0 =
new G4DynamicParticle;
370 p0->SetDefinition(outgoingRhadron);
371 p0->SetMomentum(p_new);
374 G4Track* Track0 =
new G4Track(p0, aTrack.GetGlobalTime(), aPosition);
375 Track0->SetTouchableHandle(thisTouchable);
376 aParticleChange.AddSecondary(Track0);
382 if (p0->GetKineticEnergy() > e_kin_0) {
383 G4cout <<
"ALAAAAARM!!! (incident changed from " << IncidentRhadron->GetDefinition()->GetParticleName() <<
" to " 384 << p0->GetDefinition()->GetParticleName() <<
")" << G4endl;
385 G4cout <<
"Energy loss: " << (e_kin_0 - p0->GetKineticEnergy()) /
GeV <<
" GeV (should be positive)" << G4endl;
388 G4cout <<
"DOUBLE ALAAAAARM!!!" << G4endl;
392 if (
std::abs(p0->GetKineticEnergy() - e_kin_0) > 100 *
GeV) {
393 G4cout <<
"Diff. too big" << G4endl;
395 aParticleChange.ProposeTrackStatus(fStopAndKill);
397 G4double p = p_new.mag();
399 aParticleChange.ProposeMomentumDirection(p_new.x() /
p, p_new.y() /
p, p_new.z() /
p);
401 aParticleChange.ProposeMomentumDirection(1.0, 0.0, 0.0);
405 if (targetParticle.GetMass() > 0.0)
407 G4DynamicParticle*
p1 =
new G4DynamicParticle;
408 p1->SetDefinition(targetParticle.GetDefinition());
410 G4ThreeVector momentum = targetParticle.GetMomentum();
412 p1->SetMomentum(momentum);
413 p1->SetMomentum((trans * p1->Get4Momentum()).vect());
414 G4Track* Track1 =
new G4Track(p1, aTrack.GetGlobalTime(), aPosition);
415 Track1->SetTouchableHandle(thisTouchable);
416 aParticleChange.AddSecondary(Track1);
418 G4DynamicParticle*
pa;
424 for (
int i = 0;
i < vecLen; ++
i) {
425 pa =
new G4DynamicParticle();
426 pa->SetDefinition(vec[
i]->GetDefinition());
427 pa->SetMomentum(vec[
i]->GetMomentum());
428 pa->Set4Momentum(trans * (pa->Get4Momentum()));
429 G4ThreeVector pvec = pa->GetMomentum();
430 G4Track* Trackn =
new G4Track(pa, aTrack.GetGlobalTime(), aPosition);
431 Trackn->SetTouchableHandle(thisTouchable);
432 aParticleChange.AddSecondary(Trackn);
438 const G4DynamicParticle* theRhadron =
FindRhadron(&aParticleChange);
440 if (theRhadron !=
nullptr || IncidentSurvives) {
442 if (IncidentSurvives) {
445 E_new = theRhadron->GetKineticEnergy();
458 G4LorentzVector p4_old_full = FullRhadron4Momentum;
459 p4_old_full.boost(trafo_full_cms);
460 G4LorentzVector p4_old_cloud = FullRhadron4Momentum;
461 p4_old_cloud.boost(trafo_cloud_cms);
462 G4LorentzVector p4_full = p4_new;
464 p4_full = p4_full.boost(trafo_full_cms);
466 G4LorentzVector p4_cloud = p4_new;
467 p4_cloud.boost(trafo_cloud_cms);
469 G4double AbsDeltaE = E_0 - E_new;
471 if (AbsDeltaE > 10 *
GeV) {
472 G4cout <<
"Energy loss larger than 10 GeV..." << G4endl;
473 G4cout <<
"E_0: " << E_0 /
GeV <<
" GeV" << G4endl;
474 G4cout <<
"E_new: " << E_new /
GeV <<
" GeV" << G4endl;
475 G4cout <<
"Gamma: " << IncidentRhadron->GetTotalEnergy() / IncidentRhadron->GetDefinition()->GetPDGMass()
477 G4cout <<
"x: " << aPosition.x() / cm <<
" cm" << G4endl;
480 delete originalIncident;
481 delete originalTarget;
486 ClearNumberOfInteractionLengthLeft();
488 return &aParticleChange;
492 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE>& vec,
494 const G4HadProjectile* originalIncident,
495 const G4DynamicParticle* originalTarget,
496 G4ReactionProduct& modifiedOriginal,
497 G4Nucleus& targetNucleus,
498 G4ReactionProduct& currentParticle,
499 G4ReactionProduct& targetParticle,
500 G4bool& incidentHasChanged,
501 G4bool& targetHasChanged,
502 G4bool quasiElastic) {
506 what = originalIncident->Get4Momentum().vect();
511 vec, vecLen, modifiedOriginal, originalTarget, currentParticle, targetParticle, targetNucleus, targetHasChanged);
517 G4ReactionProduct leadingStrangeParticle;
523 G4bool finishedGenXPt =
false;
524 G4bool annihilation =
false;
525 if (originalIncident->GetDefinition()->GetPDGEncoding() < 0 && currentParticle.GetMass() == 0.0 &&
526 targetParticle.GetMass() == 0.0) {
529 G4double ekcor = 1.0;
530 G4double ek = originalIncident->GetKineticEnergy();
533 const G4double tarmas = originalTarget->GetDefinition()->GetPDGMass();
535 ekcor = 1. / (ek /
GeV);
536 const G4double atomicWeight = G4double(targetNucleus.GetN_asInt());
537 ek = 2 * tarmas + ek * (1. + ekcor / atomicWeight);
539 G4double tkin = targetNucleus.Cinema(ek);
542 modifiedOriginal.SetKineticEnergy(ekOrg);
545 const G4double twsup[] = {1.0, 0.7, 0.5, 0.3, 0.2, 0.1};
546 G4double rand1 = G4UniformRand();
547 G4double rand2 = G4UniformRand();
548 if ((annihilation || (vecLen >= 6) || (modifiedOriginal.GetKineticEnergy() /
GeV >= 1.0)) &&
549 (((originalIncident->GetDefinition() == G4KaonPlus::KaonPlus()) ||
550 (originalIncident->GetDefinition() == G4KaonMinus::KaonMinus()) ||
551 (originalIncident->GetDefinition() == G4KaonZeroLong::KaonZeroLong()) ||
552 (originalIncident->GetDefinition() == G4KaonZeroShort::KaonZeroShort())) &&
553 ((rand1 < 0.5) || (rand2 > twsup[vecLen]))))
564 leadingStrangeParticle);
565 if (finishedGenXPt) {
570 G4bool finishedTwoClu =
false;
571 if (modifiedOriginal.GetTotalMomentum() /
MeV < 1.0) {
572 for (G4int
i = 0;
i < vecLen;
i++)
586 finishedTwoClu = theReactionDynamics.
TwoCluster(vec,
596 leadingStrangeParticle);
597 }
catch (G4HadReentrentException& aC) {
599 throw G4HadReentrentException(__FILE__, __LINE__,
"Failing to calculate momenta");
602 if (finishedTwoClu) {
619 vec, vecLen, modifiedOriginal, originalTarget, currentParticle, targetParticle, targetNucleus, targetHasChanged);
623 const G4ReactionProduct& targetParticle,
624 G4ReactionProduct& leadParticle) {
631 if ((currentParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
632 (currentParticle.GetDefinition() != G4Proton::Proton()) &&
633 (currentParticle.GetDefinition() != G4Neutron::Neutron())) {
635 leadParticle = currentParticle;
636 }
else if ((targetParticle.GetMass() >= G4KaonPlus::KaonPlus()->GetPDGMass()) &&
637 (targetParticle.GetDefinition() != G4Proton::Proton()) &&
638 (targetParticle.GetDefinition() != G4Neutron::Neutron())) {
640 leadParticle = targetParticle;
646 G4double
rotation = 2. *
pi * G4UniformRand();
649 for (i = 0; i < vecLen; ++
i) {
650 G4ThreeVector momentum = vec[
i]->GetMomentum();
651 momentum = momentum.rotate(rotation,
what);
652 vec[
i]->SetMomentum(momentum);
657 G4int nsec = aParticleChange->GetNumberOfSecondaries();
661 G4bool
found =
false;
662 while (i != nsec && !found) {
665 if (dynamic_cast<CustomParticle*>(aParticleChange->GetSecondary(i)->GetDynamicParticle()->GetDefinition()) !=
672 return aParticleChange->GetSecondary(i)->GetDynamicParticle();
G4bool MarkLeadingStrangeParticle(const G4ReactionProduct ¤tParticle, const G4ReactionProduct &targetParticle, G4ReactionProduct &leadParticle)
G4bool ApplicabilityTester(const G4ParticleDefinition &aPart)
void TwoBody(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, G4ReactionProduct &modifiedOriginal, const G4DynamicParticle *originalTarget, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &targetHasChanged)
G4ParticleDefinition * GetCloud()
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
static bool s_isRMeson(int pdg)
virtual G4double GetMicroscopicCrossSection(const G4DynamicParticle *aParticle, const G4Element *anElement, G4double aTemp)
std::vector< G4int > ReactionProduct
static bool s_isMesonino(int pdg)
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *) override
~FullModelHadronicProcess() override
Abs< T >::type abs(const T &t)
ReactionProduct GetFinalState(const G4Track &aTrack, G4ParticleDefinition *&aTarget)
G4bool TwoCluster(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged, G4bool leadFlag, G4ReactionProduct &leadingStrangeParticle)
G4double GetInclusiveCrossSection(const G4DynamicParticle *aParticle, const G4Element *anElement)
G4ParticleDefinition * GetSpectator()
G4bool GenerateXandPt(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged, G4bool leadFlag, G4ReactionProduct &leadingStrangeParticle)
void CalculateMomenta(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4HadProjectile *originalIncident, const G4DynamicParticle *originalTarget, G4ReactionProduct &modifiedOriginal, G4Nucleus &targetNucleus, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4bool &incidentHasChanged, G4bool &targetHasChanged, G4bool quasiElastic)
FullModelHadronicProcess(G4ProcessHelper *aHelper, const G4String &processName="FullModelHadronicProcess")
G4ProcessHelper * theHelper
void SuppressChargedPions(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged)
void Rotate(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
const G4DynamicParticle * FindRhadron(G4ParticleChange *)
G4bool IsApplicable(const G4ParticleDefinition &aP) override
Basic3DVector unit() const