52 #include "G4AntiProton.hh" 53 #include "G4AntiNeutron.hh" 54 #include "Randomize.hh" 56 #include "G4ParticleTable.hh" 57 #include "G4Poisson.hh" 59 using namespace CLHEP;
62 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
64 G4ReactionProduct &modifiedOriginal,
65 const G4HadProjectile *originalIncident,
66 G4ReactionProduct ¤tParticle,
67 G4ReactionProduct &targetParticle,
68 const G4Nucleus &targetNucleus,
69 G4bool &incidentHasChanged,
70 G4bool &targetHasChanged,
72 G4ReactionProduct &leadingStrangeParticle) {
89 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
90 G4ParticleDefinition *aProton = G4Proton::Proton();
91 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
92 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
93 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
94 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
95 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
96 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
97 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
100 G4bool veryForward =
false;
102 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
103 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
104 const G4double mOriginal = modifiedOriginal.GetMass() / GeV;
105 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
106 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() / GeV;
107 G4double centerofmassEnergy =
108 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
109 G4double currentMass = currentParticle.GetMass() / GeV;
110 targetMass = targetParticle.GetMass() / GeV;
115 for (
i = 0;
i < vecLen; ++
i) {
116 G4int itemp = G4int(G4UniformRand() * vecLen);
117 G4ReactionProduct pTemp = *vec[itemp];
118 *vec[itemp] = *vec[
i];
123 if (currentMass == 0.0 && targetMass == 0.0)
126 G4double ek = currentParticle.GetKineticEnergy();
127 G4ThreeVector
m = currentParticle.GetMomentum();
128 currentParticle = *vec[0];
129 targetParticle = *vec[1];
130 for (
i = 0;
i < (vecLen - 2); ++
i)
131 *vec[
i] = *vec[
i + 2];
132 G4ReactionProduct *
temp = vec[vecLen - 1];
134 temp = vec[vecLen - 2];
137 currentMass = currentParticle.GetMass() / GeV;
138 targetMass = targetParticle.GetMass() / GeV;
139 incidentHasChanged =
true;
140 targetHasChanged =
true;
141 currentParticle.SetKineticEnergy(ek);
142 currentParticle.SetMomentum(
m);
145 const G4double atomicWeight = targetNucleus.GetN_asInt();
146 const G4double atomicNumber = targetNucleus.GetZ_asInt();
147 const G4double protonMass = aProton->GetPDGMass() / MeV;
148 if ((originalIncident->GetDefinition() == aKaonMinus || originalIncident->GetDefinition() == aKaonZeroL ||
149 originalIncident->GetDefinition() == aKaonZeroS || originalIncident->GetDefinition() == aKaonPlus) &&
150 G4UniformRand() >= 0.7) {
151 G4ReactionProduct
temp = currentParticle;
152 currentParticle = targetParticle;
153 targetParticle =
temp;
154 incidentHasChanged =
true;
155 targetHasChanged =
true;
156 currentMass = currentParticle.GetMass() / GeV;
157 targetMass = targetParticle.GetMass() / GeV;
160 0.312 + 0.200 *
std::log(
std::log(centerofmassEnergy * centerofmassEnergy)) +
161 std::pow(centerofmassEnergy * centerofmassEnergy, 1.5) / 6000.0);
163 G4double freeEnergy = centerofmassEnergy - currentMass - targetMass;
165 if (freeEnergy < 0) {
166 G4cout <<
"Free energy < 0!" << G4endl;
167 G4cout <<
"E_CMS = " << centerofmassEnergy <<
" GeV" << G4endl;
168 G4cout <<
"m_curr = " << currentMass <<
" GeV" << G4endl;
169 G4cout <<
"m_orig = " << mOriginal <<
" GeV" << G4endl;
170 G4cout <<
"m_targ = " << targetMass <<
" GeV" << G4endl;
171 G4cout <<
"E_free = " << freeEnergy <<
" GeV" << G4endl;
174 G4double forwardEnergy = freeEnergy / 2.;
175 G4int forwardCount = 1;
177 G4double backwardEnergy = freeEnergy / 2.;
178 G4int backwardCount = 1;
180 if (currentParticle.GetSide() == -1) {
181 forwardEnergy += currentMass;
183 backwardEnergy -= currentMass;
186 if (targetParticle.GetSide() != -1) {
187 backwardEnergy += targetMass;
189 forwardEnergy -= targetMass;
193 for (
i = 0;
i < vecLen; ++
i) {
194 if (vec[
i]->GetSide() == -1) {
196 backwardEnergy -= vec[
i]->GetMass() / GeV;
199 forwardEnergy -= vec[
i]->GetMass() / GeV;
208 if (centerofmassEnergy < (2.0 + G4UniformRand()))
209 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount + vecLen + 2) / 2.0;
211 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2.0 * backwardCount);
214 G4int nuclearExcitationCount = G4Poisson(xtarg);
215 if (atomicWeight < 1.0001)
216 nuclearExcitationCount = 0;
217 G4int extraNucleonCount = 0;
218 if (nuclearExcitationCount > 0) {
219 const G4double nucsup[] = {1.00, 0.7, 0.5, 0.4, 0.35, 0.3};
220 const G4double psup[] = {3., 6., 20., 50., 100., 1000.};
221 G4int momentumBin = 0;
222 while ((momentumBin < 6) && (modifiedOriginal.GetTotalMomentum() / GeV > psup[momentumBin]))
224 momentumBin =
std::min(5, momentumBin);
229 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
230 G4ReactionProduct *pVec =
new G4ReactionProduct();
231 if (G4UniformRand() < nucsup[momentumBin]) {
232 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
233 pVec->SetDefinition(aProton);
235 pVec->SetDefinition(aNeutron);
238 backwardEnergy += pVec->GetMass() / GeV;
240 G4double
ran = G4UniformRand();
242 pVec->SetDefinition(aPiPlus);
243 else if (
ran < 0.6819)
244 pVec->SetDefinition(aPiZero);
246 pVec->SetDefinition(aPiMinus);
249 pVec->SetNewlyAdded(
true);
250 vec.SetElement(vecLen++, pVec);
252 backwardEnergy -= pVec->GetMass() / GeV;
260 while (forwardEnergy <= 0.0)
263 iskip = G4int(G4UniformRand() * forwardCount) + 1;
265 G4int forwardParticlesLeft = 0;
266 for (
i = (vecLen - 1);
i >= 0; --
i) {
267 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
268 forwardParticlesLeft = 1;
270 forwardEnergy += vec[
i]->GetMass() / GeV;
271 for (G4int
j =
i;
j < (vecLen - 1);
j++)
272 *vec[
j] = *vec[
j + 1];
274 G4ReactionProduct *
temp = vec[vecLen - 1];
283 if (forwardParticlesLeft == 0) {
284 forwardEnergy += currentParticle.GetMass() / GeV;
285 currentParticle.SetDefinitionAndUpdateE(targetParticle.GetDefinition());
286 targetParticle.SetDefinitionAndUpdateE(vec[0]->GetDefinition());
289 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
290 *vec[
j] = *vec[
j + 1];
291 G4ReactionProduct *
temp = vec[vecLen - 1];
299 while (backwardEnergy <= 0.0)
302 iskip = G4int(G4UniformRand() * backwardCount) + 1;
304 G4int backwardParticlesLeft = 0;
305 for (
i = (vecLen - 1);
i >= 0; --
i) {
306 if (vec[
i]->GetSide() < 0 && vec[
i]->GetMayBeKilled()) {
307 backwardParticlesLeft = 1;
310 if (vec[
i]->GetSide() == -2) {
313 backwardEnergy -= vec[
i]->GetTotalEnergy() / GeV;
315 backwardEnergy += vec[
i]->GetTotalEnergy() / GeV;
316 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
317 *vec[
j] = *vec[
j + 1];
319 G4ReactionProduct *
temp = vec[vecLen - 1];
328 if (backwardParticlesLeft == 0) {
329 backwardEnergy += targetParticle.GetMass() / GeV;
330 targetParticle = *vec[0];
332 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
333 *vec[
j] = *vec[
j + 1];
334 G4ReactionProduct *
temp = vec[vecLen - 1];
346 G4ReactionProduct pseudoParticle[10];
347 for (
i = 0;
i < 10; ++
i)
348 pseudoParticle[
i].SetZero();
350 pseudoParticle[0].SetMass(mOriginal * GeV);
351 pseudoParticle[0].SetMomentum(0.0, 0.0, pOriginal * GeV);
352 pseudoParticle[0].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
354 pseudoParticle[1].SetMass(protonMass * MeV);
355 pseudoParticle[1].SetTotalEnergy(protonMass * MeV);
357 pseudoParticle[3].SetMass(protonMass * (1 + extraNucleonCount) * MeV);
358 pseudoParticle[3].SetTotalEnergy(protonMass * (1 + extraNucleonCount) * MeV);
360 pseudoParticle[8].SetMomentum(1.0 * GeV, 0.0, 0.0);
362 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
363 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0];
365 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
366 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
373 G4double aspar,
pt,
et,
x, pp, pp1, rthnve, phinve, rmb, wgt;
374 G4int innerCounter, outerCounter;
375 G4bool eliminateThisParticle, resetEnergies, constantCrossSection;
377 G4double forwardKinetic = 0.0, backwardKinetic = 0.0;
383 G4double binl[20] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
384 1.0, 1.11, 1.25, 1.43, 1.67, 2.0, 2.5, 3.33, 5.00, 10.00};
385 G4int backwardNucleonCount = 0;
386 G4double totalEnergy, kineticEnergy, vecMass;
388 for (
i = (vecLen - 1);
i >= 0; --
i) {
389 G4double phi = G4UniformRand() * twopi;
390 if (vec[
i]->GetNewlyAdded())
392 if (vec[
i]->GetSide() == -2)
394 if (backwardNucleonCount < 18) {
395 if (vec[
i]->GetDefinition() == G4PionMinus::PionMinus() ||
396 vec[
i]->GetDefinition() == G4PionPlus::PionPlus() || vec[
i]->GetDefinition() == G4PionZero::PionZero()) {
397 for (G4int
i = 0;
i < vecLen;
i++)
400 G4ExceptionDescription ed;
401 ed <<
"FullModelReactionDynamics::GenerateXandPt : a pion has been counted as a backward nucleon";
402 G4Exception(
"FullModelReactionDynamics::GenerateXandPt",
"had064", FatalException, ed);
405 ++backwardNucleonCount;
414 vecMass = vec[
i]->GetMass() / GeV;
415 G4double
ran = -
std::log(1.0 - G4UniformRand()) / 3.5;
416 if (vec[
i]->GetSide() == -2)
418 if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
419 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus ||
420 vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
421 vec[
i]->GetDefinition() == aPiPlus) {
429 if (vec[
i]->GetDefinition() == aPiMinus || vec[
i]->GetDefinition() == aPiZero ||
430 vec[
i]->GetDefinition() == aPiPlus) {
433 }
else if (vec[
i]->GetDefinition() == aKaonMinus || vec[
i]->GetDefinition() == aKaonZeroL ||
434 vec[
i]->GetDefinition() == aKaonZeroS || vec[
i]->GetDefinition() == aKaonPlus) {
444 for (G4int
j = 0;
j < 20; ++
j)
445 binl[
j] =
j / (19. *
pt);
446 if (vec[
i]->GetSide() > 0)
447 et = pseudoParticle[0].GetTotalEnergy() / GeV;
449 et = pseudoParticle[1].GetTotalEnergy() / GeV;
455 eliminateThisParticle =
true;
456 resetEnergies =
true;
457 while (++outerCounter < 3) {
458 for (
l = 1;
l < 20; ++
l) {
459 x = (binl[
l] + binl[
l - 1]) / 2.;
462 dndl[
l] += dndl[
l - 1];
473 while (++innerCounter < 7) {
474 ran = G4UniformRand() * dndl[19];
476 while ((
ran >= dndl[
l]) && (
l < 20))
479 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
480 if (vec[
i]->GetSide() < 0)
482 vec[
i]->SetMomentum(
x *
et * GeV);
484 vec[
i]->SetTotalEnergy(totalEnergy * GeV);
485 kineticEnergy = vec[
i]->GetKineticEnergy() / GeV;
486 if (vec[
i]->GetSide() > 0)
488 if ((forwardKinetic + kineticEnergy) < 0.95 * forwardEnergy) {
489 pseudoParticle[4] = pseudoParticle[4] + (*vec[
i]);
490 forwardKinetic += kineticEnergy;
491 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
492 pseudoParticle[6].SetMomentum(0.0);
493 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
494 if (pseudoParticle[6].GetMomentum().y() / MeV < 0.0)
502 eliminateThisParticle =
false;
503 resetEnergies =
false;
506 if (innerCounter > 5)
508 if (backwardEnergy >= vecMass)
511 forwardEnergy += vecMass;
512 backwardEnergy -= vecMass;
516 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
517 if ((backwardKinetic + kineticEnergy) <
xxx * backwardEnergy) {
518 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
519 backwardKinetic += kineticEnergy;
520 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
521 pseudoParticle[6].SetMomentum(0.0);
522 phi = pseudoParticle[6].Angle(pseudoParticle[8]);
523 if (pseudoParticle[6].GetMomentum().y() / MeV < 0.0)
531 eliminateThisParticle =
false;
532 resetEnergies =
false;
535 if (innerCounter > 5)
537 if (forwardEnergy >= vecMass)
540 forwardEnergy -= vecMass;
541 backwardEnergy += vecMass;
545 G4ThreeVector momentum = vec[
i]->GetMomentum();
546 vec[
i]->SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
556 forwardKinetic = 0.0;
557 backwardKinetic = 0.0;
558 pseudoParticle[4].SetZero();
559 pseudoParticle[5].SetZero();
560 for (
l =
i + 1;
l < vecLen; ++
l) {
561 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
562 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
563 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
564 vec[
l]->GetDefinition() == aPiPlus) {
565 G4double tempMass = vec[
l]->GetMass() / MeV;
566 totalEnergy = 0.95 * vec[
l]->GetTotalEnergy() / MeV + 0.05 * tempMass;
567 totalEnergy =
std::max(tempMass, totalEnergy);
568 vec[
l]->SetTotalEnergy(totalEnergy * MeV);
570 pp1 = vec[
l]->GetMomentum().mag() / MeV;
571 if (pp1 < 1.0
e-6 * GeV) {
572 G4double rthnve =
pi * G4UniformRand();
573 G4double phinve = twopi * G4UniformRand();
578 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (pp / pp1));
580 G4double
px = vec[
l]->GetMomentum().x() / MeV;
581 G4double
py = vec[
l]->GetMomentum().y() / MeV;
583 if (vec[
l]->GetSide() > 0) {
584 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
585 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
587 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
588 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
595 if (eliminateThisParticle && vec[
i]->GetMayBeKilled())
597 if (vec[
i]->GetSide() > 0) {
599 forwardEnergy += vecMass;
601 if (vec[
i]->GetSide() == -2) {
603 backwardEnergy -= vecMass;
606 backwardEnergy += vecMass;
608 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
609 *vec[
j] = *vec[
j + 1];
610 G4ReactionProduct *
temp = vec[vecLen - 1];
615 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
616 pseudoParticle[6].SetMomentum(0.0);
625 G4double phi = G4UniformRand() * twopi;
627 if (currentParticle.GetDefinition() == aPiMinus || currentParticle.GetDefinition() == aPiZero ||
628 currentParticle.GetDefinition() == aPiPlus) {
631 }
else if (currentParticle.GetDefinition() == aKaonMinus || currentParticle.GetDefinition() == aKaonZeroL ||
632 currentParticle.GetDefinition() == aKaonZeroS || currentParticle.GetDefinition() == aKaonPlus) {
639 for (G4int
j = 0;
j < 20; ++
j)
640 binl[
j] =
j / (19. *
pt);
642 et = pseudoParticle[0].GetTotalEnergy() / GeV;
644 vecMass = currentParticle.GetMass() / GeV;
645 for (
l = 1;
l < 20; ++
l) {
646 x = (binl[
l] + binl[
l - 1]) / 2.;
648 dndl[
l] += dndl[
l - 1];
654 ran = G4UniformRand() * dndl[19];
656 while ((
ran > dndl[
l]) && (
l < 20))
659 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
660 currentParticle.SetMomentum(
x *
et * GeV);
661 if (forwardEnergy < forwardKinetic)
662 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
664 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
665 currentParticle.SetTotalEnergy(totalEnergy * GeV);
667 pp1 = currentParticle.GetMomentum().mag() / MeV;
668 if (pp1 < 1.0
e-6 * GeV) {
669 G4double rthnve =
pi * G4UniformRand();
670 G4double phinve = twopi * G4UniformRand();
672 currentParticle.SetMomentum(
675 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
677 pseudoParticle[4] = pseudoParticle[4] + currentParticle;
682 if (backwardNucleonCount < 18) {
683 targetParticle.SetSide(-3);
684 ++backwardNucleonCount;
689 vecMass = targetParticle.GetMass() / GeV;
694 for (G4int
j = 0;
j < 20; ++
j)
695 binl[
j] = (
j - 1.) / (19. *
pt);
696 et = pseudoParticle[1].GetTotalEnergy() / GeV;
699 resetEnergies =
true;
700 while (++outerCounter < 3)
702 for (
l = 1;
l < 20; ++
l) {
703 x = (binl[
l] + binl[
l - 1]) / 2.;
705 dndl[
l] += dndl[
l - 1];
712 while (++innerCounter < 7)
715 ran = G4UniformRand() * dndl[19];
716 while ((
ran >= dndl[
l]) && (
l < 20))
719 x =
std::min(1.0,
pt * (binl[
l - 1] + G4UniformRand() * (binl[
l] - binl[
l - 1]) / 2.));
720 if (targetParticle.GetSide() < 0)
722 targetParticle.SetMomentum(
x *
et * GeV);
724 targetParticle.SetTotalEnergy(totalEnergy * GeV);
725 if (targetParticle.GetSide() < 0) {
726 G4double
xxx = 0.95 + 0.05 * extraNucleonCount / 20.0;
727 if ((backwardKinetic + totalEnergy - vecMass) <
xxx * backwardEnergy) {
728 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
729 backwardKinetic += totalEnergy - vecMass;
730 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
731 pseudoParticle[6].SetMomentum(0.0);
733 resetEnergies =
false;
736 if (innerCounter > 5)
738 if (forwardEnergy >= vecMass)
740 targetParticle.SetSide(1);
741 forwardEnergy -= vecMass;
742 backwardEnergy += vecMass;
745 G4ThreeVector momentum = targetParticle.GetMomentum();
746 targetParticle.SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9);
751 if (forwardEnergy < forwardKinetic)
752 totalEnergy = vecMass + 0.04 * std::fabs(
normal());
754 totalEnergy = vecMass + forwardEnergy - forwardKinetic;
755 targetParticle.SetTotalEnergy(totalEnergy * GeV);
757 pp1 = targetParticle.GetMomentum().mag() / MeV;
758 if (pp1 < 1.0
e-6 * GeV) {
759 G4double rthnve =
pi * G4UniformRand();
760 G4double phinve = twopi * G4UniformRand();
762 targetParticle.SetMomentum(
765 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
767 pseudoParticle[4] = pseudoParticle[4] + targetParticle;
770 resetEnergies =
false;
780 forwardKinetic = backwardKinetic = 0.0;
781 pseudoParticle[4].SetZero();
782 pseudoParticle[5].SetZero();
783 for (
l = 0;
l < vecLen; ++
l)
785 if (vec[
l]->GetSide() > 0 || vec[
l]->GetDefinition() == aKaonMinus || vec[
l]->GetDefinition() == aKaonZeroL ||
786 vec[
l]->GetDefinition() == aKaonZeroS || vec[
l]->GetDefinition() == aKaonPlus ||
787 vec[
l]->GetDefinition() == aPiMinus || vec[
l]->GetDefinition() == aPiZero ||
788 vec[
l]->GetDefinition() == aPiPlus) {
789 G4double tempMass = vec[
l]->GetMass() / GeV;
790 totalEnergy =
std::max(tempMass, 0.95 * vec[
l]->GetTotalEnergy() / GeV + 0.05 * tempMass);
791 vec[
l]->SetTotalEnergy(totalEnergy * GeV);
793 pp1 = vec[
l]->GetMomentum().mag() / MeV;
794 if (pp1 < 1.0
e-6 * GeV) {
795 G4double rthnve =
pi * G4UniformRand();
796 G4double phinve = twopi * G4UniformRand();
801 vec[
l]->SetMomentum(vec[
l]->GetMomentum() * (pp / pp1));
804 std::sqrt(
sqr(vec[
l]->GetMomentum().
x() / MeV) +
sqr(vec[
l]->GetMomentum().y() / MeV))) /
806 if (vec[
l]->GetSide() > 0) {
807 forwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
808 pseudoParticle[4] = pseudoParticle[4] + (*vec[
l]);
810 backwardKinetic += vec[
l]->GetKineticEnergy() / GeV;
811 pseudoParticle[5] = pseudoParticle[5] + (*vec[
l]);
822 pseudoParticle[6].Lorentz(pseudoParticle[3], pseudoParticle[2]);
823 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4];
824 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5];
825 if (backwardNucleonCount == 1)
827 G4double ekin =
std::min(backwardEnergy - backwardKinetic, centerofmassEnergy / 2.0 - protonMass / GeV);
829 ekin = 0.04 * std::fabs(
normal());
830 vecMass = targetParticle.GetMass() / GeV;
831 totalEnergy = ekin + vecMass;
832 targetParticle.SetTotalEnergy(totalEnergy * GeV);
834 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
835 if (pp1 < 1.0
e-6 * GeV) {
836 rthnve =
pi * G4UniformRand();
837 phinve = twopi * G4UniformRand();
839 targetParticle.SetMomentum(
842 targetParticle.SetMomentum(pseudoParticle[6].GetMomentum() * (pp / pp1));
844 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
847 const G4double
cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
848 const G4double gpar[] = {2.6, 2.6, 1.80, 1.30, 1.20};
854 if (targetParticle.GetSide() == -3)
855 rmb0 += targetParticle.GetMass() / GeV;
856 for (
i = 0;
i < vecLen; ++
i) {
857 if (vec[
i]->GetSide() == -3)
858 rmb0 += vec[
i]->GetMass() / GeV;
861 totalEnergy = pseudoParticle[6].GetTotalEnergy() / GeV;
862 vecMass =
std::min(rmb, totalEnergy);
863 pseudoParticle[6].SetMass(vecMass * GeV);
865 pp1 = pseudoParticle[6].GetMomentum().mag() / MeV;
866 if (pp1 < 1.0
e-6 * GeV) {
867 rthnve =
pi * G4UniformRand();
868 phinve = twopi * G4UniformRand();
870 pseudoParticle[6].SetMomentum(
873 pseudoParticle[6].SetMomentum(pseudoParticle[6].GetMomentum() * (-pp / pp1));
875 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
876 tempV.Initialize(backwardNucleonCount);
878 if (targetParticle.GetSide() == -3)
879 tempV.SetElement(tempLen++, &targetParticle);
880 for (
i = 0;
i < vecLen; ++
i) {
881 if (vec[
i]->GetSide() == -3)
882 tempV.SetElement(tempLen++, vec[
i]);
884 if (tempLen != backwardNucleonCount) {
885 G4ExceptionDescription ed;
886 ed <<
"tempLen is not the same as backwardNucleonCount" << G4endl;
887 ed <<
"tempLen = " << tempLen <<
", backwardNucleonCount = " << backwardNucleonCount << G4endl;
888 ed <<
"targetParticle side = " << targetParticle.GetSide() << G4endl;
889 ed <<
"currentParticle side = " << currentParticle.GetSide() << G4endl;
890 for (
i = 0;
i < vecLen; ++
i)
891 ed <<
"particle #" <<
i <<
" side = " << vec[
i]->GetSide() << G4endl;
892 G4Exception(
"FullModelReactionDynamics::GenerateXandPt",
"had064", FatalException, ed);
894 constantCrossSection =
true;
897 GenerateNBodyEvent(pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen);
899 if (targetParticle.GetSide() == -3) {
900 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
902 pseudoParticle[5] = pseudoParticle[5] + targetParticle;
904 for (
i = 0;
i < vecLen; ++
i) {
905 if (vec[
i]->GetSide() == -3) {
906 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
907 pseudoParticle[5] = pseudoParticle[5] + (*vec[
i]);
920 G4int numberofFinalStateNucleons =
921 currentParticle.GetDefinition()->GetBaryonNumber() + targetParticle.GetDefinition()->GetBaryonNumber();
922 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
923 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
925 for (
i = 0;
i < vecLen; ++
i) {
926 numberofFinalStateNucleons += vec[
i]->GetDefinition()->GetBaryonNumber();
927 vec[
i]->Lorentz(*vec[
i], pseudoParticle[1]);
931 numberofFinalStateNucleons++;
932 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
943 G4bool leadingStrangeParticleHasChanged =
true;
945 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
946 leadingStrangeParticleHasChanged =
false;
947 if (leadingStrangeParticleHasChanged && (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()))
948 leadingStrangeParticleHasChanged =
false;
949 if (leadingStrangeParticleHasChanged) {
950 for (
i = 0;
i < vecLen;
i++) {
951 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
952 leadingStrangeParticleHasChanged =
false;
957 if (leadingStrangeParticleHasChanged) {
959 (leadingStrangeParticle.GetDefinition() == aKaonMinus ||
960 leadingStrangeParticle.GetDefinition() == aKaonZeroL ||
961 leadingStrangeParticle.GetDefinition() == aKaonZeroS ||
962 leadingStrangeParticle.GetDefinition() == aKaonPlus || leadingStrangeParticle.GetDefinition() == aPiMinus ||
963 leadingStrangeParticle.GetDefinition() == aPiZero || leadingStrangeParticle.GetDefinition() == aPiPlus);
964 G4bool targetTest =
false;
968 if ((leadTest && targetTest) || !(leadTest || targetTest))
970 targetParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
971 targetHasChanged =
true;
974 currentParticle.SetDefinitionAndUpdateE(leadingStrangeParticle.GetDefinition());
975 incidentHasChanged =
false;
981 pseudoParticle[3].SetMomentum(0.0, 0.0, pOriginal * GeV);
982 pseudoParticle[3].SetMass(mOriginal * GeV);
983 pseudoParticle[3].SetTotalEnergy(
std::sqrt(pOriginal * pOriginal + mOriginal * mOriginal) * GeV);
985 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
987 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
989 if (numberofFinalStateNucleons == 1)
991 pseudoParticle[4].SetMomentum(0.0, 0.0, 0.0);
992 pseudoParticle[4].SetMass(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
993 pseudoParticle[4].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
995 G4double theoreticalKinetic = pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV -
996 currentParticle.GetMass() / MeV - targetParticle.GetMass() / MeV;
998 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / MeV + targetParticle.GetKineticEnergy() / MeV;
1000 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4];
1001 pseudoParticle[3].Lorentz(pseudoParticle[3], pseudoParticle[5]);
1002 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[5]);
1004 pseudoParticle[7].SetZero();
1005 pseudoParticle[7] = pseudoParticle[7] + currentParticle;
1006 pseudoParticle[7] = pseudoParticle[7] + targetParticle;
1008 for (
i = 0;
i < vecLen; ++
i) {
1009 pseudoParticle[7] = pseudoParticle[7] + *vec[
i];
1010 simulatedKinetic += vec[
i]->GetKineticEnergy() / MeV;
1011 theoreticalKinetic -= vec[
i]->GetMass() / MeV;
1013 if (vecLen <= 16 && vecLen > 0) {
1017 G4ReactionProduct tempR[130];
1018 tempR[0] = currentParticle;
1019 tempR[1] = targetParticle;
1020 for (
i = 0;
i < vecLen; ++
i)
1021 tempR[
i + 2] = *vec[
i];
1022 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1023 tempV.Initialize(vecLen + 2);
1025 for (
i = 0;
i < vecLen + 2; ++
i)
1026 tempV.SetElement(tempLen++, &tempR[
i]);
1027 constantCrossSection =
true;
1029 wgt = GenerateNBodyEvent(pseudoParticle[3].GetTotalEnergy() / MeV + pseudoParticle[4].GetTotalEnergy() / MeV,
1030 constantCrossSection,
1034 theoreticalKinetic = 0.0;
1035 for (
i = 0;
i < tempLen; ++
i) {
1036 pseudoParticle[6].Lorentz(*tempV[
i], pseudoParticle[4]);
1037 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy() / MeV;
1045 if (simulatedKinetic != 0.0) {
1046 wgt = (theoreticalKinetic) / simulatedKinetic;
1047 theoreticalKinetic = currentParticle.GetKineticEnergy() / MeV * wgt;
1048 simulatedKinetic = theoreticalKinetic;
1049 currentParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1050 pp = currentParticle.GetTotalMomentum() / MeV;
1051 pp1 = currentParticle.GetMomentum().mag() / MeV;
1052 if (pp1 < 1.0
e-6 * GeV) {
1053 rthnve =
pi * G4UniformRand();
1054 phinve = twopi * G4UniformRand();
1055 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
1059 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
1061 theoreticalKinetic = targetParticle.GetKineticEnergy() / MeV * wgt;
1062 targetParticle.SetKineticEnergy(theoreticalKinetic * MeV);
1063 simulatedKinetic += theoreticalKinetic;
1064 pp = targetParticle.GetTotalMomentum() / MeV;
1065 pp1 = targetParticle.GetMomentum().mag() / MeV;
1067 if (pp1 < 1.0
e-6 * GeV) {
1068 rthnve =
pi * G4UniformRand();
1069 phinve = twopi * G4UniformRand();
1074 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
1076 for (
i = 0;
i < vecLen; ++
i) {
1077 theoreticalKinetic = vec[
i]->GetKineticEnergy() / MeV * wgt;
1078 simulatedKinetic += theoreticalKinetic;
1079 vec[
i]->SetKineticEnergy(theoreticalKinetic * MeV);
1080 pp = vec[
i]->GetTotalMomentum() / MeV;
1081 pp1 = vec[
i]->GetMomentum().mag() / MeV;
1082 if (pp1 < 1.0
e-6 * GeV) {
1083 rthnve =
pi * G4UniformRand();
1084 phinve = twopi * G4UniformRand();
1089 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pp / pp1));
1093 Rotate(numberofFinalStateNucleons,
1094 pseudoParticle[3].GetMomentum(),
1108 if (atomicWeight >= 1.5) {
1114 G4double epnb, edta;
1118 epnb = targetNucleus.GetPNBlackTrackEnergy();
1119 edta = targetNucleus.GetDTABlackTrackEnergy();
1120 const G4double pnCutOff = 0.001;
1121 const G4double dtaCutOff = 0.001;
1122 const G4double kineticMinimum = 1.e-6;
1123 const G4double kineticFactor = -0.010;
1124 G4double sprob = 0.0;
1125 const G4double ekIncident = originalIncident->GetKineticEnergy() / GeV;
1126 if (ekIncident >= 5.0)
1128 if (epnb >= pnCutOff) {
1129 npnb = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
1130 if (numberofFinalStateNucleons + npnb > atomicWeight)
1131 npnb = G4int(atomicWeight + 0.00001 - numberofFinalStateNucleons);
1132 npnb =
std::min(npnb, 127 - vecLen);
1134 if (edta >= dtaCutOff) {
1135 ndta = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
1136 ndta =
std::min(ndta, 127 - vecLen);
1138 G4double spall = numberofFinalStateNucleons;
1141 AddBlackTrackParticles(epnb,
1159 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
1160 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
1162 currentParticle.SetTOF(1.0);
1169 const G4ReactionProduct &modifiedOriginal,
1170 G4ReactionProduct ¤tParticle,
1171 G4ReactionProduct &targetParticle,
1172 const G4Nucleus &targetNucleus,
1173 G4bool &incidentHasChanged,
1174 G4bool &targetHasChanged) {
1179 const G4double atomicWeight = targetNucleus.GetN_asInt();
1180 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1181 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() / GeV;
1183 G4ParticleDefinition *aProton = G4Proton::Proton();
1184 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
1185 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1186 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
1187 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1188 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1190 const G4bool antiTest =
1191 modifiedOriginal.GetDefinition() != anAntiProton && modifiedOriginal.GetDefinition() != anAntiNeutron;
1192 if (antiTest && (currentParticle.GetDefinition() == aPiPlus || currentParticle.GetDefinition() == aPiMinus) &&
1193 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1194 if (G4UniformRand() > atomicNumber / atomicWeight)
1195 currentParticle.SetDefinitionAndUpdateE(aNeutron);
1197 currentParticle.SetDefinitionAndUpdateE(aProton);
1198 incidentHasChanged =
true;
1200 for (G4int
i = 0;
i < vecLen; ++
i) {
1201 if (antiTest && (vec[
i]->GetDefinition() == aPiPlus || vec[
i]->GetDefinition() == aPiMinus) &&
1202 (G4UniformRand() <= (10.0 - pOriginal) / 6.0) && (G4UniformRand() <= atomicWeight / 300.0)) {
1203 if (G4UniformRand() > atomicNumber / atomicWeight)
1204 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
1206 vec[
i]->SetDefinitionAndUpdateE(aProton);
1214 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
1216 G4ReactionProduct &modifiedOriginal,
1217 const G4HadProjectile *originalIncident,
1218 G4ReactionProduct ¤tParticle,
1219 G4ReactionProduct &targetParticle,
1220 const G4Nucleus &targetNucleus,
1221 G4bool &incidentHasChanged,
1222 G4bool &targetHasChanged,
1224 G4ReactionProduct &leadingStrangeParticle) {
1239 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1240 G4ParticleDefinition *aProton = G4Proton::Proton();
1241 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
1242 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1243 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1244 const G4double protonMass = aProton->GetPDGMass() / MeV;
1245 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
1246 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
1247 const G4double mOriginal = modifiedOriginal.GetMass() / GeV;
1248 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
1249 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass() / GeV;
1250 G4double centerofmassEnergy =
1251 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
1252 G4double currentMass = currentParticle.GetMass() / GeV;
1253 targetMass = targetParticle.GetMass() / GeV;
1255 if (currentMass == 0.0 && targetMass == 0.0) {
1256 G4double ek = currentParticle.GetKineticEnergy();
1257 G4ThreeVector
m = currentParticle.GetMomentum();
1258 currentParticle = *vec[0];
1259 targetParticle = *vec[1];
1260 for (
i = 0;
i < (vecLen - 2); ++
i)
1261 *vec[
i] = *vec[
i + 2];
1263 for (G4int
i = 0;
i < vecLen;
i++)
1266 G4ExceptionDescription ed;
1267 ed <<
"Negative number of particles";
1268 G4Exception(
"FullModelReactionDynamics::TwoCluster",
"had064", FatalException, ed);
1270 delete vec[vecLen - 1];
1271 delete vec[vecLen - 2];
1273 incidentHasChanged =
true;
1274 targetHasChanged =
true;
1275 currentParticle.SetKineticEnergy(ek);
1276 currentParticle.SetMomentum(
m);
1278 const G4double atomicWeight = targetNucleus.GetN_asInt();
1279 const G4double atomicNumber = targetNucleus.GetZ_asInt();
1285 G4int forwardCount = 1;
1286 currentParticle.SetSide(1);
1287 G4double forwardMass = currentParticle.GetMass() / GeV;
1291 G4int backwardCount = 1;
1292 targetParticle.SetSide(-1);
1293 G4double backwardMass = targetParticle.GetMass() / GeV;
1296 for (
i = 0;
i < vecLen; ++
i) {
1297 if (vec[
i]->GetSide() < 0)
1298 vec[
i]->SetSide(-1);
1301 if (vec[
i]->GetSide() == -1) {
1303 backwardMass += vec[
i]->GetMass() / GeV;
1306 forwardMass += vec[
i]->GetMass() / GeV;
1312 G4double term1 =
std::log(centerofmassEnergy * centerofmassEnergy);
1315 const G4double afc = 0.312 + 0.2 *
std::log(term1);
1317 if (centerofmassEnergy < 2.0 + G4UniformRand())
1318 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount + vecLen + 2) / 2.0;
1320 xtarg = afc * (
std::pow(atomicWeight, 0.33) - 1.0) * (2 * backwardCount);
1323 G4int nuclearExcitationCount = G4Poisson(xtarg);
1324 if (atomicWeight < 1.0001)
1325 nuclearExcitationCount = 0;
1326 if (nuclearExcitationCount > 0) {
1327 G4int momentumBin =
std::min(4, G4int(pOriginal / 3.0));
1328 const G4double nucsup[] = {1.0, 0.8, 0.6, 0.5, 0.4};
1333 for (
i = 0;
i < nuclearExcitationCount; ++
i) {
1334 G4ReactionProduct *pVec =
new G4ReactionProduct();
1335 if (G4UniformRand() < nucsup[momentumBin])
1337 if (G4UniformRand() > 1.0 - atomicNumber / atomicWeight)
1339 pVec->SetDefinition(aProton);
1341 pVec->SetDefinition(aNeutron);
1343 G4double
ran = G4UniformRand();
1345 pVec->SetDefinition(aPiPlus);
1346 else if (
ran < 0.6819)
1347 pVec->SetDefinition(aPiZero);
1349 pVec->SetDefinition(aPiMinus);
1352 pVec->SetNewlyAdded(
true);
1353 vec.SetElement(vecLen++, pVec);
1358 G4double eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1359 G4bool secondaryDeleted;
1361 while (eAvailable <= 0.0)
1363 secondaryDeleted =
false;
1364 for (
i = (vecLen - 1);
i >= 0; --
i) {
1365 if (vec[
i]->GetSide() == 1 && vec[
i]->GetMayBeKilled()) {
1366 pMass = vec[
i]->GetMass() / GeV;
1367 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
1368 *vec[
j] = *vec[
j + 1];
1371 forwardMass -= pMass;
1372 secondaryDeleted =
true;
1374 }
else if (vec[
i]->GetSide() == -1 && vec[
i]->GetMayBeKilled()) {
1375 pMass = vec[
i]->GetMass() / GeV;
1376 for (G4int
j =
i;
j < (vecLen - 1); ++
j)
1377 *vec[
j] = *vec[
j + 1];
1380 backwardMass -= pMass;
1381 secondaryDeleted =
true;
1385 if (secondaryDeleted) {
1386 G4ReactionProduct *
temp = vec[vecLen - 1];
1394 if (targetParticle.GetSide() == -1) {
1395 pMass = targetParticle.GetMass() / GeV;
1396 targetParticle = *vec[0];
1397 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1398 *vec[
j] = *vec[
j + 1];
1401 backwardMass -= pMass;
1402 secondaryDeleted =
true;
1403 }
else if (targetParticle.GetSide() == 1) {
1404 pMass = targetParticle.GetMass() / GeV;
1405 targetParticle = *vec[0];
1406 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1407 *vec[
j] = *vec[
j + 1];
1410 forwardMass -= pMass;
1411 secondaryDeleted =
true;
1413 if (secondaryDeleted) {
1414 G4ReactionProduct *
temp = vec[vecLen - 1];
1419 if (currentParticle.GetSide() == -1) {
1420 pMass = currentParticle.GetMass() / GeV;
1421 currentParticle = *vec[0];
1422 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1423 *vec[
j] = *vec[
j + 1];
1426 backwardMass -= pMass;
1427 secondaryDeleted =
true;
1428 }
else if (currentParticle.GetSide() == 1) {
1429 pMass = currentParticle.GetMass() / GeV;
1430 currentParticle = *vec[0];
1431 for (G4int
j = 0;
j < (vecLen - 1); ++
j)
1432 *vec[
j] = *vec[
j + 1];
1435 forwardMass -= pMass;
1436 secondaryDeleted =
true;
1438 if (secondaryDeleted) {
1439 G4ReactionProduct *
temp = vec[vecLen - 1];
1447 eAvailable = centerofmassEnergy - (forwardMass + backwardMass);
1456 G4double rmc = 0.0, rmd = 0.0;
1457 const G4double
cpar[] = {0.6, 0.6, 0.35, 0.15, 0.10};
1458 const G4double gpar[] = {2.6, 2.6, 1.8, 1.30, 1.20};
1460 if (forwardCount == 0)
1463 if (forwardCount == 1)
1469 if (backwardCount == 1)
1475 while (rmc + rmd > centerofmassEnergy) {
1476 if ((rmc <= forwardMass) && (rmd <= backwardMass)) {
1477 G4double
temp = 0.999 * centerofmassEnergy / (rmc + rmd);
1481 rmc = 0.1 * forwardMass + 0.9 * rmc;
1482 rmd = 0.1 * backwardMass + 0.9 * rmd;
1488 G4ReactionProduct pseudoParticle[8];
1489 for (
i = 0;
i < 8; ++
i)
1490 pseudoParticle[
i].SetZero();
1492 pseudoParticle[1].SetMass(mOriginal * GeV);
1493 pseudoParticle[1].SetTotalEnergy(etOriginal * GeV);
1494 pseudoParticle[1].SetMomentum(0.0, 0.0, pOriginal * GeV);
1496 pseudoParticle[2].SetMass(protonMass * MeV);
1497 pseudoParticle[2].SetTotalEnergy(protonMass * MeV);
1498 pseudoParticle[2].SetMomentum(0.0, 0.0, 0.0);
1502 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
1503 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[0]);
1504 pseudoParticle[2].Lorentz(pseudoParticle[2], pseudoParticle[0]);
1506 const G4double pfMin = 0.0001;
1507 G4double
pf = (centerofmassEnergy * centerofmassEnergy + rmd * rmd - rmc * rmc);
1509 pf -= 4 * centerofmassEnergy * centerofmassEnergy * rmd * rmd;
1514 pseudoParticle[3].SetMass(rmc * GeV);
1515 pseudoParticle[3].SetTotalEnergy(
std::sqrt(
pf *
pf + rmc * rmc) * GeV);
1517 pseudoParticle[4].SetMass(rmd * GeV);
1518 pseudoParticle[4].SetTotalEnergy(
std::sqrt(
pf *
pf + rmd * rmd) * GeV);
1522 const G4double
bMin = 0.01;
1523 const G4double
b1 = 4.0;
1524 const G4double
b2 = 1.6;
1526 G4double
t1 = pseudoParticle[1].GetTotalEnergy() / GeV - pseudoParticle[3].GetTotalEnergy() / GeV;
1527 G4double pin = pseudoParticle[1].GetMomentum().mag() / GeV;
1528 G4double tacmin =
t1 *
t1 - (pin -
pf) * (pin -
pf);
1532 const G4double smallValue = 1.0e-10;
1533 G4double dumnve = 4.0 * pin *
pf;
1535 dumnve = smallValue;
1536 G4double ctet =
std::max(-1.0,
std::min(1.0, 1.0 + 2.0 * (
t - tacmin) / dumnve));
1537 dumnve =
std::max(0.0, 1.0 - ctet * ctet);
1539 G4double phi = G4UniformRand() * twopi;
1543 pseudoParticle[3].SetMomentum(
pf * stet *
std::sin(phi) * GeV,
pf * stet *
std::cos(phi) * GeV,
pf * ctet * GeV);
1544 pseudoParticle[4].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1548 G4double pp, pp1, rthnve, phinve;
1549 if (nuclearExcitationCount > 0) {
1550 const G4double ga = 1.2;
1551 G4double ekit1 = 0.04;
1552 G4double ekit2 = 0.6;
1553 if (ekOriginal <= 5.0) {
1554 ekit1 *= ekOriginal * ekOriginal / 25.0;
1555 ekit2 *= ekOriginal * ekOriginal / 25.0;
1557 const G4double
a = (1.0 - ga) / (
std::pow(ekit2, (1.0 - ga)) -
std::pow(ekit1, (1.0 - ga)));
1558 for (
i = 0;
i < vecLen; ++
i) {
1559 if (vec[
i]->GetSide() == -2) {
1561 std::pow((G4UniformRand() * (1.0 - ga) /
a +
std::pow(ekit1, (1.0 - ga))), (1.0 / (1.0 - ga)));
1562 vec[
i]->SetKineticEnergy(kineticE * GeV);
1563 G4double vMass = vec[
i]->GetMass() / MeV;
1564 G4double totalE = kineticE + vMass;
1568 phi = twopi * G4UniformRand();
1569 vec[
i]->SetMomentum(pp * sint *
std::sin(phi) * MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
1570 vec[
i]->Lorentz(*vec[
i], pseudoParticle[0]);
1578 currentParticle.SetMomentum(pseudoParticle[3].GetMomentum());
1579 currentParticle.SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1581 targetParticle.SetMomentum(pseudoParticle[4].GetMomentum());
1582 targetParticle.SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1584 pseudoParticle[5].SetMomentum(pseudoParticle[3].GetMomentum() * (-1.0));
1585 pseudoParticle[5].SetMass(pseudoParticle[3].GetMass());
1586 pseudoParticle[5].SetTotalEnergy(pseudoParticle[3].GetTotalEnergy());
1588 pseudoParticle[6].SetMomentum(pseudoParticle[4].GetMomentum() * (-1.0));
1589 pseudoParticle[6].SetMass(pseudoParticle[4].GetMass());
1590 pseudoParticle[6].SetTotalEnergy(pseudoParticle[4].GetTotalEnergy());
1594 if (forwardCount > 1)
1596 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1597 tempV.Initialize(forwardCount);
1598 G4bool constantCrossSection =
true;
1600 if (currentParticle.GetSide() == 1)
1601 tempV.SetElement(tempLen++, ¤tParticle);
1602 if (targetParticle.GetSide() == 1)
1603 tempV.SetElement(tempLen++, &targetParticle);
1604 for (
i = 0;
i < vecLen; ++
i) {
1605 if (vec[
i]->GetSide() == 1) {
1607 tempV.SetElement(tempLen++, vec[
i]);
1609 vec[
i]->SetSide(-1);
1615 GenerateNBodyEvent(pseudoParticle[3].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1616 if (currentParticle.GetSide() == 1)
1617 currentParticle.Lorentz(currentParticle, pseudoParticle[5]);
1618 if (targetParticle.GetSide() == 1)
1619 targetParticle.Lorentz(targetParticle, pseudoParticle[5]);
1620 for (
i = 0;
i < vecLen; ++
i) {
1621 if (vec[
i]->GetSide() == 1)
1622 vec[
i]->Lorentz(*vec[
i], pseudoParticle[5]);
1627 if (backwardCount > 1)
1629 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1630 tempV.Initialize(backwardCount);
1631 G4bool constantCrossSection =
true;
1633 if (currentParticle.GetSide() == -1)
1634 tempV.SetElement(tempLen++, ¤tParticle);
1635 if (targetParticle.GetSide() == -1)
1636 tempV.SetElement(tempLen++, &targetParticle);
1637 for (
i = 0;
i < vecLen; ++
i) {
1638 if (vec[
i]->GetSide() == -1) {
1640 tempV.SetElement(tempLen++, vec[
i]);
1642 vec[
i]->SetSide(-2);
1643 vec[
i]->SetKineticEnergy(0.0);
1644 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
1650 GenerateNBodyEvent(pseudoParticle[4].GetMass() / MeV, constantCrossSection, tempV, tempLen);
1651 if (currentParticle.GetSide() == -1)
1652 currentParticle.Lorentz(currentParticle, pseudoParticle[6]);
1653 if (targetParticle.GetSide() == -1)
1654 targetParticle.Lorentz(targetParticle, pseudoParticle[6]);
1655 for (
i = 0;
i < vecLen; ++
i) {
1656 if (vec[
i]->GetSide() == -1)
1657 vec[
i]->Lorentz(*vec[
i], pseudoParticle[6]);
1665 G4int numberofFinalStateNucleons =
1666 currentParticle.GetDefinition()->GetBaryonNumber() + targetParticle.GetDefinition()->GetBaryonNumber();
1667 currentParticle.Lorentz(currentParticle, pseudoParticle[2]);
1668 targetParticle.Lorentz(targetParticle, pseudoParticle[2]);
1670 for (
i = 0;
i < vecLen; ++
i) {
1671 numberofFinalStateNucleons += vec[
i]->GetDefinition()->GetBaryonNumber();
1672 vec[
i]->Lorentz(*vec[
i], pseudoParticle[2]);
1675 numberofFinalStateNucleons =
std::max(1, numberofFinalStateNucleons);
1690 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1692 else if (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition())
1695 for (
i = 0;
i < vecLen; ++
i) {
1696 if (vec[
i]->GetDefinition() == leadingStrangeParticle.GetDefinition()) {
1703 G4double leadMass = leadingStrangeParticle.GetMass() / MeV;
1705 if (((leadMass < protonMass) && (targetParticle.GetMass() / MeV < protonMass)) ||
1706 ((leadMass >= protonMass) && (targetParticle.GetMass() / MeV >= protonMass))) {
1707 ekin = targetParticle.GetKineticEnergy() / GeV;
1708 pp1 = targetParticle.GetMomentum().mag() / MeV;
1709 targetParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1710 targetParticle.SetKineticEnergy(ekin * GeV);
1711 pp = targetParticle.GetTotalMomentum() / MeV;
1713 rthnve =
pi * G4UniformRand();
1714 phinve = twopi * G4UniformRand();
1719 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
1721 targetHasChanged =
true;
1723 ekin = currentParticle.GetKineticEnergy() / GeV;
1724 pp1 = currentParticle.GetMomentum().mag() / MeV;
1725 currentParticle.SetDefinition(leadingStrangeParticle.GetDefinition());
1726 currentParticle.SetKineticEnergy(ekin * GeV);
1727 pp = currentParticle.GetTotalMomentum() / MeV;
1729 rthnve =
pi * G4UniformRand();
1730 phinve = twopi * G4UniformRand();
1731 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
1735 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
1737 incidentHasChanged =
true;
1745 pseudoParticle[4].SetMass(mOriginal * GeV);
1746 pseudoParticle[4].SetTotalEnergy(etOriginal * GeV);
1747 pseudoParticle[4].SetMomentum(0.0, 0.0, pOriginal * GeV);
1749 const G4ParticleDefinition *aOrgDef = modifiedOriginal.GetDefinition();
1751 if (aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron())
1753 if (numberofFinalStateNucleons == 1)
1755 pseudoParticle[5].SetMomentum(0.0, 0.0, 0.0);
1756 pseudoParticle[5].SetMass(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1757 pseudoParticle[5].SetTotalEnergy(protonMass * (numberofFinalStateNucleons -
diff) * MeV);
1760 G4double theoreticalKinetic = pseudoParticle[4].GetTotalEnergy() / GeV + pseudoParticle[5].GetTotalEnergy() / GeV;
1762 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
1763 pseudoParticle[4].Lorentz(pseudoParticle[4], pseudoParticle[6]);
1764 pseudoParticle[5].Lorentz(pseudoParticle[5], pseudoParticle[6]);
1767 G4ReactionProduct tempR[130];
1769 tempR[0] = currentParticle;
1770 tempR[1] = targetParticle;
1771 for (
i = 0;
i < vecLen; ++
i)
1772 tempR[
i + 2] = *vec[
i];
1774 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
1775 tempV.Initialize(vecLen + 2);
1776 G4bool constantCrossSection =
true;
1778 for (
i = 0;
i < vecLen + 2; ++
i)
1779 tempV.SetElement(tempLen++, &tempR[
i]);
1783 GenerateNBodyEvent(pseudoParticle[4].GetTotalEnergy() / MeV + pseudoParticle[5].GetTotalEnergy() / MeV,
1784 constantCrossSection,
1787 theoreticalKinetic = 0.0;
1788 for (
i = 0;
i < vecLen + 2; ++
i) {
1789 pseudoParticle[7].SetMomentum(tempV[
i]->GetMomentum());
1790 pseudoParticle[7].SetMass(tempV[
i]->GetMass());
1791 pseudoParticle[7].SetTotalEnergy(tempV[
i]->GetTotalEnergy());
1792 pseudoParticle[7].Lorentz(pseudoParticle[7], pseudoParticle[5]);
1793 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy() / GeV;
1799 theoreticalKinetic -= (currentParticle.GetMass() / GeV + targetParticle.GetMass() / GeV);
1800 for (
i = 0;
i < vecLen; ++
i)
1801 theoreticalKinetic -= vec[
i]->GetMass() / GeV;
1803 G4double simulatedKinetic = currentParticle.GetKineticEnergy() / GeV + targetParticle.GetKineticEnergy() / GeV;
1804 for (
i = 0;
i < vecLen; ++
i)
1805 simulatedKinetic += vec[
i]->GetKineticEnergy() / GeV;
1811 if (simulatedKinetic != 0.0) {
1812 wgt = (theoreticalKinetic) / simulatedKinetic;
1813 currentParticle.SetKineticEnergy(wgt * currentParticle.GetKineticEnergy());
1814 pp = currentParticle.GetTotalMomentum() / MeV;
1815 pp1 = currentParticle.GetMomentum().mag() / MeV;
1816 if (pp1 < 0.001 * MeV) {
1817 rthnve =
pi * G4UniformRand();
1818 phinve = twopi * G4UniformRand();
1819 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
1823 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
1825 targetParticle.SetKineticEnergy(wgt * targetParticle.GetKineticEnergy());
1826 pp = targetParticle.GetTotalMomentum() / MeV;
1827 pp1 = targetParticle.GetMomentum().mag() / MeV;
1828 if (pp1 < 0.001 * MeV) {
1829 rthnve =
pi * G4UniformRand();
1830 phinve = twopi * G4UniformRand();
1835 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
1837 for (
i = 0;
i < vecLen; ++
i) {
1838 vec[
i]->SetKineticEnergy(wgt * vec[
i]->GetKineticEnergy());
1839 pp = vec[
i]->GetTotalMomentum() / MeV;
1840 pp1 = vec[
i]->GetMomentum().mag() / MeV;
1842 rthnve =
pi * G4UniformRand();
1843 phinve = twopi * G4UniformRand();
1848 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pp / pp1));
1852 Rotate(numberofFinalStateNucleons,
1853 pseudoParticle[4].GetMomentum(),
1866 if (atomicWeight >= 1.5) {
1872 G4double epnb, edta;
1876 epnb = targetNucleus.GetPNBlackTrackEnergy();
1877 edta = targetNucleus.GetDTABlackTrackEnergy();
1878 const G4double pnCutOff = 0.001;
1879 const G4double dtaCutOff = 0.001;
1880 const G4double kineticMinimum = 1.e-6;
1881 const G4double kineticFactor = -0.005;
1883 G4double sprob = 0.0;
1884 const G4double ekIncident = originalIncident->GetKineticEnergy() / GeV;
1885 if (ekIncident >= 5.0)
1888 if (epnb >= pnCutOff) {
1889 npnb = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * epnb / (epnb + edta));
1890 if (numberofFinalStateNucleons + npnb > atomicWeight)
1891 npnb = G4int(atomicWeight - numberofFinalStateNucleons);
1892 npnb =
std::min(npnb, 127 - vecLen);
1894 if (edta >= dtaCutOff) {
1895 ndta = G4Poisson((1.5 + 1.25 * numberofFinalStateNucleons) * edta / (epnb + edta));
1896 ndta =
std::min(ndta, 127 - vecLen);
1898 G4double spall = numberofFinalStateNucleons;
1901 AddBlackTrackParticles(epnb,
1921 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
1922 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
1924 currentParticle.SetTOF(1.0);
1932 G4ReactionProduct &modifiedOriginal,
1933 const G4DynamicParticle * ,
1934 G4ReactionProduct ¤tParticle,
1935 G4ReactionProduct &targetParticle,
1936 const G4Nucleus &targetNucleus,
1948 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
1949 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
1950 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
1951 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
1952 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
1953 G4ParticleDefinition *aKaonZeroS = G4KaonZeroShort::KaonZeroShort();
1954 G4ParticleDefinition *aKaonZeroL = G4KaonZeroLong::KaonZeroLong();
1957 static const G4double expxu = 82.;
1958 static const G4double expxl = -expxu;
1960 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / GeV;
1961 const G4double pOriginal = modifiedOriginal.GetMomentum().mag() / GeV;
1962 G4double currentMass = currentParticle.GetMass() / GeV;
1963 G4double targetMass = targetParticle.GetMass() / GeV;
1964 const G4double atomicWeight = targetNucleus.GetN_asInt();
1966 G4double etCurrent = currentParticle.GetTotalEnergy() / GeV;
1967 G4double pCurrent = currentParticle.GetTotalMomentum() / GeV;
1970 std::sqrt(currentMass * currentMass + targetMass * targetMass + 2.0 * targetMass * etCurrent);
1978 if ((pCurrent < 0.1) || (cmEnergy < 0.01))
1980 targetParticle.SetMass(0.0);
1982 G4double
pf = cmEnergy * cmEnergy + targetMass * targetMass - currentMass * currentMass;
1983 pf =
pf *
pf - 4 * cmEnergy * cmEnergy * targetMass * targetMass;
1988 for (G4int
i = 0;
i < vecLen;
i++)
1991 throw G4HadronicException(__FILE__, __LINE__,
"FullModelReactionDynamics::TwoBody: pf is too small ");
1998 G4ReactionProduct pseudoParticle[3];
1999 pseudoParticle[0].SetMass(currentMass * GeV);
2000 pseudoParticle[0].SetTotalEnergy(etCurrent * GeV);
2001 pseudoParticle[0].SetMomentum(0.0, 0.0, pCurrent * GeV);
2003 pseudoParticle[1].SetMomentum(0.0, 0.0, 0.0);
2004 pseudoParticle[1].SetMass(targetMass * GeV);
2005 pseudoParticle[1].SetKineticEnergy(0.0);
2009 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1];
2010 pseudoParticle[0].Lorentz(pseudoParticle[0], pseudoParticle[2]);
2011 pseudoParticle[1].Lorentz(pseudoParticle[1], pseudoParticle[2]);
2015 currentParticle.SetTotalEnergy(
std::sqrt(
pf *
pf + currentMass * currentMass) * GeV);
2016 targetParticle.SetTotalEnergy(
std::sqrt(
pf *
pf + targetMass * targetMass) * GeV);
2020 const G4double cb = 0.01;
2021 const G4double
b1 = 4.225;
2022 const G4double
b2 = 1.795;
2027 G4double btrang =
b * 4.0 *
pf * pseudoParticle[0].GetMomentum().mag() / GeV;
2029 G4double exindt = -1.0;
2034 G4double ctet = 1.0 + 2 *
std::log(1.0 + G4UniformRand() * exindt) / btrang;
2035 if (std::fabs(ctet) > 1.0)
2036 ctet > 0.0 ? ctet = 1.0 : ctet = -1.0;
2037 G4double stet =
std::sqrt((1.0 - ctet) * (1.0 + ctet));
2038 G4double phi = twopi * G4UniformRand();
2042 if (targetParticle.GetDefinition() == aKaonMinus || targetParticle.GetDefinition() == aKaonZeroL ||
2043 targetParticle.GetDefinition() == aKaonZeroS || targetParticle.GetDefinition() == aKaonPlus ||
2044 targetParticle.GetDefinition() == aPiMinus || targetParticle.GetDefinition() == aPiZero ||
2045 targetParticle.GetDefinition() == aPiPlus) {
2046 currentParticle.SetMomentum(-
pf * stet *
std::sin(phi) * GeV, -
pf * stet *
std::cos(phi) * GeV, -
pf * ctet * GeV);
2048 currentParticle.SetMomentum(
pf * stet *
std::sin(phi) * GeV,
pf * stet *
std::cos(phi) * GeV,
pf * ctet * GeV);
2050 targetParticle.SetMomentum(currentParticle.GetMomentum() * (-1.0));
2054 currentParticle.Lorentz(currentParticle, pseudoParticle[1]);
2055 targetParticle.Lorentz(targetParticle, pseudoParticle[1]);
2065 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2067 G4double pp, pp1, ekin;
2068 if (atomicWeight >= 1.5) {
2069 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2070 pp1 = currentParticle.GetMomentum().mag() / MeV;
2072 ekin = currentParticle.GetKineticEnergy() / MeV - cfa * (1.0 + 0.5 *
normal()) * GeV;
2073 ekin =
std::max(0.0001 * GeV, ekin);
2074 currentParticle.SetKineticEnergy(ekin * MeV);
2075 pp = currentParticle.GetTotalMomentum() / MeV;
2076 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2078 pp1 = targetParticle.GetMomentum().mag() / MeV;
2080 ekin = targetParticle.GetKineticEnergy() / MeV - cfa * (1.0 +
normal() / 2.) * GeV;
2081 ekin =
std::max(0.0001 * GeV, ekin);
2082 targetParticle.SetKineticEnergy(ekin * MeV);
2083 pp = targetParticle.GetTotalMomentum() / MeV;
2084 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
2089 if (atomicWeight >= 1.5) {
2100 G4double epnb, edta;
2101 G4int npnb = 0, ndta = 0;
2103 epnb = targetNucleus.GetPNBlackTrackEnergy();
2104 edta = targetNucleus.GetDTABlackTrackEnergy();
2105 const G4double pnCutOff = 0.0001;
2106 const G4double dtaCutOff = 0.0001;
2107 const G4double kineticMinimum = 0.0001;
2108 const G4double kineticFactor = -0.010;
2109 G4double sprob = 0.0;
2110 if (epnb >= pnCutOff) {
2111 npnb = G4Poisson(epnb / 0.02);
2117 if (npnb > atomicWeight)
2118 npnb = G4int(atomicWeight);
2119 if ((epnb > pnCutOff) && (npnb <= 0))
2121 npnb =
std::min(npnb, 127 - vecLen);
2123 if (edta >= dtaCutOff) {
2124 ndta = G4int(2.0 *
std::log(atomicWeight));
2125 ndta =
std::min(ndta, 127 - vecLen);
2127 G4double spall = 0.0;
2146 AddBlackTrackParticles(epnb,
2164 if ((atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2))
2165 currentParticle.SetTOF(1.0 - 500.0 *
std::exp(-ekOriginal / 0.04) *
std::log(G4UniformRand()));
2167 currentParticle.SetTOF(1.0);
2172 const G4bool constantCrossSection,
2173 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2180 const G4double expxu = 82.;
2181 const G4double expxl = -expxu;
2183 G4cerr <<
"*** Error in FullModelReactionDynamics::GenerateNBodyEvent" << G4endl;
2184 G4cerr <<
" number of particles < 2" << G4endl;
2185 G4cerr <<
"totalEnergy = " << totalEnergy <<
"MeV, vecLen = " << vecLen << G4endl;
2190 G4double pcm[3][18];
2191 G4double totalMass = 0.0;
2195 for (
i = 0;
i < vecLen; ++
i) {
2196 mass[
i] = vec[
i]->GetMass() / GeV;
2199 vec[
i]->SetMomentum(0.0, 0.0, 0.0);
2204 totalMass +=
mass[
i];
2207 G4double totalE = totalEnergy / GeV;
2208 if (totalMass > totalE) {
2211 G4double kineticEnergy = totalE - totalMass;
2215 emm[vecLen - 1] = totalE;
2219 for (
i = 0;
i < vecLen; ++
i)
2220 ran[
i] = G4UniformRand();
2221 for (
i = 0;
i < vecLen - 2; ++
i) {
2222 for (G4int
j = vecLen - 2;
j >
i; --
j) {
2230 for (
i = 1;
i < vecLen - 1; ++
i)
2231 emm[
i] =
ran[
i - 1] * kineticEnergy +
sm[
i];
2234 G4bool lzero =
true;
2235 G4double wtmax = 0.0;
2236 if (constantCrossSection)
2238 G4double emmax = kineticEnergy +
mass[0];
2239 G4double emmin = 0.0;
2240 for (
i = 1;
i < vecLen; ++
i) {
2241 emmin +=
mass[
i - 1];
2243 G4double wtfc = 0.0;
2244 if (emmax * emmax > 0.0) {
2245 G4double
arg = emmax * emmax +
2263 const G4double ffq[18] = {0.,
2281 wtmax =
std::log(
std::pow(kineticEnergy, vecLen - 2) * ffq[vecLen - 1] / totalE);
2286 for (
i = 0;
i < vecLen - 1; ++
i) {
2288 if (emm[
i + 1] * emm[
i + 1] > 0.0) {
2289 G4double
arg = emm[
i + 1] * emm[
i + 1] +
2291 (emm[
i + 1] * emm[
i + 1]) -
2305 G4double bang, cb, sb, s0, s1, s2,
c,
s, esys,
a,
b, gama,
beta;
2309 for (
i = 1;
i < vecLen; ++
i) {
2311 pcm[1][
i] = -pd[
i - 1];
2313 bang = twopi * G4UniformRand();
2316 c = 2.0 * G4UniformRand() - 1.0;
2318 if (
i < vecLen - 1) {
2320 beta = pd[
i] / esys;
2321 gama = esys / emm[
i];
2322 for (G4int
j = 0;
j <=
i; ++
j) {
2327 a = s0 *
c - s1 *
s;
2328 pcm[1][
j] = s0 *
s + s1 *
c;
2330 pcm[0][
j] =
a * cb -
b * sb;
2331 pcm[2][
j] =
a * sb +
b * cb;
2335 for (G4int
j = 0;
j <=
i; ++
j) {
2340 a = s0 *
c - s1 *
s;
2341 pcm[1][
j] = s0 *
s + s1 *
c;
2343 pcm[0][
j] =
a * cb -
b * sb;
2344 pcm[2][
j] =
a * sb +
b * cb;
2348 for (
i = 0;
i < vecLen; ++
i) {
2349 vec[
i]->SetMomentum(pcm[0][
i] * GeV, pcm[1][
i] * GeV, pcm[2][
i] * GeV);
2350 vec[
i]->SetTotalEnergy(
energy[
i] * GeV);
2357 G4double
ran = -6.0;
2358 for (G4int
i = 0;
i < 12; ++
i)
2359 ran += G4UniformRand();
2368 for (G4int
i = 2;
i <=
m; ++
i)
2374 G4ReactionProduct ¤tParticle,
2375 G4ReactionProduct &targetParticle,
2376 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2378 const G4double pjx = modifiedOriginal.GetMomentum().x() / MeV;
2379 const G4double pjy = modifiedOriginal.GetMomentum().y() / MeV;
2380 const G4double pjz = modifiedOriginal.GetMomentum().z() / MeV;
2381 const G4double
p = modifiedOriginal.GetMomentum().mag() / MeV;
2382 if (pjx * pjx + pjy * pjy > 0.0) {
2383 G4double cost, sint,
ph, cosp, sinp, pix, piy, piz;
2394 pix = currentParticle.GetMomentum().x() / MeV;
2395 piy = currentParticle.GetMomentum().y() / MeV;
2396 piz = currentParticle.GetMomentum().z() / MeV;
2397 currentParticle.SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2398 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2399 -sint * pix * MeV + cost * piz * MeV);
2400 pix = targetParticle.GetMomentum().x() / MeV;
2401 piy = targetParticle.GetMomentum().y() / MeV;
2402 piz = targetParticle.GetMomentum().z() / MeV;
2403 targetParticle.SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2404 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2405 -sint * pix * MeV + cost * piz * MeV);
2406 for (G4int
i = 0;
i < vecLen; ++
i) {
2407 pix = vec[
i]->GetMomentum().x() / MeV;
2408 piy = vec[
i]->GetMomentum().y() / MeV;
2409 piz = vec[
i]->GetMomentum().z() / MeV;
2410 vec[
i]->SetMomentum(cost * cosp * pix * MeV - sinp * piy + sint * cosp * piz * MeV,
2411 cost * sinp * pix * MeV + cosp * piy + sint * sinp * piz * MeV,
2412 -sint * pix * MeV + cost * piz * MeV);
2416 currentParticle.SetMomentum(-currentParticle.GetMomentum().z());
2417 targetParticle.SetMomentum(-targetParticle.GetMomentum().z());
2418 for (G4int
i = 0;
i < vecLen; ++
i)
2425 const G4double numberofFinalStateNucleons,
2426 const G4ThreeVector &
temp,
2427 const G4ReactionProduct &modifiedOriginal,
2428 const G4HadProjectile *originalIncident,
2429 const G4Nucleus &targetNucleus,
2430 G4ReactionProduct ¤tParticle,
2431 G4ReactionProduct &targetParticle,
2432 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2439 const G4double atomicWeight = targetNucleus.GetN_asInt();
2440 const G4double logWeight =
std::log(atomicWeight);
2442 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus();
2443 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus();
2444 G4ParticleDefinition *aPiZero = G4PionZero::PionZero();
2447 G4ThreeVector pseudoParticle[4];
2448 for (
i = 0;
i < 4; ++
i)
2449 pseudoParticle[
i].
set(0, 0, 0);
2450 pseudoParticle[0] = currentParticle.GetMomentum() + targetParticle.GetMomentum();
2451 for (
i = 0;
i < vecLen; ++
i)
2452 pseudoParticle[0] = pseudoParticle[0] + (vec[
i]->GetMomentum());
2457 G4double alekw,
p, rthnve, phinve;
2458 G4double r1,
r2,
a1, ran1, ran2, xxh, exh, pxTemp, pyTemp, pzTemp;
2460 r1 = twopi * G4UniformRand();
2461 r2 = G4UniformRand();
2463 ran1 =
a1 *
std::sin(r1) * 0.020 * numberofFinalStateNucleons * GeV;
2464 ran2 =
a1 *
std::cos(r1) * 0.020 * numberofFinalStateNucleons * GeV;
2465 G4ThreeVector fermi(ran1, ran2, 0);
2467 pseudoParticle[0] = pseudoParticle[0] + fermi;
2468 pseudoParticle[2] =
temp;
2469 pseudoParticle[3] = pseudoParticle[0];
2471 pseudoParticle[1] = pseudoParticle[2].cross(pseudoParticle[3]);
2472 G4double
rotation = 2. *
pi * G4UniformRand();
2473 pseudoParticle[1] = pseudoParticle[1].rotate(
rotation, pseudoParticle[3]);
2474 pseudoParticle[2] = pseudoParticle[3].cross(pseudoParticle[1]);
2475 for (G4int
ii = 1;
ii <= 3;
ii++) {
2476 p = pseudoParticle[
ii].mag();
2478 pseudoParticle[
ii] = G4ThreeVector(0.0, 0.0, 0.0);
2480 pseudoParticle[
ii] = pseudoParticle[
ii] * (1. /
p);
2483 pxTemp = pseudoParticle[1].dot(currentParticle.GetMomentum());
2484 pyTemp = pseudoParticle[2].dot(currentParticle.GetMomentum());
2485 pzTemp = pseudoParticle[3].dot(currentParticle.GetMomentum());
2486 currentParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2488 pxTemp = pseudoParticle[1].dot(targetParticle.GetMomentum());
2489 pyTemp = pseudoParticle[2].dot(targetParticle.GetMomentum());
2490 pzTemp = pseudoParticle[3].dot(targetParticle.GetMomentum());
2491 targetParticle.SetMomentum(pxTemp, pyTemp, pzTemp);
2493 for (
i = 0;
i < vecLen; ++
i) {
2494 pxTemp = pseudoParticle[1].dot(vec[
i]->GetMomentum());
2495 pyTemp = pseudoParticle[2].dot(vec[
i]->GetMomentum());
2496 pzTemp = pseudoParticle[3].dot(vec[
i]->GetMomentum());
2497 vec[
i]->SetMomentum(pxTemp, pyTemp, pzTemp);
2503 Defs1(modifiedOriginal, currentParticle, targetParticle, vec, vecLen);
2505 G4double dekin = 0.0;
2508 if (atomicWeight >= 1.5)
2512 const G4double alem[] = {1.40, 2.30, 2.70, 3.00, 3.40, 4.60, 7.00};
2513 const G4double val0[] = {0.00, 0.40, 0.48, 0.51, 0.54, 0.60, 0.65};
2514 alekw =
std::log(originalIncident->GetKineticEnergy() / GeV);
2516 if (alekw > alem[0])
2519 for (G4int
j = 1;
j < 7; ++
j) {
2520 if (alekw < alem[
j])
2522 G4double rcnve = (val0[
j] - val0[
j - 1]) / (alem[
j] - alem[
j - 1]);
2523 exh = rcnve * alekw + val0[
j - 1] - rcnve * alem[
j - 1];
2529 const G4double cfa = 0.025 * ((atomicWeight - 1.) / 120.) *
std::exp(-(atomicWeight - 1.) / 120.);
2530 ekin = currentParticle.GetKineticEnergy() / GeV - cfa * (1 +
normal() / 2.0);
2533 dekin += ekin * (1.0 - xxh);
2535 currentParticle.SetKineticEnergy(ekin * GeV);
2536 pp = currentParticle.GetTotalMomentum() / MeV;
2537 pp1 = currentParticle.GetMomentum().mag() / MeV;
2538 if (pp1 < 0.001 * MeV) {
2539 rthnve =
pi * G4UniformRand();
2540 phinve = twopi * G4UniformRand();
2541 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
2545 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2546 ekin = targetParticle.GetKineticEnergy() / GeV - cfa * (1 +
normal() / 2.0);
2549 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2550 (targetParticle.GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2552 dekin += ekin * (1.0 - xxh);
2554 if ((targetParticle.GetDefinition() == aPiPlus) || (targetParticle.GetDefinition() == aPiZero) ||
2555 (targetParticle.GetDefinition() == aPiMinus)) {
2559 targetParticle.SetKineticEnergy(ekin * GeV);
2560 pp = targetParticle.GetTotalMomentum() / MeV;
2561 pp1 = targetParticle.GetMomentum().mag() / MeV;
2562 if (pp1 < 0.001 * MeV) {
2563 rthnve =
pi * G4UniformRand();
2564 phinve = twopi * G4UniformRand();
2569 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp / pp1));
2570 for (
i = 0;
i < vecLen; ++
i) {
2571 ekin = vec[
i]->GetKineticEnergy() / GeV - cfa * (1 +
normal() / 2.0);
2574 if (((modifiedOriginal.GetDefinition() == aPiPlus) || (modifiedOriginal.GetDefinition() == aPiMinus)) &&
2575 (vec[
i]->GetDefinition() == aPiZero) && (G4UniformRand() < logWeight))
2577 dekin += ekin * (1.0 - xxh);
2579 if ((vec[
i]->GetDefinition() == aPiPlus) || (vec[
i]->GetDefinition() == aPiZero) ||
2580 (vec[
i]->GetDefinition() == aPiMinus)) {
2584 vec[
i]->SetKineticEnergy(ekin * GeV);
2585 pp = vec[
i]->GetTotalMomentum() / MeV;
2586 pp1 = vec[
i]->GetMomentum().mag() / MeV;
2587 if (pp1 < 0.001 * MeV) {
2588 rthnve =
pi * G4UniformRand();
2589 phinve = twopi * G4UniformRand();
2594 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pp / pp1));
2597 if ((ek1 != 0.0) && (npions > 0)) {
2598 dekin = 1.0 + dekin / ek1;
2602 if ((currentParticle.GetDefinition() == aPiPlus) || (currentParticle.GetDefinition() == aPiZero) ||
2603 (currentParticle.GetDefinition() == aPiMinus)) {
2604 currentParticle.SetKineticEnergy(
std::max(0.001 * MeV, dekin * currentParticle.GetKineticEnergy()));
2605 pp = currentParticle.GetTotalMomentum() / MeV;
2606 pp1 = currentParticle.GetMomentum().mag() / MeV;
2608 rthnve =
pi * G4UniformRand();
2609 phinve = twopi * G4UniformRand();
2610 currentParticle.SetMomentum(pp *
std::sin(rthnve) *
std::cos(phinve) * MeV,
2614 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp / pp1));
2616 for (
i = 0;
i < vecLen; ++
i) {
2617 if ((vec[
i]->GetDefinition() == aPiPlus) || (vec[
i]->GetDefinition() == aPiZero) ||
2618 (vec[
i]->GetDefinition() == aPiMinus)) {
2619 vec[
i]->SetKineticEnergy(
std::max(0.001 * MeV, dekin * vec[
i]->GetKineticEnergy()));
2620 pp = vec[
i]->GetTotalMomentum() / MeV;
2621 pp1 = vec[
i]->GetMomentum().mag() / MeV;
2623 rthnve =
pi * G4UniformRand();
2624 phinve = twopi * G4UniformRand();
2629 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pp / pp1));
2637 const G4double edta,
2639 const G4double sprob,
2640 const G4double kineticMinimum,
2641 const G4double kineticFactor,
2642 const G4ReactionProduct &modifiedOriginal,
2644 const G4Nucleus &targetNucleus,
2645 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2655 G4ParticleDefinition *aProton = G4Proton::Proton();
2656 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
2657 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
2658 G4ParticleDefinition *aTriton = G4Triton::Triton();
2661 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy() / MeV;
2662 G4double atomicWeight = targetNucleus.GetN_asInt();
2663 G4double atomicNumber = targetNucleus.GetZ_asInt();
2665 const G4double ika1 = 3.6;
2666 const G4double ika2 = 35.56;
2667 const G4double ika3 = 6.45;
2668 const G4double sp1 = 1.066;
2674 G4double cfa = 0.025 * ((atomicWeight - 1.0) / 120.0) *
std::exp(-(atomicWeight - 1.0) / 120.0);
2677 G4double backwardKinetic = 0.0;
2678 G4int local_npnb = npnb;
2679 for (
i = 0;
i < npnb; ++
i)
2680 if (G4UniformRand() < sprob)
2682 G4double ekin = epnb / local_npnb;
2684 for (
i = 0;
i < local_npnb; ++
i) {
2685 G4ReactionProduct *
p1 =
new G4ReactionProduct();
2686 if (backwardKinetic > epnb) {
2690 G4double
ran = G4UniformRand();
2694 backwardKinetic += kinetic;
2695 if (backwardKinetic > epnb)
2696 kinetic =
std::max(kineticMinimum, epnb - (backwardKinetic - kinetic));
2697 if (G4UniformRand() > (1.0 - atomicNumber / atomicWeight))
2698 p1->SetDefinition(aProton);
2700 p1->SetDefinition(aNeutron);
2701 vec.SetElement(vecLen,
p1);
2703 G4double cost = G4UniformRand() * 2.0 - 1.0;
2704 G4double sint =
std::sqrt(std::fabs(1.0 - cost * cost));
2705 G4double phi = twopi * G4UniformRand();
2706 vec[vecLen]->SetNewlyAdded(
true);
2707 vec[vecLen]->SetKineticEnergy(kinetic * GeV);
2709 pp = vec[vecLen]->GetTotalMomentum() / MeV;
2710 vec[vecLen]->SetMomentum(pp * sint *
std::sin(phi) * MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
2714 if ((atomicWeight >= 10.0) && (ekOriginal <= 2.0 * GeV)) {
2715 G4double ekw = ekOriginal / GeV;
2720 ika = G4int(ika1 *
std::exp((atomicNumber * atomicNumber / atomicWeight - ika2) / ika3) / ekw);
2722 for (
i = (vecLen - 1);
i >= 0; --
i) {
2723 if ((vec[
i]->GetDefinition() == aProton) && vec[
i]->GetNewlyAdded()) {
2724 vec[
i]->SetDefinitionAndUpdateE(aNeutron);
2734 G4double backwardKinetic = 0.0;
2735 G4int local_ndta = ndta;
2736 for (
i = 0;
i < ndta; ++
i)
2737 if (G4UniformRand() < sprob)
2739 G4double ekin = edta / local_ndta;
2741 for (
i = 0;
i < local_ndta; ++
i) {
2742 G4ReactionProduct *
p2 =
new G4ReactionProduct();
2743 if (backwardKinetic > edta) {
2747 G4double
ran = G4UniformRand();
2751 backwardKinetic += kinetic;
2752 if (backwardKinetic > edta)
2753 kinetic = edta - (backwardKinetic - kinetic);
2755 kinetic = kineticMinimum;
2756 G4double cost = 2.0 * G4UniformRand() - 1.0;
2758 G4double phi = twopi * G4UniformRand();
2759 ran = G4UniformRand();
2761 p2->SetDefinition(aDeuteron);
2762 else if (
ran <= 0.90)
2763 p2->SetDefinition(aTriton);
2765 p2->SetDefinition(anAlpha);
2766 spall +=
p2->GetMass() / GeV * sp1;
2767 if (spall > atomicWeight) {
2771 vec.SetElement(vecLen,
p2);
2772 vec[vecLen]->SetNewlyAdded(
true);
2773 vec[vecLen]->SetKineticEnergy(kinetic * GeV);
2775 pp = vec[vecLen]->GetTotalMomentum() / MeV;
2776 vec[vecLen++]->SetMomentum(pp * sint *
std::sin(phi) * MeV, pp * sint *
std::cos(phi) * MeV, pp * cost * MeV);
2784 G4ReactionProduct ¤tParticle,
2785 G4ReactionProduct &targetParticle,
2786 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> &vec,
2788 const G4double pOriginal = modifiedOriginal.GetTotalMomentum() / MeV;
2789 G4double testMomentum = currentParticle.GetMomentum().mag() / MeV;
2791 if (testMomentum >= pOriginal) {
2792 pMass = currentParticle.GetMass() / MeV;
2793 currentParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
2794 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pOriginal / testMomentum));
2796 testMomentum = targetParticle.GetMomentum().mag() / MeV;
2797 if (testMomentum >= pOriginal) {
2798 pMass = targetParticle.GetMass() / MeV;
2799 targetParticle.SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
2800 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pOriginal / testMomentum));
2802 for (G4int
i = 0;
i < vecLen; ++
i) {
2803 testMomentum = vec[
i]->GetMomentum().mag() / MeV;
2804 if (testMomentum >= pOriginal) {
2805 pMass = vec[
i]->GetMass() / MeV;
2806 vec[
i]->SetTotalEnergy(
std::sqrt(pMass * pMass + pOriginal * pOriginal) * MeV);
2807 vec[
i]->SetMomentum(vec[
i]->GetMomentum() * (pOriginal / testMomentum));
2814 const G4ReactionProduct &modifiedOriginal,
2815 const G4DynamicParticle *originalTarget,
2816 G4ReactionProduct ¤tParticle,
2817 G4ReactionProduct &targetParticle,
2818 G4bool &incidentHasChanged,
2819 G4bool &targetHasChanged) {
2834 if (currentParticle.GetMass() == 0.0 || targetParticle.GetMass() == 0.0)
2837 const G4double etOriginal = modifiedOriginal.GetTotalEnergy() / GeV;
2838 const G4double mOriginal = modifiedOriginal.GetDefinition()->GetPDGMass() / GeV;
2839 G4double targetMass = originalTarget->GetDefinition()->GetPDGMass() / GeV;
2840 G4double centerofmassEnergy =
2841 std::sqrt(mOriginal * mOriginal + targetMass * targetMass + 2.0 * targetMass * etOriginal);
2842 G4double currentMass = currentParticle.GetMass() / GeV;
2843 G4double availableEnergy = centerofmassEnergy - (targetMass + currentMass);
2844 if (availableEnergy <= 1.0)
2847 G4ParticleDefinition *aProton = G4Proton::Proton();
2848 G4ParticleDefinition *anAntiProton = G4AntiProton::AntiProton();
2849 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
2850 G4ParticleDefinition *anAntiNeutron = G4AntiNeutron::AntiNeutron();
2851 G4ParticleDefinition *aSigmaMinus = G4SigmaMinus::SigmaMinus();
2852 G4ParticleDefinition *aSigmaPlus = G4SigmaPlus::SigmaPlus();
2854 G4ParticleDefinition *anAntiSigmaMinus = G4AntiSigmaMinus::AntiSigmaMinus();
2855 G4ParticleDefinition *anAntiSigmaPlus = G4AntiSigmaPlus::AntiSigmaPlus();
2856 G4ParticleDefinition *anAntiSigmaZero = G4AntiSigmaZero::AntiSigmaZero();
2857 G4ParticleDefinition *aKaonMinus = G4KaonMinus::KaonMinus();
2858 G4ParticleDefinition *aKaonPlus = G4KaonPlus::KaonPlus();
2859 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();
2860 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();
2862 G4ParticleDefinition *anAntiLambda = G4AntiLambda::AntiLambda();
2864 const G4double protonMass = aProton->GetPDGMass() / GeV;
2865 const G4double sigmaMinusMass = aSigmaMinus->GetPDGMass() / GeV;
2869 const G4double avrs[] = {3., 4., 5., 6., 7., 8., 9., 10., 20., 30., 40., 50.};
2872 G4double avk, avy, avn,
ran;
2874 while ((
i < 12) && (centerofmassEnergy > avrs[
i]))
2890 G4double
ran = G4UniformRand();
2892 ran = G4UniformRand();
2893 i4 =
i3 = G4int(vecLen *
ran);
2895 ran = G4UniformRand();
2897 ran = G4UniformRand();
2898 i4 = G4int(vecLen *
ran);
2904 const G4double avkkb[] = {0.0015, 0.005, 0.012, 0.0285, 0.0525, 0.075, 0.0975, 0.123, 0.28, 0.398, 0.495, 0.573};
2905 const G4double avky[] = {0.005, 0.03, 0.064, 0.095, 0.115, 0.13, 0.145, 0.155, 0.20, 0.205, 0.210, 0.212};
2906 const G4double avnnb[] = {0.00001, 0.0001, 0.0006, 0.0025, 0.01, 0.02, 0.04, 0.05, 0.12, 0.15, 0.18, 0.20};
2908 avk = (
std::log(avkkb[ibin]) -
std::log(avkkb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
2909 (avrs[ibin] - avrs[ibin - 1]) +
2913 avy = (
std::log(avky[ibin]) -
std::log(avky[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
2914 (avrs[ibin] - avrs[ibin - 1]) +
2918 avn = (
std::log(avnnb[ibin]) -
std::log(avnnb[ibin - 1])) * (centerofmassEnergy - avrs[ibin - 1]) /
2919 (avrs[ibin] - avrs[ibin - 1]) +
2923 if (avk + avy + avn <= 0.0)
2926 if (currentMass < protonMass)
2928 if (targetMass < protonMass)
2932 ran = G4UniformRand();
2934 if (availableEnergy < 2.0)
2938 G4ReactionProduct *
p1 =
new G4ReactionProduct;
2939 if (G4UniformRand() < 0.5) {
2940 vec[0]->SetDefinition(aNeutron);
2941 p1->SetDefinition(anAntiNeutron);
2942 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
2943 vec[0]->SetMayBeKilled(
false);
2944 p1->SetMayBeKilled(
false);
2946 vec[0]->SetDefinition(aProton);
2947 p1->SetDefinition(anAntiProton);
2948 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
2949 vec[0]->SetMayBeKilled(
false);
2950 p1->SetMayBeKilled(
false);
2952 vec.SetElement(vecLen++,
p1);
2955 if (G4UniformRand() < 0.5) {
2956 vec[
i3]->SetDefinition(aNeutron);
2957 vec[i4]->SetDefinition(anAntiNeutron);
2958 vec[
i3]->SetMayBeKilled(
false);
2959 vec[i4]->SetMayBeKilled(
false);
2961 vec[
i3]->SetDefinition(aProton);
2962 vec[i4]->SetDefinition(anAntiProton);
2963 vec[
i3]->SetMayBeKilled(
false);
2964 vec[i4]->SetMayBeKilled(
false);
2967 }
else if (
ran < avk) {
2968 if (availableEnergy < 1.0)
2971 const G4double kkb[] = {0.2500, 0.3750, 0.5000, 0.5625, 0.6250, 0.6875, 0.7500, 0.8750, 1.000};
2972 const G4int ipakkb1[] = {10, 10, 10, 11, 11, 12, 12, 11, 12};
2973 const G4int ipakkb2[] = {13, 11, 12, 11, 12, 11, 12, 13, 13};
2974 ran = G4UniformRand();
2976 while ((
i < 9) && (
ran >= kkb[
i]))
2984 switch (ipakkb1[
i]) {
2986 vec[
i3]->SetDefinition(aKaonPlus);
2987 vec[
i3]->SetMayBeKilled(
false);
2990 vec[
i3]->SetDefinition(aKaonZS);
2991 vec[
i3]->SetMayBeKilled(
false);
2994 vec[
i3]->SetDefinition(aKaonZL);
2995 vec[
i3]->SetMayBeKilled(
false);
3000 G4ReactionProduct *
p1 =
new G4ReactionProduct;
3001 switch (ipakkb2[
i]) {
3003 p1->SetDefinition(aKaonZS);
3004 p1->SetMayBeKilled(
false);
3007 p1->SetDefinition(aKaonZL);
3008 p1->SetMayBeKilled(
false);
3011 p1->SetDefinition(aKaonMinus);
3012 p1->SetMayBeKilled(
false);
3015 (G4UniformRand() < 0.5) ?
p1->SetSide(-1) :
p1->SetSide(1);
3016 vec.SetElement(vecLen++,
p1);
3020 switch (ipakkb2[
i]) {
3022 vec[i4]->SetDefinition(aKaonZS);
3023 vec[i4]->SetMayBeKilled(
false);
3026 vec[i4]->SetDefinition(aKaonZL);
3027 vec[i4]->SetMayBeKilled(
false);
3030 vec[i4]->SetDefinition(aKaonMinus);
3031 vec[i4]->SetMayBeKilled(
false);
3035 }
else if (
ran < avy) {
3036 if (availableEnergy < 1.6)
3039 const G4double ky[] = {0.200, 0.300, 0.400, 0.550, 0.625, 0.700, 0.800, 0.850, 0.900, 0.950, 0.975, 1.000};
3040 const G4int ipaky1[] = {18, 18, 18, 20, 20, 20, 21, 21, 21, 22, 22, 22};
3041 const G4int ipaky2[] = {10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12};
3042 const G4int ipakyb1[] = {19, 19, 19, 23, 23, 23, 24, 24, 24, 25, 25, 25};
3043 const G4int ipakyb2[] = {13, 12, 11, 13, 12, 11, 13, 12, 11, 13, 12, 11};
3044 ran = G4UniformRand();
3046 while ((
i < 12) && (
ran > ky[
i]))
3050 if ((currentMass < protonMass) || (G4UniformRand() < 0.5)) {
3051 switch (ipaky1[
i]) {
3053 targetParticle.SetDefinition(aLambda);
3056 targetParticle.SetDefinition(aSigmaPlus);
3059 targetParticle.SetDefinition(aSigmaZero);
3062 targetParticle.SetDefinition(aSigmaMinus);
3065 targetHasChanged =
true;
3066 switch (ipaky2[
i]) {
3068 vec[
i3]->SetDefinition(aKaonPlus);
3069 vec[
i3]->SetMayBeKilled(
false);
3072 vec[
i3]->SetDefinition(aKaonZS);
3073 vec[
i3]->SetMayBeKilled(
false);
3076 vec[
i3]->SetDefinition(aKaonZL);
3077 vec[
i3]->SetMayBeKilled(
false);
3082 if ((currentParticle.GetDefinition() == anAntiProton) || (currentParticle.GetDefinition() == anAntiNeutron) ||
3083 (currentParticle.GetDefinition() == anAntiLambda) || (currentMass > sigmaMinusMass)) {
3084 switch (ipakyb1[
i]) {
3086 currentParticle.SetDefinitionAndUpdateE(anAntiLambda);
3089 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaPlus);
3092 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaZero);
3095 currentParticle.SetDefinitionAndUpdateE(anAntiSigmaMinus);
3098 incidentHasChanged =
true;
3099 switch (ipakyb2[
i]) {
3101 vec[
i3]->SetDefinition(aKaonZS);
3102 vec[
i3]->SetMayBeKilled(
false);
3105 vec[
i3]->SetDefinition(aKaonZL);
3106 vec[
i3]->SetMayBeKilled(
false);
3109 vec[
i3]->SetDefinition(aKaonMinus);
3110 vec[
i3]->SetMayBeKilled(
false);
3114 switch (ipaky1[
i]) {
3116 currentParticle.SetDefinitionAndUpdateE(aLambda);
3119 currentParticle.SetDefinitionAndUpdateE(aSigmaPlus);
3122 currentParticle.SetDefinitionAndUpdateE(aSigmaZero);
3125 currentParticle.SetDefinitionAndUpdateE(aSigmaMinus);
3128 incidentHasChanged =
true;
3129 switch (ipaky2[
i]) {
3131 vec[
i3]->SetDefinition(aKaonPlus);
3132 vec[
i3]->SetMayBeKilled(
false);
3135 vec[
i3]->SetDefinition(aKaonZS);
3136 vec[
i3]->SetMayBeKilled(
false);
3139 vec[
i3]->SetDefinition(aKaonZL);
3140 vec[
i3]->SetMayBeKilled(
false);
3156 currentMass = currentParticle.GetMass() / GeV;
3157 targetMass = targetParticle.GetMass() / GeV;
3159 G4double energyCheck = centerofmassEnergy - (currentMass + targetMass);
3160 for (
i = 0;
i < vecLen; ++
i) {
3161 energyCheck -= vec[
i]->GetMass() / GeV;
3162 if (energyCheck < 0.0)
3166 for (
j =
i;
j < vecLen;
j++)
3176 const G4HadProjectile *originalIncident,
3177 const G4Nucleus &targetNucleus,
3178 const G4double theAtomicMass,
3179 const G4double *
mass) {
3184 G4ParticleDefinition *aGamma = G4Gamma::Gamma();
3185 G4ParticleDefinition *aProton = G4Proton::Proton();
3186 G4ParticleDefinition *aNeutron = G4Neutron::Neutron();
3187 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron();
3188 G4ParticleDefinition *aTriton = G4Triton::Triton();
3191 const G4double aProtonMass = aProton->GetPDGMass() / MeV;
3192 const G4double aNeutronMass = aNeutron->GetPDGMass() / MeV;
3193 const G4double aDeuteronMass = aDeuteron->GetPDGMass() / MeV;
3194 const G4double aTritonMass = aTriton->GetPDGMass() / MeV;
3195 const G4double anAlphaMass = anAlpha->GetPDGMass() / MeV;
3197 G4ReactionProduct currentParticle;
3198 currentParticle = *originalIncident;
3204 G4double
p = currentParticle.GetTotalMomentum();
3205 G4double pp = currentParticle.GetMomentum().mag();
3206 if (pp <= 0.001 * MeV) {
3207 G4double phinve = twopi * G4UniformRand();
3208 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3209 currentParticle.SetMomentum(
3212 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
p / pp));
3216 G4double currentKinetic = currentParticle.GetKineticEnergy() / MeV;
3217 G4double currentMass = currentParticle.GetDefinition()->GetPDGMass() / MeV;
3218 G4double qv = currentKinetic + theAtomicMass + currentMass;
3221 qval[0] = qv -
mass[0];
3222 qval[1] = qv -
mass[1] - aNeutronMass;
3223 qval[2] = qv -
mass[2] - aProtonMass;
3224 qval[3] = qv -
mass[3] - aDeuteronMass;
3225 qval[4] = qv -
mass[4] - aTritonMass;
3226 qval[5] = qv -
mass[5] - anAlphaMass;
3227 qval[6] = qv -
mass[6] - aNeutronMass - aNeutronMass;
3228 qval[7] = qv -
mass[7] - aNeutronMass - aProtonMass;
3229 qval[8] = qv -
mass[8] - aProtonMass - aProtonMass;
3231 if (currentParticle.GetDefinition() == aNeutron) {
3232 const G4double
A = targetNucleus.GetN_asInt();
3233 if (G4UniformRand() > ((
A - 1.0) / 230.0) * ((
A - 1.0) / 230.0))
3235 if (G4UniformRand() >= currentKinetic / 7.9254 *
A)
3236 qval[2] = qval[3] = qval[4] = qval[5] = qval[8] = 0.0;
3242 for (
i = 0;
i < 9; ++
i) {
3243 if (
mass[
i] < 500.0 * MeV)
3250 G4double
ran = G4UniformRand();
3253 if (qval[
index] > 0.0) {
3254 qv1 += qval[
index] / qv;
3261 throw G4HadronicException(
3264 "FullModelReactionDynamics::NuclearReaction: inelastic reaction kinematically not possible");
3266 G4double ke = currentParticle.GetKineticEnergy() / GeV;
3268 if ((
index >= 6) || (G4UniformRand() <
std::min(0.5, ke * 10.0)))
3271 G4ReactionProduct **
v =
new G4ReactionProduct *[3];
3272 v[0] =
new G4ReactionProduct;
3273 v[1] =
new G4ReactionProduct;
3274 v[2] =
new G4ReactionProduct;
3279 v[1]->SetDefinition(aGamma);
3280 v[2]->SetDefinition(aGamma);
3283 v[1]->SetDefinition(aNeutron);
3284 v[2]->SetDefinition(aGamma);
3287 v[1]->SetDefinition(aProton);
3288 v[2]->SetDefinition(aGamma);
3291 v[1]->SetDefinition(aDeuteron);
3292 v[2]->SetDefinition(aGamma);
3295 v[1]->SetDefinition(aTriton);
3296 v[2]->SetDefinition(aGamma);
3299 v[1]->SetDefinition(anAlpha);
3300 v[2]->SetDefinition(aGamma);
3303 v[1]->SetDefinition(aNeutron);
3304 v[2]->SetDefinition(aNeutron);
3307 v[1]->SetDefinition(aNeutron);
3308 v[2]->SetDefinition(aProton);
3311 v[1]->SetDefinition(aProton);
3312 v[2]->SetDefinition(aProton);
3318 G4ReactionProduct pseudo1;
3319 pseudo1.SetMass(theAtomicMass * MeV);
3320 pseudo1.SetTotalEnergy(theAtomicMass * MeV);
3321 G4ReactionProduct pseudo2 = currentParticle + pseudo1;
3322 pseudo2.SetMomentum(pseudo2.GetMomentum() * (-1.0));
3326 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> tempV;
3327 tempV.Initialize(
nt);
3329 tempV.SetElement(tempLen++,
v[0]);
3330 tempV.SetElement(tempLen++,
v[1]);
3332 tempV.SetElement(tempLen++,
v[2]);
3333 G4bool constantCrossSection =
true;
3334 GenerateNBodyEvent(pseudo2.GetMass() / MeV, constantCrossSection, tempV, tempLen);
3335 v[0]->Lorentz(*
v[0], pseudo2);
3336 v[1]->Lorentz(*
v[1], pseudo2);
3338 v[2]->Lorentz(*
v[2], pseudo2);
3340 G4bool particleIsDefined =
false;
3341 if (
v[0]->GetMass() / MeV - aProtonMass < 0.1) {
3342 v[0]->SetDefinition(aProton);
3343 particleIsDefined =
true;
3344 }
else if (
v[0]->GetMass() / MeV - aNeutronMass < 0.1) {
3345 v[0]->SetDefinition(aNeutron);
3346 particleIsDefined =
true;
3347 }
else if (
v[0]->GetMass() / MeV - aDeuteronMass < 0.1) {
3348 v[0]->SetDefinition(aDeuteron);
3349 particleIsDefined =
true;
3350 }
else if (
v[0]->GetMass() / MeV - aTritonMass < 0.1) {
3351 v[0]->SetDefinition(aTriton);
3352 particleIsDefined =
true;
3353 }
else if (
v[0]->GetMass() / MeV - anAlphaMass < 0.1) {
3354 v[0]->SetDefinition(anAlpha);
3355 particleIsDefined =
true;
3357 currentParticle.SetKineticEnergy(
std::max(0.001, currentParticle.GetKineticEnergy() / MeV));
3358 p = currentParticle.GetTotalMomentum();
3359 pp = currentParticle.GetMomentum().mag();
3360 if (pp <= 0.001 * MeV) {
3361 G4double phinve = twopi * G4UniformRand();
3362 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3363 currentParticle.SetMomentum(
3366 currentParticle.SetMomentum(currentParticle.GetMomentum() * (
p / pp));
3368 if (particleIsDefined) {
3369 v[0]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[0]->GetKineticEnergy() / MeV));
3370 p =
v[0]->GetTotalMomentum();
3371 pp =
v[0]->GetMomentum().mag();
3372 if (pp <= 0.001 * MeV) {
3373 G4double phinve = twopi * G4UniformRand();
3374 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3378 v[0]->SetMomentum(
v[0]->GetMomentum() * (
p / pp));
3380 if ((
v[1]->GetDefinition() == aDeuteron) || (
v[1]->GetDefinition() == aTriton) || (
v[1]->GetDefinition() == anAlpha))
3381 v[1]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[1]->GetKineticEnergy() / MeV));
3383 v[1]->SetKineticEnergy(
std::max(0.001,
v[1]->GetKineticEnergy() / MeV));
3385 p =
v[1]->GetTotalMomentum();
3386 pp =
v[1]->GetMomentum().mag();
3387 if (pp <= 0.001 * MeV) {
3388 G4double phinve = twopi * G4UniformRand();
3389 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3393 v[1]->SetMomentum(
v[1]->GetMomentum() * (
p / pp));
3396 if ((
v[2]->GetDefinition() == aDeuteron) || (
v[2]->GetDefinition() == aTriton) ||
3397 (
v[2]->GetDefinition() == anAlpha))
3398 v[2]->SetKineticEnergy(
std::max(0.001, 0.5 * G4UniformRand() *
v[2]->GetKineticEnergy() / MeV));
3400 v[2]->SetKineticEnergy(
std::max(0.001,
v[2]->GetKineticEnergy() / MeV));
3402 p =
v[2]->GetTotalMomentum();
3403 pp =
v[2]->GetMomentum().mag();
3404 if (pp <= 0.001 * MeV) {
3405 G4double phinve = twopi * G4UniformRand();
3406 G4double rthnve = std::acos(
std::max(-1.0,
std::min(1.0, -1.0 + 2.0 * G4UniformRand())));
3410 v[2]->SetMomentum(
v[2]->GetMomentum() * (
p / pp));
3413 for (del = 0; del < vecLen; del++)
3416 if (particleIsDefined) {
3417 vec.SetElement(vecLen++,
v[0]);
3421 vec.SetElement(vecLen++,
v[1]);
3423 vec.SetElement(vecLen++,
v[2]);
void Defs1(const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
static const char * normal
void MomentumCheck(const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
void TwoBody(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, G4ReactionProduct &modifiedOriginal, const G4DynamicParticle *originalTarget, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &targetHasChanged)
Sin< T >::type sin(const T &t)
Cos< T >::type cos(const T &t)
void ProduceStrangeParticlePairs(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4ReactionProduct &modifiedOriginal, const G4DynamicParticle *originalTarget, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4bool &incidentHasChanged, G4bool &targetHasChanged)
Abs< T >::type abs(const T &t)
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)
void NuclearReaction(G4FastVector< G4ReactionProduct, 4 > &vec, G4int &vecLen, const G4HadProjectile *originalIncident, const G4Nucleus &aNucleus, const G4double theAtomicMass, const G4double *massVec)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
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 AddBlackTrackParticles(const G4double epnb, const G4int npnb, const G4double edta, const G4int ndta, const G4double sprob, const G4double kineticMinimum, const G4double kineticFactor, const G4ReactionProduct &modifiedOriginal, G4double spall, const G4Nucleus &aNucleus, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
void Rotate(const G4double numberofFinalStateNucleons, const G4ThreeVector &temp, const G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, const G4Nucleus &targetNucleus, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen)
ALPAKA_FN_ACC int sm(int ieta, int iphi)
Square< F >::type sqr(const F &f)
void SuppressChargedPions(G4FastVector< G4ReactionProduct, MYGHADLISTSIZE > &vec, G4int &vecLen, const G4ReactionProduct &modifiedOriginal, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, const G4Nucleus &targetNucleus, G4bool &incidentHasChanged, G4bool &targetHasChanged)
Power< A, B >::type pow(const A &a, const B &b)
static constexpr float b1
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)